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.c168
1 files changed, 134 insertions, 34 deletions
diff --git a/fs/proc/base.c b/fs/proc/base.c
index aeaf0d0f2f51..33537487f5ab 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -199,9 +199,29 @@ static int proc_root_link(struct inode *inode, struct dentry **dentry, struct vf
199 (task == current || \ 199 (task == current || \
200 (task->parent == current && \ 200 (task->parent == current && \
201 (task->ptrace & PT_PTRACED) && \ 201 (task->ptrace & PT_PTRACED) && \
202 (task->state == TASK_STOPPED || task->state == TASK_TRACED) && \ 202 (task_is_stopped_or_traced(task)) && \
203 security_ptrace(current,task) == 0)) 203 security_ptrace(current,task) == 0))
204 204
205struct mm_struct *mm_for_maps(struct task_struct *task)
206{
207 struct mm_struct *mm = get_task_mm(task);
208 if (!mm)
209 return NULL;
210 down_read(&mm->mmap_sem);
211 task_lock(task);
212 if (task->mm != mm)
213 goto out;
214 if (task->mm != current->mm && __ptrace_may_attach(task) < 0)
215 goto out;
216 task_unlock(task);
217 return mm;
218out:
219 task_unlock(task);
220 up_read(&mm->mmap_sem);
221 mmput(mm);
222 return NULL;
223}
224
205static int proc_pid_cmdline(struct task_struct *task, char * buffer) 225static int proc_pid_cmdline(struct task_struct *task, char * buffer)
206{ 226{
207 int res = 0; 227 int res = 0;
@@ -290,6 +310,77 @@ static int proc_pid_schedstat(struct task_struct *task, char *buffer)
290} 310}
291#endif 311#endif
292 312
313#ifdef CONFIG_LATENCYTOP
314static int lstats_show_proc(struct seq_file *m, void *v)
315{
316 int i;
317 struct task_struct *task = m->private;
318 seq_puts(m, "Latency Top version : v0.1\n");
319
320 for (i = 0; i < 32; i++) {
321 if (task->latency_record[i].backtrace[0]) {
322 int q;
323 seq_printf(m, "%i %li %li ",
324 task->latency_record[i].count,
325 task->latency_record[i].time,
326 task->latency_record[i].max);
327 for (q = 0; q < LT_BACKTRACEDEPTH; q++) {
328 char sym[KSYM_NAME_LEN];
329 char *c;
330 if (!task->latency_record[i].backtrace[q])
331 break;
332 if (task->latency_record[i].backtrace[q] == ULONG_MAX)
333 break;
334 sprint_symbol(sym, task->latency_record[i].backtrace[q]);
335 c = strchr(sym, '+');
336 if (c)
337 *c = 0;
338 seq_printf(m, "%s ", sym);
339 }
340 seq_printf(m, "\n");
341 }
342
343 }
344 return 0;
345}
346
347static int lstats_open(struct inode *inode, struct file *file)
348{
349 int ret;
350 struct seq_file *m;
351 struct task_struct *task = get_proc_task(inode);
352
353 ret = single_open(file, lstats_show_proc, NULL);
354 if (!ret) {
355 m = file->private_data;
356 m->private = task;
357 }
358 return ret;
359}
360
361static ssize_t lstats_write(struct file *file, const char __user *buf,
362 size_t count, loff_t *offs)
363{
364 struct seq_file *m;
365 struct task_struct *task;
366
367 m = file->private_data;
368 task = m->private;
369 clear_all_latency_tracing(task);
370
371 return count;
372}
373
374static const struct file_operations proc_lstats_operations = {
375 .open = lstats_open,
376 .read = seq_read,
377 .write = lstats_write,
378 .llseek = seq_lseek,
379 .release = single_release,
380};
381
382#endif
383
293/* The badness from the OOM killer */ 384/* The badness from the OOM killer */
294unsigned long badness(struct task_struct *p, unsigned long uptime); 385unsigned long badness(struct task_struct *p, unsigned long uptime);
295static int proc_oom_score(struct task_struct *task, char *buffer) 386static int proc_oom_score(struct task_struct *task, char *buffer)
@@ -893,7 +984,7 @@ static ssize_t proc_loginuid_read(struct file * file, char __user * buf,
893 if (!task) 984 if (!task)
894 return -ESRCH; 985 return -ESRCH;
895 length = scnprintf(tmpbuf, TMPBUFLEN, "%u", 986 length = scnprintf(tmpbuf, TMPBUFLEN, "%u",
896 audit_get_loginuid(task->audit_context)); 987 audit_get_loginuid(task));
897 put_task_struct(task); 988 put_task_struct(task);
898 return simple_read_from_buffer(buf, count, ppos, tmpbuf, length); 989 return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
899} 990}
@@ -1000,6 +1091,7 @@ static const struct file_operations proc_fault_inject_operations = {
1000}; 1091};
1001#endif 1092#endif
1002 1093
1094
1003#ifdef CONFIG_SCHED_DEBUG 1095#ifdef CONFIG_SCHED_DEBUG
1004/* 1096/*
1005 * Print out various scheduling related per-task fields: 1097 * Print out various scheduling related per-task fields:
@@ -2210,6 +2302,9 @@ static const struct pid_entry tgid_base_stuff[] = {
2210#ifdef CONFIG_SCHEDSTATS 2302#ifdef CONFIG_SCHEDSTATS
2211 INF("schedstat", S_IRUGO, pid_schedstat), 2303 INF("schedstat", S_IRUGO, pid_schedstat),
2212#endif 2304#endif
2305#ifdef CONFIG_LATENCYTOP
2306 REG("latency", S_IRUGO, lstats),
2307#endif
2213#ifdef CONFIG_PROC_PID_CPUSET 2308#ifdef CONFIG_PROC_PID_CPUSET
2214 REG("cpuset", S_IRUGO, cpuset), 2309 REG("cpuset", S_IRUGO, cpuset),
2215#endif 2310#endif
@@ -2328,21 +2423,18 @@ out:
2328 2423
2329void proc_flush_task(struct task_struct *task) 2424void proc_flush_task(struct task_struct *task)
2330{ 2425{
2331 int i, leader; 2426 int i;
2332 struct pid *pid, *tgid; 2427 struct pid *pid, *tgid = NULL;
2333 struct upid *upid; 2428 struct upid *upid;
2334 2429
2335 leader = thread_group_leader(task);
2336 proc_flush_task_mnt(proc_mnt, task->pid, leader ? task->tgid : 0);
2337 pid = task_pid(task); 2430 pid = task_pid(task);
2338 if (pid->level == 0) 2431 if (thread_group_leader(task))
2339 return; 2432 tgid = task_tgid(task);
2340 2433
2341 tgid = task_tgid(task); 2434 for (i = 0; i <= pid->level; i++) {
2342 for (i = 1; i <= pid->level; i++) {
2343 upid = &pid->numbers[i]; 2435 upid = &pid->numbers[i];
2344 proc_flush_task_mnt(upid->ns->proc_mnt, upid->nr, 2436 proc_flush_task_mnt(upid->ns->proc_mnt, upid->nr,
2345 leader ? 0 : tgid->numbers[i].nr); 2437 tgid ? tgid->numbers[i].nr : 0);
2346 } 2438 }
2347 2439
2348 upid = &pid->numbers[pid->level]; 2440 upid = &pid->numbers[pid->level];
@@ -2414,19 +2506,23 @@ out:
2414 * Find the first task with tgid >= tgid 2506 * Find the first task with tgid >= tgid
2415 * 2507 *
2416 */ 2508 */
2417static struct task_struct *next_tgid(unsigned int tgid, 2509struct tgid_iter {
2418 struct pid_namespace *ns) 2510 unsigned int tgid;
2419{
2420 struct task_struct *task; 2511 struct task_struct *task;
2512};
2513static struct tgid_iter next_tgid(struct pid_namespace *ns, struct tgid_iter iter)
2514{
2421 struct pid *pid; 2515 struct pid *pid;
2422 2516
2517 if (iter.task)
2518 put_task_struct(iter.task);
2423 rcu_read_lock(); 2519 rcu_read_lock();
2424retry: 2520retry:
2425 task = NULL; 2521 iter.task = NULL;
2426 pid = find_ge_pid(tgid, ns); 2522 pid = find_ge_pid(iter.tgid, ns);
2427 if (pid) { 2523 if (pid) {
2428 tgid = pid_nr_ns(pid, ns) + 1; 2524 iter.tgid = pid_nr_ns(pid, ns);
2429 task = pid_task(pid, PIDTYPE_PID); 2525 iter.task = pid_task(pid, PIDTYPE_PID);
2430 /* What we to know is if the pid we have find is the 2526 /* What we to know is if the pid we have find is the
2431 * pid of a thread_group_leader. Testing for task 2527 * pid of a thread_group_leader. Testing for task
2432 * being a thread_group_leader is the obvious thing 2528 * being a thread_group_leader is the obvious thing
@@ -2439,23 +2535,25 @@ retry:
2439 * found doesn't happen to be a thread group leader. 2535 * found doesn't happen to be a thread group leader.
2440 * As we don't care in the case of readdir. 2536 * As we don't care in the case of readdir.
2441 */ 2537 */
2442 if (!task || !has_group_leader_pid(task)) 2538 if (!iter.task || !has_group_leader_pid(iter.task)) {
2539 iter.tgid += 1;
2443 goto retry; 2540 goto retry;
2444 get_task_struct(task); 2541 }
2542 get_task_struct(iter.task);
2445 } 2543 }
2446 rcu_read_unlock(); 2544 rcu_read_unlock();
2447 return task; 2545 return iter;
2448} 2546}
2449 2547
2450#define TGID_OFFSET (FIRST_PROCESS_ENTRY + ARRAY_SIZE(proc_base_stuff)) 2548#define TGID_OFFSET (FIRST_PROCESS_ENTRY + ARRAY_SIZE(proc_base_stuff))
2451 2549
2452static int proc_pid_fill_cache(struct file *filp, void *dirent, filldir_t filldir, 2550static int proc_pid_fill_cache(struct file *filp, void *dirent, filldir_t filldir,
2453 struct task_struct *task, int tgid) 2551 struct tgid_iter iter)
2454{ 2552{
2455 char name[PROC_NUMBUF]; 2553 char name[PROC_NUMBUF];
2456 int len = snprintf(name, sizeof(name), "%d", tgid); 2554 int len = snprintf(name, sizeof(name), "%d", iter.tgid);
2457 return proc_fill_cache(filp, dirent, filldir, name, len, 2555 return proc_fill_cache(filp, dirent, filldir, name, len,
2458 proc_pid_instantiate, task, NULL); 2556 proc_pid_instantiate, iter.task, NULL);
2459} 2557}
2460 2558
2461/* for the /proc/ directory itself, after non-process stuff has been done */ 2559/* for the /proc/ directory itself, after non-process stuff has been done */
@@ -2463,8 +2561,7 @@ int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir)
2463{ 2561{
2464 unsigned int nr = filp->f_pos - FIRST_PROCESS_ENTRY; 2562 unsigned int nr = filp->f_pos - FIRST_PROCESS_ENTRY;
2465 struct task_struct *reaper = get_proc_task(filp->f_path.dentry->d_inode); 2563 struct task_struct *reaper = get_proc_task(filp->f_path.dentry->d_inode);
2466 struct task_struct *task; 2564 struct tgid_iter iter;
2467 int tgid;
2468 struct pid_namespace *ns; 2565 struct pid_namespace *ns;
2469 2566
2470 if (!reaper) 2567 if (!reaper)
@@ -2477,14 +2574,14 @@ int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir)
2477 } 2574 }
2478 2575
2479 ns = filp->f_dentry->d_sb->s_fs_info; 2576 ns = filp->f_dentry->d_sb->s_fs_info;
2480 tgid = filp->f_pos - TGID_OFFSET; 2577 iter.task = NULL;
2481 for (task = next_tgid(tgid, ns); 2578 iter.tgid = filp->f_pos - TGID_OFFSET;
2482 task; 2579 for (iter = next_tgid(ns, iter);
2483 put_task_struct(task), task = next_tgid(tgid + 1, ns)) { 2580 iter.task;
2484 tgid = task_pid_nr_ns(task, ns); 2581 iter.tgid += 1, iter = next_tgid(ns, iter)) {
2485 filp->f_pos = tgid + TGID_OFFSET; 2582 filp->f_pos = iter.tgid + TGID_OFFSET;
2486 if (proc_pid_fill_cache(filp, dirent, filldir, task, tgid) < 0) { 2583 if (proc_pid_fill_cache(filp, dirent, filldir, iter) < 0) {
2487 put_task_struct(task); 2584 put_task_struct(iter.task);
2488 goto out; 2585 goto out;
2489 } 2586 }
2490 } 2587 }
@@ -2533,6 +2630,9 @@ static const struct pid_entry tid_base_stuff[] = {
2533#ifdef CONFIG_SCHEDSTATS 2630#ifdef CONFIG_SCHEDSTATS
2534 INF("schedstat", S_IRUGO, pid_schedstat), 2631 INF("schedstat", S_IRUGO, pid_schedstat),
2535#endif 2632#endif
2633#ifdef CONFIG_LATENCYTOP
2634 REG("latency", S_IRUGO, lstats),
2635#endif
2536#ifdef CONFIG_PROC_PID_CPUSET 2636#ifdef CONFIG_PROC_PID_CPUSET
2537 REG("cpuset", S_IRUGO, cpuset), 2637 REG("cpuset", S_IRUGO, cpuset),
2538#endif 2638#endif