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)
committerRuchi Kandoi <kandoiruchi@google.com>
Wed, 23 Apr 2014 00:31:53 +0000 (17:31 -0700)
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 253856a2a8ad07d720087e01a1d5e45c4420a1d9..28bb0b3a08bf99b20b64500ee9ef0a824b4f2707 100644 (file)
 
 #define PR_GET_TID_ADDRESS     40
 
+/* 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 41
+
 #define PR_SET_VMA             0x53564d41
 # define PR_SET_VMA_ANON_NAME          0
 
index 126b7c939d1f76fdb4c6fe60a79f71da873ab307..875529e936abae09b01082555edd9357a6001507 100644 (file)
@@ -44,6 +44,7 @@
 #include <linux/ctype.h>
 #include <linux/mm.h>
 #include <linux/mempolicy.h>
+#include <linux/sched.h>
 
 #include <linux/compat.h>
 #include <linux/syscalls.h>
@@ -2252,6 +2253,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;
 
@@ -2375,6 +2377,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;
                }