On Mon, Sep 03, 2018 at 04:28:01PM +0200, Juri Lelli wrote: > +/* > + * Called with cpuset_mutex held (rebuild_sched_domains()) > + * Called with hotplug lock held (rebuild_sched_domains_locked()) > + * Called with sched_domains_mutex held (partition_and_rebuild_domains()) Isn't that what we have lockdep_assert_held() for? > + */ > +static void rebuild_root_domains(void) > +{ > + struct cpuset *cs = NULL; > + struct cgroup_subsys_state *pos_css; > + > + rcu_read_lock(); > + > + /* > + * Clear default root domain DL accounting, it will be computed again > + * if a task belongs to it. > + */ > + dl_clear_root_domain(&def_root_domain); > + > + cpuset_for_each_descendant_pre(cs, pos_css, &top_cpuset) { > + > + if (cpumask_empty(cs->effective_cpus)) { > + pos_css = css_rightmost_descendant(pos_css); > + continue; > + } > + > + css_get(&cs->css); > + > + rcu_read_unlock(); That looks really dodgy, but I suppose the comment near css_next_descendant_pre() spells out that this is in fact OK. > + update_tasks_root_domain(cs); > + > + rcu_read_lock(); > + css_put(&cs->css); > + } > + rcu_read_unlock(); > +}