LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
* [RFC v2 PATCH] RTTIME watchdog timer proc interface
@ 2008-02-12 22:41 Hiroshi Shimamoto
  2008-02-13  9:13 ` Andrew Morton
  0 siblings, 1 reply; 5+ messages in thread
From: Hiroshi Shimamoto @ 2008-02-12 22:41 UTC (permalink / raw)
  To: linux-kernel; +Cc: mingo, a.p.zijlstra

From: Hiroshi Shimamoto <h-shimamoto@ct.jp.nec.com>

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.

Signed-off-by: Hiroshi Shimamoto <h-shimamoto@ct.jp.nec.com>
---
 fs/proc/base.c |   89 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 89 insertions(+), 0 deletions(-)

diff --git a/fs/proc/base.c b/fs/proc/base.c
index 7c6b4ec..3212b44 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -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_MONITOR
 	REG("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_MONITOR
 	REG("clear_refs", S_IWUSR, clear_refs),
 	REG("smaps",     S_IRUGO, smaps),
-- 
1.5.3.8


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [RFC v2 PATCH] RTTIME watchdog timer proc interface
  2008-02-12 22:41 [RFC v2 PATCH] RTTIME watchdog timer proc interface Hiroshi Shimamoto
@ 2008-02-13  9:13 ` Andrew Morton
  2008-02-13 17:45   ` Hiroshi Shimamoto
  0 siblings, 1 reply; 5+ messages in thread
From: Andrew Morton @ 2008-02-13  9:13 UTC (permalink / raw)
  To: Hiroshi Shimamoto; +Cc: linux-kernel, mingo, a.p.zijlstra

On Tue, 12 Feb 2008 14:41:42 -0800 Hiroshi Shimamoto <h-shimamoto@ct.jp.nec.com> wrote:

> From: Hiroshi Shimamoto <h-shimamoto@ct.jp.nec.com>
> 
> 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'?

> And /proc/<pid>/task/<tid>/rttime is also accessible.

Please describe the format in the changelog.

> Signed-off-by: Hiroshi Shimamoto <h-shimamoto@ct.jp.nec.com>
> ---
>  fs/proc/base.c |   89 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 files changed, 89 insertions(+), 0 deletions(-)
> 
> diff --git a/fs/proc/base.c b/fs/proc/base.c
> index 7c6b4ec..3212b44 100644
> --- a/fs/proc/base.c
> +++ b/fs/proc/base.c
> @@ -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;
> +}

get_proc_task() can return NULL, in which case it appears that the kernel
will later oops?

> +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.

> +	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()

> +	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()

> +		if (copy_from_user(buffer, buf, n))
> +			return -EFAULT;
> +		new_rlim.rlim_max = simple_strtoul(buffer, &end, 0);

strict_strtoul()?

> +	}
> +	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?

> +	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_MONITOR
>  	REG("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_MONITOR
>  	REG("clear_refs", S_IWUSR, clear_refs),
>  	REG("smaps",     S_IRUGO, smaps),


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [RFC v2 PATCH] RTTIME watchdog timer proc interface
  2008-02-13  9:13 ` Andrew Morton
@ 2008-02-13 17:45   ` Hiroshi Shimamoto
  2008-02-13 19:39     ` Andrew Morton
  0 siblings, 1 reply; 5+ messages in thread
From: Hiroshi Shimamoto @ 2008-02-13 17:45 UTC (permalink / raw)
  To: Andrew Morton; +Cc: linux-kernel, mingo, a.p.zijlstra

Andrew Morton wrote:
> On Tue, 12 Feb 2008 14:41:42 -0800 Hiroshi Shimamoto <h-shimamoto@ct.jp.nec.com> wrote:
> 
>> From: Hiroshi Shimamoto <h-shimamoto@ct.jp.nec.com>
>>
>> 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'?

There is no way now. Will add.

> 
>> And /proc/<pid>/task/<tid>/rttime is also accessible.
> 
> Please describe the format in the changelog.

I'm sorry I cannot catch your meaning.

> 
>> Signed-off-by: Hiroshi Shimamoto <h-shimamoto@ct.jp.nec.com>
>> ---
>>  fs/proc/base.c |   89 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>>  1 files changed, 89 insertions(+), 0 deletions(-)
>>
>> diff --git a/fs/proc/base.c b/fs/proc/base.c
>> index 7c6b4ec..3212b44 100644
>> --- a/fs/proc/base.c
>> +++ b/fs/proc/base.c
>> @@ -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;
>> +}
> 
> get_proc_task() can return NULL, in which case it appears that the kernel
> will later oops?

Yes, it could cause oops. Will fix.

> 
>> +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.

> 
>> +	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().

> 
>> +	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()
> 
>> +		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.

> 
>> +	}
>> +	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.

> 
>> +	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_MONITOR
>>  	REG("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_MONITOR
>>  	REG("clear_refs", S_IWUSR, clear_refs),
>>  	REG("smaps",     S_IRUGO, smaps),

Thanks for reviewing.

Hiroshi Shimamoto

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [RFC v2 PATCH] RTTIME watchdog timer proc interface
  2008-02-13 17:45   ` Hiroshi Shimamoto
@ 2008-02-13 19:39     ` Andrew Morton
  2008-02-13 20:38       ` Hiroshi Shimamoto
  0 siblings, 1 reply; 5+ messages in thread
From: Andrew Morton @ 2008-02-13 19:39 UTC (permalink / raw)
  To: Hiroshi Shimamoto; +Cc: linux-kernel, mingo, a.p.zijlstra

On Wed, 13 Feb 2008 09:45:54 -0800
Hiroshi Shimamoto <h-shimamoto@ct.jp.nec.com> wrote:

> > 
> >> 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.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [RFC v2 PATCH] RTTIME watchdog timer proc interface
  2008-02-13 19:39     ` Andrew Morton
@ 2008-02-13 20:38       ` Hiroshi Shimamoto
  0 siblings, 0 replies; 5+ messages in thread
From: Hiroshi Shimamoto @ 2008-02-13 20:38 UTC (permalink / raw)
  To: Andrew Morton; +Cc: linux-kernel, mingo, a.p.zijlstra

Andrew Morton wrote:
> On Wed, 13 Feb 2008 09:45:54 -0800
> Hiroshi Shimamoto <h-shimamoto@ct.jp.nec.com> wrote:
> 
>>>> 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.


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2008-02-13 20:39 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-02-12 22:41 [RFC v2 PATCH] RTTIME watchdog timer proc interface Hiroshi Shimamoto
2008-02-13  9:13 ` Andrew Morton
2008-02-13 17:45   ` Hiroshi Shimamoto
2008-02-13 19:39     ` Andrew Morton
2008-02-13 20:38       ` Hiroshi Shimamoto

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).