]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
Merge branch 'perf/urgent' of git://git.kernel.org/pub/scm/linux/kernel/git/frederic...
authorIngo Molnar <mingo@elte.hu>
Thu, 18 Nov 2010 09:37:51 +0000 (10:37 +0100)
committerIngo Molnar <mingo@elte.hu>
Thu, 18 Nov 2010 09:37:51 +0000 (10:37 +0100)
1  2 
kernel/perf_event.c

diff --combined kernel/perf_event.c
index cb6c0d2af68f64b16bd0557f3c7fb7001151b71d,05b7d8c72c6c73c2efc0f0591a5f7fd220222408..f818d9d2dc93e398fd459357a532b805d9d5de07
@@@ -31,6 -31,7 +31,7 @@@
  #include <linux/kernel_stat.h>
  #include <linux/perf_event.h>
  #include <linux/ftrace_event.h>
+ #include <linux/hw_breakpoint.h>
  
  #include <asm/irq_regs.h>
  
@@@ -674,8 -675,6 +675,8 @@@ event_sched_in(struct perf_event *event
  
        event->tstamp_running += ctx->time - event->tstamp_stopped;
  
 +      event->shadow_ctx_time = ctx->time - ctx->timestamp;
 +
        if (!is_software_event(event))
                cpuctx->active_oncpu++;
        ctx->nr_active++;
@@@ -3398,8 -3397,7 +3399,8 @@@ static u32 perf_event_tid(struct perf_e
  }
  
  static void perf_output_read_one(struct perf_output_handle *handle,
 -                               struct perf_event *event)
 +                               struct perf_event *event,
 +                               u64 enabled, u64 running)
  {
        u64 read_format = event->attr.read_format;
        u64 values[4];
  
        values[n++] = perf_event_count(event);
        if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED) {
 -              values[n++] = event->total_time_enabled +
 +              values[n++] = enabled +
                        atomic64_read(&event->child_total_time_enabled);
        }
        if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING) {
 -              values[n++] = event->total_time_running +
 +              values[n++] = running +
                        atomic64_read(&event->child_total_time_running);
        }
        if (read_format & PERF_FORMAT_ID)
   * XXX PERF_FORMAT_GROUP vs inherited events seems difficult.
   */
  static void perf_output_read_group(struct perf_output_handle *handle,
 -                          struct perf_event *event)
 +                          struct perf_event *event,
 +                          u64 enabled, u64 running)
  {
        struct perf_event *leader = event->group_leader, *sub;
        u64 read_format = event->attr.read_format;
        values[n++] = 1 + leader->nr_siblings;
  
        if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED)
 -              values[n++] = leader->total_time_enabled;
 +              values[n++] = enabled;
  
        if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING)
 -              values[n++] = leader->total_time_running;
 +              values[n++] = running;
  
        if (leader != event)
                leader->pmu->read(leader);
        }
  }
  
 +#define PERF_FORMAT_TOTAL_TIMES (PERF_FORMAT_TOTAL_TIME_ENABLED|\
 +                               PERF_FORMAT_TOTAL_TIME_RUNNING)
 +
  static void perf_output_read(struct perf_output_handle *handle,
                             struct perf_event *event)
  {
 +      u64 enabled = 0, running = 0, now, ctx_time;
 +      u64 read_format = event->attr.read_format;
 +
 +      /*
 +       * compute total_time_enabled, total_time_running
 +       * based on snapshot values taken when the event
 +       * was last scheduled in.
 +       *
 +       * we cannot simply called update_context_time()
 +       * because of locking issue as we are called in
 +       * NMI context
 +       */
 +      if (read_format & PERF_FORMAT_TOTAL_TIMES) {
 +              now = perf_clock();
 +              ctx_time = event->shadow_ctx_time + now;
 +              enabled = ctx_time - event->tstamp_enabled;
 +              running = ctx_time - event->tstamp_running;
 +      }
 +
        if (event->attr.read_format & PERF_FORMAT_GROUP)
 -              perf_output_read_group(handle, event);
 +              perf_output_read_group(handle, event, enabled, running);
        else
 -              perf_output_read_one(handle, event);
 +              perf_output_read_one(handle, event, enabled, running);
  }
  
  void perf_output_sample(struct perf_output_handle *handle,
@@@ -6321,6 -6296,8 +6322,8 @@@ perf_cpu_notify(struct notifier_block *
  
  void __init perf_event_init(void)
  {
+       int ret;
        perf_event_init_all_cpus();
        init_srcu_struct(&pmus_srcu);
        perf_pmu_register(&perf_swevent);
        perf_pmu_register(&perf_task_clock);
        perf_tp_register();
        perf_cpu_notifier(perf_cpu_notify);
+       ret = init_hw_breakpoint();
+       WARN(ret, "hw_breakpoint initialization failed with: %d", ret);
  }