]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
cgroup: avoid the unnecessary list_add(dying_tasks) in cgroup_exit()
authorOleg Nesterov <oleg@redhat.com>
Mon, 17 Jun 2024 14:31:52 +0000 (16:31 +0200)
committerTejun Heo <tj@kernel.org>
Wed, 19 Jun 2024 17:18:41 +0000 (07:18 -1000)
cgroup_exit() needs to do this only if the exiting task is a leader and it
is not the last live thread.  The patch doesn't use delay_group_leader(),
atomic_read(signal->live) matches the code css_task_iter_advance() more.

cgroup_release() can now check list_empty(task->cg_list) before it takes
css_set_lock and calls ss_set_skip_task_iters().

Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
kernel/cgroup/cgroup.c

index 4abd817b0c7cde1cfb822f21cf508f3621f52856..ff3c14fa62e6bbf0239f0ae39939844006e29980 100644 (file)
@@ -6701,8 +6701,10 @@ void cgroup_exit(struct task_struct *tsk)
        WARN_ON_ONCE(list_empty(&tsk->cg_list));
        cset = task_css_set(tsk);
        css_set_move_task(tsk, cset, NULL, false);
-       list_add_tail(&tsk->cg_list, &cset->dying_tasks);
        cset->nr_tasks--;
+       /* matches the signal->live check in css_task_iter_advance() */
+       if (thread_group_leader(tsk) && atomic_read(&tsk->signal->live))
+               list_add_tail(&tsk->cg_list, &cset->dying_tasks);
 
        if (dl_task(tsk))
                dec_dl_tasks_cs(tsk);
@@ -6729,10 +6731,12 @@ void cgroup_release(struct task_struct *task)
                ss->release(task);
        } while_each_subsys_mask();
 
-       spin_lock_irq(&css_set_lock);
-       css_set_skip_task_iters(task_css_set(task), task);
-       list_del_init(&task->cg_list);
-       spin_unlock_irq(&css_set_lock);
+       if (!list_empty(&task->cg_list)) {
+               spin_lock_irq(&css_set_lock);
+               css_set_skip_task_iters(task_css_set(task), task);
+               list_del_init(&task->cg_list);
+               spin_unlock_irq(&css_set_lock);
+       }
 }
 
 void cgroup_free(struct task_struct *task)