]> git.hungrycats.org Git - linux/commitdiff
[PATCH] move profile_operations
authorWilliam Lee Irwin III <wli@holomorphy.com>
Fri, 27 Aug 2004 03:31:44 +0000 (20:31 -0700)
committerLinus Torvalds <torvalds@ppc970.osdl.org>
Fri, 27 Aug 2004 03:31:44 +0000 (20:31 -0700)
proc_misc.c is a trainwreck.  Move the file_operations for /proc/profile into
kernel/profile.c and call the profiling setup via initcall.

Signed-off-by: William Irwin <wli@holomorphy.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
fs/proc/proc_misc.c
include/linux/profile.h
kernel/profile.c

index e0733123f5aba34d1353db424a77dea369e1b6ad..4f4c34eba9ea70582174d2fd58a8428d6f725b46 100644 (file)
@@ -541,70 +541,6 @@ static int execdomains_read_proc(char *page, char **start, off_t off,
        return proc_calc_metrics(page, start, off, count, eof, len);
 }
 
-/*
- * This function accesses profiling information. The returned data is
- * binary: the sampling step and the actual contents of the profile
- * buffer. Use of the program readprofile is recommended in order to
- * get meaningful info out of these data.
- */
-static ssize_t
-read_profile(struct file *file, char __user *buf, size_t count, loff_t *ppos)
-{
-       unsigned long p = *ppos;
-       ssize_t read;
-       char * pnt;
-       unsigned int sample_step = 1 << prof_shift;
-
-       if (p >= (prof_len+1)*sizeof(unsigned int))
-               return 0;
-       if (count > (prof_len+1)*sizeof(unsigned int) - p)
-               count = (prof_len+1)*sizeof(unsigned int) - p;
-       read = 0;
-
-       while (p < sizeof(unsigned int) && count > 0) {
-               put_user(*((char *)(&sample_step)+p),buf);
-               buf++; p++; count--; read++;
-       }
-       pnt = (char *)prof_buffer + p - sizeof(unsigned int);
-       if (copy_to_user(buf,(void *)pnt,count))
-               return -EFAULT;
-       read += count;
-       *ppos += read;
-       return read;
-}
-
-/*
- * Writing to /proc/profile resets the counters
- *
- * Writing a 'profiling multiplier' value into it also re-sets the profiling
- * interrupt frequency, on architectures that support this.
- */
-static ssize_t write_profile(struct file *file, const char __user *buf,
-                            size_t count, loff_t *ppos)
-{
-#ifdef CONFIG_SMP
-       extern int setup_profiling_timer (unsigned int multiplier);
-
-       if (count == sizeof(int)) {
-               unsigned int multiplier;
-
-               if (copy_from_user(&multiplier, buf, sizeof(int)))
-                       return -EFAULT;
-
-               if (setup_profiling_timer(multiplier))
-                       return -EINVAL;
-       }
-#endif
-
-       memset(prof_buffer, 0, prof_len * sizeof(*prof_buffer));
-       return count;
-}
-
-static struct file_operations proc_profile_operations = {
-       .read           = read_profile,
-       .write          = write_profile,
-};
-
 #ifdef CONFIG_MAGIC_SYSRQ
 /*
  * writing 'C' to /proc/sysrq-trigger is like sysrq-C
@@ -692,13 +628,6 @@ void __init proc_misc_init(void)
                                (size_t)high_memory - PAGE_OFFSET + PAGE_SIZE;
        }
 #endif
-       if (prof_on) {
-               entry = create_proc_entry("profile", S_IWUSR | S_IRUGO, NULL);
-               if (entry) {
-                       entry->proc_fops = &proc_profile_operations;
-                       entry->size = (1+prof_len) * sizeof(unsigned int);
-               }
-       }
 #ifdef CONFIG_MAGIC_SYSRQ
        entry = create_proc_entry("sysrq-trigger", S_IWUSR, NULL);
        if (entry)
index 2baf8139461966c833e1f5abbd5a5834d7b502bc..603761004085bdd2cd3c897480fa979bfacaee65 100644 (file)
@@ -20,9 +20,13 @@ int __init profile_setup(char * str);
 
 /* init basic kernel profiler */
 void __init profile_init(void);
-void create_prof_cpu_mask(struct proc_dir_entry *);
 void profile_tick(int, struct pt_regs *);
 void profile_hit(int, void *);
+#ifdef CONFIG_PROC_FS
+void create_prof_cpu_mask(struct proc_dir_entry *);
+#else
+#define create_prof_cpu_mask(x)                        do { (void)(x); } while (0)
+#endif
 
 extern unsigned int * prof_buffer;
 extern unsigned long prof_len;
index 458c1542085cd3fdc06690b17fca3733b94d8604..7c258229a167e7d5a5058514b84bd2bce05400c6 100644 (file)
@@ -167,11 +167,6 @@ EXPORT_SYMBOL_GPL(unregister_profile_notifier);
 EXPORT_SYMBOL_GPL(profile_event_register);
 EXPORT_SYMBOL_GPL(profile_event_unregister);
 
-#ifdef CONFIG_PROC_FS
-#include <linux/proc_fs.h>
-#include <asm/uaccess.h>
-#include <asm/ptrace.h>
-
 void profile_hit(int type, void *__pc)
 {
        unsigned long pc;
@@ -190,6 +185,11 @@ void profile_tick(int type, struct pt_regs *regs)
                profile_hit(type, (void *)profile_pc(regs));
 }
 
+#ifdef CONFIG_PROC_FS
+#include <linux/proc_fs.h>
+#include <asm/uaccess.h>
+#include <asm/ptrace.h>
+
 static int prof_cpu_mask_read_proc (char *page, char **start, off_t off,
                        int count, int *eof, void *data)
 {
@@ -227,4 +227,82 @@ void create_prof_cpu_mask(struct proc_dir_entry *root_irq_dir)
        entry->read_proc = prof_cpu_mask_read_proc;
        entry->write_proc = prof_cpu_mask_write_proc;
 }
+
+/*
+ * This function accesses profiling information. The returned data is
+ * binary: the sampling step and the actual contents of the profile
+ * buffer. Use of the program readprofile is recommended in order to
+ * get meaningful info out of these data.
+ */
+static ssize_t
+read_profile(struct file *file, char __user *buf, size_t count, loff_t *ppos)
+{
+       unsigned long p = *ppos;
+       ssize_t read;
+       char * pnt;
+       unsigned int sample_step = 1 << prof_shift;
+
+       if (p >= (prof_len+1)*sizeof(unsigned int))
+               return 0;
+       if (count > (prof_len+1)*sizeof(unsigned int) - p)
+               count = (prof_len+1)*sizeof(unsigned int) - p;
+       read = 0;
+
+       while (p < sizeof(unsigned int) && count > 0) {
+               put_user(*((char *)(&sample_step)+p),buf);
+               buf++; p++; count--; read++;
+       }
+       pnt = (char *)prof_buffer + p - sizeof(unsigned int);
+       if (copy_to_user(buf,(void *)pnt,count))
+               return -EFAULT;
+       read += count;
+       *ppos += read;
+       return read;
+}
+
+/*
+ * Writing to /proc/profile resets the counters
+ *
+ * Writing a 'profiling multiplier' value into it also re-sets the profiling
+ * interrupt frequency, on architectures that support this.
+ */
+static ssize_t write_profile(struct file *file, const char __user *buf,
+                            size_t count, loff_t *ppos)
+{
+#ifdef CONFIG_SMP
+       extern int setup_profiling_timer (unsigned int multiplier);
+
+       if (count == sizeof(int)) {
+               unsigned int multiplier;
+
+               if (copy_from_user(&multiplier, buf, sizeof(int)))
+                       return -EFAULT;
+
+               if (setup_profiling_timer(multiplier))
+                       return -EINVAL;
+       }
+#endif
+
+       memset(prof_buffer, 0, prof_len * sizeof(*prof_buffer));
+       return count;
+}
+
+static struct file_operations proc_profile_operations = {
+       .read           = read_profile,
+       .write          = write_profile,
+};
+
+static int __init create_proc_profile(void)
+{
+       struct proc_dir_entry *entry;
+
+       if (!prof_on)
+               return 0;
+       if (!(entry = create_proc_entry("profile", S_IWUSR | S_IRUGO, NULL)))
+               return 0;
+       entry->proc_fops = &proc_profile_operations;
+       entry->size = (1+prof_len) * sizeof(atomic_t);
+       return 0;
+}
+module_init(create_proc_profile);
 #endif /* CONFIG_PROC_FS */