]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/commitdiff
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rric/oprofile
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 23 Oct 2008 17:05:40 +0000 (10:05 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 23 Oct 2008 17:05:40 +0000 (10:05 -0700)
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rric/oprofile: (21 commits)
  OProfile: Fix buffer synchronization for IBS
  oprofile: hotplug cpu fix
  oprofile: fixing whitespaces in arch/x86/oprofile/*
  oprofile: fixing whitespaces in arch/x86/oprofile/*
  oprofile: fixing whitespaces in drivers/oprofile/*
  x86/oprofile: add the logic for enabling additional IBS bits
  x86/oprofile: reordering functions in nmi_int.c
  x86/oprofile: removing unused function parameter in add_ibs_begin()
  oprofile: more whitespace fixes
  oprofile: whitespace fixes
  OProfile: Rename IBS sysfs dir into "ibs_op"
  OProfile: Rework string handling in setup_ibs_files()
  OProfile: Rework oprofile_add_ibs_sample() function
  oprofile: discover counters for op ppro too
  oprofile: Implement Intel architectural perfmon support
  oprofile: Don't report Nehalem as core_2
  oprofile: drop const in num counters field
  Revert "Oprofile Multiplexing Patch"
  x86, oprofile: BUG: using smp_processor_id() in preemptible code
  x86/oprofile: fix on_each_cpu build error
  ...

Manually fixed trivial conflicts in
drivers/oprofile/{cpu_buffer.c,event_buffer.h}

1  2 
drivers/oprofile/buffer_sync.c
drivers/oprofile/cpu_buffer.c
drivers/oprofile/event_buffer.h

index 37681700b61a6816137cef46ca5ecc5fd666325e,6c0c92a745dd7b7ba27294691a8cec5a828ea0ee..b55cd23ffdefc81dfb80409a98c5697c21822b50
@@@ -41,7 -41,6 +41,6 @@@ static cpumask_t marked_cpus = CPU_MASK
  static DEFINE_SPINLOCK(task_mortuary);
  static void process_task_mortuary(void);
  
  /* Take ownership of the task struct and place it on the
   * list for processing. Only after two full buffer syncs
   * does the task eventually get freed, because by then
@@@ -341,7 -340,7 +340,7 @@@ static void add_trace_begin(void
   * Add IBS fetch and op entries to event buffer
   */
  static void add_ibs_begin(struct oprofile_cpu_buffer *cpu_buf, int code,
-       int in_kernel, struct mm_struct *mm)
+                         struct mm_struct *mm)
  {
        unsigned long rip;
        int i, count;
@@@ -565,9 -564,11 +564,11 @@@ void sync_buffer(int cpu
        struct task_struct *new;
        unsigned long cookie = 0;
        int in_kernel = 1;
-       unsigned int i;
        sync_buffer_state state = sb_buffer_start;
+ #ifndef CONFIG_OPROFILE_IBS
+       unsigned int i;
        unsigned long available;
+ #endif
  
        mutex_lock(&buffer_mutex);
  
  
        /* Remember, only we can modify tail_pos */
  
+ #ifndef CONFIG_OPROFILE_IBS
        available = get_slots(cpu_buf);
  
        for (i = 0; i < available; ++i) {
+ #else
+       while (get_slots(cpu_buf)) {
+ #endif
                struct op_sample *s = &cpu_buf->buffer[cpu_buf->tail_pos];
  
                if (is_code(s->eip)) {
  #ifdef CONFIG_OPROFILE_IBS
                        } else if (s->event == IBS_FETCH_BEGIN) {
                                state = sb_bt_start;
-                               add_ibs_begin(cpu_buf,
-                                       IBS_FETCH_CODE, in_kernel, mm);
+                               add_ibs_begin(cpu_buf, IBS_FETCH_CODE, mm);
                        } else if (s->event == IBS_OP_BEGIN) {
                                state = sb_bt_start;
-                               add_ibs_begin(cpu_buf,
-                                       IBS_OP_CODE, in_kernel, mm);
+                               add_ibs_begin(cpu_buf, IBS_OP_CODE, mm);
  #endif
                        } else {
                                struct mm_struct *oldmm = mm;
  
        mutex_unlock(&buffer_mutex);
  }
 +
 +/* The function can be used to add a buffer worth of data directly to
 + * the kernel buffer. The buffer is assumed to be a circular buffer.
 + * Take the entries from index start and end at index end, wrapping
 + * at max_entries.
 + */
 +void oprofile_put_buff(unsigned long *buf, unsigned int start,
 +                     unsigned int stop, unsigned int max)
 +{
 +      int i;
 +
 +      i = start;
 +
 +      mutex_lock(&buffer_mutex);
 +      while (i != stop) {
 +              add_event_entry(buf[i++]);
 +
 +              if (i >= max)
 +                      i = 0;
 +      }
 +
 +      mutex_unlock(&buffer_mutex);
 +}
 +
index 7ba39fe20a8a286c6ab5ea1063b3c63b38926898,67bcc1c95e60dd7d8b56b9c16c7d0803d80416b1..01d38e78cde18bd341fca22940249e4a80068217
@@@ -22,7 -22,7 +22,7 @@@
  #include <linux/oprofile.h>
  #include <linux/vmalloc.h>
  #include <linux/errno.h>
-  
  #include "event_buffer.h"
  #include "cpu_buffer.h"
  #include "buffer_sync.h"
@@@ -39,39 -39,26 +39,39 @@@ void free_cpu_buffers(void
  {
        int i;
  
-       for_each_online_cpu(i) {
+       for_each_possible_cpu(i) {
                vfree(per_cpu(cpu_buffer, i).buffer);
                per_cpu(cpu_buffer, i).buffer = NULL;
        }
  }
  
 +unsigned long oprofile_get_cpu_buffer_size(void)
 +{
 +      return fs_cpu_buffer_size;
 +}
 +
 +void oprofile_cpu_buffer_inc_smpl_lost(void)
 +{
 +      struct oprofile_cpu_buffer *cpu_buf
 +              = &__get_cpu_var(cpu_buffer);
 +
 +      cpu_buf->sample_lost_overflow++;
 +}
 +
  int alloc_cpu_buffers(void)
  {
        int i;
-  
        unsigned long buffer_size = fs_cpu_buffer_size;
-  
-       for_each_online_cpu(i) {
+       for_each_possible_cpu(i) {
                struct oprofile_cpu_buffer *b = &per_cpu(cpu_buffer, i);
-  
                b->buffer = vmalloc_node(sizeof(struct op_sample) * buffer_size,
                        cpu_to_node(i));
                if (!b->buffer)
                        goto fail;
-  
                b->last_task = NULL;
                b->last_is_kernel = -1;
                b->tracing = 0;
@@@ -125,7 -112,7 +125,7 @@@ void end_cpu_work(void
  }
  
  /* Resets the cpu buffer to a sane state. */
- void cpu_buffer_reset(struct oprofile_cpu_buffer * cpu_buf)
+ void cpu_buffer_reset(struct oprofile_cpu_buffer *cpu_buf)
  {
        /* reset these to invalid values; the next sample
         * collected will populate the buffer with proper
  }
  
  /* compute number of available slots in cpu_buffer queue */
- static unsigned long nr_available_slots(struct oprofile_cpu_buffer const * b)
+ static unsigned long nr_available_slots(struct oprofile_cpu_buffer const *b)
  {
        unsigned long head = b->head_pos;
        unsigned long tail = b->tail_pos;
        return tail + (b->buffer_size - head) - 1;
  }
  
- static void increment_head(struct oprofile_cpu_buffer * b)
+ static void increment_head(struct oprofile_cpu_buffer *b)
  {
        unsigned long new_head = b->head_pos + 1;
  
  }
  
  static inline void
- add_sample(struct oprofile_cpu_buffer * cpu_buf,
-            unsigned long pc, unsigned long event)
+ add_sample(struct oprofile_cpu_buffer *cpu_buf,
+          unsigned long pc, unsigned long event)
  {
-       struct op_sample * entry = &cpu_buf->buffer[cpu_buf->head_pos];
+       struct op_sample *entry = &cpu_buf->buffer[cpu_buf->head_pos];
        entry->eip = pc;
        entry->event = event;
        increment_head(cpu_buf);
  }
  
  static inline void
- add_code(struct oprofile_cpu_buffer * buffer, unsigned long value)
+ add_code(struct oprofile_cpu_buffer *buffer, unsigned long value)
  {
        add_sample(buffer, ESCAPE_CODE, value);
  }
   * pc. We tag this in the buffer by generating kernel enter/exit
   * events whenever is_kernel changes
   */
- static int log_sample(struct oprofile_cpu_buffer * cpu_buf, unsigned long pc,
+ static int log_sample(struct oprofile_cpu_buffer *cpu_buf, unsigned long pc,
                      int is_kernel, unsigned long event)
  {
-       struct task_struct * task;
+       struct task_struct *task;
  
        cpu_buf->sample_received++;
  
                cpu_buf->last_task = task;
                add_code(cpu_buf, (unsigned long)task);
        }
-  
        add_sample(cpu_buf, pc, event);
        return 1;
  }
@@@ -235,7 -222,7 +235,7 @@@ static int oprofile_begin_trace(struct 
        return 1;
  }
  
- static void oprofile_end_trace(struct oprofile_cpu_buffer * cpu_buf)
+ static void oprofile_end_trace(struct oprofile_cpu_buffer *cpu_buf)
  {
        cpu_buf->tracing = 0;
  }
@@@ -270,21 -257,23 +270,23 @@@ void oprofile_add_sample(struct pt_reg
  
  #ifdef CONFIG_OPROFILE_IBS
  
- #define MAX_IBS_SAMPLE_SIZE   14
- static int log_ibs_sample(struct oprofile_cpu_buffer *cpu_buf,
-       unsigned long pc, int is_kernel, unsigned  int *ibs, int ibs_code)
+ #define MAX_IBS_SAMPLE_SIZE 14
+ void oprofile_add_ibs_sample(struct pt_regs *const regs,
+                            unsigned int *const ibs_sample, int ibs_code)
  {
+       int is_kernel = !user_mode(regs);
+       struct oprofile_cpu_buffer *cpu_buf = &__get_cpu_var(cpu_buffer);
        struct task_struct *task;
  
        cpu_buf->sample_received++;
  
        if (nr_available_slots(cpu_buf) < MAX_IBS_SAMPLE_SIZE) {
+               /* we can't backtrace since we lost the source of this event */
                cpu_buf->sample_lost_overflow++;
-               return 0;
+               return;
        }
  
-       is_kernel = !!is_kernel;
        /* notice a switch from user->kernel or vice versa */
        if (cpu_buf->last_is_kernel != is_kernel) {
                cpu_buf->last_is_kernel = is_kernel;
        /* notice a task switch */
        if (!is_kernel) {
                task = current;
                if (cpu_buf->last_task != task) {
                        cpu_buf->last_task = task;
                        add_code(cpu_buf, (unsigned long)task);
        }
  
        add_code(cpu_buf, ibs_code);
-       add_sample(cpu_buf, ibs[0], ibs[1]);
-       add_sample(cpu_buf, ibs[2], ibs[3]);
-       add_sample(cpu_buf, ibs[4], ibs[5]);
+       add_sample(cpu_buf, ibs_sample[0], ibs_sample[1]);
+       add_sample(cpu_buf, ibs_sample[2], ibs_sample[3]);
+       add_sample(cpu_buf, ibs_sample[4], ibs_sample[5]);
  
        if (ibs_code == IBS_OP_BEGIN) {
-       add_sample(cpu_buf, ibs[6], ibs[7]);
-       add_sample(cpu_buf, ibs[8], ibs[9]);
-       add_sample(cpu_buf, ibs[10], ibs[11]);
-       }
-       return 1;
- }
- void oprofile_add_ibs_sample(struct pt_regs *const regs,
-                               unsigned int * const ibs_sample, u8 code)
- {
-       int is_kernel = !user_mode(regs);
-       unsigned long pc = profile_pc(regs);
-       struct oprofile_cpu_buffer *cpu_buf =
-                        &per_cpu(cpu_buffer, smp_processor_id());
-       if (!backtrace_depth) {
-               log_ibs_sample(cpu_buf, pc, is_kernel, ibs_sample, code);
-               return;
+               add_sample(cpu_buf, ibs_sample[6], ibs_sample[7]);
+               add_sample(cpu_buf, ibs_sample[8], ibs_sample[9]);
+               add_sample(cpu_buf, ibs_sample[10], ibs_sample[11]);
        }
  
-       /* if log_sample() fails we can't backtrace since we lost the source
-       * of this event */
-       if (log_ibs_sample(cpu_buf, pc, is_kernel, ibs_sample, code))
+       if (backtrace_depth)
                oprofile_ops.backtrace(regs, backtrace_depth);
  }
  
@@@ -376,11 -345,16 +358,16 @@@ void oprofile_add_trace(unsigned long p
   */
  static void wq_sync_buffer(struct work_struct *work)
  {
-       struct oprofile_cpu_buffer * b =
+       struct oprofile_cpu_buffer *b =
                container_of(work, struct oprofile_cpu_buffer, work.work);
        if (b->cpu != smp_processor_id()) {
                printk(KERN_DEBUG "WQ on CPU%d, prefer CPU%d\n",
                       smp_processor_id(), b->cpu);
+               if (!cpu_online(b->cpu)) {
+                       cancel_delayed_work(&b->work);
+                       return;
+               }
        }
        sync_buffer(b->cpu);
  
index 84bf324c577129c04a771c985e050eca9136e978,00db2e665708b9f3b62ccd0a5d9d5a87df4d9cd4..4e70749f8d16e122a0fab36fa065889e018ef954
  #ifndef EVENT_BUFFER_H
  #define EVENT_BUFFER_H
  
- #include <linux/types.h> 
+ #include <linux/types.h>
  #include <asm/mutex.h>
-  
  int alloc_event_buffer(void);
  
  void free_event_buffer(void);
-  
 +/**
 + * Add data to the event buffer.
 + * The data passed is free-form, but typically consists of
 + * file offsets, dcookies, context information, and ESCAPE codes.
 + */
 +void add_event_entry(unsigned long data);
 +
  /* wake up the process sleeping on the event file */
  void wake_up_buffer_waiter(void);
  
  #define NO_COOKIE 0UL
  
  extern const struct file_operations event_buffer_fops;
-  
  /* mutex between sync_cpu_buffers() and the
   * file reading code.
   */
  extern struct mutex buffer_mutex;
-  
  #endif /* EVENT_BUFFER_H */