From 8808117ca571fd63e188a2306baae86cca9fce7a Mon Sep 17 00:00:00 2001 From: Eugene Teo Date: Sat, 23 Feb 2008 15:23:52 -0800 Subject: proc: add RLIMIT_RTTIME to /proc//limits RLIMIT_RTTIME was introduced to allow the user to set a runtime timeout on real-time tasks: http://lkml.org/lkml/2007/12/18/218. This patch updates /proc//limits with the new rlimit. Signed-off-by: Eugene Teo Acked-by: Peter Zijlstra Cc: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/proc/base.c | 1 + 1 file changed, 1 insertion(+) (limited to 'fs/proc/base.c') diff --git a/fs/proc/base.c b/fs/proc/base.c index 88f8edf1825..96ee899d650 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -416,6 +416,7 @@ static const struct limit_names lnames[RLIM_NLIMITS] = { [RLIMIT_MSGQUEUE] = {"Max msgqueue size", "bytes"}, [RLIMIT_NICE] = {"Max nice priority", NULL}, [RLIMIT_RTPRIO] = {"Max realtime priority", NULL}, + [RLIMIT_RTTIME] = {"Max realtime timeout", "us"}, }; /* Display limits for a process */ -- cgit From ae0027869db7d28563cd783865fab04ffd18419c Mon Sep 17 00:00:00 2001 From: Hiroshi Shimamoto Date: Thu, 14 Feb 2008 10:26:24 -0800 Subject: latencytop: fix kernel panic while reading latency proc file Reading /proc//latency or /proc//task//latency could cause NULL pointer dereference. In lstats_open(), get_proc_task() can return NULL, in which case the kernel will oops at lstats_show_proc() because m->private is NULL. When get_proc_task() returns NULL, the kernel should return -ENOENT. This can be reproduced by the following script. while : do date bash -c 'ls > ls.$$' & pid=$! cat /proc/$pid/latency & cat /proc/$pid/latency & cat /proc/$pid/latency & cat /proc/$pid/latency done Signed-off-by: Hiroshi Shimamoto Signed-off-by: Ingo Molnar --- fs/proc/base.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'fs/proc/base.c') diff --git a/fs/proc/base.c b/fs/proc/base.c index 96ee899d650..989e3078d7a 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -350,6 +350,8 @@ static int lstats_open(struct inode *inode, struct file *file) struct seq_file *m; struct task_struct *task = get_proc_task(inode); + if (!task) + return -ENOENT; ret = single_open(file, lstats_show_proc, NULL); if (!ret) { m = file->private_data; -- cgit From d6643d12cb0885d06a1491b16c1476abcbd53d40 Mon Sep 17 00:00:00 2001 From: Hiroshi Shimamoto Date: Thu, 14 Feb 2008 10:27:00 -0800 Subject: latencytop: fix memory leak on latency proc file At lstats_open(), calling get_proc_task() gets task struct, but it never put. put_task_struct() should be called when releasing. Signed-off-by: Hiroshi Shimamoto Signed-off-by: Ingo Molnar --- fs/proc/base.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'fs/proc/base.c') diff --git a/fs/proc/base.c b/fs/proc/base.c index 989e3078d7a..85e06e49807 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -360,6 +360,15 @@ static int lstats_open(struct inode *inode, struct file *file) return ret; } +static int lstats_release(struct inode *inode, struct file *file) +{ + struct seq_file *m = file->private_data; + struct task_struct *task = m->private; + + put_task_struct(task); + return single_release(inode, file); +} + static ssize_t lstats_write(struct file *file, const char __user *buf, size_t count, loff_t *offs) { @@ -378,7 +387,7 @@ static const struct file_operations proc_lstats_operations = { .read = seq_read, .write = lstats_write, .llseek = seq_lseek, - .release = single_release, + .release = lstats_release, }; #endif -- cgit From 13d77c37cab2bb906022309e1e7182c327e49916 Mon Sep 17 00:00:00 2001 From: Hiroshi Shimamoto Date: Wed, 20 Feb 2008 16:53:29 -0800 Subject: latencytop: change /proc task_struct access method Change getting task_struct by get_proc_task() at read or write time, and returns -ESRCH if get_proc_task() returns NULL. This is same behavior as other /proc files. Signed-off-by: Hiroshi Shimamoto Signed-off-by: Ingo Molnar --- fs/proc/base.c | 40 ++++++++++++---------------------------- 1 file changed, 12 insertions(+), 28 deletions(-) (limited to 'fs/proc/base.c') diff --git a/fs/proc/base.c b/fs/proc/base.c index 85e06e49807..91a1bd67ac1 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -314,9 +314,12 @@ static int proc_pid_schedstat(struct task_struct *task, char *buffer) static int lstats_show_proc(struct seq_file *m, void *v) { int i; - struct task_struct *task = m->private; - seq_puts(m, "Latency Top version : v0.1\n"); + struct inode *inode = m->private; + struct task_struct *task = get_proc_task(inode); + if (!task) + return -ESRCH; + seq_puts(m, "Latency Top version : v0.1\n"); for (i = 0; i < 32; i++) { if (task->latency_record[i].backtrace[0]) { int q; @@ -341,43 +344,24 @@ static int lstats_show_proc(struct seq_file *m, void *v) } } + put_task_struct(task); return 0; } static int lstats_open(struct inode *inode, struct file *file) { - int ret; - struct seq_file *m; - struct task_struct *task = get_proc_task(inode); - - if (!task) - return -ENOENT; - ret = single_open(file, lstats_show_proc, NULL); - if (!ret) { - m = file->private_data; - m->private = task; - } - return ret; -} - -static int lstats_release(struct inode *inode, struct file *file) -{ - struct seq_file *m = file->private_data; - struct task_struct *task = m->private; - - put_task_struct(task); - return single_release(inode, file); + return single_open(file, lstats_show_proc, inode); } static ssize_t lstats_write(struct file *file, const char __user *buf, size_t count, loff_t *offs) { - struct seq_file *m; - struct task_struct *task; + struct task_struct *task = get_proc_task(file->f_dentry->d_inode); - m = file->private_data; - task = m->private; + if (!task) + return -ESRCH; clear_all_latency_tracing(task); + put_task_struct(task); return count; } @@ -387,7 +371,7 @@ static const struct file_operations proc_lstats_operations = { .read = seq_read, .write = lstats_write, .llseek = seq_lseek, - .release = lstats_release, + .release = single_release, }; #endif -- cgit