Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
[linux-2.6.git] / drivers / oprofile / buffer_sync.c
index f9031d3..f34b5b2 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/fs.h>
 #include <linux/oprofile.h>
 #include <linux/sched.h>
+#include <linux/gfp.h>
 
 #include "oprofile_stats.h"
 #include "event_buffer.h"
@@ -38,7 +39,7 @@
 
 static LIST_HEAD(dying_tasks);
 static LIST_HEAD(dead_tasks);
-static cpumask_t marked_cpus = CPU_MASK_NONE;
+static cpumask_var_t marked_cpus;
 static DEFINE_SPINLOCK(task_mortuary);
 static void process_task_mortuary(void);
 
@@ -140,21 +141,19 @@ static struct notifier_block module_load_nb = {
        .notifier_call = module_load_notify,
 };
 
-
-static void end_sync(void)
+static void free_all_tasks(void)
 {
-       end_cpu_work();
        /* make sure we don't leak task structs */
        process_task_mortuary();
        process_task_mortuary();
 }
 
-
 int sync_start(void)
 {
        int err;
 
-       start_cpu_work();
+       if (!zalloc_cpumask_var(&marked_cpus, GFP_KERNEL))
+               return -ENOMEM;
 
        err = task_handoff_register(&task_free_nb);
        if (err)
@@ -169,6 +168,8 @@ int sync_start(void)
        if (err)
                goto out4;
 
+       start_cpu_work();
+
 out:
        return err;
 out4:
@@ -177,19 +178,26 @@ out3:
        profile_event_unregister(PROFILE_TASK_EXIT, &task_exit_nb);
 out2:
        task_handoff_unregister(&task_free_nb);
+       free_all_tasks();
 out1:
-       end_sync();
+       free_cpumask_var(marked_cpus);
        goto out;
 }
 
 
 void sync_stop(void)
 {
+       end_cpu_work();
        unregister_module_notifier(&module_load_nb);
        profile_event_unregister(PROFILE_MUNMAP, &munmap_nb);
        profile_event_unregister(PROFILE_TASK_EXIT, &task_exit_nb);
        task_handoff_unregister(&task_free_nb);
-       end_sync();
+       barrier();                      /* do all of the above first */
+
+       flush_cpu_work();
+
+       free_all_tasks();
+       free_cpumask_var(marked_cpus);
 }
 
 
@@ -201,7 +209,7 @@ static inline unsigned long fast_get_dcookie(struct path *path)
 {
        unsigned long cookie;
 
-       if (path->dentry->d_cookie)
+       if (path->dentry->d_flags & DCACHE_COOKIE)
                return (unsigned long)path->dentry;
        get_dcookie(path, &cookie);
        return cookie;
@@ -316,31 +324,18 @@ static void add_trace_begin(void)
        add_event_entry(TRACE_BEGIN_CODE);
 }
 
-#ifdef CONFIG_OPROFILE_IBS
-
-#define IBS_FETCH_CODE_SIZE    2
-#define IBS_OP_CODE_SIZE       5
-
-/*
- * Add IBS fetch and op entries to event buffer
- */
-static void add_ibs_begin(int cpu, int code, struct mm_struct *mm)
+static void add_data(struct op_entry *entry, struct mm_struct *mm)
 {
-       unsigned long pc;
-       int i, count;
-       unsigned long cookie = 0;
+       unsigned long code, pc, val;
+       unsigned long cookie;
        off_t offset;
-       struct op_entry entry;
-       struct op_sample *sample;
 
-       sample = op_cpu_buffer_read_entry(&entry, cpu);
-       if (!sample)
+       if (!op_cpu_buffer_get_data(entry, &code))
+               return;
+       if (!op_cpu_buffer_get_data(entry, &pc))
+               return;
+       if (!op_cpu_buffer_get_size(entry))
                return;
-       pc = sample->eip;
-
-#ifdef __LP64__
-       pc += sample->event << 32;
-#endif
 
        if (mm) {
                cookie = lookup_dcookie(mm, pc, &offset);
@@ -362,28 +357,10 @@ static void add_ibs_begin(int cpu, int code, struct mm_struct *mm)
        add_event_entry(code);
        add_event_entry(offset);        /* Offset from Dcookie */
 
-       /* we send the Dcookie offset, but send the raw Linear Add also*/
-       add_event_entry(sample->eip);
-       add_event_entry(sample->event);
-
-       if (code == IBS_FETCH_CODE)
-               count = IBS_FETCH_CODE_SIZE;    /*IBS FETCH is 2 int64s*/
-       else
-               count = IBS_OP_CODE_SIZE;       /*IBS OP is 5 int64s*/
-
-       for (i = 0; i < count; i++) {
-               sample = op_cpu_buffer_read_entry(&entry, cpu);
-               if (!sample)
-                       return;
-               add_event_entry(sample->eip);
-               add_event_entry(sample->event);
-       }
-
-       return;
+       while (op_cpu_buffer_get_data(entry, &val))
+               add_event_entry(val);
 }
 
-#endif
-
 static inline void add_sample_entry(unsigned long offset, unsigned long event)
 {
        add_event_entry(offset);
@@ -487,10 +464,10 @@ static void mark_done(int cpu)
 {
        int i;
 
-       cpu_set(cpu, marked_cpus);
+       cpumask_set_cpu(cpu, marked_cpus);
 
        for_each_online_cpu(i) {
-               if (!cpu_isset(i, marked_cpus))
+               if (!cpumask_test_cpu(i, marked_cpus))
                        return;
        }
 
@@ -499,7 +476,7 @@ static void mark_done(int cpu)
         */
        process_task_mortuary();
 
-       cpus_clear(marked_cpus);
+       cpumask_clear(marked_cpus);
 }
 
 
@@ -571,12 +548,8 @@ void sync_buffer(int cpu)
                                        cookie = get_exec_dcookie(mm);
                                add_user_ctx_switch(new, cookie);
                        }
-#ifdef CONFIG_OPROFILE_IBS
-                       if (flags & IBS_FETCH_BEGIN)
-                               add_ibs_begin(cpu, IBS_FETCH_CODE, mm);
-                       if (flags & IBS_OP_BEGIN)
-                               add_ibs_begin(cpu, IBS_OP_CODE, mm);
-#endif
+                       if (op_cpu_buffer_get_size(&entry))
+                               add_data(&entry, mm);
                        continue;
                }