]> Git Repo - linux.git/commitdiff
Merge commit 'v2.6.27-rc5' into tip/oprofile
authorRobert Richter <[email protected]>
Wed, 24 Sep 2008 09:25:31 +0000 (11:25 +0200)
committerRobert Richter <[email protected]>
Wed, 24 Sep 2008 09:25:31 +0000 (11:25 +0200)
Conflicts:
arch/x86/oprofile/nmi_int.c

1  2 
arch/x86/oprofile/nmi_int.c
drivers/oprofile/cpu_buffer.c
include/linux/pci_ids.h

index 287513a0981907bea5cba717ff793c80a50639fa,0227694f7dab9b156350eaef0e90f79e8ec2ecc4..d988574107463737a44471b4445f92f16dfd1f9f
@@@ -1,11 -1,10 +1,11 @@@
  /**
   * @file nmi_int.c
   *
 - * @remark Copyright 2002 OProfile authors
 + * @remark Copyright 2002-2008 OProfile authors
   * @remark Read the file COPYING
   *
   * @author John Levon <[email protected]>
 + * @author Robert Richter <[email protected]>
   */
  
  #include <linux/init.h>
@@@ -16,6 -15,7 +16,7 @@@
  #include <linux/slab.h>
  #include <linux/moduleparam.h>
  #include <linux/kdebug.h>
+ #include <linux/cpu.h>
  #include <asm/nmi.h>
  #include <asm/msr.h>
  #include <asm/apic.h>
@@@ -29,23 -29,48 +30,48 @@@ static DEFINE_PER_CPU(unsigned long, sa
  
  static int nmi_start(void);
  static void nmi_stop(void);
+ static void nmi_cpu_start(void *dummy);
+ static void nmi_cpu_stop(void *dummy);
  
  /* 0 == registered but off, 1 == registered and on */
  static int nmi_enabled = 0;
  
+ #ifdef CONFIG_SMP
+ static int oprofile_cpu_notifier(struct notifier_block *b, unsigned long action,
+                                void *data)
+ {
+       int cpu = (unsigned long)data;
+       switch (action) {
+       case CPU_DOWN_FAILED:
+       case CPU_ONLINE:
+               smp_call_function_single(cpu, nmi_cpu_start, NULL, 0);
+               break;
+       case CPU_DOWN_PREPARE:
+               smp_call_function_single(cpu, nmi_cpu_stop, NULL, 1);
+               break;
+       }
+       return NOTIFY_DONE;
+ }
+ static struct notifier_block oprofile_cpu_nb = {
+       .notifier_call = oprofile_cpu_notifier
+ };
+ #endif
  #ifdef CONFIG_PM
  
  static int nmi_suspend(struct sys_device *dev, pm_message_t state)
  {
+       /* Only one CPU left, just stop that one */
        if (nmi_enabled == 1)
-               nmi_stop();
+               nmi_cpu_stop(NULL);
        return 0;
  }
  
  static int nmi_resume(struct sys_device *dev)
  {
        if (nmi_enabled == 1)
-               nmi_start();
+               nmi_cpu_start(NULL);
        return 0;
  }
  
@@@ -412,7 -437,6 +438,7 @@@ int __init op_nmi_init(struct oprofile_
        __u8 vendor = boot_cpu_data.x86_vendor;
        __u8 family = boot_cpu_data.x86;
        char *cpu_type;
 +      int ret = 0;
  
        if (!cpu_has_apic)
                return -ENODEV;
                default:
                        return -ENODEV;
                case 6:
 -                      model = &op_athlon_spec;
 +                      model = &op_amd_spec;
                        cpu_type = "i386/athlon";
                        break;
                case 0xf:
 -                      model = &op_athlon_spec;
 +                      model = &op_amd_spec;
                        /* Actually it could be i386/hammer too, but give
                         user space an consistent name. */
                        cpu_type = "x86-64/hammer";
                        break;
                case 0x10:
 -                      model = &op_athlon_spec;
 +                      model = &op_amd_spec;
                        cpu_type = "x86-64/family10";
                        break;
 +              case 0x11:
 +                      model = &op_amd_spec;
 +                      cpu_type = "x86-64/family11h";
 +                      break;
                }
                break;
  
                return -ENODEV;
        }
  
 -      init_sysfs();
+ #ifdef CONFIG_SMP
+       register_cpu_notifier(&oprofile_cpu_nb);
+ #endif
 -      using_nmi = 1;
 +      /* default values, can be overwritten by model */
        ops->create_files = nmi_create_files;
        ops->setup = nmi_setup;
        ops->shutdown = nmi_shutdown;
        ops->start = nmi_start;
        ops->stop = nmi_stop;
        ops->cpu_type = cpu_type;
 +
 +      if (model->init)
 +              ret = model->init(ops);
 +      if (ret)
 +              return ret;
 +
 +      init_sysfs();
 +      using_nmi = 1;
        printk(KERN_INFO "oprofile: using NMI interrupt.\n");
        return 0;
  }
  
  void op_nmi_exit(void)
  {
-       if (using_nmi)
+       if (using_nmi) {
                exit_sysfs();
+ #ifdef CONFIG_SMP
+               unregister_cpu_notifier(&oprofile_cpu_nb);
+ #endif
+       }
 +      if (model->exit)
 +              model->exit();
  }
index 4decab624e76ddb5cd22c894831dfd7cc84f2b9e,7ba78e6d210e72ac9b41395ccc25fb6b4bfcd658..e1bd5a937f6c77d33ac1f92a16966e556c8bfff8
@@@ -5,7 -5,6 +5,7 @@@
   * @remark Read the file COPYING
   *
   * @author John Levon <[email protected]>
 + * @author Barry Kasindorf <[email protected]>
   *
   * Each CPU has a local buffer that stores PC value/event
   * pairs. We also log context switches when we notice them.
@@@ -39,8 -38,10 +39,10 @@@ void free_cpu_buffers(void
  {
        int i;
   
-       for_each_online_cpu(i)
+       for_each_online_cpu(i) {
                vfree(per_cpu(cpu_buffer, i).buffer);
+               per_cpu(cpu_buffer, i).buffer = NULL;
+       }
  }
  
  int alloc_cpu_buffers(void)
@@@ -208,7 -209,7 +210,7 @@@ static int log_sample(struct oprofile_c
        return 1;
  }
  
 -static int oprofile_begin_trace(struct oprofile_cpu_buffer * cpu_buf)
 +static int oprofile_begin_trace(struct oprofile_cpu_buffer *cpu_buf)
  {
        if (nr_available_slots(cpu_buf) < 4) {
                cpu_buf->sample_lost_overflow++;
@@@ -253,75 -254,6 +255,75 @@@ void oprofile_add_sample(struct pt_reg
        oprofile_add_ext_sample(pc, regs, event, is_kernel);
  }
  
 +#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)
 +{
 +      struct task_struct *task;
 +
 +      cpu_buf->sample_received++;
 +
 +      if (nr_available_slots(cpu_buf) < MAX_IBS_SAMPLE_SIZE) {
 +              cpu_buf->sample_lost_overflow++;
 +              return 0;
 +      }
 +
 +      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;
 +              add_code(cpu_buf, 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]);
 +
 +      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;
 +      }
 +
 +      /* 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))
 +              oprofile_ops.backtrace(regs, backtrace_depth);
 +}
 +
 +#endif
 +
  void oprofile_add_pc(unsigned long pc, int is_kernel, unsigned long event)
  {
        struct oprofile_cpu_buffer *cpu_buf = &__get_cpu_var(cpu_buffer);
@@@ -364,7 -296,7 +366,7 @@@ static void wq_sync_buffer(struct work_
        struct oprofile_cpu_buffer * b =
                container_of(work, struct oprofile_cpu_buffer, work.work);
        if (b->cpu != smp_processor_id()) {
 -              printk("WQ on CPU%d, prefer CPU%d\n",
 +              printk(KERN_DEBUG "WQ on CPU%d, prefer CPU%d\n",
                       smp_processor_id(), b->cpu);
        }
        sync_buffer(b->cpu);
diff --combined include/linux/pci_ids.h
index 4463ca5b893454b54425cdf5f51e4efc2123546f,f1624b3967548fc116211aee27114e65e91f5d36..f719d91afd93a25789d9fc86c8835d537678c543
  #define PCI_DEVICE_ID_AMD_K8_NB_ADDRMAP       0x1101
  #define PCI_DEVICE_ID_AMD_K8_NB_MEMCTL        0x1102
  #define PCI_DEVICE_ID_AMD_K8_NB_MISC  0x1103
 +#define PCI_DEVICE_ID_AMD_10H_NB_HT   0x1200
 +#define PCI_DEVICE_ID_AMD_10H_NB_MAP  0x1201
 +#define PCI_DEVICE_ID_AMD_10H_NB_DRAM 0x1202
 +#define PCI_DEVICE_ID_AMD_10H_NB_MISC 0x1203
 +#define PCI_DEVICE_ID_AMD_10H_NB_LINK 0x1204
  #define PCI_DEVICE_ID_AMD_LANCE               0x2000
  #define PCI_DEVICE_ID_AMD_LANCE_HOME  0x2001
  #define PCI_DEVICE_ID_AMD_SCSI                0x2020
  #define PCI_DEVICE_ID_INTEL_ICH10_3   0x3a1a
  #define PCI_DEVICE_ID_INTEL_ICH10_4   0x3a30
  #define PCI_DEVICE_ID_INTEL_ICH10_5   0x3a60
+ #define PCI_DEVICE_ID_INTEL_PCH_0     0x3b10
+ #define PCI_DEVICE_ID_INTEL_PCH_1     0x3b11
+ #define PCI_DEVICE_ID_INTEL_PCH_2     0x3b30
  #define PCI_DEVICE_ID_INTEL_IOAT_SNB  0x402f
  #define PCI_DEVICE_ID_INTEL_5100_16   0x65f0
  #define PCI_DEVICE_ID_INTEL_5100_21   0x65f5
This page took 0.05824 seconds and 4 git commands to generate.