cpuset: rcu_read_lock() to protect task_cs()
PATCH 1/1 cpuset: rcu_read_lock() to protect task_cs()
task_cs() calls cgroup_subsys_state().
we must use rcu_read_lock() to protect cgroup_subsys_state().
it's correct that top_cpuset is never freed, but cgroup_subsys_state() accesses css_set, this css_set maybe freed when task_cs() called.
we use use rcu_read_lock() to protect it.
---
kernel/cpuset.c +3 -8
@@ -363,14 +363,9 @@ void cpuset_update_task_memory_state(void)struct task_struct *tsk = current;struct cpuset *cs; -if (task_cs (tsk) == &top_cpuset) { -/* Don't need rcu for top_cpuset. It's never freed. */ - my_cpusets_mem_gen = top_cpuset.mems_generation; - }else { -rcu_read_lock (); - my_cpusets_mem_gen =task_cs (tsk)->mems_generation; -rcu_read_unlock (); - } +rcu_read_lock (); + my_cpusets_mem_gen =task_cs (tsk)->mems_generation; +rcu_read_unlock ();if (my_cpusets_mem_gen != tsk->cpuset_mems_generation) {mutex_lock (&callback_mutex);
A message that is not in the archive (sent off-list or not yet received): [email protected]
Paul Menage
Acked-byQuoted 2 lines · Lai Jiangshan
task_cs()callscgroup_subsys_state().
You mean it calls task_subsys_state().
Quoted 5 lines
we must use
rcu_read_lock()to protectcgroup_subsys_state().it's correct that
top_cpusetis never freed, butcgroup_subsys_state()accessescss_set, thiscss_setmaybe freed whentask_cs()called.
It would be nice to have an RCU debug mode where rcu_dereference() does a WARN() if it's invoked not under rcu_read_lock().
Quoted 14 lines
we use use
rcu_read_lock()to protect it.Signed-off-by Lai Jiangshan <[email protected]>---
kernel/cpuset.c +0
-1@@ -363,14 +363,9 @@ void cpuset_update_task_memory_state(void)struct task_struct *tsk = current;struct cpuset *cs; -if (task_cs (tsk) == &top_cpuset) {
kernel/cpuset.c void cpuset_update_task_memory_state(void) · line 368
Quoted 10 lines
kernel/cpuset.c +3
-7-/* Don't need rcu for top_cpuset. It's never freed. */ - my_cpusets_mem_gen = top_cpuset.mems_generation; - }else { -rcu_read_lock (); - my_cpusets_mem_gen =task_cs (tsk)->mems_generation; -rcu_read_unlock (); - } +rcu_read_lock (); + my_cpusets_mem_gen =task_cs (tsk)->mems_generation; +rcu_read_unlock ();
Yes, I guess this old cpusets assumption is no longer valid in cgroups.
Thanks
Paul
Quoted 2 lines · Lai Jiangshan
task_cs()callscgroup_subsys_state().
You mean it calls task_subsys_state().
Quoted 5 lines
we must use
rcu_read_lock()to protectcgroup_subsys_state().it's correct that
top_cpusetis never freed, butcgroup_subsys_state()accessescss_set, thiscss_setmaybe freed whentask_cs()called.
It would be nice to have an RCU debug mode where rcu_dereference() does a WARN() if it's invoked not under rcu_read_lock().
Quoted 14 lines
we use use
rcu_read_lock()to protect it.Signed-off-by Lai Jiangshan <[email protected]>---
kernel/cpuset.c +0
-1@@ -363,14 +363,9 @@ void cpuset_update_task_memory_state(void)struct task_struct *tsk = current;struct cpuset *cs; -if (task_cs (tsk) == &top_cpuset) {
kernel/cpuset.c void cpuset_update_task_memory_state(void) · line 368
Quoted 10 lines
kernel/cpuset.c +3
-7-/* Don't need rcu for top_cpuset. It's never freed. */ - my_cpusets_mem_gen = top_cpuset.mems_generation; - }else { -rcu_read_lock (); - my_cpusets_mem_gen =task_cs (tsk)->mems_generation; -rcu_read_unlock (); - } +rcu_read_lock (); + my_cpusets_mem_gen =task_cs (tsk)->mems_generation; +rcu_read_unlock ();
Yes, I guess this old cpusets assumption is no longer valid in cgroups.
Thanks
Paul