RTTIME watchdog timer proc interface
RFC PATCH v2 1/1 RTTIME watchdog timer proc interface
From: Hiroshi Shimamoto <[email protected]>
Introduce new proc interface for RTTIME watchdog.
It makes administrator able to set RTTIME watchdog to existing real-time applications without impact.
$ echo 10000000 > /proc/<pid>/rttime set RTTIME current value to 10000000, it means 10sec.
$ echo "10000000 20000000" > /proc/<pid>/rttime set RTTIME current value to 10000000 and max value to 20000000.
And /proc/<pid>/task/<tid>/rttime is also accessible.
--- fs/proc/base.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 89 insertions(+), 0 deletions(-)
fs/proc/base.c +89 -0
@@ -381,6 +381,93 @@ static const struct file_operations proc_lstats_operations = {#endif +static int rttime_show_proc (struct seq_file *m,void *v) +{ +struct task_struct *task = m->private; +struct signal_struct *signal = task->signal; +struct rlimit *rt = &signal->rlim[RLIMIT_RTTIME ]; + +if (rt->rlim_cur ==RLIM_INFINITY ) +seq_printf (m,"unlimited " ); +else +seq_printf (m,"%lu " , rt->rlim_cur); + +if (rt->rlim_max ==RLIM_INFINITY ) +seq_printf (m,"unlimited\n" ); +else +seq_printf (m,"%lu\n" , rt->rlim_max); + +return 0 ; +} + +static int rttime_open (struct inode *inode,struct file *file) +{ +int ret; +struct seq_file *m; +struct task_struct *task =get_proc_task (inode); + + ret =single_open (file, rttime_show_proc,NULL ); +if (!ret) { + m = file->private_data; + m->private = task; + } +return ret; +} + +static ssize_t rttime_write (struct file *file, +const char __user *buf, +size_t count, +loff_t *ppos) +{ +struct seq_file *m = file->private_data; +struct task_struct *task = m->private; +char buffer[PROC_NUMBUF ], *end; +struct rlimit new_rlim, *old_rlim; +int n, ret; + + old_rlim = task->signal->rlim +RLIMIT_RTTIME ; + new_rlim = *old_rlim; +memset (buffer,0 ,sizeof (buffer)); + n = count; +if (n >sizeof (buffer) -1 ) + n =sizeof (buffer) -1 ; +if (copy_from_user (buffer, buf, n)) +return -EFAULT ; + new_rlim.rlim_cur =simple_strtoul (buffer, &end,0 ); +if (*end ==' ' ) { + ++end; + buf += end - buffer; +memset (buffer,0 ,sizeof (buffer)); + n = count - (end - buffer); +if (n >sizeof (buffer) -1 ) + n =sizeof (buffer) -1 ; +if (copy_from_user (buffer, buf, n)) +return -EFAULT ; + new_rlim.rlim_max =simple_strtoul (buffer, &end,0 ); + } +if (new_rlim.rlim_cur > new_rlim.rlim_max) +return -EINVAL ; +if ((new_rlim.rlim_max > old_rlim->rlim_max) && + !capable (CAP_SYS_RESOURCE )) +return -EPERM ; + ret =security_task_setrlimit (RLIMIT_RTTIME , &new_rlim); +if (ret) +return ret; +task_lock (task->group_leader); + *old_rlim = new_rlim; +task_unlock (task->group_leader); + +return count; +} + +static const struct file_operations proc_rttime_operations = { + .open = rttime_open, + .read = seq_read, + .write = rttime_write, + .llseek = seq_lseek, + .release = single_release, +}; +/* The badness from the OOM killer */ unsigned long badness (struct task_struct *p,unsigned long uptime);static int proc_oom_score (struct task_struct *task,char *buffer)
@@ -2300,6 +2387,7 @@ static const struct pid_entry tgid_base_stuff[] = {LNK ("exe" , exe),REG ("mounts" ,S_IRUGO , mounts),REG ("mountstats" ,S_IRUSR , mountstats), +REG ("rttime" ,S_IRUSR |S_IWUSR , rttime), #ifdef CONFIG_PROC_PAGE_MONITORREG ("clear_refs" ,S_IWUSR , clear_refs), REG("smaps", S_IRUGO, smaps),
@@ -2630,6 +2718,7 @@ static const struct pid_entry tid_base_stuff[] = {LNK ("root" , root),LNK ("exe" , exe),REG ("mounts" ,S_IRUGO , mounts), +REG ("rttime" ,S_IRUSR |S_IWUSR , rttime), #ifdef CONFIG_PROC_PAGE_MONITORREG ("clear_refs" ,S_IWUSR , clear_refs), REG("smaps", S_IRUGO, smaps),
Signature · 1 line
1.5.3.8
Quoted 11 lines · On Tue, 12 Feb 2008 14:41:42 -0800 Hiroshi Shimamoto…
From: Hiroshi Shimamoto <[email protected]>
Introduce new proc interface for RTTIME watchdog.
It makes administrator able to set RTTIME watchdog to existing real-time applications without impact.$ echo 10000000 > /proc/<pid>/rttime set RTTIME current value to 10000000, it means 10sec.$ echo "10000000 20000000" > /proc/<pid>/rttime set RTTIME current value to 10000000 and max value to 20000000.
How does one set it to `unlimited'?
Quoted 1 line
And /proc/<pid>/task/<tid>/rttime is also accessible.
Please describe the format in the changelog.
Quoted 35 lines
Signed-off-by Hiroshi Shimamoto <[email protected]>--- fs/proc/base.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 89 insertions(+), 0 deletions(-)fs/proc/base.c +22
-0@@ -381,6 +381,93 @@ static const struct file_operations proc_lstats_operations = {#endif +static int rttime_show_proc (struct seq_file *m,void *v) +{ +struct task_struct *task = m->private; +struct signal_struct *signal = task->signal; +struct rlimit *rt = &signal->rlim[RLIMIT_RTTIME ]; + +if (rt->rlim_cur ==RLIM_INFINITY ) +seq_printf (m,"unlimited " ); +else +seq_printf (m,"%lu " , rt->rlim_cur); + +if (rt->rlim_max ==RLIM_INFINITY ) +seq_printf (m,"unlimited\n" ); +else +seq_printf (m,"%lu\n" , rt->rlim_max); + +return 0 ; +} + +static int rttime_open (struct inode *inode,struct file *file) +{ +int ret;
fs/proc/base.c static const struct file_operations proc_lstats_operations = { · line 415
Quoted 10 lines
fs/proc/base.c +10
-0+struct seq_file *m; +struct task_struct *task =get_proc_task (inode); + + ret =single_open (file, rttime_show_proc,NULL ); +if (!ret) { + m = file->private_data; + m->private = task; + } +return ret; +}
get_proc_task() can return NULL, in which case it appears that the kernel will later oops?
fs/proc/base.c static const struct file_operations proc_lstats_operations = { · line 426
Quoted 10 lines
fs/proc/base.c +10
-0+static ssize_t rttime_write (struct file *file, +const char __user *buf, +size_t count, +loff_t *ppos) +{ +struct seq_file *m = file->private_data; +struct task_struct *task = m->private; +char buffer[PROC_NUMBUF ], *end; +struct rlimit new_rlim, *old_rlim; +int n, ret;
`n' should be size_t. And a better name would be nice.
fs/proc/base.c static const struct file_operations proc_lstats_operations = { · line 433
Quoted 6 lines
fs/proc/base.c +6
-0+ old_rlim = task->signal->rlim +RLIMIT_RTTIME ; + new_rlim = *old_rlim; +memset (buffer,0 ,sizeof (buffer)); + n = count; +if (n >sizeof (buffer) -1 ) + n =sizeof (buffer) -1 ;
min()
fs/proc/base.c static const struct file_operations proc_lstats_operations = { · line 443
Quoted 10 lines
fs/proc/base.c +10
-0+if (copy_from_user (buffer, buf, n)) +return -EFAULT ; + new_rlim.rlim_cur =simple_strtoul (buffer, &end,0 ); +if (*end ==' ' ) { + ++end; + buf += end - buffer; +memset (buffer,0 ,sizeof (buffer)); + n = count - (end - buffer); +if (n >sizeof (buffer) -1 ) + n =sizeof (buffer) -1 ;
min()
fs/proc/base.c static const struct file_operations proc_lstats_operations = { · line 446
Quoted 3 lines
fs/proc/base.c +3
-0+if (copy_from_user (buffer, buf, n)) +return -EFAULT ; + new_rlim.rlim_max =simple_strtoul (buffer, &end,0 );
strict_strtoul()?
fs/proc/base.c static const struct file_operations proc_lstats_operations = { · line 458
Quoted 12 lines
fs/proc/base.c +12
-0+ } +if (new_rlim.rlim_cur > new_rlim.rlim_max) +return -EINVAL ; +if ((new_rlim.rlim_max > old_rlim->rlim_max) && + !capable (CAP_SYS_RESOURCE )) +return -EPERM ; + ret =security_task_setrlimit (RLIMIT_RTTIME , &new_rlim); +if (ret) +return ret; +task_lock (task->group_leader); + *old_rlim = new_rlim; +task_unlock (task->group_leader);
hm. Why do we lock on ->group_leader rather than the task itself?
Quoted 30 lines
fs/proc/base.c +13
-0+return count; +} + +static const struct file_operations proc_rttime_operations = { + .open = rttime_open, + .read = seq_read, + .write = rttime_write, + .llseek = seq_lseek, + .release = single_release, +}; +/* The badness from the OOM killer */ unsigned long badness (struct task_struct *p,unsigned long uptime);static int proc_oom_score (struct task_struct *task,char *buffer)@@ -2300,6 +2387,7 @@ static const struct pid_entry tgid_base_stuff[] = {LNK ("exe" , exe),REG ("mounts" ,S_IRUGO , mounts),REG ("mountstats" ,S_IRUSR , mountstats), +REG ("rttime" ,S_IRUSR |S_IWUSR , rttime), #ifdef CONFIG_PROC_PAGE_MONITORREG ("clear_refs" ,S_IWUSR , clear_refs), REG("smaps", S_IRUGO, smaps),@@ -2630,6 +2718,7 @@ static const struct pid_entry tid_base_stuff[] = {LNK ("root" , root),LNK ("exe" , exe),REG ("mounts" ,S_IRUGO , mounts), +REG ("rttime" ,S_IRUSR |S_IWUSR , rttime), #ifdef CONFIG_PROC_PAGE_MONITORREG ("clear_refs" ,S_IWUSR , clear_refs), REG("smaps", S_IRUGO, smaps),
Quoted 8 lines · Andrew Morton
Quoted 6 lines · On Tue, 12 Feb 2008 14:41:42 -0800 Hiroshi Shimamoto…
From: Hiroshi Shimamoto <[email protected]>
Introduce new proc interface for RTTIME watchdog.
It makes administrator able to set RTTIME watchdog to existing real-time applications without impact.
Quoted 7 lines
Quoted 5 lines
$ echo 10000000 > /proc/<pid>/rttime set RTTIME current value to 10000000, it means 10sec.$ echo "10000000 20000000" > /proc/<pid>/rttime set RTTIME current value to 10000000 and max value to 20000000.How does one set it to `unlimited'?
There is no way now. Will add.
Quoted 4 lines
Quoted 2 lines
And /proc/<pid>/task/<tid>/rttime is also accessible.
Please describe the format in the changelog.
I'm sorry I cannot catch your meaning.
Quoted 41 lines
Quoted 41 lines
Signed-off-by Hiroshi Shimamoto <[email protected]>--- fs/proc/base.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 89 insertions(+), 0 deletions(-)fs/proc/base.c +27
-0@@ -381,6 +381,93 @@ static const struct file_operations proc_lstats_operations = {#endif +static int rttime_show_proc (struct seq_file *m,void *v) +{ +struct task_struct *task = m->private; +struct signal_struct *signal = task->signal; +struct rlimit *rt = &signal->rlim[RLIMIT_RTTIME ]; + +if (rt->rlim_cur ==RLIM_INFINITY ) +seq_printf (m,"unlimited " ); +else +seq_printf (m,"%lu " , rt->rlim_cur); + +if (rt->rlim_max ==RLIM_INFINITY ) +seq_printf (m,"unlimited\n" ); +else +seq_printf (m,"%lu\n" , rt->rlim_max); + +return 0 ; +} + +static int rttime_open (struct inode *inode,struct file *file) +{ +int ret; +struct seq_file *m; +struct task_struct *task =get_proc_task (inode); + + ret =single_open (file, rttime_show_proc,NULL ); +if (!ret) {
Quoted 8 lines
fs/proc/base.c static const struct file_operations proc_lstats_operations = { · line 415
Quoted 5 lines
fs/proc/base.c +5
-0+ m = file->private_data; + m->private = task; + } +return ret; +}
get_proc_task()can return NULL, in which case it appears that the kernel will later oops?
Yes, it could cause oops. Will fix.
Quoted 13 lines
fs/proc/base.c static const struct file_operations proc_lstats_operations = { · line 426
Quoted 11 lines
fs/proc/base.c +10
-0+static ssize_t rttime_write (struct file *file, +const char __user *buf, +size_t count, +loff_t *ppos) +{ +struct seq_file *m = file->private_data; +struct task_struct *task = m->private; +char buffer[PROC_NUMBUF ], *end; +struct rlimit new_rlim, *old_rlim; +int n, ret;`n' should be
size_t. And a better name would be nice.
Agree.
Quoted 9 lines
fs/proc/base.c static const struct file_operations proc_lstats_operations = { · line 433
Quoted 7 lines
fs/proc/base.c +6
-0+ old_rlim = task->signal->rlim +RLIMIT_RTTIME ; + new_rlim = *old_rlim; +memset (buffer,0 ,sizeof (buffer)); + n = count; +if (n >sizeof (buffer) -1 ) + n =sizeof (buffer) -1 ;
min()
Thanks, I hadn't noticed min().
Quoted 14 lines
fs/proc/base.c static const struct file_operations proc_lstats_operations = { · line 443
Quoted 11 lines
fs/proc/base.c +10
-0+if (copy_from_user (buffer, buf, n)) +return -EFAULT ; + new_rlim.rlim_cur =simple_strtoul (buffer, &end,0 ); +if (*end ==' ' ) { + ++end; + buf += end - buffer; +memset (buffer,0 ,sizeof (buffer)); + n = count - (end - buffer); +if (n >sizeof (buffer) -1 ) + n =sizeof (buffer) -1 ;
min()
Quoted 5 lines
fs/proc/base.c static const struct file_operations proc_lstats_operations = { · line 446
Quoted 3 lines
fs/proc/base.c +3
-0+if (copy_from_user (buffer, buf, n)) +return -EFAULT ; + new_rlim.rlim_max =simple_strtoul (buffer, &end,0 );
strict_strtoul()?
OK, I should look at it.
Quoted 15 lines
fs/proc/base.c static const struct file_operations proc_lstats_operations = { · line 458
Quoted 13 lines
fs/proc/base.c +12
-0+ } +if (new_rlim.rlim_cur > new_rlim.rlim_max) +return -EINVAL ; +if ((new_rlim.rlim_max > old_rlim->rlim_max) && + !capable (CAP_SYS_RESOURCE )) +return -EPERM ; + ret =security_task_setrlimit (RLIMIT_RTTIME , &new_rlim); +if (ret) +return ret; +task_lock (task->group_leader); + *old_rlim = new_rlim; +task_unlock (task->group_leader);hm. Why do we lock on ->group_leader rather than the task itself?
It's same as setrlimit.
Quoted 23 lines
Quoted 23 lines
fs/proc/base.c +12
-0+return count; +} + +static const struct file_operations proc_rttime_operations = { + .open = rttime_open, + .read = seq_read, + .write = rttime_write, + .llseek = seq_lseek, + .release = single_release, +}; +/* The badness from the OOM killer */ unsigned long badness (struct task_struct *p,unsigned long uptime);static int proc_oom_score (struct task_struct *task,char *buffer)@@ -2300,6 +2387,7 @@ static const struct pid_entry tgid_base_stuff[] = {LNK ("exe" , exe),REG ("mounts" ,S_IRUGO , mounts),REG ("mountstats" ,S_IRUSR , mountstats), +REG ("rttime" ,S_IRUSR |S_IWUSR , rttime), #ifdef CONFIG_PROC_PAGE_MONITORREG ("clear_refs" ,S_IWUSR , clear_refs), REG("smaps", S_IRUGO, smaps),
Quoted 8 lines
fs/proc/base.c static const struct pid_entry tid_base_stuff[] = { · line 2724
Quoted 8 lines
fs/proc/base.c +1
-0@@ -2630,6 +2718,7 @@ static const struct pid_entry tid_base_stuff[] = {LNK ("root" , root),LNK ("exe" , exe),REG ("mounts" ,S_IRUGO , mounts), +REG ("rttime" ,S_IRUSR |S_IWUSR , rttime), #ifdef CONFIG_PROC_PAGE_MONITORREG ("clear_refs" ,S_IWUSR , clear_refs), REG("smaps", S_IRUGO, smaps),
Thanks for reviewing.
Hiroshi Shimamoto
Quoted 6 lines · On Wed, 13 Feb 2008 09:45:54 -0800 Hiroshi Shimamoto…
Quoted 4 lines
Quoted 2 lines
And /proc/<pid>/task/<tid>/rttime is also accessible.
Please describe the format in the changelog.
I'm sorry I cannot catch your meaning.
Please include an example of the output of
`cat /proc/<pid>/task/<tid>/rttime' in the changelog so that we can see precisely what interface you are proposing.
Quoted 10 lines · Andrew Morton
Quoted 3 lines · On Wed, 13 Feb 2008 09:45:54 -0800 Hiroshi Shimamoto…
Quoted 2 lines
Quoted 1 line
And /proc/<pid>/task/<tid>/rttime is also accessible.
Please describe the format in the changelog.
I'm sorry I cannot catch your meaning.
Please include an example of the output of
`cat /proc/<pid>/task/<tid>/rttime' in the changelog so that we can see precisely what interface you are proposing.
thanks, I see.