aboutsummaryrefslogtreecommitdiffstats
path: root/fs/proc/base.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/proc/base.c')
-rw-r--r--fs/proc/base.c71
1 files changed, 70 insertions, 1 deletions
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 4f764c2ac1a5..b1755b23893e 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -434,7 +434,7 @@ static int proc_pid_wchan(struct seq_file *m, struct pid_namespace *ns,
434 && !lookup_symbol_name(wchan, symname)) 434 && !lookup_symbol_name(wchan, symname))
435 seq_printf(m, "%s", symname); 435 seq_printf(m, "%s", symname);
436 else 436 else
437 seq_putc(m, '0'); 437 seq_puts(m, "0\n");
438 438
439 return 0; 439 return 0;
440} 440}
@@ -2158,6 +2158,7 @@ static const struct file_operations proc_map_files_operations = {
2158 .llseek = default_llseek, 2158 .llseek = default_llseek,
2159}; 2159};
2160 2160
2161#ifdef CONFIG_CHECKPOINT_RESTORE
2161struct timers_private { 2162struct timers_private {
2162 struct pid *pid; 2163 struct pid *pid;
2163 struct task_struct *task; 2164 struct task_struct *task;
@@ -2256,6 +2257,73 @@ static const struct file_operations proc_timers_operations = {
2256 .llseek = seq_lseek, 2257 .llseek = seq_lseek,
2257 .release = seq_release_private, 2258 .release = seq_release_private,
2258}; 2259};
2260#endif
2261
2262static ssize_t timerslack_ns_write(struct file *file, const char __user *buf,
2263 size_t count, loff_t *offset)
2264{
2265 struct inode *inode = file_inode(file);
2266 struct task_struct *p;
2267 u64 slack_ns;
2268 int err;
2269
2270 err = kstrtoull_from_user(buf, count, 10, &slack_ns);
2271 if (err < 0)
2272 return err;
2273
2274 p = get_proc_task(inode);
2275 if (!p)
2276 return -ESRCH;
2277
2278 if (ptrace_may_access(p, PTRACE_MODE_ATTACH_FSCREDS)) {
2279 task_lock(p);
2280 if (slack_ns == 0)
2281 p->timer_slack_ns = p->default_timer_slack_ns;
2282 else
2283 p->timer_slack_ns = slack_ns;
2284 task_unlock(p);
2285 } else
2286 count = -EPERM;
2287
2288 put_task_struct(p);
2289
2290 return count;
2291}
2292
2293static int timerslack_ns_show(struct seq_file *m, void *v)
2294{
2295 struct inode *inode = m->private;
2296 struct task_struct *p;
2297 int err = 0;
2298
2299 p = get_proc_task(inode);
2300 if (!p)
2301 return -ESRCH;
2302
2303 if (ptrace_may_access(p, PTRACE_MODE_ATTACH_FSCREDS)) {
2304 task_lock(p);
2305 seq_printf(m, "%llu\n", p->timer_slack_ns);
2306 task_unlock(p);
2307 } else
2308 err = -EPERM;
2309
2310 put_task_struct(p);
2311
2312 return err;
2313}
2314
2315static int timerslack_ns_open(struct inode *inode, struct file *filp)
2316{
2317 return single_open(filp, timerslack_ns_show, inode);
2318}
2319
2320static const struct file_operations proc_pid_set_timerslack_ns_operations = {
2321 .open = timerslack_ns_open,
2322 .read = seq_read,
2323 .write = timerslack_ns_write,
2324 .llseek = seq_lseek,
2325 .release = single_release,
2326};
2259 2327
2260static int proc_pident_instantiate(struct inode *dir, 2328static int proc_pident_instantiate(struct inode *dir,
2261 struct dentry *dentry, struct task_struct *task, const void *ptr) 2329 struct dentry *dentry, struct task_struct *task, const void *ptr)
@@ -2831,6 +2899,7 @@ static const struct pid_entry tgid_base_stuff[] = {
2831#ifdef CONFIG_CHECKPOINT_RESTORE 2899#ifdef CONFIG_CHECKPOINT_RESTORE
2832 REG("timers", S_IRUGO, proc_timers_operations), 2900 REG("timers", S_IRUGO, proc_timers_operations),
2833#endif 2901#endif
2902 REG("timerslack_ns", S_IRUGO|S_IWUGO, proc_pid_set_timerslack_ns_operations),
2834}; 2903};
2835 2904
2836static int proc_tgid_base_readdir(struct file *file, struct dir_context *ctx) 2905static int proc_tgid_base_readdir(struct file *file, struct dir_context *ctx)