prctl: adds PR_SET_TIMERSLACK_PID for setting timer slack of an arbitrary thread.
authorRuchi Kandoi <kandoiruchi@google.com>
Fri, 18 Apr 2014 21:07:28 +0000 (14:07 -0700)
committerJohn Stultz <john.stultz@linaro.org>
Tue, 16 Feb 2016 21:53:47 +0000 (13:53 -0800)
Second argument is similar to PR_SET_TIMERSLACK, if non-zero then the
slack is set to that value otherwise sets it to the default for the thread.

Takes PID of the thread as the third argument.

This allows power/performance management software to set timer slack for
other threads according to its policy for the thread (such as when the
thread is designated foreground vs. background activity)

Change-Id: I744d451ff4e60dae69f38f53948ff36c51c14a3f
Signed-off-by: Ruchi Kandoi <kandoiruchi@google.com>
include/uapi/linux/prctl.h
kernel/sys.c

index a8d0759a9e400c5d472fe37d13a924bc9e9777a6..eea2fc75a98f6d6f01426915608ef2b98f98948a 100644 (file)
@@ -197,4 +197,10 @@ struct prctl_mm_map {
 # define PR_CAP_AMBIENT_LOWER          3
 # define PR_CAP_AMBIENT_CLEAR_ALL      4
 
+/* Sets the timerslack for arbitrary threads
+ * arg2 slack value, 0 means "use default"
+ * arg3 pid of the thread whose timer slack needs to be set
+ */
+#define PR_SET_TIMERSLACK_PID 47
+
 #endif /* _LINUX_PRCTL_H */
index 6af9212ab5aab7cef491eb4e40e7c9277c1f2ac0..fd06809929129465f96e38aa47a5d84a0bcad490 100644 (file)
@@ -2076,6 +2076,7 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3,
                unsigned long, arg4, unsigned long, arg5)
 {
        struct task_struct *me = current;
+       struct task_struct *tsk;
        unsigned char comm[sizeof(me->comm)];
        long error;
 
@@ -2199,6 +2200,23 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3,
                        else
                                return -EINVAL;
                        break;
+               case PR_SET_TIMERSLACK_PID:
+                       rcu_read_lock();
+                       tsk = find_task_by_pid_ns((pid_t)arg3, &init_pid_ns);
+                       if (tsk == NULL) {
+                               rcu_read_unlock();
+                               return -EINVAL;
+                       }
+                       get_task_struct(tsk);
+                       rcu_read_unlock();
+                       if (arg2 <= 0)
+                               tsk->timer_slack_ns =
+                                       tsk->default_timer_slack_ns;
+                       else
+                               tsk->timer_slack_ns = arg2;
+                       put_task_struct(tsk);
+                       error = 0;
+                       break;
                default:
                        return -EINVAL;
                }