OSDN Git Service

Merge 4.4.160 into android-4.4-p
[sagit-ice-cold/kernel_xiaomi_msm8998.git] / fs / proc / base.c
index 4beed30..d780651 100644 (file)
@@ -87,6 +87,7 @@
 #include <linux/slab.h>
 #include <linux/flex_array.h>
 #include <linux/posix-timers.h>
+#include <linux/cpufreq_times.h>
 #ifdef CONFIG_HARDWALL
 #include <asm/hardwall.h>
 #endif
@@ -2288,6 +2289,92 @@ static const struct file_operations proc_timers_operations = {
        .release        = seq_release_private,
 };
 
+static ssize_t timerslack_ns_write(struct file *file, const char __user *buf,
+                                       size_t count, loff_t *offset)
+{
+       struct inode *inode = file_inode(file);
+       struct task_struct *p;
+       u64 slack_ns;
+       int err;
+
+       err = kstrtoull_from_user(buf, count, 10, &slack_ns);
+       if (err < 0)
+               return err;
+
+       p = get_proc_task(inode);
+       if (!p)
+               return -ESRCH;
+
+       if (p != current) {
+               if (!capable(CAP_SYS_NICE)) {
+                       count = -EPERM;
+                       goto out;
+               }
+
+               err = security_task_setscheduler(p);
+               if (err) {
+                       count = err;
+                       goto out;
+               }
+       }
+
+       task_lock(p);
+       if (slack_ns == 0)
+               p->timer_slack_ns = p->default_timer_slack_ns;
+       else
+               p->timer_slack_ns = slack_ns;
+       task_unlock(p);
+
+out:
+       put_task_struct(p);
+
+       return count;
+}
+
+static int timerslack_ns_show(struct seq_file *m, void *v)
+{
+       struct inode *inode = m->private;
+       struct task_struct *p;
+       int err = 0;
+
+       p = get_proc_task(inode);
+       if (!p)
+               return -ESRCH;
+
+       if (p != current) {
+
+               if (!capable(CAP_SYS_NICE)) {
+                       err = -EPERM;
+                       goto out;
+               }
+               err = security_task_getscheduler(p);
+               if (err)
+                       goto out;
+       }
+
+       task_lock(p);
+       seq_printf(m, "%llu\n", p->timer_slack_ns);
+       task_unlock(p);
+
+out:
+       put_task_struct(p);
+
+       return err;
+}
+
+static int timerslack_ns_open(struct inode *inode, struct file *filp)
+{
+       return single_open(filp, timerslack_ns_show, inode);
+}
+
+static const struct file_operations proc_pid_set_timerslack_ns_operations = {
+       .open           = timerslack_ns_open,
+       .read           = seq_read,
+       .write          = timerslack_ns_write,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+};
+
 static int proc_pident_instantiate(struct inode *dir,
        struct dentry *dentry, struct task_struct *task, const void *ptr)
 {
@@ -2865,6 +2952,10 @@ static const struct pid_entry tgid_base_stuff[] = {
 #ifdef CONFIG_CHECKPOINT_RESTORE
        REG("timers",     S_IRUGO, proc_timers_operations),
 #endif
+       REG("timerslack_ns", S_IRUGO|S_IWUGO, proc_pid_set_timerslack_ns_operations),
+#ifdef CONFIG_CPU_FREQ_TIMES
+       ONE("time_in_state", 0444, proc_time_in_state_show),
+#endif
 };
 
 static int proc_tgid_base_readdir(struct file *file, struct dir_context *ctx)
@@ -3249,6 +3340,9 @@ static const struct pid_entry tid_base_stuff[] = {
        REG("projid_map", S_IRUGO|S_IWUSR, proc_projid_map_operations),
        REG("setgroups",  S_IRUGO|S_IWUSR, proc_setgroups_operations),
 #endif
+#ifdef CONFIG_CPU_FREQ_TIMES
+       ONE("time_in_state", 0444, proc_time_in_state_show),
+#endif
 };
 
 static int proc_tid_base_readdir(struct file *file, struct dir_context *ctx)