Ingo Molnar wrote:
> * Alexey Dobriyan <[EMAIL PROTECTED]> wrote:
>   
>> Use register_sysctl_table() for sysctls.
>>     
>
> yes - i just wanted to point out the incompatibility and subtle breakage 
> that this change caused. I'll now have to convert the current code over 
> to sysctl_table, which isnt that hard but not trivial either, and i 
> certainly could make use that time for other purposes.
>
>       Ingo
>   

How about this? It works for me.

Signed-off-by: Michal Schmidt <[EMAIL PROTECTED]>

diff --git a/kernel/latency_trace.c b/kernel/latency_trace.c
index e07bb95..a13d001 100644
--- a/kernel/latency_trace.c
+++ b/kernel/latency_trace.c
@@ -19,7 +19,7 @@
 #include <linux/seq_file.h>
 #include <linux/interrupt.h>
 #include <linux/clocksource.h>
-#include <linux/proc_fs.h>
+#include <linux/sysctl.h>
 #include <linux/latency_hist.h>
 #include <linux/utsrelease.h>
 #include <asm/uaccess.h>
@@ -2661,66 +2661,94 @@ void print_traces(struct task_struct *task)
 }
 #endif
 
-static int preempt_read_proc(char *page, char **start, off_t off,
-                            int count, int *eof, void *data)
+#if defined(CONFIG_WAKEUP_TIMING) || defined(CONFIG_EVENT_TRACE)
+
+static int preempt_proc_handler(ctl_table *table, int write, struct file *filp,
+                               void __user *buffer, size_t *lenp, loff_t *ppos)
 {
-       cycle_t *max = data;
+#define TMPBUFLEN 21
+       char buf[TMPBUFLEN];
+       size_t left = *lenp;
+       cycle_t *max = table->data;
 
-       return sprintf(page, "%ld\n", cycles_to_usecs(*max));
-}
+       if (!table->data || table->maxlen!=sizeof(cycles_t) || !*lenp ||
+                       (*ppos && !write)) {
+               *lenp = 0;
+               return 0;
+       }
 
-static int preempt_write_proc(struct file *file, const char __user *buffer,
-                             unsigned long count, void *data)
-{
-       unsigned int c, done = 0, val, sum = 0;
-       cycle_t *max = data;
+       if (!write) {
+               int len;
 
-       while (count) {
-               if (get_user(c, buffer))
-                       return -EFAULT;
-               val = c - '0';
-               buffer++;
-               done++;
-               count--;
-               if (c == 0 || c == '\n')
-                       break;
-               if (val > 9)
+               len = snprintf(buf, TMPBUFLEN, "%ld\n", cycles_to_usecs(*max));
+               if (len >= TMPBUFLEN)
                        return -EINVAL;
-               sum *= 10;
-               sum += val;
+               if (len > left)
+                       len = left;
+               if (copy_to_user(buffer, buf, len))
+                       return -EFAULT;
+               left -= len;
+       } else {
+               unsigned int c, val, sum = 0;
+
+               while (left) {
+                       if (get_user(c, (char __user *)buffer))
+                               return -EFAULT;
+                       val = c - '0';
+                       buffer++;
+                       left--;
+                       if (c == 0 || c == '\n')
+                               break;
+                       if (val > 9)
+                               return -EINVAL;
+                       sum *= 10;
+                       sum += val;
+               }
+               *max = usecs_to_cycles(sum);
        }
-       *max = usecs_to_cycles(sum);
-       return done;
+
+       *lenp -= left;
+       *ppos += *lenp;
+       return 0;
 }
 
-#if defined(CONFIG_WAKEUP_TIMING) || defined(CONFIG_EVENT_TRACE)
+static ctl_table preempt_latency_table[] = {
+       {
+               .ctl_name       = CTL_UNNUMBERED,
+               .procname       = "preempt_max_latency",
+               .data           = &preempt_max_latency,
+               .maxlen         = sizeof(cycles_t),
+               .mode           = 0644,
+               .proc_handler   = &preempt_proc_handler,
+       },
+#ifdef CONFIG_EVENT_TRACE
+       {
+               .ctl_name       = CTL_UNNUMBERED,
+               .procname       = "preempt_thresh",
+               .data           = &preempt_thresh,
+               .maxlen         = sizeof(cycles_t),
+               .mode           = 0644,
+               .proc_handler   = &preempt_proc_handler,
+       },
+#endif
+       { .ctl_name = 0 }
+};
 
-#define        PROCNAME_PML    "sys/kernel/preempt_max_latency"
-#define PROCNAME_PT    "sys/kernel/preempt_thresh"
+static ctl_table kernel_root[] = {
+       {
+               .ctl_name       = CTL_KERN,
+               .procname       = "kernel",
+               .mode           = 0555,
+               .child          = preempt_latency_table,
+       },
+       { .ctl_name = 0 }
+};
+
+static struct ctl_table_header *sysctl_header;
 
 static __init int latency_fs_init(void)
 {
-       struct proc_dir_entry *entry;
-
-       if (!(entry = create_proc_entry(PROCNAME_PML, 0644, NULL)))
-               printk("latency_fs_init(): can't create %s\n", PROCNAME_PML);
-       else {
-               entry->nlink = 1;
-               entry->data = &preempt_max_latency;
-               entry->read_proc = preempt_read_proc;
-               entry->write_proc = preempt_write_proc;
-       }
-
-#ifdef CONFIG_EVENT_TRACE
-       if (!(entry = create_proc_entry(PROCNAME_PT, 0644, NULL)))
-               printk("latency_fs_init(): can't create %s\n", PROCNAME_PT);
-       else {
-               entry->nlink = 1;
-               entry->data = &preempt_thresh;
-               entry->read_proc = preempt_read_proc;
-               entry->write_proc = preempt_write_proc;
-       }
-#endif
+       sysctl_header = register_sysctl_table(kernel_root);
        return 0;
 }
 __initcall(latency_fs_init);



-- 
Michal Schmidt             Kernel Developer
[EMAIL PROTECTED]    Red Hat Czech s.r.o.

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to