This option does not iterate the tasklist and we already have
an rcu aware stable pointer. Also, the nice value is not serialized
by this lock. Reduce the scope of this lock to just PRIO_PGRP
and PRIO_USER - which need to to set the priorities atomically
to the list of tasks, at least vs fork().

Signed-off-by: Davidlohr Bueso <dbu...@suse.de>
---
 kernel/sys.c | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/kernel/sys.c b/kernel/sys.c
index 0b72184f5e3e..f9f87775d6d2 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -214,16 +214,19 @@ SYSCALL_DEFINE3(setpriority, int, which, int, who, int, 
niceval)
                niceval = MAX_NICE;
 
        rcu_read_lock();
-       read_lock(&tasklist_lock);
-       switch (which) {
-       case PRIO_PROCESS:
+
+       if (which == PRIO_PROCESS) {
                if (who)
                        p = find_task_by_vpid(who);
                else
                        p = current;
                if (p)
                        error = set_one_prio(p, niceval, error);
-               break;
+               goto out_rcu;
+       }
+
+       read_lock(&tasklist_lock);
+       switch (which) {
        case PRIO_PGRP:
                if (who)
                        pgrp = find_vpid(who);
@@ -253,6 +256,7 @@ SYSCALL_DEFINE3(setpriority, int, which, int, who, int, 
niceval)
        }
 out_unlock:
        read_unlock(&tasklist_lock);
+out_rcu:
        rcu_read_unlock();
 out:
        return error;
-- 
2.26.1

Reply via email to