Merge branch 'perf-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull perf updates from Ingo Molnar:
 "Main kernel side changes:

   - Big reorganization of the x86 perf support code.  The old code grew
     organically deep inside arch/x86/kernel/cpu/perf* and its naming
     became somewhat messy.

     The new location is under arch/x86/events/, using the following
     cleaner hierarchy of source code files:

       perf/x86: Move perf_event.c .................. => x86/events/core.c
       perf/x86: Move perf_event_amd.c .............. => x86/events/amd/core.c
       perf/x86: Move perf_event_amd_ibs.c .......... => x86/events/amd/ibs.c
       perf/x86: Move perf_event_amd_iommu.[ch] ..... => x86/events/amd/iommu.[ch]
       perf/x86: Move perf_event_amd_uncore.c ....... => x86/events/amd/uncore.c
       perf/x86: Move perf_event_intel_bts.c ........ => x86/events/intel/bts.c
       perf/x86: Move perf_event_intel.c ............ => x86/events/intel/core.c
       perf/x86: Move perf_event_intel_cqm.c ........ => x86/events/intel/cqm.c
       perf/x86: Move perf_event_intel_cstate.c ..... => x86/events/intel/cstate.c
       perf/x86: Move perf_event_intel_ds.c ......... => x86/events/intel/ds.c
       perf/x86: Move perf_event_intel_lbr.c ........ => x86/events/intel/lbr.c
       perf/x86: Move perf_event_intel_pt.[ch] ...... => x86/events/intel/pt.[ch]
       perf/x86: Move perf_event_intel_rapl.c ....... => x86/events/intel/rapl.c
       perf/x86: Move perf_event_intel_uncore.[ch] .. => x86/events/intel/uncore.[ch]
       perf/x86: Move perf_event_intel_uncore_nhmex.c => x86/events/intel/uncore_nmhex.c
       perf/x86: Move perf_event_intel_uncore_snb.c   => x86/events/intel/uncore_snb.c
       perf/x86: Move perf_event_intel_uncore_snbep.c => x86/events/intel/uncore_snbep.c
       perf/x86: Move perf_event_knc.c .............. => x86/events/intel/knc.c
       perf/x86: Move perf_event_p4.c ............... => x86/events/intel/p4.c
       perf/x86: Move perf_event_p6.c ............... => x86/events/intel/p6.c
       perf/x86: Move perf_event_msr.c .............. => x86/events/msr.c

     (Borislav Petkov)

   - Update various x86 PMU constraint and hw support details (Stephane
     Eranian)

   - Optimize kprobes for BPF execution (Martin KaFai Lau)

   - Rewrite, refactor and fix the Intel uncore PMU driver code (Thomas
     Gleixner)

   - Rewrite, refactor and fix the Intel RAPL PMU code (Thomas Gleixner)

   - Various fixes and smaller cleanups.

  There are lots of perf tooling updates as well.  A few highlights:

  perf report/top:

     - Hierarchy histogram mode for 'perf top' and 'perf report',
       showing multiple levels, one per --sort entry: (Namhyung Kim)

       On a mostly idle system:

         # perf top --hierarchy -s comm,dso

       Then expand some levels and use 'P' to take a snapshot:

         # cat perf.hist.0
         -  92.32%         perf
               58.20%         perf
               22.29%         libc-2.22.so
                5.97%         [kernel]
                4.18%         libelf-0.165.so
                1.69%         [unknown]
         -   4.71%         qemu-system-x86
                3.10%         [kernel]
                1.60%         qemu-system-x86_64 (deleted)
         +   2.97%         swapper
         #

     - Add 'L' hotkey to dynamicly set the percent threshold for
       histogram entries and callchains, i.e.  dynamicly do what the
       --percent-limit command line option to 'top' and 'report' does.
       (Namhyung Kim)

  perf mem:

     - Allow specifying events via -e in 'perf mem record', also listing
       what events can be specified via 'perf mem record -e list' (Jiri
       Olsa)

  perf record:

     - Add 'perf record' --all-user/--all-kernel options, so that one
       can tell that all the events in the command line should be
       restricted to the user or kernel levels (Jiri Olsa), i.e.:

         perf record -e cycles:u,instructions:u

       is equivalent to:

         perf record --all-user -e cycles,instructions

     - Make 'perf record' collect CPU cache info in the perf.data file header:

         $ perf record usleep 1
         [ perf record: Woken up 1 times to write data ]
         [ perf record: Captured and wrote 0.017 MB perf.data (7 samples) ]
         $ perf report --header-only -I | tail -10 | head -8
         # CPU cache info:
         #  L1 Data                 32K [0-1]
         #  L1 Instruction          32K [0-1]
         #  L1 Data                 32K [2-3]
         #  L1 Instruction          32K [2-3]
         #  L2 Unified             256K [0-1]
         #  L2 Unified             256K [2-3]
         #  L3 Unified            4096K [0-3]

       Will be used in 'perf c2c' and eventually in 'perf diff' to
       allow, for instance running the same workload in multiple
       machines and then when using 'diff' show the hardware difference.
       (Jiri Olsa)

     - Improved support for Java, using the JVMTI agent library to do
       jitdumps that then will be inserted in synthesized
       PERF_RECORD_MMAP2 events via 'perf inject' pointed to synthesized
       ELF files stored in ~/.debug and keyed with build-ids, to allow
       symbol resolution and even annotation with source line info, see
       the changeset comments to see how to use it (Stephane Eranian)

  perf script/trace:

     - Decode data_src values (e.g.  perf.data files generated by 'perf
       mem record') in 'perf script': (Jiri Olsa)

         # perf script
           perf 693 [1] 4.088652: 1 cpu/mem-loads,ldlat=30/P: ffff88007d0b0f40 68100142 L1 hit|SNP None|TLB L1 or L2 hit|LCK No <SNIP>
                                                                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
     - Improve support to 'data_src', 'weight' and 'addr' fields in
       'perf script' (Jiri Olsa)

     - Handle empty print fmts in 'perf script -s' i.e. when running
       python or perl scripts (Taeung Song)

  perf stat:

     - 'perf stat' now shows shadow metrics (insn per cycle, etc) in
       interval mode too.  E.g:

         # perf stat -I 1000 -e instructions,cycles sleep 1
         #         time   counts unit events
            1.000215928  519,620      instructions     #  0.69 insn per cycle
            1.000215928  752,003      cycles
         <SNIP>

     - Port 'perf kvm stat' to PowerPC (Hemant Kumar)

     - Implement CSV metrics output in 'perf stat' (Andi Kleen)

  perf BPF support:

     - Support converting data from bpf events in 'perf data' (Wang Nan)

     - Print bpf-output events in 'perf script': (Wang Nan).

         # perf record -e bpf-output/no-inherit,name=evt/ -e ./test_bpf_output_3.c/map:channel.event=evt/ usleep 1000
         # perf script
            usleep  4882 21384.532523:   evt:  ffffffff810e97d1 sys_nanosleep ([kernel.kallsyms])
             BPF output: 0000: 52 61 69 73 65 20 61 20  Raise a
                         0008: 42 50 46 20 65 76 65 6e  BPF even
                         0010: 74 21 00 00              t!..
             BPF string: "Raise a BPF event!"
         #

     - Add API to set values of map entries in a BPF object, be it
       individual map slots or ranges (Wang Nan)

     - Introduce support for the 'bpf-output' event (Wang Nan)

     - Add glue to read perf events in a BPF program (Wang Nan)

     - Improve support for bpf-output events in 'perf trace' (Wang Nan)

  ... and tons of other changes as well - see the shortlog and git log
  for details!"

* 'perf-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (342 commits)
  perf stat: Add --metric-only support for -A
  perf stat: Implement --metric-only mode
  perf stat: Document CSV format in manpage
  perf hists browser: Check sort keys before hot key actions
  perf hists browser: Allow thread filtering for comm sort key
  perf tools: Add sort__has_comm variable
  perf tools: Recalc total periods using top-level entries in hierarchy
  perf tools: Remove nr_sort_keys field
  perf hists browser: Cleanup hist_browser__fprintf_hierarchy_entry()
  perf tools: Remove hist_entry->fmt field
  perf tools: Fix command line filters in hierarchy mode
  perf tools: Add more sort entry check functions
  perf tools: Fix hist_entry__filter() for hierarchy
  perf jitdump: Build only on supported archs
  tools lib traceevent: Add '~' operation within arg_num_eval()
  perf tools: Omit unnecessary cast in perf_pmu__parse_scale
  perf tools: Pass perf_hpp_list all the way through setup_sort_list
  perf tools: Fix perf script python database export crash
  perf jitdump: DWARF is also needed
  perf bench mem: Prepare the x86-64 build for upstream memcpy_mcsafe() changes
  ...
This commit is contained in:
Linus Torvalds 2016-03-14 17:58:53 -07:00
commit e71c2c1eeb
219 changed files with 12266 additions and 2462 deletions

View File

@ -58,6 +58,8 @@ show up in /proc/sys/kernel:
- panic_on_stackoverflow
- panic_on_unrecovered_nmi
- panic_on_warn
- perf_cpu_time_max_percent
- perf_event_paranoid
- pid_max
- powersave-nap [ PPC only ]
- printk
@ -639,6 +641,17 @@ allowed to execute.
==============================================================
perf_event_paranoid:
Controls use of the performance events system by unprivileged
users (without CAP_SYS_ADMIN). The default value is 1.
-1: Allow use of (almost) all events by all users
>=0: Disallow raw tracepoint access by users without CAP_IOC_LOCK
>=1: Disallow CPU event access by users without CAP_SYS_ADMIN
>=2: Disallow kernel profiling by users without CAP_SYS_ADMIN
==============================================================
pid_max:

View File

@ -8475,6 +8475,7 @@ PERFORMANCE EVENTS SUBSYSTEM
M: Peter Zijlstra <peterz@infradead.org>
M: Ingo Molnar <mingo@redhat.com>
M: Arnaldo Carvalho de Melo <acme@kernel.org>
R: Alexander Shishkin <alexander.shishkin@linux.intel.com>
L: linux-kernel@vger.kernel.org
T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git perf/core
S: Supported

View File

@ -1,6 +1,7 @@
obj-y += entry/
obj-$(CONFIG_PERF_EVENTS) += events/
obj-$(CONFIG_KVM) += kvm/
# Xen paravirtualization support

13
arch/x86/events/Makefile Normal file
View File

@ -0,0 +1,13 @@
obj-y += core.o
obj-$(CONFIG_CPU_SUP_AMD) += amd/core.o amd/uncore.o
obj-$(CONFIG_X86_LOCAL_APIC) += amd/ibs.o msr.o
ifdef CONFIG_AMD_IOMMU
obj-$(CONFIG_CPU_SUP_AMD) += amd/iommu.o
endif
obj-$(CONFIG_CPU_SUP_INTEL) += intel/core.o intel/bts.o intel/cqm.o
obj-$(CONFIG_CPU_SUP_INTEL) += intel/cstate.o intel/ds.o intel/knc.o
obj-$(CONFIG_CPU_SUP_INTEL) += intel/lbr.o intel/p4.o intel/p6.o intel/pt.o
obj-$(CONFIG_CPU_SUP_INTEL) += intel/rapl.o msr.o
obj-$(CONFIG_PERF_EVENTS_INTEL_UNCORE) += intel/uncore.o intel/uncore_nhmex.o
obj-$(CONFIG_PERF_EVENTS_INTEL_UNCORE) += intel/uncore_snb.o intel/uncore_snbep.o

View File

@ -5,7 +5,7 @@
#include <linux/slab.h>
#include <asm/apicdef.h>
#include "perf_event.h"
#include "../perf_event.h"
static __initconst const u64 amd_hw_cache_event_ids
[PERF_COUNT_HW_CACHE_MAX]

View File

@ -14,7 +14,7 @@
#include <asm/apic.h>
#include "perf_event.h"
#include "../perf_event.h"
static u32 ibs_caps;
@ -670,7 +670,7 @@ static __init int perf_event_ibs_init(void)
perf_ibs_pmu_init(&perf_ibs_op, "ibs_op");
register_nmi_handler(NMI_LOCAL, perf_ibs_nmi_handler, 0, "perf_ibs");
printk(KERN_INFO "perf: AMD IBS detected (0x%08x)\n", ibs_caps);
pr_info("perf: AMD IBS detected (0x%08x)\n", ibs_caps);
return 0;
}
@ -774,14 +774,14 @@ static int setup_ibs_ctl(int ibs_eilvt_off)
pci_read_config_dword(cpu_cfg, IBSCTL, &value);
if (value != (ibs_eilvt_off | IBSCTL_LVT_OFFSET_VALID)) {
pci_dev_put(cpu_cfg);
printk(KERN_DEBUG "Failed to setup IBS LVT offset, "
"IBSCTL = 0x%08x\n", value);
pr_debug("Failed to setup IBS LVT offset, IBSCTL = 0x%08x\n",
value);
return -EINVAL;
}
} while (1);
if (!nodes) {
printk(KERN_DEBUG "No CPU node configured for IBS\n");
pr_debug("No CPU node configured for IBS\n");
return -ENODEV;
}
@ -810,7 +810,7 @@ static void force_ibs_eilvt_setup(void)
preempt_enable();
if (offset == APIC_EILVT_NR_MAX) {
printk(KERN_DEBUG "No EILVT entry available\n");
pr_debug("No EILVT entry available\n");
return;
}

View File

@ -16,8 +16,8 @@
#include <linux/cpumask.h>
#include <linux/slab.h>
#include "perf_event.h"
#include "perf_event_amd_iommu.h"
#include "../perf_event.h"
#include "iommu.h"
#define COUNTER_SHIFT 16

View File

@ -538,7 +538,7 @@ static int __init amd_uncore_init(void)
if (ret)
goto fail_nb;
printk(KERN_INFO "perf: AMD NB counters detected\n");
pr_info("perf: AMD NB counters detected\n");
ret = 0;
}
@ -552,7 +552,7 @@ static int __init amd_uncore_init(void)
if (ret)
goto fail_l2;
printk(KERN_INFO "perf: AMD L2I counters detected\n");
pr_info("perf: AMD L2I counters detected\n");
ret = 0;
}

View File

@ -254,15 +254,16 @@ static bool check_hw_exists(void)
* We still allow the PMU driver to operate:
*/
if (bios_fail) {
printk(KERN_CONT "Broken BIOS detected, complain to your hardware vendor.\n");
printk(KERN_ERR FW_BUG "the BIOS has corrupted hw-PMU resources (MSR %x is %Lx)\n", reg_fail, val_fail);
pr_cont("Broken BIOS detected, complain to your hardware vendor.\n");
pr_err(FW_BUG "the BIOS has corrupted hw-PMU resources (MSR %x is %Lx)\n",
reg_fail, val_fail);
}
return true;
msr_fail:
printk(KERN_CONT "Broken PMU hardware detected, using software events only.\n");
printk("%sFailed to access perfctr msr (MSR %x is %Lx)\n",
pr_cont("Broken PMU hardware detected, using software events only.\n");
pr_info("%sFailed to access perfctr msr (MSR %x is %Lx)\n",
boot_cpu_has(X86_FEATURE_HYPERVISOR) ? KERN_INFO : KERN_ERR,
reg, val_new);
@ -596,6 +597,19 @@ void x86_pmu_disable_all(void)
}
}
/*
* There may be PMI landing after enabled=0. The PMI hitting could be before or
* after disable_all.
*
* If PMI hits before disable_all, the PMU will be disabled in the NMI handler.
* It will not be re-enabled in the NMI handler again, because enabled=0. After
* handling the NMI, disable_all will be called, which will not change the
* state either. If PMI hits after disable_all, the PMU is already disabled
* before entering NMI handler. The NMI handler will not change the state
* either.
*
* So either situation is harmless.
*/
static void x86_pmu_disable(struct pmu *pmu)
{
struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);

View File

@ -26,7 +26,7 @@
#include <asm-generic/sizes.h>
#include <asm/perf_event.h>
#include "perf_event.h"
#include "../perf_event.h"
struct bts_ctx {
struct perf_output_handle handle;

View File

@ -18,7 +18,7 @@
#include <asm/hardirq.h>
#include <asm/apic.h>
#include "perf_event.h"
#include "../perf_event.h"
/*
* Intel PerfMon, used on Core and later.
@ -1502,7 +1502,15 @@ static __initconst const u64 knl_hw_cache_extra_regs
};
/*
* Use from PMIs where the LBRs are already disabled.
* Used from PMIs where the LBRs are already disabled.
*
* This function could be called consecutively. It is required to remain in
* disabled state if called consecutively.
*
* During consecutive calls, the same disable value will be written to related
* registers, so the PMU state remains unchanged. hw.state in
* intel_bts_disable_local will remain PERF_HES_STOPPED too in consecutive
* calls.
*/
static void __intel_pmu_disable_all(void)
{
@ -1884,6 +1892,16 @@ again:
if (__test_and_clear_bit(62, (unsigned long *)&status)) {
handled++;
x86_pmu.drain_pebs(regs);
/*
* There are cases where, even though, the PEBS ovfl bit is set
* in GLOBAL_OVF_STATUS, the PEBS events may also have their
* overflow bits set for their counters. We must clear them
* here because they have been processed as exact samples in
* the drain_pebs() routine. They must not be processed again
* in the for_each_bit_set() loop for regular samples below.
*/
status &= ~cpuc->pebs_enabled;
status &= x86_pmu.intel_ctrl | GLOBAL_STATUS_TRACE_TOPAPMI;
}
/*
@ -1929,7 +1947,10 @@ again:
goto again;
done:
__intel_pmu_enable_all(0, true);
/* Only restore PMU state when it's active. See x86_pmu_disable(). */
if (cpuc->enabled)
__intel_pmu_enable_all(0, true);
/*
* Only unmask the NMI after the overflow counters
* have been reset. This avoids spurious NMIs on
@ -3396,6 +3417,7 @@ __init int intel_pmu_init(void)
intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES_BACKEND] =
X86_CONFIG(.event=0xb1, .umask=0x3f, .inv=1, .cmask=1);
intel_pmu_pebs_data_source_nhm();
x86_add_quirk(intel_nehalem_quirk);
pr_cont("Nehalem events, ");
@ -3459,6 +3481,7 @@ __init int intel_pmu_init(void)
intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES_BACKEND] =
X86_CONFIG(.event=0xb1, .umask=0x3f, .inv=1, .cmask=1);
intel_pmu_pebs_data_source_nhm();
pr_cont("Westmere events, ");
break;
@ -3581,7 +3604,7 @@ __init int intel_pmu_init(void)
intel_pmu_lbr_init_hsw();
x86_pmu.event_constraints = intel_bdw_event_constraints;
x86_pmu.pebs_constraints = intel_hsw_pebs_event_constraints;
x86_pmu.pebs_constraints = intel_bdw_pebs_event_constraints;
x86_pmu.extra_regs = intel_snbep_extra_regs;
x86_pmu.pebs_aliases = intel_pebs_aliases_ivb;
x86_pmu.pebs_prec_dist = true;

View File

@ -7,7 +7,7 @@
#include <linux/perf_event.h>
#include <linux/slab.h>
#include <asm/cpu_device_id.h>
#include "perf_event.h"
#include "../perf_event.h"
#define MSR_IA32_PQR_ASSOC 0x0c8f
#define MSR_IA32_QM_CTR 0x0c8e
@ -1244,15 +1244,12 @@ static struct pmu intel_cqm_pmu = {
static inline void cqm_pick_event_reader(int cpu)
{
int phys_id = topology_physical_package_id(cpu);
int i;
int reader;
for_each_cpu(i, &cqm_cpumask) {
if (phys_id == topology_physical_package_id(i))
return; /* already got reader for this socket */
}
cpumask_set_cpu(cpu, &cqm_cpumask);
/* First online cpu in package becomes the reader */
reader = cpumask_any_and(&cqm_cpumask, topology_core_cpumask(cpu));
if (reader >= nr_cpu_ids)
cpumask_set_cpu(cpu, &cqm_cpumask);
}
static void intel_cqm_cpu_starting(unsigned int cpu)
@ -1270,24 +1267,17 @@ static void intel_cqm_cpu_starting(unsigned int cpu)
static void intel_cqm_cpu_exit(unsigned int cpu)
{
int phys_id = topology_physical_package_id(cpu);
int i;
int target;
/*
* Is @cpu a designated cqm reader?
*/
/* Is @cpu the current cqm reader for this package ? */
if (!cpumask_test_and_clear_cpu(cpu, &cqm_cpumask))
return;
for_each_online_cpu(i) {
if (i == cpu)
continue;
/* Find another online reader in this package */
target = cpumask_any_but(topology_core_cpumask(cpu), cpu);
if (phys_id == topology_physical_package_id(i)) {
cpumask_set_cpu(i, &cqm_cpumask);
break;
}
}
if (target < nr_cpu_ids)
cpumask_set_cpu(target, &cqm_cpumask);
}
static int intel_cqm_cpu_notifier(struct notifier_block *nb,

View File

@ -89,7 +89,7 @@
#include <linux/slab.h>
#include <linux/perf_event.h>
#include <asm/cpu_device_id.h>
#include "perf_event.h"
#include "../perf_event.h"
#define DEFINE_CSTATE_FORMAT_ATTR(_var, _name, _format) \
static ssize_t __cstate_##_var##_show(struct kobject *kobj, \

View File

@ -5,7 +5,7 @@
#include <asm/perf_event.h>
#include <asm/insn.h>
#include "perf_event.h"
#include "../perf_event.h"
/* The size of a BTS record in bytes: */
#define BTS_RECORD_SIZE 24
@ -51,7 +51,8 @@ union intel_x86_pebs_dse {
#define OP_LH (P(OP, LOAD) | P(LVL, HIT))
#define SNOOP_NONE_MISS (P(SNOOP, NONE) | P(SNOOP, MISS))
static const u64 pebs_data_source[] = {
/* Version for Sandy Bridge and later */
static u64 pebs_data_source[] = {
P(OP, LOAD) | P(LVL, MISS) | P(LVL, L3) | P(SNOOP, NA),/* 0x00:ukn L3 */
OP_LH | P(LVL, L1) | P(SNOOP, NONE), /* 0x01: L1 local */
OP_LH | P(LVL, LFB) | P(SNOOP, NONE), /* 0x02: LFB hit */
@ -70,6 +71,14 @@ static const u64 pebs_data_source[] = {
OP_LH | P(LVL, UNC) | P(SNOOP, NONE), /* 0x0f: uncached */
};
/* Patch up minor differences in the bits */
void __init intel_pmu_pebs_data_source_nhm(void)
{
pebs_data_source[0x05] = OP_LH | P(LVL, L3) | P(SNOOP, HIT);
pebs_data_source[0x06] = OP_LH | P(LVL, L3) | P(SNOOP, HITM);
pebs_data_source[0x07] = OP_LH | P(LVL, L3) | P(SNOOP, HITM);
}
static u64 precise_store_data(u64 status)
{
union intel_x86_pebs_dse dse;
@ -269,7 +278,7 @@ static int alloc_pebs_buffer(int cpu)
if (!x86_pmu.pebs)
return 0;
buffer = kzalloc_node(PEBS_BUFFER_SIZE, GFP_KERNEL, node);
buffer = kzalloc_node(x86_pmu.pebs_buffer_size, GFP_KERNEL, node);
if (unlikely(!buffer))
return -ENOMEM;
@ -286,7 +295,7 @@ static int alloc_pebs_buffer(int cpu)
per_cpu(insn_buffer, cpu) = ibuffer;
}
max = PEBS_BUFFER_SIZE / x86_pmu.pebs_record_size;
max = x86_pmu.pebs_buffer_size / x86_pmu.pebs_record_size;
ds->pebs_buffer_base = (u64)(unsigned long)buffer;
ds->pebs_index = ds->pebs_buffer_base;
@ -722,6 +731,30 @@ struct event_constraint intel_hsw_pebs_event_constraints[] = {
EVENT_CONSTRAINT_END
};
struct event_constraint intel_bdw_pebs_event_constraints[] = {
INTEL_FLAGS_UEVENT_CONSTRAINT(0x01c0, 0x2), /* INST_RETIRED.PRECDIST */
INTEL_PLD_CONSTRAINT(0x01cd, 0xf), /* MEM_TRANS_RETIRED.* */
/* UOPS_RETIRED.ALL, inv=1, cmask=16 (cycles:p). */
INTEL_FLAGS_EVENT_CONSTRAINT(0x108001c2, 0xf),
/* INST_RETIRED.PREC_DIST, inv=1, cmask=16 (cycles:ppp). */
INTEL_FLAGS_EVENT_CONSTRAINT(0x108001c0, 0x2),
INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_NA(0x01c2, 0xf), /* UOPS_RETIRED.ALL */
INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(0x11d0, 0xf), /* MEM_UOPS_RETIRED.STLB_MISS_LOADS */
INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(0x21d0, 0xf), /* MEM_UOPS_RETIRED.LOCK_LOADS */
INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(0x41d0, 0xf), /* MEM_UOPS_RETIRED.SPLIT_LOADS */
INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(0x81d0, 0xf), /* MEM_UOPS_RETIRED.ALL_LOADS */
INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_ST(0x12d0, 0xf), /* MEM_UOPS_RETIRED.STLB_MISS_STORES */
INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_ST(0x42d0, 0xf), /* MEM_UOPS_RETIRED.SPLIT_STORES */
INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_ST(0x82d0, 0xf), /* MEM_UOPS_RETIRED.ALL_STORES */
INTEL_FLAGS_EVENT_CONSTRAINT_DATALA_LD(0xd1, 0xf), /* MEM_LOAD_UOPS_RETIRED.* */
INTEL_FLAGS_EVENT_CONSTRAINT_DATALA_LD(0xd2, 0xf), /* MEM_LOAD_UOPS_L3_HIT_RETIRED.* */
INTEL_FLAGS_EVENT_CONSTRAINT_DATALA_LD(0xd3, 0xf), /* MEM_LOAD_UOPS_L3_MISS_RETIRED.* */
/* Allow all events as PEBS with no flags */
INTEL_ALL_EVENT_CONSTRAINT(0, 0xf),
EVENT_CONSTRAINT_END
};
struct event_constraint intel_skl_pebs_event_constraints[] = {
INTEL_FLAGS_UEVENT_CONSTRAINT(0x1c0, 0x2), /* INST_RETIRED.PREC_DIST */
/* INST_RETIRED.PREC_DIST, inv=1, cmask=16 (cycles:ppp). */
@ -1319,19 +1352,28 @@ void __init intel_ds_init(void)
x86_pmu.bts = boot_cpu_has(X86_FEATURE_BTS);
x86_pmu.pebs = boot_cpu_has(X86_FEATURE_PEBS);
x86_pmu.pebs_buffer_size = PEBS_BUFFER_SIZE;
if (x86_pmu.pebs) {
char pebs_type = x86_pmu.intel_cap.pebs_trap ? '+' : '-';
int format = x86_pmu.intel_cap.pebs_format;
switch (format) {
case 0:
printk(KERN_CONT "PEBS fmt0%c, ", pebs_type);
pr_cont("PEBS fmt0%c, ", pebs_type);
x86_pmu.pebs_record_size = sizeof(struct pebs_record_core);
/*
* Using >PAGE_SIZE buffers makes the WRMSR to
* PERF_GLOBAL_CTRL in intel_pmu_enable_all()
* mysteriously hang on Core2.
*
* As a workaround, we don't do this.
*/
x86_pmu.pebs_buffer_size = PAGE_SIZE;
x86_pmu.drain_pebs = intel_pmu_drain_pebs_core;
break;
case 1:
printk(KERN_CONT "PEBS fmt1%c, ", pebs_type);
pr_cont("PEBS fmt1%c, ", pebs_type);
x86_pmu.pebs_record_size = sizeof(struct pebs_record_nhm);
x86_pmu.drain_pebs = intel_pmu_drain_pebs_nhm;
break;
@ -1351,7 +1393,7 @@ void __init intel_ds_init(void)
break;
default:
printk(KERN_CONT "no PEBS fmt%d%c, ", format, pebs_type);
pr_cont("no PEBS fmt%d%c, ", format, pebs_type);
x86_pmu.pebs = 0;
}
}

View File

@ -5,7 +5,7 @@
#include <asm/hardirq.h>
#include "perf_event.h"
#include "../perf_event.h"
static const u64 knc_perfmon_event_map[] =
{
@ -263,7 +263,9 @@ again:
goto again;
done:
knc_pmu_enable_all(0);
/* Only restore PMU state when it's active. See x86_pmu_disable(). */
if (cpuc->enabled)
knc_pmu_enable_all(0);
return handled;
}

View File

@ -5,7 +5,7 @@
#include <asm/msr.h>
#include <asm/insn.h>
#include "perf_event.h"
#include "../perf_event.h"
enum {
LBR_FORMAT_32 = 0x00,

View File

@ -13,7 +13,7 @@
#include <asm/hardirq.h>
#include <asm/apic.h>
#include "perf_event.h"
#include "../perf_event.h"
#define P4_CNTR_LIMIT 3
/*

View File

@ -1,7 +1,7 @@
#include <linux/perf_event.h>
#include <linux/types.h>
#include "perf_event.h"
#include "../perf_event.h"
/*
* Not sure about some of these

View File

@ -29,8 +29,8 @@
#include <asm/io.h>
#include <asm/intel_pt.h>
#include "perf_event.h"
#include "intel_pt.h"
#include "../perf_event.h"
#include "pt.h"
static DEFINE_PER_CPU(struct pt, pt_ctx);

View File

@ -44,11 +44,14 @@
* the duration of the measurement. Tools may use a function such as
* ldexp(raw_count, -32);
*/
#define pr_fmt(fmt) "RAPL PMU: " fmt
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/perf_event.h>
#include <asm/cpu_device_id.h>
#include "perf_event.h"
#include "../perf_event.h"
/*
* RAPL energy status counters
@ -107,7 +110,7 @@ static ssize_t __rapl_##_var##_show(struct kobject *kobj, \
static struct kobj_attribute format_attr_##_var = \
__ATTR(_name, 0444, __rapl_##_var##_show, NULL)
#define RAPL_CNTR_WIDTH 32 /* 32-bit rapl counters */
#define RAPL_CNTR_WIDTH 32
#define RAPL_EVENT_ATTR_STR(_name, v, str) \
static struct perf_pmu_events_attr event_attr_##v = { \
@ -117,23 +120,33 @@ static struct perf_pmu_events_attr event_attr_##v = { \
};
struct rapl_pmu {
spinlock_t lock;
int n_active; /* number of active events */
struct list_head active_list;
struct pmu *pmu; /* pointer to rapl_pmu_class */
ktime_t timer_interval; /* in ktime_t unit */
struct hrtimer hrtimer;
raw_spinlock_t lock;
int n_active;
int cpu;
struct list_head active_list;
struct pmu *pmu;
ktime_t timer_interval;
struct hrtimer hrtimer;
};
static int rapl_hw_unit[NR_RAPL_DOMAINS] __read_mostly; /* 1/2^hw_unit Joule */
static struct pmu rapl_pmu_class;
struct rapl_pmus {
struct pmu pmu;
unsigned int maxpkg;
struct rapl_pmu *pmus[];
};
/* 1/2^hw_unit Joule */
static int rapl_hw_unit[NR_RAPL_DOMAINS] __read_mostly;
static struct rapl_pmus *rapl_pmus;
static cpumask_t rapl_cpu_mask;
static int rapl_cntr_mask;
static unsigned int rapl_cntr_mask;
static u64 rapl_timer_ms;
static DEFINE_PER_CPU(struct rapl_pmu *, rapl_pmu);
static DEFINE_PER_CPU(struct rapl_pmu *, rapl_pmu_to_free);
static inline struct rapl_pmu *cpu_to_rapl_pmu(unsigned int cpu)
{
return rapl_pmus->pmus[topology_logical_package_id(cpu)];
}
static struct x86_pmu_quirk *rapl_quirks;
static inline u64 rapl_read_counter(struct perf_event *event)
{
u64 raw;
@ -141,19 +154,10 @@ static inline u64 rapl_read_counter(struct perf_event *event)
return raw;
}
#define rapl_add_quirk(func_) \
do { \
static struct x86_pmu_quirk __quirk __initdata = { \
.func = func_, \
}; \
__quirk.next = rapl_quirks; \
rapl_quirks = &__quirk; \
} while (0)
static inline u64 rapl_scale(u64 v, int cfg)
{
if (cfg > NR_RAPL_DOMAINS) {
pr_warn("invalid domain %d, failed to scale data\n", cfg);
pr_warn("Invalid domain %d, failed to scale data\n", cfg);
return v;
}
/*
@ -206,27 +210,21 @@ static void rapl_start_hrtimer(struct rapl_pmu *pmu)
HRTIMER_MODE_REL_PINNED);
}
static void rapl_stop_hrtimer(struct rapl_pmu *pmu)
{
hrtimer_cancel(&pmu->hrtimer);
}
static enum hrtimer_restart rapl_hrtimer_handle(struct hrtimer *hrtimer)
{
struct rapl_pmu *pmu = __this_cpu_read(rapl_pmu);
struct rapl_pmu *pmu = container_of(hrtimer, struct rapl_pmu, hrtimer);
struct perf_event *event;
unsigned long flags;
if (!pmu->n_active)
return HRTIMER_NORESTART;
spin_lock_irqsave(&pmu->lock, flags);
raw_spin_lock_irqsave(&pmu->lock, flags);
list_for_each_entry(event, &pmu->active_list, active_entry) {
list_for_each_entry(event, &pmu->active_list, active_entry)
rapl_event_update(event);
}
spin_unlock_irqrestore(&pmu->lock, flags);
raw_spin_unlock_irqrestore(&pmu->lock, flags);
hrtimer_forward_now(hrtimer, pmu->timer_interval);
@ -260,28 +258,28 @@ static void __rapl_pmu_event_start(struct rapl_pmu *pmu,
static void rapl_pmu_event_start(struct perf_event *event, int mode)
{
struct rapl_pmu *pmu = __this_cpu_read(rapl_pmu);
struct rapl_pmu *pmu = event->pmu_private;
unsigned long flags;
spin_lock_irqsave(&pmu->lock, flags);
raw_spin_lock_irqsave(&pmu->lock, flags);
__rapl_pmu_event_start(pmu, event);
spin_unlock_irqrestore(&pmu->lock, flags);
raw_spin_unlock_irqrestore(&pmu->lock, flags);
}
static void rapl_pmu_event_stop(struct perf_event *event, int mode)
{
struct rapl_pmu *pmu = __this_cpu_read(rapl_pmu);
struct rapl_pmu *pmu = event->pmu_private;
struct hw_perf_event *hwc = &event->hw;
unsigned long flags;
spin_lock_irqsave(&pmu->lock, flags);
raw_spin_lock_irqsave(&pmu->lock, flags);
/* mark event as deactivated and stopped */
if (!(hwc->state & PERF_HES_STOPPED)) {
WARN_ON_ONCE(pmu->n_active <= 0);
pmu->n_active--;
if (pmu->n_active == 0)
rapl_stop_hrtimer(pmu);
hrtimer_cancel(&pmu->hrtimer);
list_del(&event->active_entry);
@ -299,23 +297,23 @@ static void rapl_pmu_event_stop(struct perf_event *event, int mode)
hwc->state |= PERF_HES_UPTODATE;
}
spin_unlock_irqrestore(&pmu->lock, flags);
raw_spin_unlock_irqrestore(&pmu->lock, flags);
}
static int rapl_pmu_event_add(struct perf_event *event, int mode)
{
struct rapl_pmu *pmu = __this_cpu_read(rapl_pmu);
struct rapl_pmu *pmu = event->pmu_private;
struct hw_perf_event *hwc = &event->hw;
unsigned long flags;
spin_lock_irqsave(&pmu->lock, flags);
raw_spin_lock_irqsave(&pmu->lock, flags);
hwc->state = PERF_HES_UPTODATE | PERF_HES_STOPPED;
if (mode & PERF_EF_START)
__rapl_pmu_event_start(pmu, event);
spin_unlock_irqrestore(&pmu->lock, flags);
raw_spin_unlock_irqrestore(&pmu->lock, flags);
return 0;
}
@ -329,15 +327,19 @@ static int rapl_pmu_event_init(struct perf_event *event)
{
u64 cfg = event->attr.config & RAPL_EVENT_MASK;
int bit, msr, ret = 0;
struct rapl_pmu *pmu;
/* only look at RAPL events */
if (event->attr.type != rapl_pmu_class.type)
if (event->attr.type != rapl_pmus->pmu.type)
return -ENOENT;
/* check only supported bits are set */
if (event->attr.config & ~RAPL_EVENT_MASK)
return -EINVAL;
if (event->cpu < 0)
return -EINVAL;
/*
* check event is known (determines counter)
*/
@ -376,6 +378,9 @@ static int rapl_pmu_event_init(struct perf_event *event)
return -EINVAL;
/* must be done before validate_group */
pmu = cpu_to_rapl_pmu(event->cpu);
event->cpu = pmu->cpu;
event->pmu_private = pmu;
event->hw.event_base = msr;
event->hw.config = cfg;
event->hw.idx = bit;
@ -506,139 +511,62 @@ const struct attribute_group *rapl_attr_groups[] = {
NULL,
};
static struct pmu rapl_pmu_class = {
.attr_groups = rapl_attr_groups,
.task_ctx_nr = perf_invalid_context, /* system-wide only */
.event_init = rapl_pmu_event_init,
.add = rapl_pmu_event_add, /* must have */
.del = rapl_pmu_event_del, /* must have */
.start = rapl_pmu_event_start,
.stop = rapl_pmu_event_stop,
.read = rapl_pmu_event_read,
};
static void rapl_cpu_exit(int cpu)
{
struct rapl_pmu *pmu = per_cpu(rapl_pmu, cpu);
int i, phys_id = topology_physical_package_id(cpu);
int target = -1;
struct rapl_pmu *pmu = cpu_to_rapl_pmu(cpu);
int target;
/* find a new cpu on same package */
for_each_online_cpu(i) {
if (i == cpu)
continue;
if (phys_id == topology_physical_package_id(i)) {
target = i;
break;
}
}
/*
* clear cpu from cpumask
* if was set in cpumask and still some cpu on package,
* then move to new cpu
*/
if (cpumask_test_and_clear_cpu(cpu, &rapl_cpu_mask) && target >= 0)
/* Check if exiting cpu is used for collecting rapl events */
if (!cpumask_test_and_clear_cpu(cpu, &rapl_cpu_mask))
return;
pmu->cpu = -1;
/* Find a new cpu to collect rapl events */
target = cpumask_any_but(topology_core_cpumask(cpu), cpu);
/* Migrate rapl events to the new target */
if (target < nr_cpu_ids) {
cpumask_set_cpu(target, &rapl_cpu_mask);
WARN_ON(cpumask_empty(&rapl_cpu_mask));
/*
* migrate events and context to new cpu
*/
if (target >= 0)
pmu->cpu = target;
perf_pmu_migrate_context(pmu->pmu, cpu, target);
/* cancel overflow polling timer for CPU */
rapl_stop_hrtimer(pmu);
}
}
static void rapl_cpu_init(int cpu)
{
int i, phys_id = topology_physical_package_id(cpu);
struct rapl_pmu *pmu = cpu_to_rapl_pmu(cpu);
int target;
/* check if phys_is is already covered */
for_each_cpu(i, &rapl_cpu_mask) {
if (phys_id == topology_physical_package_id(i))
return;
}
/* was not found, so add it */
cpumask_set_cpu(cpu, &rapl_cpu_mask);
}
static __init void rapl_hsw_server_quirk(void)
{
/*
* DRAM domain on HSW server has fixed energy unit which can be
* different than the unit from power unit MSR.
* "Intel Xeon Processor E5-1600 and E5-2600 v3 Product Families, V2
* of 2. Datasheet, September 2014, Reference Number: 330784-001 "
* Check if there is an online cpu in the package which collects rapl
* events already.
*/
rapl_hw_unit[RAPL_IDX_RAM_NRG_STAT] = 16;
target = cpumask_any_and(&rapl_cpu_mask, topology_core_cpumask(cpu));
if (target < nr_cpu_ids)
return;
cpumask_set_cpu(cpu, &rapl_cpu_mask);
pmu->cpu = cpu;
}
static int rapl_cpu_prepare(int cpu)
{
struct rapl_pmu *pmu = per_cpu(rapl_pmu, cpu);
int phys_id = topology_physical_package_id(cpu);
u64 ms;
struct rapl_pmu *pmu = cpu_to_rapl_pmu(cpu);
if (pmu)
return 0;
if (phys_id < 0)
return -1;
pmu = kzalloc_node(sizeof(*pmu), GFP_KERNEL, cpu_to_node(cpu));
if (!pmu)
return -1;
spin_lock_init(&pmu->lock);
return -ENOMEM;
raw_spin_lock_init(&pmu->lock);
INIT_LIST_HEAD(&pmu->active_list);
pmu->pmu = &rapl_pmu_class;
/*
* use reference of 200W for scaling the timeout
* to avoid missing counter overflows.
* 200W = 200 Joules/sec
* divide interval by 2 to avoid lockstep (2 * 100)
* if hw unit is 32, then we use 2 ms 1/200/2
*/
if (rapl_hw_unit[0] < 32)
ms = (1000 / (2 * 100)) * (1ULL << (32 - rapl_hw_unit[0] - 1));
else
ms = 2;
pmu->timer_interval = ms_to_ktime(ms);
pmu->pmu = &rapl_pmus->pmu;
pmu->timer_interval = ms_to_ktime(rapl_timer_ms);
pmu->cpu = -1;
rapl_hrtimer_init(pmu);
/* set RAPL pmu for this cpu for now */
per_cpu(rapl_pmu, cpu) = pmu;
per_cpu(rapl_pmu_to_free, cpu) = NULL;
return 0;
}
static void rapl_cpu_kfree(int cpu)
{
struct rapl_pmu *pmu = per_cpu(rapl_pmu_to_free, cpu);
kfree(pmu);
per_cpu(rapl_pmu_to_free, cpu) = NULL;
}
static int rapl_cpu_dying(int cpu)
{
struct rapl_pmu *pmu = per_cpu(rapl_pmu, cpu);
if (!pmu)
return 0;
per_cpu(rapl_pmu, cpu) = NULL;
per_cpu(rapl_pmu_to_free, cpu) = pmu;
rapl_pmus->pmus[topology_logical_package_id(cpu)] = pmu;
return 0;
}
@ -651,28 +579,20 @@ static int rapl_cpu_notifier(struct notifier_block *self,
case CPU_UP_PREPARE:
rapl_cpu_prepare(cpu);
break;
case CPU_STARTING:
case CPU_DOWN_FAILED:
case CPU_ONLINE:
rapl_cpu_init(cpu);
break;
case CPU_UP_CANCELED:
case CPU_DYING:
rapl_cpu_dying(cpu);
break;
case CPU_ONLINE:
case CPU_DEAD:
rapl_cpu_kfree(cpu);
break;
case CPU_DOWN_PREPARE:
rapl_cpu_exit(cpu);
break;
default:
break;
}
return NOTIFY_OK;
}
static int rapl_check_hw_unit(void)
static int rapl_check_hw_unit(bool apply_quirk)
{
u64 msr_rapl_power_unit_bits;
int i;
@ -683,28 +603,107 @@ static int rapl_check_hw_unit(void)
for (i = 0; i < NR_RAPL_DOMAINS; i++)
rapl_hw_unit[i] = (msr_rapl_power_unit_bits >> 8) & 0x1FULL;
/*
* DRAM domain on HSW server and KNL has fixed energy unit which can be
* different than the unit from power unit MSR. See
* "Intel Xeon Processor E5-1600 and E5-2600 v3 Product Families, V2
* of 2. Datasheet, September 2014, Reference Number: 330784-001 "
*/
if (apply_quirk)
rapl_hw_unit[RAPL_IDX_RAM_NRG_STAT] = 16;
/*
* Calculate the timer rate:
* Use reference of 200W for scaling the timeout to avoid counter
* overflows. 200W = 200 Joules/sec
* Divide interval by 2 to avoid lockstep (2 * 100)
* if hw unit is 32, then we use 2 ms 1/200/2
*/
rapl_timer_ms = 2;
if (rapl_hw_unit[0] < 32) {
rapl_timer_ms = (1000 / (2 * 100));
rapl_timer_ms *= (1ULL << (32 - rapl_hw_unit[0] - 1));
}
return 0;
}
static const struct x86_cpu_id rapl_cpu_match[] = {
static void __init rapl_advertise(void)
{
int i;
pr_info("API unit is 2^-32 Joules, %d fixed counters, %llu ms ovfl timer\n",
hweight32(rapl_cntr_mask), rapl_timer_ms);
for (i = 0; i < NR_RAPL_DOMAINS; i++) {
if (rapl_cntr_mask & (1 << i)) {
pr_info("hw unit of domain %s 2^-%d Joules\n",
rapl_domain_names[i], rapl_hw_unit[i]);
}
}
}
static int __init rapl_prepare_cpus(void)
{
unsigned int cpu, pkg;
int ret;
for_each_online_cpu(cpu) {
pkg = topology_logical_package_id(cpu);
if (rapl_pmus->pmus[pkg])
continue;
ret = rapl_cpu_prepare(cpu);
if (ret)
return ret;
rapl_cpu_init(cpu);
}
return 0;
}
static void __init cleanup_rapl_pmus(void)
{
int i;
for (i = 0; i < rapl_pmus->maxpkg; i++)
kfree(rapl_pmus->pmus + i);
kfree(rapl_pmus);
}
static int __init init_rapl_pmus(void)
{
int maxpkg = topology_max_packages();
size_t size;
size = sizeof(*rapl_pmus) + maxpkg * sizeof(struct rapl_pmu *);
rapl_pmus = kzalloc(size, GFP_KERNEL);
if (!rapl_pmus)
return -ENOMEM;
rapl_pmus->maxpkg = maxpkg;
rapl_pmus->pmu.attr_groups = rapl_attr_groups;
rapl_pmus->pmu.task_ctx_nr = perf_invalid_context;
rapl_pmus->pmu.event_init = rapl_pmu_event_init;
rapl_pmus->pmu.add = rapl_pmu_event_add;
rapl_pmus->pmu.del = rapl_pmu_event_del;
rapl_pmus->pmu.start = rapl_pmu_event_start;
rapl_pmus->pmu.stop = rapl_pmu_event_stop;
rapl_pmus->pmu.read = rapl_pmu_event_read;
return 0;
}
static const struct x86_cpu_id rapl_cpu_match[] __initconst = {
[0] = { .vendor = X86_VENDOR_INTEL, .family = 6 },
[1] = {},
};
static int __init rapl_pmu_init(void)
{
struct rapl_pmu *pmu;
int cpu, ret;
struct x86_pmu_quirk *quirk;
int i;
bool apply_quirk = false;
int ret;
/*
* check for Intel processor family 6
*/
if (!x86_match_cpu(rapl_cpu_match))
return 0;
return -ENODEV;
/* check supported CPU */
switch (boot_cpu_data.x86_model) {
case 42: /* Sandy Bridge */
case 58: /* Ivy Bridge */
@ -712,7 +711,7 @@ static int __init rapl_pmu_init(void)
rapl_pmu_events_group.attrs = rapl_events_cln_attr;
break;
case 63: /* Haswell-Server */
rapl_add_quirk(rapl_hsw_server_quirk);
apply_quirk = true;
rapl_cntr_mask = RAPL_IDX_SRV;
rapl_pmu_events_group.attrs = rapl_events_srv_attr;
break;
@ -728,56 +727,41 @@ static int __init rapl_pmu_init(void)
rapl_pmu_events_group.attrs = rapl_events_srv_attr;
break;
case 87: /* Knights Landing */
rapl_add_quirk(rapl_hsw_server_quirk);
apply_quirk = true;
rapl_cntr_mask = RAPL_IDX_KNL;
rapl_pmu_events_group.attrs = rapl_events_knl_attr;
break;
default:
/* unsupported */
return 0;
return -ENODEV;
}
ret = rapl_check_hw_unit();
ret = rapl_check_hw_unit(apply_quirk);
if (ret)
return ret;
ret = init_rapl_pmus();
if (ret)
return ret;
/* run cpu model quirks */
for (quirk = rapl_quirks; quirk; quirk = quirk->next)
quirk->func();
cpu_notifier_register_begin();
for_each_online_cpu(cpu) {
ret = rapl_cpu_prepare(cpu);
if (ret)
goto out;
rapl_cpu_init(cpu);
}
ret = rapl_prepare_cpus();
if (ret)
goto out;
ret = perf_pmu_register(&rapl_pmus->pmu, "power", -1);
if (ret)
goto out;
__perf_cpu_notifier(rapl_cpu_notifier);
ret = perf_pmu_register(&rapl_pmu_class, "power", -1);
if (WARN_ON(ret)) {
pr_info("RAPL PMU detected, registration failed (%d), RAPL PMU disabled\n", ret);
cpu_notifier_register_done();
return -1;
}
pmu = __this_cpu_read(rapl_pmu);
pr_info("RAPL PMU detected,"
" API unit is 2^-32 Joules,"
" %d fixed counters"
" %llu ms ovfl timer\n",
hweight32(rapl_cntr_mask),
ktime_to_ms(pmu->timer_interval));
for (i = 0; i < NR_RAPL_DOMAINS; i++) {
if (rapl_cntr_mask & (1 << i)) {
pr_info("hw unit of domain %s 2^-%d Joules\n",
rapl_domain_names[i], rapl_hw_unit[i]);
}
}
out:
cpu_notifier_register_done();
rapl_advertise();
return 0;
out:
pr_warn("Initialization failed (%d), disabled\n", ret);
cleanup_rapl_pmus();
cpu_notifier_register_done();
return ret;
}
device_initcall(rapl_pmu_init);

View File

@ -1,8 +1,10 @@
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/pci.h>
#include <asm/apicdef.h>
#include <linux/perf_event.h>
#include "perf_event.h"
#include "../perf_event.h"
#define UNCORE_PMU_NAME_LEN 32
#define UNCORE_PMU_HRTIMER_INTERVAL (60LL * NSEC_PER_SEC)
@ -19,11 +21,12 @@
#define UNCORE_EXTRA_PCI_DEV 0xff
#define UNCORE_EXTRA_PCI_DEV_MAX 3
/* support up to 8 sockets */
#define UNCORE_SOCKET_MAX 8
#define UNCORE_EVENT_CONSTRAINT(c, n) EVENT_CONSTRAINT(c, n, 0xff)
struct pci_extra_dev {
struct pci_dev *dev[UNCORE_EXTRA_PCI_DEV_MAX];
};
struct intel_uncore_ops;
struct intel_uncore_pmu;
struct intel_uncore_box;
@ -61,6 +64,7 @@ struct intel_uncore_type {
struct intel_uncore_ops {
void (*init_box)(struct intel_uncore_box *);
void (*exit_box)(struct intel_uncore_box *);
void (*disable_box)(struct intel_uncore_box *);
void (*enable_box)(struct intel_uncore_box *);
void (*disable_event)(struct intel_uncore_box *, struct perf_event *);
@ -73,13 +77,14 @@ struct intel_uncore_ops {
};
struct intel_uncore_pmu {
struct pmu pmu;
char name[UNCORE_PMU_NAME_LEN];
int pmu_idx;
int func_id;
struct intel_uncore_type *type;
struct intel_uncore_box ** __percpu box;
struct list_head box_list;
struct pmu pmu;
char name[UNCORE_PMU_NAME_LEN];
int pmu_idx;
int func_id;
bool registered;
atomic_t activeboxes;
struct intel_uncore_type *type;
struct intel_uncore_box **boxes;
};
struct intel_uncore_extra_reg {
@ -89,7 +94,8 @@ struct intel_uncore_extra_reg {
};
struct intel_uncore_box {
int phys_id;
int pci_phys_id;
int pkgid;
int n_active; /* number of active events */
int n_events;
int cpu; /* cpu to collect events */
@ -123,7 +129,6 @@ struct pci2phy_map {
int pbus_to_physid[256];
};
int uncore_pcibus_to_physid(struct pci_bus *bus);
struct pci2phy_map *__find_pci2phy_map(int segment);
ssize_t uncore_event_show(struct kobject *kobj,
@ -305,14 +310,30 @@ static inline void uncore_box_init(struct intel_uncore_box *box)
}
}
static inline bool uncore_box_is_fake(struct intel_uncore_box *box)
static inline void uncore_box_exit(struct intel_uncore_box *box)
{
return (box->phys_id < 0);
if (test_and_clear_bit(UNCORE_BOX_FLAG_INITIATED, &box->flags)) {
if (box->pmu->type->ops->exit_box)
box->pmu->type->ops->exit_box(box);
}
}
static inline bool uncore_box_is_fake(struct intel_uncore_box *box)
{
return (box->pkgid < 0);
}
static inline struct intel_uncore_pmu *uncore_event_to_pmu(struct perf_event *event)
{
return container_of(event->pmu, struct intel_uncore_pmu, pmu);
}
static inline struct intel_uncore_box *uncore_event_to_box(struct perf_event *event)
{
return event->pmu_private;
}
struct intel_uncore_pmu *uncore_event_to_pmu(struct perf_event *event);
struct intel_uncore_box *uncore_pmu_to_box(struct intel_uncore_pmu *pmu, int cpu);
struct intel_uncore_box *uncore_event_to_box(struct perf_event *event);
u64 uncore_msr_read_counter(struct intel_uncore_box *box, struct perf_event *event);
void uncore_pmu_start_hrtimer(struct intel_uncore_box *box);
void uncore_pmu_cancel_hrtimer(struct intel_uncore_box *box);
@ -328,7 +349,7 @@ extern struct intel_uncore_type **uncore_pci_uncores;
extern struct pci_driver *uncore_pci_driver;
extern raw_spinlock_t pci2phy_map_lock;
extern struct list_head pci2phy_map_head;
extern struct pci_dev *uncore_extra_pci_dev[UNCORE_SOCKET_MAX][UNCORE_EXTRA_PCI_DEV_MAX];
extern struct pci_extra_dev *uncore_extra_pci_dev;
extern struct event_constraint uncore_constraint_empty;
/* perf_event_intel_uncore_snb.c */

View File

@ -1,5 +1,5 @@
/* Nehalem-EX/Westmere-EX uncore support */
#include "perf_event_intel_uncore.h"
#include "uncore.h"
/* NHM-EX event control */
#define NHMEX_PMON_CTL_EV_SEL_MASK 0x000000ff
@ -201,6 +201,11 @@ static void nhmex_uncore_msr_init_box(struct intel_uncore_box *box)
wrmsrl(NHMEX_U_MSR_PMON_GLOBAL_CTL, NHMEX_U_PMON_GLOBAL_EN_ALL);
}
static void nhmex_uncore_msr_exit_box(struct intel_uncore_box *box)
{
wrmsrl(NHMEX_U_MSR_PMON_GLOBAL_CTL, 0);
}
static void nhmex_uncore_msr_disable_box(struct intel_uncore_box *box)
{
unsigned msr = uncore_msr_box_ctl(box);
@ -250,6 +255,7 @@ static void nhmex_uncore_msr_enable_event(struct intel_uncore_box *box, struct p
#define NHMEX_UNCORE_OPS_COMMON_INIT() \
.init_box = nhmex_uncore_msr_init_box, \
.exit_box = nhmex_uncore_msr_exit_box, \
.disable_box = nhmex_uncore_msr_disable_box, \
.enable_box = nhmex_uncore_msr_enable_box, \
.disable_event = nhmex_uncore_msr_disable_event, \

View File

@ -1,5 +1,5 @@
/* Nehalem/SandBridge/Haswell uncore support */
#include "perf_event_intel_uncore.h"
#include "uncore.h"
/* Uncore IMC PCI IDs */
#define PCI_DEVICE_ID_INTEL_SNB_IMC 0x0100
@ -95,6 +95,12 @@ static void snb_uncore_msr_init_box(struct intel_uncore_box *box)
}
}
static void snb_uncore_msr_exit_box(struct intel_uncore_box *box)
{
if (box->pmu->pmu_idx == 0)
wrmsrl(SNB_UNC_PERF_GLOBAL_CTL, 0);
}
static struct uncore_event_desc snb_uncore_events[] = {
INTEL_UNCORE_EVENT_DESC(clockticks, "event=0xff,umask=0x00"),
{ /* end: all zeroes */ },
@ -116,6 +122,7 @@ static struct attribute_group snb_uncore_format_group = {
static struct intel_uncore_ops snb_uncore_msr_ops = {
.init_box = snb_uncore_msr_init_box,
.exit_box = snb_uncore_msr_exit_box,
.disable_event = snb_uncore_msr_disable_event,
.enable_event = snb_uncore_msr_enable_event,
.read_counter = uncore_msr_read_counter,
@ -231,6 +238,11 @@ static void snb_uncore_imc_init_box(struct intel_uncore_box *box)
box->hrtimer_duration = UNCORE_SNB_IMC_HRTIMER_INTERVAL;
}
static void snb_uncore_imc_exit_box(struct intel_uncore_box *box)
{
iounmap(box->io_addr);
}
static void snb_uncore_imc_enable_box(struct intel_uncore_box *box)
{}
@ -301,6 +313,7 @@ static int snb_uncore_imc_event_init(struct perf_event *event)
return -EINVAL;
event->cpu = box->cpu;
event->pmu_private = box;
event->hw.idx = -1;
event->hw.last_tag = ~0ULL;
@ -458,6 +471,7 @@ static struct pmu snb_uncore_imc_pmu = {
static struct intel_uncore_ops snb_uncore_imc_ops = {
.init_box = snb_uncore_imc_init_box,
.exit_box = snb_uncore_imc_exit_box,
.enable_box = snb_uncore_imc_enable_box,
.disable_box = snb_uncore_imc_disable_box,
.disable_event = snb_uncore_imc_disable_event,

View File

@ -1,6 +1,5 @@
/* SandyBridge-EP/IvyTown uncore support */
#include "perf_event_intel_uncore.h"
#include "uncore.h"
/* SNB-EP Box level control */
#define SNBEP_PMON_BOX_CTL_RST_CTRL (1 << 0)
@ -987,7 +986,9 @@ static void snbep_qpi_enable_event(struct intel_uncore_box *box, struct perf_eve
if (reg1->idx != EXTRA_REG_NONE) {
int idx = box->pmu->pmu_idx + SNBEP_PCI_QPI_PORT0_FILTER;
struct pci_dev *filter_pdev = uncore_extra_pci_dev[box->phys_id][idx];
int pkg = topology_phys_to_logical_pkg(box->pci_phys_id);
struct pci_dev *filter_pdev = uncore_extra_pci_dev[pkg].dev[idx];
if (filter_pdev) {
pci_write_config_dword(filter_pdev, reg1->reg,
(u32)reg1->config);
@ -2521,14 +2522,16 @@ static struct intel_uncore_type *hswep_msr_uncores[] = {
void hswep_uncore_cpu_init(void)
{
int pkg = topology_phys_to_logical_pkg(0);
if (hswep_uncore_cbox.num_boxes > boot_cpu_data.x86_max_cores)
hswep_uncore_cbox.num_boxes = boot_cpu_data.x86_max_cores;
/* Detect 6-8 core systems with only two SBOXes */
if (uncore_extra_pci_dev[0][HSWEP_PCI_PCU_3]) {
if (uncore_extra_pci_dev[pkg].dev[HSWEP_PCI_PCU_3]) {
u32 capid4;
pci_read_config_dword(uncore_extra_pci_dev[0][HSWEP_PCI_PCU_3],
pci_read_config_dword(uncore_extra_pci_dev[pkg].dev[HSWEP_PCI_PCU_3],
0x94, &capid4);
if (((capid4 >> 6) & 0x3) == 0)
hswep_uncore_sbox.num_boxes = 2;
@ -2875,11 +2878,13 @@ static struct intel_uncore_type bdx_uncore_sbox = {
.format_group = &hswep_uncore_sbox_format_group,
};
#define BDX_MSR_UNCORE_SBOX 3
static struct intel_uncore_type *bdx_msr_uncores[] = {
&bdx_uncore_ubox,
&bdx_uncore_cbox,
&bdx_uncore_sbox,
&hswep_uncore_pcu,
&bdx_uncore_sbox,
NULL,
};
@ -2888,6 +2893,10 @@ void bdx_uncore_cpu_init(void)
if (bdx_uncore_cbox.num_boxes > boot_cpu_data.x86_max_cores)
bdx_uncore_cbox.num_boxes = boot_cpu_data.x86_max_cores;
uncore_msr_uncores = bdx_msr_uncores;
/* BDX-DE doesn't have SBOX */
if (boot_cpu_data.x86_model == 86)
uncore_msr_uncores[BDX_MSR_UNCORE_SBOX] = NULL;
}
static struct intel_uncore_type bdx_uncore_ha = {

View File

@ -586,6 +586,7 @@ struct x86_pmu {
pebs_broken :1,
pebs_prec_dist :1;
int pebs_record_size;
int pebs_buffer_size;
void (*drain_pebs)(struct pt_regs *regs);
struct event_constraint *pebs_constraints;
void (*pebs_aliases)(struct perf_event *event);
@ -860,6 +861,8 @@ extern struct event_constraint intel_ivb_pebs_event_constraints[];
extern struct event_constraint intel_hsw_pebs_event_constraints[];
extern struct event_constraint intel_bdw_pebs_event_constraints[];
extern struct event_constraint intel_skl_pebs_event_constraints[];
struct event_constraint *intel_pebs_constraints(struct perf_event *event);
@ -904,6 +907,8 @@ void intel_pmu_lbr_init_skl(void);
void intel_pmu_lbr_init_knl(void);
void intel_pmu_pebs_data_source_nhm(void);
int intel_pmu_setup_lbr_filter(struct perf_event *event);
void intel_pt_interrupt(void);

View File

@ -256,7 +256,7 @@ extern int force_personality32;
instruction set this CPU supports. This could be done in user space,
but it's not easy, and we've already done it here. */
#define ELF_HWCAP (boot_cpu_data.x86_capability[0])
#define ELF_HWCAP (boot_cpu_data.x86_capability[CPUID_1_EDX])
/* This yields a string that ld.so will use to load implementation
specific libraries for optimization. This is more specific in

View File

@ -165,6 +165,7 @@ struct x86_pmu_capability {
#define GLOBAL_STATUS_ASIF BIT_ULL(60)
#define GLOBAL_STATUS_COUNTERS_FROZEN BIT_ULL(59)
#define GLOBAL_STATUS_LBRS_FROZEN BIT_ULL(58)
#define GLOBAL_STATUS_TRACE_TOPAPMI BIT_ULL(55)
/*
* IBS cpuid feature detection

View File

@ -129,6 +129,8 @@ struct cpuinfo_x86 {
u16 booted_cores;
/* Physical processor id: */
u16 phys_proc_id;
/* Logical processor id: */
u16 logical_proc_id;
/* Core id: */
u16 cpu_core_id;
/* Compute unit id */

View File

@ -119,12 +119,23 @@ static inline void setup_node_to_cpumask_map(void) { }
extern const struct cpumask *cpu_coregroup_mask(int cpu);
#define topology_logical_package_id(cpu) (cpu_data(cpu).logical_proc_id)
#define topology_physical_package_id(cpu) (cpu_data(cpu).phys_proc_id)
#define topology_core_id(cpu) (cpu_data(cpu).cpu_core_id)
#ifdef ENABLE_TOPO_DEFINES
#define topology_core_cpumask(cpu) (per_cpu(cpu_core_map, cpu))
#define topology_sibling_cpumask(cpu) (per_cpu(cpu_sibling_map, cpu))
extern unsigned int __max_logical_packages;
#define topology_max_packages() (__max_logical_packages)
int topology_update_package_map(unsigned int apicid, unsigned int cpu);
extern int topology_phys_to_logical_pkg(unsigned int pkg);
#else
#define topology_max_packages() (1)
static inline int
topology_update_package_map(unsigned int apicid, unsigned int cpu) { return 0; }
static inline int topology_phys_to_logical_pkg(unsigned int pkg) { return 0; }
#endif
static inline void arch_fix_phys_package_id(int num, u32 slot)

View File

@ -2077,6 +2077,20 @@ int generic_processor_info(int apicid, int version)
} else
cpu = cpumask_next_zero(-1, cpu_present_mask);
/*
* This can happen on physical hotplug. The sanity check at boot time
* is done from native_smp_prepare_cpus() after num_possible_cpus() is
* established.
*/
if (topology_update_package_map(apicid, cpu) < 0) {
int thiscpu = max + disabled_cpus;
pr_warning("ACPI: Package limit reached. Processor %d/0x%x ignored.\n",
thiscpu, apicid);
disabled_cpus++;
return -ENOSPC;
}
/*
* Validate version
*/

View File

@ -30,33 +30,11 @@ obj-$(CONFIG_CPU_SUP_CENTAUR) += centaur.o
obj-$(CONFIG_CPU_SUP_TRANSMETA_32) += transmeta.o
obj-$(CONFIG_CPU_SUP_UMC_32) += umc.o
obj-$(CONFIG_PERF_EVENTS) += perf_event.o
ifdef CONFIG_PERF_EVENTS
obj-$(CONFIG_CPU_SUP_AMD) += perf_event_amd.o perf_event_amd_uncore.o
ifdef CONFIG_AMD_IOMMU
obj-$(CONFIG_CPU_SUP_AMD) += perf_event_amd_iommu.o
endif
obj-$(CONFIG_CPU_SUP_INTEL) += perf_event_p6.o perf_event_knc.o perf_event_p4.o
obj-$(CONFIG_CPU_SUP_INTEL) += perf_event_intel_lbr.o perf_event_intel_ds.o perf_event_intel.o
obj-$(CONFIG_CPU_SUP_INTEL) += perf_event_intel_rapl.o perf_event_intel_cqm.o
obj-$(CONFIG_CPU_SUP_INTEL) += perf_event_intel_pt.o perf_event_intel_bts.o
obj-$(CONFIG_CPU_SUP_INTEL) += perf_event_intel_cstate.o
obj-$(CONFIG_PERF_EVENTS_INTEL_UNCORE) += perf_event_intel_uncore.o \
perf_event_intel_uncore_snb.o \
perf_event_intel_uncore_snbep.o \
perf_event_intel_uncore_nhmex.o
obj-$(CONFIG_CPU_SUP_INTEL) += perf_event_msr.o
obj-$(CONFIG_CPU_SUP_AMD) += perf_event_msr.o
endif
obj-$(CONFIG_X86_MCE) += mcheck/
obj-$(CONFIG_MTRR) += mtrr/
obj-$(CONFIG_MICROCODE) += microcode/
obj-$(CONFIG_X86_LOCAL_APIC) += perfctr-watchdog.o perf_event_amd_ibs.o
obj-$(CONFIG_X86_LOCAL_APIC) += perfctr-watchdog.o
obj-$(CONFIG_HYPERVISOR_GUEST) += vmware.o hypervisor.o mshyperv.o

View File

@ -117,7 +117,7 @@ static void init_amd_k6(struct cpuinfo_x86 *c)
void (*f_vide)(void);
u64 d, d2;
printk(KERN_INFO "AMD K6 stepping B detected - ");
pr_info("AMD K6 stepping B detected - ");
/*
* It looks like AMD fixed the 2.6.2 bug and improved indirect
@ -133,10 +133,9 @@ static void init_amd_k6(struct cpuinfo_x86 *c)
d = d2-d;
if (d > 20*K6_BUG_LOOP)
printk(KERN_CONT
"system stability may be impaired when more than 32 MB are used.\n");
pr_cont("system stability may be impaired when more than 32 MB are used.\n");
else
printk(KERN_CONT "probably OK (after B9730xxxx).\n");
pr_cont("probably OK (after B9730xxxx).\n");
}
/* K6 with old style WHCR */
@ -154,7 +153,7 @@ static void init_amd_k6(struct cpuinfo_x86 *c)
wbinvd();
wrmsr(MSR_K6_WHCR, l, h);
local_irq_restore(flags);
printk(KERN_INFO "Enabling old style K6 write allocation for %d Mb\n",
pr_info("Enabling old style K6 write allocation for %d Mb\n",
mbytes);
}
return;
@ -175,7 +174,7 @@ static void init_amd_k6(struct cpuinfo_x86 *c)
wbinvd();
wrmsr(MSR_K6_WHCR, l, h);
local_irq_restore(flags);
printk(KERN_INFO "Enabling new style K6 write allocation for %d Mb\n",
pr_info("Enabling new style K6 write allocation for %d Mb\n",
mbytes);
}
@ -202,7 +201,7 @@ static void init_amd_k7(struct cpuinfo_x86 *c)
*/
if (c->x86_model >= 6 && c->x86_model <= 10) {
if (!cpu_has(c, X86_FEATURE_XMM)) {
printk(KERN_INFO "Enabling disabled K7/SSE Support.\n");
pr_info("Enabling disabled K7/SSE Support.\n");
msr_clear_bit(MSR_K7_HWCR, 15);
set_cpu_cap(c, X86_FEATURE_XMM);
}
@ -216,9 +215,8 @@ static void init_amd_k7(struct cpuinfo_x86 *c)
if ((c->x86_model == 8 && c->x86_mask >= 1) || (c->x86_model > 8)) {
rdmsr(MSR_K7_CLK_CTL, l, h);
if ((l & 0xfff00000) != 0x20000000) {
printk(KERN_INFO
"CPU: CLK_CTL MSR was %x. Reprogramming to %x\n",
l, ((l & 0x000fffff)|0x20000000));
pr_info("CPU: CLK_CTL MSR was %x. Reprogramming to %x\n",
l, ((l & 0x000fffff)|0x20000000));
wrmsr(MSR_K7_CLK_CTL, (l & 0x000fffff)|0x20000000, h);
}
}
@ -485,7 +483,7 @@ static void bsp_init_amd(struct cpuinfo_x86 *c)
if (!rdmsrl_safe(MSR_K8_TSEG_ADDR, &tseg)) {
unsigned long pfn = tseg >> PAGE_SHIFT;
printk(KERN_DEBUG "tseg: %010llx\n", tseg);
pr_debug("tseg: %010llx\n", tseg);
if (pfn_range_is_mapped(pfn, pfn + 1))
set_memory_4k((unsigned long)__va(tseg), 1);
}
@ -500,8 +498,7 @@ static void bsp_init_amd(struct cpuinfo_x86 *c)
rdmsrl(MSR_K7_HWCR, val);
if (!(val & BIT(24)))
printk(KERN_WARNING FW_BUG "TSC doesn't count "
"with P0 frequency!\n");
pr_warn(FW_BUG "TSC doesn't count with P0 frequency!\n");
}
}

View File

@ -15,7 +15,7 @@ void __init check_bugs(void)
{
identify_boot_cpu();
#if !defined(CONFIG_SMP)
printk(KERN_INFO "CPU: ");
pr_info("CPU: ");
print_cpu_info(&boot_cpu_data);
#endif
alternative_instructions();

View File

@ -29,7 +29,7 @@ static void init_c3(struct cpuinfo_x86 *c)
rdmsr(MSR_VIA_FCR, lo, hi);
lo |= ACE_FCR; /* enable ACE unit */
wrmsr(MSR_VIA_FCR, lo, hi);
printk(KERN_INFO "CPU: Enabled ACE h/w crypto\n");
pr_info("CPU: Enabled ACE h/w crypto\n");
}
/* enable RNG unit, if present and disabled */
@ -37,7 +37,7 @@ static void init_c3(struct cpuinfo_x86 *c)
rdmsr(MSR_VIA_RNG, lo, hi);
lo |= RNG_ENABLE; /* enable RNG unit */
wrmsr(MSR_VIA_RNG, lo, hi);
printk(KERN_INFO "CPU: Enabled h/w RNG\n");
pr_info("CPU: Enabled h/w RNG\n");
}
/* store Centaur Extended Feature Flags as
@ -130,7 +130,7 @@ static void init_centaur(struct cpuinfo_x86 *c)
name = "C6";
fcr_set = ECX8|DSMC|EDCTLB|EMMX|ERETSTK;
fcr_clr = DPDC;
printk(KERN_NOTICE "Disabling bugged TSC.\n");
pr_notice("Disabling bugged TSC.\n");
clear_cpu_cap(c, X86_FEATURE_TSC);
break;
case 8:
@ -163,11 +163,11 @@ static void init_centaur(struct cpuinfo_x86 *c)
newlo = (lo|fcr_set) & (~fcr_clr);
if (newlo != lo) {
printk(KERN_INFO "Centaur FCR was 0x%X now 0x%X\n",
pr_info("Centaur FCR was 0x%X now 0x%X\n",
lo, newlo);
wrmsr(MSR_IDT_FCR1, newlo, hi);
} else {
printk(KERN_INFO "Centaur FCR is 0x%X\n", lo);
pr_info("Centaur FCR is 0x%X\n", lo);
}
/* Emulate MTRRs using Centaur's MCR. */
set_cpu_cap(c, X86_FEATURE_CENTAUR_MCR);

View File

@ -228,7 +228,7 @@ static void squash_the_stupid_serial_number(struct cpuinfo_x86 *c)
lo |= 0x200000;
wrmsr(MSR_IA32_BBL_CR_CTL, lo, hi);
printk(KERN_NOTICE "CPU serial number disabled.\n");
pr_notice("CPU serial number disabled.\n");
clear_cpu_cap(c, X86_FEATURE_PN);
/* Disabling the serial number may affect the cpuid level */
@ -329,9 +329,8 @@ static void filter_cpuid_features(struct cpuinfo_x86 *c, bool warn)
if (!warn)
continue;
printk(KERN_WARNING
"CPU: CPU feature " X86_CAP_FMT " disabled, no CPUID level 0x%x\n",
x86_cap_flag(df->feature), df->level);
pr_warn("CPU: CPU feature " X86_CAP_FMT " disabled, no CPUID level 0x%x\n",
x86_cap_flag(df->feature), df->level);
}
}
@ -510,7 +509,7 @@ void detect_ht(struct cpuinfo_x86 *c)
smp_num_siblings = (ebx & 0xff0000) >> 16;
if (smp_num_siblings == 1) {
printk_once(KERN_INFO "CPU0: Hyper-Threading is disabled\n");
pr_info_once("CPU0: Hyper-Threading is disabled\n");
goto out;
}
@ -531,10 +530,10 @@ void detect_ht(struct cpuinfo_x86 *c)
out:
if (!printed && (c->x86_max_cores * smp_num_siblings) > 1) {
printk(KERN_INFO "CPU: Physical Processor ID: %d\n",
c->phys_proc_id);
printk(KERN_INFO "CPU: Processor Core ID: %d\n",
c->cpu_core_id);
pr_info("CPU: Physical Processor ID: %d\n",
c->phys_proc_id);
pr_info("CPU: Processor Core ID: %d\n",
c->cpu_core_id);
printed = 1;
}
#endif
@ -559,9 +558,8 @@ static void get_cpu_vendor(struct cpuinfo_x86 *c)
}
}
printk_once(KERN_ERR
"CPU: vendor_id '%s' unknown, using generic init.\n" \
"CPU: Your system may be unstable.\n", v);
pr_err_once("CPU: vendor_id '%s' unknown, using generic init.\n" \
"CPU: Your system may be unstable.\n", v);
c->x86_vendor = X86_VENDOR_UNKNOWN;
this_cpu = &default_cpu;
@ -760,7 +758,7 @@ void __init early_cpu_init(void)
int count = 0;
#ifdef CONFIG_PROCESSOR_SELECT
printk(KERN_INFO "KERNEL supported cpus:\n");
pr_info("KERNEL supported cpus:\n");
#endif
for (cdev = __x86_cpu_dev_start; cdev < __x86_cpu_dev_end; cdev++) {
@ -778,7 +776,7 @@ void __init early_cpu_init(void)
for (j = 0; j < 2; j++) {
if (!cpudev->c_ident[j])
continue;
printk(KERN_INFO " %s %s\n", cpudev->c_vendor,
pr_info(" %s %s\n", cpudev->c_vendor,
cpudev->c_ident[j]);
}
}
@ -977,6 +975,8 @@ static void identify_cpu(struct cpuinfo_x86 *c)
#ifdef CONFIG_NUMA
numa_add_cpu(smp_processor_id());
#endif
/* The boot/hotplug time assigment got cleared, restore it */
c->logical_proc_id = topology_phys_to_logical_pkg(c->phys_proc_id);
}
/*
@ -1061,7 +1061,7 @@ static void __print_cpu_msr(void)
for (index = index_min; index < index_max; index++) {
if (rdmsrl_safe(index, &val))
continue;
printk(KERN_INFO " MSR%08x: %016llx\n", index, val);
pr_info(" MSR%08x: %016llx\n", index, val);
}
}
}
@ -1100,19 +1100,19 @@ void print_cpu_info(struct cpuinfo_x86 *c)
}
if (vendor && !strstr(c->x86_model_id, vendor))
printk(KERN_CONT "%s ", vendor);
pr_cont("%s ", vendor);
if (c->x86_model_id[0])
printk(KERN_CONT "%s", c->x86_model_id);
pr_cont("%s", c->x86_model_id);
else
printk(KERN_CONT "%d86", c->x86);
pr_cont("%d86", c->x86);
printk(KERN_CONT " (family: 0x%x, model: 0x%x", c->x86, c->x86_model);
pr_cont(" (family: 0x%x, model: 0x%x", c->x86, c->x86_model);
if (c->x86_mask || c->cpuid_level >= 0)
printk(KERN_CONT ", stepping: 0x%x)\n", c->x86_mask);
pr_cont(", stepping: 0x%x)\n", c->x86_mask);
else
printk(KERN_CONT ")\n");
pr_cont(")\n");
print_cpu_msr(c);
}
@ -1438,7 +1438,7 @@ void cpu_init(void)
show_ucode_info_early();
printk(KERN_INFO "Initializing CPU#%d\n", cpu);
pr_info("Initializing CPU#%d\n", cpu);
if (cpu_feature_enabled(X86_FEATURE_VME) ||
cpu_has_tsc ||

View File

@ -103,7 +103,7 @@ static void check_cx686_slop(struct cpuinfo_x86 *c)
local_irq_restore(flags);
if (ccr5 & 2) { /* possible wrong calibration done */
printk(KERN_INFO "Recalibrating delay loop with SLOP bit reset\n");
pr_info("Recalibrating delay loop with SLOP bit reset\n");
calibrate_delay();
c->loops_per_jiffy = loops_per_jiffy;
}
@ -115,7 +115,7 @@ static void set_cx86_reorder(void)
{
u8 ccr3;
printk(KERN_INFO "Enable Memory access reorder on Cyrix/NSC processor.\n");
pr_info("Enable Memory access reorder on Cyrix/NSC processor.\n");
ccr3 = getCx86(CX86_CCR3);
setCx86(CX86_CCR3, (ccr3 & 0x0f) | 0x10); /* enable MAPEN */
@ -128,7 +128,7 @@ static void set_cx86_reorder(void)
static void set_cx86_memwb(void)
{
printk(KERN_INFO "Enable Memory-Write-back mode on Cyrix/NSC processor.\n");
pr_info("Enable Memory-Write-back mode on Cyrix/NSC processor.\n");
/* CCR2 bit 2: unlock NW bit */
setCx86_old(CX86_CCR2, getCx86_old(CX86_CCR2) & ~0x04);
@ -268,7 +268,7 @@ static void init_cyrix(struct cpuinfo_x86 *c)
* VSA1 we work around however.
*/
printk(KERN_INFO "Working around Cyrix MediaGX virtual DMA bugs.\n");
pr_info("Working around Cyrix MediaGX virtual DMA bugs.\n");
isa_dma_bridge_buggy = 2;
/* We do this before the PCI layer is running. However we
@ -426,7 +426,7 @@ static void cyrix_identify(struct cpuinfo_x86 *c)
if (dir0 == 5 || dir0 == 3) {
unsigned char ccr3;
unsigned long flags;
printk(KERN_INFO "Enabling CPUID on Cyrix processor.\n");
pr_info("Enabling CPUID on Cyrix processor.\n");
local_irq_save(flags);
ccr3 = getCx86(CX86_CCR3);
/* enable MAPEN */

View File

@ -56,7 +56,7 @@ detect_hypervisor_vendor(void)
}
if (max_pri)
printk(KERN_INFO "Hypervisor detected: %s\n", x86_hyper->name);
pr_info("Hypervisor detected: %s\n", x86_hyper->name);
}
void init_hypervisor(struct cpuinfo_x86 *c)

View File

@ -61,7 +61,7 @@ static void early_init_intel(struct cpuinfo_x86 *c)
*/
if (c->x86 == 6 && c->x86_model == 0x1c && c->x86_mask <= 2 &&
c->microcode < 0x20e) {
printk(KERN_WARNING "Atom PSE erratum detected, BIOS microcode update recommended\n");
pr_warn("Atom PSE erratum detected, BIOS microcode update recommended\n");
clear_cpu_cap(c, X86_FEATURE_PSE);
}
@ -140,7 +140,7 @@ static void early_init_intel(struct cpuinfo_x86 *c)
if (c->x86 > 6 || (c->x86 == 6 && c->x86_model >= 0xd)) {
rdmsrl(MSR_IA32_MISC_ENABLE, misc_enable);
if (!(misc_enable & MSR_IA32_MISC_ENABLE_FAST_STRING)) {
printk(KERN_INFO "Disabled fast string operations\n");
pr_info("Disabled fast string operations\n");
setup_clear_cpu_cap(X86_FEATURE_REP_GOOD);
setup_clear_cpu_cap(X86_FEATURE_ERMS);
}
@ -160,6 +160,19 @@ static void early_init_intel(struct cpuinfo_x86 *c)
pr_info("Disabling PGE capability bit\n");
setup_clear_cpu_cap(X86_FEATURE_PGE);
}
if (c->cpuid_level >= 0x00000001) {
u32 eax, ebx, ecx, edx;
cpuid(0x00000001, &eax, &ebx, &ecx, &edx);
/*
* If HTT (EDX[28]) is set EBX[16:23] contain the number of
* apicids which are reserved per package. Store the resulting
* shift value for the package management code.
*/
if (edx & (1U << 28))
c->x86_coreid_bits = get_count_order((ebx >> 16) & 0xff);
}
}
#ifdef CONFIG_X86_32
@ -176,7 +189,7 @@ int ppro_with_ram_bug(void)
boot_cpu_data.x86 == 6 &&
boot_cpu_data.x86_model == 1 &&
boot_cpu_data.x86_mask < 8) {
printk(KERN_INFO "Pentium Pro with Errata#50 detected. Taking evasive action.\n");
pr_info("Pentium Pro with Errata#50 detected. Taking evasive action.\n");
return 1;
}
return 0;
@ -225,7 +238,7 @@ static void intel_workarounds(struct cpuinfo_x86 *c)
set_cpu_bug(c, X86_BUG_F00F);
if (!f00f_workaround_enabled) {
printk(KERN_NOTICE "Intel Pentium with F0 0F bug - workaround enabled.\n");
pr_notice("Intel Pentium with F0 0F bug - workaround enabled.\n");
f00f_workaround_enabled = 1;
}
}
@ -244,7 +257,7 @@ static void intel_workarounds(struct cpuinfo_x86 *c)
* Forcefully enable PAE if kernel parameter "forcepae" is present.
*/
if (forcepae) {
printk(KERN_WARNING "PAE forced!\n");
pr_warn("PAE forced!\n");
set_cpu_cap(c, X86_FEATURE_PAE);
add_taint(TAINT_CPU_OUT_OF_SPEC, LOCKDEP_NOW_UNRELIABLE);
}

View File

@ -444,7 +444,7 @@ static ssize_t store_cache_disable(struct cacheinfo *this_leaf,
err = amd_set_l3_disable_slot(nb, cpu, slot, val);
if (err) {
if (err == -EEXIST)
pr_warning("L3 slot %d in use/index already disabled!\n",
pr_warn("L3 slot %d in use/index already disabled!\n",
slot);
return err;
}

View File

@ -115,7 +115,7 @@ static int raise_local(void)
int cpu = m->extcpu;
if (m->inject_flags & MCJ_EXCEPTION) {
printk(KERN_INFO "Triggering MCE exception on CPU %d\n", cpu);
pr_info("Triggering MCE exception on CPU %d\n", cpu);
switch (context) {
case MCJ_CTX_IRQ:
/*
@ -128,15 +128,15 @@ static int raise_local(void)
raise_exception(m, NULL);
break;
default:
printk(KERN_INFO "Invalid MCE context\n");
pr_info("Invalid MCE context\n");
ret = -EINVAL;
}
printk(KERN_INFO "MCE exception done on CPU %d\n", cpu);
pr_info("MCE exception done on CPU %d\n", cpu);
} else if (m->status) {
printk(KERN_INFO "Starting machine check poll CPU %d\n", cpu);
pr_info("Starting machine check poll CPU %d\n", cpu);
raise_poll(m);
mce_notify_irq();
printk(KERN_INFO "Machine check poll done on CPU %d\n", cpu);
pr_info("Machine check poll done on CPU %d\n", cpu);
} else
m->finished = 0;
@ -183,8 +183,7 @@ static void raise_mce(struct mce *m)
start = jiffies;
while (!cpumask_empty(mce_inject_cpumask)) {
if (!time_before(jiffies, start + 2*HZ)) {
printk(KERN_ERR
"Timeout waiting for mce inject %lx\n",
pr_err("Timeout waiting for mce inject %lx\n",
*cpumask_bits(mce_inject_cpumask));
break;
}
@ -241,7 +240,7 @@ static int inject_init(void)
{
if (!alloc_cpumask_var(&mce_inject_cpumask, GFP_KERNEL))
return -ENOMEM;
printk(KERN_INFO "Machine check injector initialized\n");
pr_info("Machine check injector initialized\n");
register_mce_write_callback(mce_write);
register_nmi_handler(NMI_LOCAL, mce_raise_notify, 0,
"mce_notify");

View File

@ -26,14 +26,12 @@ static void pentium_machine_check(struct pt_regs *regs, long error_code)
rdmsr(MSR_IA32_P5_MC_ADDR, loaddr, hi);
rdmsr(MSR_IA32_P5_MC_TYPE, lotype, hi);
printk(KERN_EMERG
"CPU#%d: Machine Check Exception: 0x%8X (type 0x%8X).\n",
smp_processor_id(), loaddr, lotype);
pr_emerg("CPU#%d: Machine Check Exception: 0x%8X (type 0x%8X).\n",
smp_processor_id(), loaddr, lotype);
if (lotype & (1<<5)) {
printk(KERN_EMERG
"CPU#%d: Possible thermal failure (CPU on fire ?).\n",
smp_processor_id());
pr_emerg("CPU#%d: Possible thermal failure (CPU on fire ?).\n",
smp_processor_id());
}
add_taint(TAINT_MACHINE_CHECK, LOCKDEP_NOW_UNRELIABLE);
@ -61,12 +59,10 @@ void intel_p5_mcheck_init(struct cpuinfo_x86 *c)
/* Read registers before enabling: */
rdmsr(MSR_IA32_P5_MC_ADDR, l, h);
rdmsr(MSR_IA32_P5_MC_TYPE, l, h);
printk(KERN_INFO
"Intel old style machine check architecture supported.\n");
pr_info("Intel old style machine check architecture supported.\n");
/* Enable MCE: */
cr4_set_bits(X86_CR4_MCE);
printk(KERN_INFO
"Intel old style machine check reporting enabled on CPU#%d.\n",
smp_processor_id());
pr_info("Intel old style machine check reporting enabled on CPU#%d.\n",
smp_processor_id());
}

View File

@ -190,7 +190,7 @@ static int therm_throt_process(bool new_event, int event, int level)
/* if we just entered the thermal event */
if (new_event) {
if (event == THERMAL_THROTTLING_EVENT)
printk(KERN_CRIT "CPU%d: %s temperature above threshold, cpu clock throttled (total events = %lu)\n",
pr_crit("CPU%d: %s temperature above threshold, cpu clock throttled (total events = %lu)\n",
this_cpu,
level == CORE_LEVEL ? "Core" : "Package",
state->count);
@ -198,8 +198,7 @@ static int therm_throt_process(bool new_event, int event, int level)
}
if (old_event) {
if (event == THERMAL_THROTTLING_EVENT)
printk(KERN_INFO "CPU%d: %s temperature/speed normal\n",
this_cpu,
pr_info("CPU%d: %s temperature/speed normal\n", this_cpu,
level == CORE_LEVEL ? "Core" : "Package");
return 1;
}
@ -417,8 +416,8 @@ static void intel_thermal_interrupt(void)
static void unexpected_thermal_interrupt(void)
{
printk(KERN_ERR "CPU%d: Unexpected LVT thermal interrupt!\n",
smp_processor_id());
pr_err("CPU%d: Unexpected LVT thermal interrupt!\n",
smp_processor_id());
}
static void (*smp_thermal_vector)(void) = unexpected_thermal_interrupt;
@ -499,7 +498,7 @@ void intel_init_thermal(struct cpuinfo_x86 *c)
if ((l & MSR_IA32_MISC_ENABLE_TM1) && (h & APIC_DM_SMI)) {
if (system_state == SYSTEM_BOOTING)
printk(KERN_DEBUG "CPU%d: Thermal monitoring handled by SMI\n", cpu);
pr_debug("CPU%d: Thermal monitoring handled by SMI\n", cpu);
return;
}
@ -557,8 +556,8 @@ void intel_init_thermal(struct cpuinfo_x86 *c)
l = apic_read(APIC_LVTTHMR);
apic_write(APIC_LVTTHMR, l & ~APIC_LVT_MASKED);
printk_once(KERN_INFO "CPU0: Thermal monitoring enabled (%s)\n",
tm2 ? "TM2" : "TM1");
pr_info_once("CPU0: Thermal monitoring enabled (%s)\n",
tm2 ? "TM2" : "TM1");
/* enable thermal throttle processing */
atomic_set(&therm_throt_en, 1);

View File

@ -12,8 +12,8 @@
static void default_threshold_interrupt(void)
{
printk(KERN_ERR "Unexpected threshold interrupt at vector %x\n",
THRESHOLD_APIC_VECTOR);
pr_err("Unexpected threshold interrupt at vector %x\n",
THRESHOLD_APIC_VECTOR);
}
void (*mce_threshold_vector)(void) = default_threshold_interrupt;

View File

@ -17,7 +17,7 @@ static void winchip_machine_check(struct pt_regs *regs, long error_code)
{
ist_enter(regs);
printk(KERN_EMERG "CPU0: Machine Check Exception.\n");
pr_emerg("CPU0: Machine Check Exception.\n");
add_taint(TAINT_MACHINE_CHECK, LOCKDEP_NOW_UNRELIABLE);
ist_exit(regs);
@ -39,6 +39,5 @@ void winchip_mcheck_init(struct cpuinfo_x86 *c)
cr4_set_bits(X86_CR4_MCE);
printk(KERN_INFO
"Winchip machine check reporting enabled on CPU#0.\n");
pr_info("Winchip machine check reporting enabled on CPU#0.\n");
}

View File

@ -953,7 +953,7 @@ struct microcode_ops * __init init_amd_microcode(void)
struct cpuinfo_x86 *c = &boot_cpu_data;
if (c->x86_vendor != X86_VENDOR_AMD || c->x86 < 0x10) {
pr_warning("AMD CPU family 0x%x not supported\n", c->x86);
pr_warn("AMD CPU family 0x%x not supported\n", c->x86);
return NULL;
}

View File

@ -161,8 +161,8 @@ static void __init ms_hyperv_init_platform(void)
ms_hyperv.misc_features = cpuid_edx(HYPERV_CPUID_FEATURES);
ms_hyperv.hints = cpuid_eax(HYPERV_CPUID_ENLIGHTMENT_INFO);
printk(KERN_INFO "HyperV: features 0x%x, hints 0x%x\n",
ms_hyperv.features, ms_hyperv.hints);
pr_info("HyperV: features 0x%x, hints 0x%x\n",
ms_hyperv.features, ms_hyperv.hints);
#ifdef CONFIG_X86_LOCAL_APIC
if (ms_hyperv.features & HV_X64_MSR_APIC_FREQUENCY_AVAILABLE) {
@ -174,8 +174,8 @@ static void __init ms_hyperv_init_platform(void)
rdmsrl(HV_X64_MSR_APIC_FREQUENCY, hv_lapic_frequency);
hv_lapic_frequency = div_u64(hv_lapic_frequency, HZ);
lapic_timer_frequency = hv_lapic_frequency;
printk(KERN_INFO "HyperV: LAPIC Timer Frequency: %#x\n",
lapic_timer_frequency);
pr_info("HyperV: LAPIC Timer Frequency: %#x\n",
lapic_timer_frequency);
}
#endif

View File

@ -103,7 +103,7 @@ centaur_validate_add_page(unsigned long base, unsigned long size, unsigned int t
*/
if (type != MTRR_TYPE_WRCOMB &&
(centaur_mcr_type == 0 || type != MTRR_TYPE_UNCACHABLE)) {
pr_warning("mtrr: only write-combining%s supported\n",
pr_warn("mtrr: only write-combining%s supported\n",
centaur_mcr_type ? " and uncacheable are" : " is");
return -EINVAL;
}

View File

@ -57,9 +57,9 @@ static int __initdata nr_range;
static struct var_mtrr_range_state __initdata range_state[RANGE_NUM];
static int __initdata debug_print;
#define Dprintk(x...) do { if (debug_print) printk(KERN_DEBUG x); } while (0)
#define Dprintk(x...) do { if (debug_print) pr_debug(x); } while (0)
#define BIOS_BUG_MSG KERN_WARNING \
#define BIOS_BUG_MSG \
"WARNING: BIOS bug: VAR MTRR %d contains strange UC entry under 1M, check with your system vendor!\n"
static int __init
@ -81,9 +81,9 @@ x86_get_mtrr_mem_range(struct range *range, int nr_range,
base, base + size);
}
if (debug_print) {
printk(KERN_DEBUG "After WB checking\n");
pr_debug("After WB checking\n");
for (i = 0; i < nr_range; i++)
printk(KERN_DEBUG "MTRR MAP PFN: %016llx - %016llx\n",
pr_debug("MTRR MAP PFN: %016llx - %016llx\n",
range[i].start, range[i].end);
}
@ -101,7 +101,7 @@ x86_get_mtrr_mem_range(struct range *range, int nr_range,
(mtrr_state.enabled & MTRR_STATE_MTRR_ENABLED) &&
(mtrr_state.enabled & MTRR_STATE_MTRR_FIXED_ENABLED)) {
/* Var MTRR contains UC entry below 1M? Skip it: */
printk(BIOS_BUG_MSG, i);
pr_warn(BIOS_BUG_MSG, i);
if (base + size <= (1<<(20-PAGE_SHIFT)))
continue;
size -= (1<<(20-PAGE_SHIFT)) - base;
@ -114,11 +114,11 @@ x86_get_mtrr_mem_range(struct range *range, int nr_range,
extra_remove_base + extra_remove_size);
if (debug_print) {
printk(KERN_DEBUG "After UC checking\n");
pr_debug("After UC checking\n");
for (i = 0; i < RANGE_NUM; i++) {
if (!range[i].end)
continue;
printk(KERN_DEBUG "MTRR MAP PFN: %016llx - %016llx\n",
pr_debug("MTRR MAP PFN: %016llx - %016llx\n",
range[i].start, range[i].end);
}
}
@ -126,9 +126,9 @@ x86_get_mtrr_mem_range(struct range *range, int nr_range,
/* sort the ranges */
nr_range = clean_sort_range(range, RANGE_NUM);
if (debug_print) {
printk(KERN_DEBUG "After sorting\n");
pr_debug("After sorting\n");
for (i = 0; i < nr_range; i++)
printk(KERN_DEBUG "MTRR MAP PFN: %016llx - %016llx\n",
pr_debug("MTRR MAP PFN: %016llx - %016llx\n",
range[i].start, range[i].end);
}
@ -544,7 +544,7 @@ static void __init print_out_mtrr_range_state(void)
start_base = to_size_factor(start_base, &start_factor),
type = range_state[i].type;
printk(KERN_DEBUG "reg %d, base: %ld%cB, range: %ld%cB, type %s\n",
pr_debug("reg %d, base: %ld%cB, range: %ld%cB, type %s\n",
i, start_base, start_factor,
size_base, size_factor,
(type == MTRR_TYPE_UNCACHABLE) ? "UC" :
@ -713,7 +713,7 @@ int __init mtrr_cleanup(unsigned address_bits)
return 0;
/* Print original var MTRRs at first, for debugging: */
printk(KERN_DEBUG "original variable MTRRs\n");
pr_debug("original variable MTRRs\n");
print_out_mtrr_range_state();
memset(range, 0, sizeof(range));
@ -733,7 +733,7 @@ int __init mtrr_cleanup(unsigned address_bits)
x_remove_base, x_remove_size);
range_sums = sum_ranges(range, nr_range);
printk(KERN_INFO "total RAM covered: %ldM\n",
pr_info("total RAM covered: %ldM\n",
range_sums >> (20 - PAGE_SHIFT));
if (mtrr_chunk_size && mtrr_gran_size) {
@ -745,12 +745,11 @@ int __init mtrr_cleanup(unsigned address_bits)
if (!result[i].bad) {
set_var_mtrr_all(address_bits);
printk(KERN_DEBUG "New variable MTRRs\n");
pr_debug("New variable MTRRs\n");
print_out_mtrr_range_state();
return 1;
}
printk(KERN_INFO "invalid mtrr_gran_size or mtrr_chunk_size, "
"will find optimal one\n");
pr_info("invalid mtrr_gran_size or mtrr_chunk_size, will find optimal one\n");
}
i = 0;
@ -768,7 +767,7 @@ int __init mtrr_cleanup(unsigned address_bits)
x_remove_base, x_remove_size, i);
if (debug_print) {
mtrr_print_out_one_result(i);
printk(KERN_INFO "\n");
pr_info("\n");
}
i++;
@ -779,7 +778,7 @@ int __init mtrr_cleanup(unsigned address_bits)
index_good = mtrr_search_optimal_index();
if (index_good != -1) {
printk(KERN_INFO "Found optimal setting for mtrr clean up\n");
pr_info("Found optimal setting for mtrr clean up\n");
i = index_good;
mtrr_print_out_one_result(i);
@ -790,7 +789,7 @@ int __init mtrr_cleanup(unsigned address_bits)
gran_size <<= 10;
x86_setup_var_mtrrs(range, nr_range, chunk_size, gran_size);
set_var_mtrr_all(address_bits);
printk(KERN_DEBUG "New variable MTRRs\n");
pr_debug("New variable MTRRs\n");
print_out_mtrr_range_state();
return 1;
} else {
@ -799,8 +798,8 @@ int __init mtrr_cleanup(unsigned address_bits)
mtrr_print_out_one_result(i);
}
printk(KERN_INFO "mtrr_cleanup: can not find optimal value\n");
printk(KERN_INFO "please specify mtrr_gran_size/mtrr_chunk_size\n");
pr_info("mtrr_cleanup: can not find optimal value\n");
pr_info("please specify mtrr_gran_size/mtrr_chunk_size\n");
return 0;
}
@ -918,7 +917,7 @@ int __init mtrr_trim_uncached_memory(unsigned long end_pfn)
/* kvm/qemu doesn't have mtrr set right, don't trim them all: */
if (!highest_pfn) {
printk(KERN_INFO "CPU MTRRs all blank - virtualized system.\n");
pr_info("CPU MTRRs all blank - virtualized system.\n");
return 0;
}
@ -973,7 +972,8 @@ int __init mtrr_trim_uncached_memory(unsigned long end_pfn)
end_pfn);
if (total_trim_size) {
pr_warning("WARNING: BIOS bug: CPU MTRRs don't cover all of memory, losing %lluMB of RAM.\n", total_trim_size >> 20);
pr_warn("WARNING: BIOS bug: CPU MTRRs don't cover all of memory, losing %lluMB of RAM.\n",
total_trim_size >> 20);
if (!changed_by_mtrr_cleanup)
WARN_ON(1);

View File

@ -55,7 +55,7 @@ static inline void k8_check_syscfg_dram_mod_en(void)
rdmsr(MSR_K8_SYSCFG, lo, hi);
if (lo & K8_MTRRFIXRANGE_DRAM_MODIFY) {
printk(KERN_ERR FW_WARN "MTRR: CPU %u: SYSCFG[MtrrFixDramModEn]"
pr_err(FW_WARN "MTRR: CPU %u: SYSCFG[MtrrFixDramModEn]"
" not cleared by BIOS, clearing this bit\n",
smp_processor_id());
lo &= ~K8_MTRRFIXRANGE_DRAM_MODIFY;
@ -501,14 +501,14 @@ void __init mtrr_state_warn(void)
if (!mask)
return;
if (mask & MTRR_CHANGE_MASK_FIXED)
pr_warning("mtrr: your CPUs had inconsistent fixed MTRR settings\n");
pr_warn("mtrr: your CPUs had inconsistent fixed MTRR settings\n");
if (mask & MTRR_CHANGE_MASK_VARIABLE)
pr_warning("mtrr: your CPUs had inconsistent variable MTRR settings\n");
pr_warn("mtrr: your CPUs had inconsistent variable MTRR settings\n");
if (mask & MTRR_CHANGE_MASK_DEFTYPE)
pr_warning("mtrr: your CPUs had inconsistent MTRRdefType settings\n");
pr_warn("mtrr: your CPUs had inconsistent MTRRdefType settings\n");
printk(KERN_INFO "mtrr: probably your BIOS does not setup all CPUs.\n");
printk(KERN_INFO "mtrr: corrected configuration.\n");
pr_info("mtrr: probably your BIOS does not setup all CPUs.\n");
pr_info("mtrr: corrected configuration.\n");
}
/*
@ -519,8 +519,7 @@ void __init mtrr_state_warn(void)
void mtrr_wrmsr(unsigned msr, unsigned a, unsigned b)
{
if (wrmsr_safe(msr, a, b) < 0) {
printk(KERN_ERR
"MTRR: CPU %u: Writing MSR %x to %x:%x failed\n",
pr_err("MTRR: CPU %u: Writing MSR %x to %x:%x failed\n",
smp_processor_id(), msr, a, b);
}
}
@ -607,7 +606,7 @@ static void generic_get_mtrr(unsigned int reg, unsigned long *base,
tmp |= ~((1ULL<<(hi - 1)) - 1);
if (tmp != mask) {
printk(KERN_WARNING "mtrr: your BIOS has configured an incorrect mask, fixing it.\n");
pr_warn("mtrr: your BIOS has configured an incorrect mask, fixing it.\n");
add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK);
mask = tmp;
}
@ -858,13 +857,13 @@ int generic_validate_add_page(unsigned long base, unsigned long size,
boot_cpu_data.x86_model == 1 &&
boot_cpu_data.x86_mask <= 7) {
if (base & ((1 << (22 - PAGE_SHIFT)) - 1)) {
pr_warning("mtrr: base(0x%lx000) is not 4 MiB aligned\n", base);
pr_warn("mtrr: base(0x%lx000) is not 4 MiB aligned\n", base);
return -EINVAL;
}
if (!(base + size < 0x70000 || base > 0x7003F) &&
(type == MTRR_TYPE_WRCOMB
|| type == MTRR_TYPE_WRBACK)) {
pr_warning("mtrr: writable mtrr between 0x70000000 and 0x7003FFFF may hang the CPU.\n");
pr_warn("mtrr: writable mtrr between 0x70000000 and 0x7003FFFF may hang the CPU.\n");
return -EINVAL;
}
}
@ -878,7 +877,7 @@ int generic_validate_add_page(unsigned long base, unsigned long size,
lbase = lbase >> 1, last = last >> 1)
;
if (lbase != last) {
pr_warning("mtrr: base(0x%lx000) is not aligned on a size(0x%lx000) boundary\n", base, size);
pr_warn("mtrr: base(0x%lx000) is not aligned on a size(0x%lx000) boundary\n", base, size);
return -EINVAL;
}
return 0;

View File

@ -300,24 +300,24 @@ int mtrr_add_page(unsigned long base, unsigned long size,
return error;
if (type >= MTRR_NUM_TYPES) {
pr_warning("mtrr: type: %u invalid\n", type);
pr_warn("mtrr: type: %u invalid\n", type);
return -EINVAL;
}
/* If the type is WC, check that this processor supports it */
if ((type == MTRR_TYPE_WRCOMB) && !have_wrcomb()) {
pr_warning("mtrr: your processor doesn't support write-combining\n");
pr_warn("mtrr: your processor doesn't support write-combining\n");
return -ENOSYS;
}
if (!size) {
pr_warning("mtrr: zero sized request\n");
pr_warn("mtrr: zero sized request\n");
return -EINVAL;
}
if ((base | (base + size - 1)) >>
(boot_cpu_data.x86_phys_bits - PAGE_SHIFT)) {
pr_warning("mtrr: base or size exceeds the MTRR width\n");
pr_warn("mtrr: base or size exceeds the MTRR width\n");
return -EINVAL;
}
@ -348,7 +348,7 @@ int mtrr_add_page(unsigned long base, unsigned long size,
} else if (types_compatible(type, ltype))
continue;
}
pr_warning("mtrr: 0x%lx000,0x%lx000 overlaps existing"
pr_warn("mtrr: 0x%lx000,0x%lx000 overlaps existing"
" 0x%lx000,0x%lx000\n", base, size, lbase,
lsize);
goto out;
@ -357,7 +357,7 @@ int mtrr_add_page(unsigned long base, unsigned long size,
if (ltype != type) {
if (types_compatible(type, ltype))
continue;
pr_warning("mtrr: type mismatch for %lx000,%lx000 old: %s new: %s\n",
pr_warn("mtrr: type mismatch for %lx000,%lx000 old: %s new: %s\n",
base, size, mtrr_attrib_to_str(ltype),
mtrr_attrib_to_str(type));
goto out;
@ -395,7 +395,7 @@ int mtrr_add_page(unsigned long base, unsigned long size,
static int mtrr_check(unsigned long base, unsigned long size)
{
if ((base & (PAGE_SIZE - 1)) || (size & (PAGE_SIZE - 1))) {
pr_warning("mtrr: size and base must be multiples of 4 kiB\n");
pr_warn("mtrr: size and base must be multiples of 4 kiB\n");
pr_debug("mtrr: size: 0x%lx base: 0x%lx\n", size, base);
dump_stack();
return -1;
@ -493,16 +493,16 @@ int mtrr_del_page(int reg, unsigned long base, unsigned long size)
}
}
if (reg >= max) {
pr_warning("mtrr: register: %d too big\n", reg);
pr_warn("mtrr: register: %d too big\n", reg);
goto out;
}
mtrr_if->get(reg, &lbase, &lsize, &ltype);
if (lsize < 1) {
pr_warning("mtrr: MTRR %d not used\n", reg);
pr_warn("mtrr: MTRR %d not used\n", reg);
goto out;
}
if (mtrr_usage_table[reg] < 1) {
pr_warning("mtrr: reg: %d has count=0\n", reg);
pr_warn("mtrr: reg: %d has count=0\n", reg);
goto out;
}
if (--mtrr_usage_table[reg] < 1)

View File

@ -51,7 +51,7 @@ void x86_init_rdrand(struct cpuinfo_x86 *c)
for (i = 0; i < SANITY_CHECK_LOOPS; i++) {
if (!rdrand_long(&tmp)) {
clear_cpu_cap(c, X86_FEATURE_RDRAND);
printk_once(KERN_WARNING "rdrand: disabled\n");
pr_warn_once("rdrand: disabled\n");
return;
}
}

View File

@ -87,10 +87,10 @@ void detect_extended_topology(struct cpuinfo_x86 *c)
c->x86_max_cores = (core_level_siblings / smp_num_siblings);
if (!printed) {
printk(KERN_INFO "CPU: Physical Processor ID: %d\n",
pr_info("CPU: Physical Processor ID: %d\n",
c->phys_proc_id);
if (c->x86_max_cores > 1)
printk(KERN_INFO "CPU: Processor Core ID: %d\n",
pr_info("CPU: Processor Core ID: %d\n",
c->cpu_core_id);
printed = 1;
}

View File

@ -33,7 +33,7 @@ static void init_transmeta(struct cpuinfo_x86 *c)
if (max >= 0x80860001) {
cpuid(0x80860001, &dummy, &cpu_rev, &cpu_freq, &cpu_flags);
if (cpu_rev != 0x02000000) {
printk(KERN_INFO "CPU: Processor revision %u.%u.%u.%u, %u MHz\n",
pr_info("CPU: Processor revision %u.%u.%u.%u, %u MHz\n",
(cpu_rev >> 24) & 0xff,
(cpu_rev >> 16) & 0xff,
(cpu_rev >> 8) & 0xff,
@ -44,10 +44,10 @@ static void init_transmeta(struct cpuinfo_x86 *c)
if (max >= 0x80860002) {
cpuid(0x80860002, &new_cpu_rev, &cms_rev1, &cms_rev2, &dummy);
if (cpu_rev == 0x02000000) {
printk(KERN_INFO "CPU: Processor revision %08X, %u MHz\n",
pr_info("CPU: Processor revision %08X, %u MHz\n",
new_cpu_rev, cpu_freq);
}
printk(KERN_INFO "CPU: Code Morphing Software revision %u.%u.%u-%u-%u\n",
pr_info("CPU: Code Morphing Software revision %u.%u.%u-%u-%u\n",
(cms_rev1 >> 24) & 0xff,
(cms_rev1 >> 16) & 0xff,
(cms_rev1 >> 8) & 0xff,
@ -76,7 +76,7 @@ static void init_transmeta(struct cpuinfo_x86 *c)
(void *)&cpu_info[56],
(void *)&cpu_info[60]);
cpu_info[64] = '\0';
printk(KERN_INFO "CPU: %s\n", cpu_info);
pr_info("CPU: %s\n", cpu_info);
}
/* Unhide possibly hidden capability flags */

View File

@ -62,7 +62,7 @@ static unsigned long vmware_get_tsc_khz(void)
tsc_hz = eax | (((uint64_t)ebx) << 32);
do_div(tsc_hz, 1000);
BUG_ON(tsc_hz >> 32);
printk(KERN_INFO "TSC freq read from hypervisor : %lu.%03lu MHz\n",
pr_info("TSC freq read from hypervisor : %lu.%03lu MHz\n",
(unsigned long) tsc_hz / 1000,
(unsigned long) tsc_hz % 1000);
@ -84,8 +84,7 @@ static void __init vmware_platform_setup(void)
if (ebx != UINT_MAX)
x86_platform.calibrate_tsc = vmware_get_tsc_khz;
else
printk(KERN_WARNING
"Failed to get TSC freq from the hypervisor\n");
pr_warn("Failed to get TSC freq from the hypervisor\n");
}
/*

View File

@ -408,7 +408,7 @@ static inline void __init construct_default_ISA_mptable(int mpc_default_type)
processor.cpuflag = CPU_ENABLED;
processor.cpufeature = (boot_cpu_data.x86 << 8) |
(boot_cpu_data.x86_model << 4) | boot_cpu_data.x86_mask;
processor.featureflag = boot_cpu_data.x86_capability[0];
processor.featureflag = boot_cpu_data.x86_capability[CPUID_1_EDX];
processor.reserved[0] = 0;
processor.reserved[1] = 0;
for (i = 0; i < 2; i++) {

View File

@ -30,6 +30,7 @@
#include <asm/nmi.h>
#include <asm/x86_init.h>
#include <asm/reboot.h>
#include <asm/cache.h>
#define CREATE_TRACE_POINTS
#include <trace/events/nmi.h>
@ -69,7 +70,7 @@ struct nmi_stats {
static DEFINE_PER_CPU(struct nmi_stats, nmi_stats);
static int ignore_nmis;
static int ignore_nmis __read_mostly;
int unknown_nmi_panic;
/*

View File

@ -97,6 +97,14 @@ DEFINE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_llc_shared_map);
DEFINE_PER_CPU_READ_MOSTLY(struct cpuinfo_x86, cpu_info);
EXPORT_PER_CPU_SYMBOL(cpu_info);
/* Logical package management. We might want to allocate that dynamically */
static int *physical_to_logical_pkg __read_mostly;
static unsigned long *physical_package_map __read_mostly;;
static unsigned long *logical_package_map __read_mostly;
static unsigned int max_physical_pkg_id __read_mostly;
unsigned int __max_logical_packages __read_mostly;
EXPORT_SYMBOL(__max_logical_packages);
static inline void smpboot_setup_warm_reset_vector(unsigned long start_eip)
{
unsigned long flags;
@ -251,6 +259,97 @@ static void notrace start_secondary(void *unused)
cpu_startup_entry(CPUHP_ONLINE);
}
int topology_update_package_map(unsigned int apicid, unsigned int cpu)
{
unsigned int new, pkg = apicid >> boot_cpu_data.x86_coreid_bits;
/* Called from early boot ? */
if (!physical_package_map)
return 0;
if (pkg >= max_physical_pkg_id)
return -EINVAL;
/* Set the logical package id */
if (test_and_set_bit(pkg, physical_package_map))
goto found;
if (pkg < __max_logical_packages) {
set_bit(pkg, logical_package_map);
physical_to_logical_pkg[pkg] = pkg;
goto found;
}
new = find_first_zero_bit(logical_package_map, __max_logical_packages);
if (new >= __max_logical_packages) {
physical_to_logical_pkg[pkg] = -1;
pr_warn("APIC(%x) Package %u exceeds logical package map\n",
apicid, pkg);
return -ENOSPC;
}
set_bit(new, logical_package_map);
pr_info("APIC(%x) Converting physical %u to logical package %u\n",
apicid, pkg, new);
physical_to_logical_pkg[pkg] = new;
found:
cpu_data(cpu).logical_proc_id = physical_to_logical_pkg[pkg];
return 0;
}
/**
* topology_phys_to_logical_pkg - Map a physical package id to a logical
*
* Returns logical package id or -1 if not found
*/
int topology_phys_to_logical_pkg(unsigned int phys_pkg)
{
if (phys_pkg >= max_physical_pkg_id)
return -1;
return physical_to_logical_pkg[phys_pkg];
}
EXPORT_SYMBOL(topology_phys_to_logical_pkg);
static void __init smp_init_package_map(void)
{
unsigned int ncpus, cpu;
size_t size;
/*
* Today neither Intel nor AMD support heterogenous systems. That
* might change in the future....
*/
ncpus = boot_cpu_data.x86_max_cores * smp_num_siblings;
__max_logical_packages = DIV_ROUND_UP(nr_cpu_ids, ncpus);
/*
* Possibly larger than what we need as the number of apic ids per
* package can be smaller than the actual used apic ids.
*/
max_physical_pkg_id = DIV_ROUND_UP(MAX_LOCAL_APIC, ncpus);
size = max_physical_pkg_id * sizeof(unsigned int);
physical_to_logical_pkg = kmalloc(size, GFP_KERNEL);
memset(physical_to_logical_pkg, 0xff, size);
size = BITS_TO_LONGS(max_physical_pkg_id) * sizeof(unsigned long);
physical_package_map = kzalloc(size, GFP_KERNEL);
size = BITS_TO_LONGS(__max_logical_packages) * sizeof(unsigned long);
logical_package_map = kzalloc(size, GFP_KERNEL);
pr_info("Max logical packages: %u\n", __max_logical_packages);
for_each_present_cpu(cpu) {
unsigned int apicid = apic->cpu_present_to_apicid(cpu);
if (apicid == BAD_APICID || !apic->apic_id_valid(apicid))
continue;
if (!topology_update_package_map(apicid, cpu))
continue;
pr_warn("CPU %u APICId %x disabled\n", cpu, apicid);
per_cpu(x86_bios_cpu_apicid, cpu) = BAD_APICID;
set_cpu_possible(cpu, false);
set_cpu_present(cpu, false);
}
}
void __init smp_store_boot_cpu_info(void)
{
int id = 0; /* CPU 0 */
@ -258,6 +357,7 @@ void __init smp_store_boot_cpu_info(void)
*c = boot_cpu_data;
c->cpu_index = id;
smp_init_package_map();
}
/*

View File

@ -1529,7 +1529,7 @@ __init void lguest_init(void)
*/
cpu_detect(&new_cpu_data);
/* head.S usually sets up the first capability word, so do it here. */
new_cpu_data.x86_capability[0] = cpuid_edx(1);
new_cpu_data.x86_capability[CPUID_1_EDX] = cpuid_edx(1);
/* Math is always hard! */
set_cpu_cap(&new_cpu_data, X86_FEATURE_FPU);

View File

@ -1654,7 +1654,7 @@ asmlinkage __visible void __init xen_start_kernel(void)
cpu_detect(&new_cpu_data);
set_cpu_cap(&new_cpu_data, X86_FEATURE_FPU);
new_cpu_data.wp_works_ok = 1;
new_cpu_data.x86_capability[0] = cpuid_edx(1);
new_cpu_data.x86_capability[CPUID_1_EDX] = cpuid_edx(1);
#endif
if (xen_start_info->mod_start) {

View File

@ -11,7 +11,7 @@
#include "pmu.h"
/* x86_pmu.handle_irq definition */
#include "../kernel/cpu/perf_event.h"
#include "../events/perf_event.h"
#define XENPMU_IRQ_PROCESSING 1
struct xenpmu {

View File

@ -468,6 +468,7 @@ struct perf_event {
int group_flags;
struct perf_event *group_leader;
struct pmu *pmu;
void *pmu_private;
enum perf_event_active_state state;
unsigned int attach_state;

View File

@ -6785,7 +6785,7 @@ static void swevent_hlist_release(struct swevent_htable *swhash)
kfree_rcu(hlist, rcu_head);
}
static void swevent_hlist_put_cpu(struct perf_event *event, int cpu)
static void swevent_hlist_put_cpu(int cpu)
{
struct swevent_htable *swhash = &per_cpu(swevent_htable, cpu);
@ -6797,15 +6797,15 @@ static void swevent_hlist_put_cpu(struct perf_event *event, int cpu)
mutex_unlock(&swhash->hlist_mutex);
}
static void swevent_hlist_put(struct perf_event *event)
static void swevent_hlist_put(void)
{
int cpu;
for_each_possible_cpu(cpu)
swevent_hlist_put_cpu(event, cpu);
swevent_hlist_put_cpu(cpu);
}
static int swevent_hlist_get_cpu(struct perf_event *event, int cpu)
static int swevent_hlist_get_cpu(int cpu)
{
struct swevent_htable *swhash = &per_cpu(swevent_htable, cpu);
int err = 0;
@ -6828,14 +6828,13 @@ exit:
return err;
}
static int swevent_hlist_get(struct perf_event *event)
static int swevent_hlist_get(void)
{
int err;
int cpu, failed_cpu;
int err, cpu, failed_cpu;
get_online_cpus();
for_each_possible_cpu(cpu) {
err = swevent_hlist_get_cpu(event, cpu);
err = swevent_hlist_get_cpu(cpu);
if (err) {
failed_cpu = cpu;
goto fail;
@ -6848,7 +6847,7 @@ fail:
for_each_possible_cpu(cpu) {
if (cpu == failed_cpu)
break;
swevent_hlist_put_cpu(event, cpu);
swevent_hlist_put_cpu(cpu);
}
put_online_cpus();
@ -6864,7 +6863,7 @@ static void sw_perf_event_destroy(struct perf_event *event)
WARN_ON(event->parent);
static_key_slow_dec(&perf_swevent_enabled[event_id]);
swevent_hlist_put(event);
swevent_hlist_put();
}
static int perf_swevent_init(struct perf_event *event)
@ -6895,7 +6894,7 @@ static int perf_swevent_init(struct perf_event *event)
if (!event->parent) {
int err;
err = swevent_hlist_get(event);
err = swevent_hlist_get();
if (err)
return err;
@ -8001,6 +8000,9 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu,
}
}
/* symmetric to unaccount_event() in _free_event() */
account_event(event);
return event;
err_per_task:
@ -8364,8 +8366,6 @@ SYSCALL_DEFINE5(perf_event_open,
}
}
account_event(event);
/*
* Special case software events and allow them to be part of
* any hardware group.
@ -8662,8 +8662,6 @@ perf_event_create_kernel_counter(struct perf_event_attr *attr, int cpu,
/* Mark owner so we could distinguish it from user events. */
event->owner = TASK_TOMBSTONE;
account_event(event);
ctx = find_get_context(event->pmu, task, event);
if (IS_ERR(ctx)) {
err = PTR_ERR(ctx);
@ -9447,6 +9445,7 @@ ssize_t perf_event_sysfs_show(struct device *dev, struct device_attribute *attr,
return 0;
}
EXPORT_SYMBOL_GPL(perf_event_sysfs_show);
static int __init perf_event_sysfs_init(void)
{

View File

@ -30,7 +30,7 @@
struct trace_kprobe {
struct list_head list;
struct kretprobe rp; /* Use rp.kp for kprobe use */
unsigned long nhit;
unsigned long __percpu *nhit;
const char *symbol; /* symbol name */
struct trace_probe tp;
};
@ -274,6 +274,10 @@ static struct trace_kprobe *alloc_trace_kprobe(const char *group,
if (!tk)
return ERR_PTR(ret);
tk->nhit = alloc_percpu(unsigned long);
if (!tk->nhit)
goto error;
if (symbol) {
tk->symbol = kstrdup(symbol, GFP_KERNEL);
if (!tk->symbol)
@ -313,6 +317,7 @@ static struct trace_kprobe *alloc_trace_kprobe(const char *group,
error:
kfree(tk->tp.call.name);
kfree(tk->symbol);
free_percpu(tk->nhit);
kfree(tk);
return ERR_PTR(ret);
}
@ -327,6 +332,7 @@ static void free_trace_kprobe(struct trace_kprobe *tk)
kfree(tk->tp.call.class->system);
kfree(tk->tp.call.name);
kfree(tk->symbol);
free_percpu(tk->nhit);
kfree(tk);
}
@ -874,9 +880,14 @@ static const struct file_operations kprobe_events_ops = {
static int probes_profile_seq_show(struct seq_file *m, void *v)
{
struct trace_kprobe *tk = v;
unsigned long nhit = 0;
int cpu;
for_each_possible_cpu(cpu)
nhit += *per_cpu_ptr(tk->nhit, cpu);
seq_printf(m, " %-44s %15lu %15lu\n",
trace_event_name(&tk->tp.call), tk->nhit,
trace_event_name(&tk->tp.call), nhit,
tk->rp.kp.nmissed);
return 0;
@ -1225,7 +1236,7 @@ static int kprobe_dispatcher(struct kprobe *kp, struct pt_regs *regs)
{
struct trace_kprobe *tk = container_of(kp, struct trace_kprobe, rp.kp);
tk->nhit++;
raw_cpu_inc(*tk->nhit);
if (tk->tp.flags & TP_FLAG_TRACE)
kprobe_trace_func(tk, regs);
@ -1242,7 +1253,7 @@ kretprobe_dispatcher(struct kretprobe_instance *ri, struct pt_regs *regs)
{
struct trace_kprobe *tk = container_of(ri->rp, struct trace_kprobe, rp);
tk->nhit++;
raw_cpu_inc(*tk->nhit);
if (tk->tp.flags & TP_FLAG_TRACE)
kretprobe_trace_func(tk, ri, regs);

View File

@ -186,11 +186,11 @@ print_syscall_exit(struct trace_iterator *iter, int flags,
extern char *__bad_type_size(void);
#define SYSCALL_FIELD(type, name) \
sizeof(type) != sizeof(trace.name) ? \
#define SYSCALL_FIELD(type, field, name) \
sizeof(type) != sizeof(trace.field) ? \
__bad_type_size() : \
#type, #name, offsetof(typeof(trace), name), \
sizeof(trace.name), is_signed_type(type)
#type, #name, offsetof(typeof(trace), field), \
sizeof(trace.field), is_signed_type(type)
static int __init
__set_enter_print_fmt(struct syscall_metadata *entry, char *buf, int len)
@ -261,7 +261,8 @@ static int __init syscall_enter_define_fields(struct trace_event_call *call)
int i;
int offset = offsetof(typeof(trace), args);
ret = trace_define_field(call, SYSCALL_FIELD(int, nr), FILTER_OTHER);
ret = trace_define_field(call, SYSCALL_FIELD(int, nr, __syscall_nr),
FILTER_OTHER);
if (ret)
return ret;
@ -281,11 +282,12 @@ static int __init syscall_exit_define_fields(struct trace_event_call *call)
struct syscall_trace_exit trace;
int ret;
ret = trace_define_field(call, SYSCALL_FIELD(int, nr), FILTER_OTHER);
ret = trace_define_field(call, SYSCALL_FIELD(int, nr, __syscall_nr),
FILTER_OTHER);
if (ret)
return ret;
ret = trace_define_field(call, SYSCALL_FIELD(long, ret),
ret = trace_define_field(call, SYSCALL_FIELD(long, ret, ret),
FILTER_OTHER);
return ret;

View File

@ -41,6 +41,7 @@ int cpumask_any_but(const struct cpumask *mask, unsigned int cpu)
break;
return i;
}
EXPORT_SYMBOL(cpumask_any_but);
/* These are not inline because of header tangles. */
#ifdef CONFIG_CPUMASK_OFFSTACK

View File

@ -85,7 +85,7 @@ $(OUTPUT)%.i: %.c FORCE
$(call rule_mkdir)
$(call if_changed_dep,cc_i_c)
$(OUTPUT)%.i: %.S FORCE
$(OUTPUT)%.s: %.S FORCE
$(call rule_mkdir)
$(call if_changed_dep,cc_i_c)

View File

@ -27,7 +27,7 @@ endef
# the rule that uses them - an example for that is the 'bionic'
# feature check. ]
#
FEATURE_TESTS ?= \
FEATURE_TESTS_BASIC := \
backtrace \
dwarf \
fortify-source \
@ -46,6 +46,7 @@ FEATURE_TESTS ?= \
libpython \
libpython-version \
libslang \
libcrypto \
libunwind \
pthread-attr-setaffinity-np \
stackprotector-all \
@ -56,6 +57,25 @@ FEATURE_TESTS ?= \
get_cpuid \
bpf
# FEATURE_TESTS_BASIC + FEATURE_TESTS_EXTRA is the complete list
# of all feature tests
FEATURE_TESTS_EXTRA := \
bionic \
compile-32 \
compile-x32 \
cplus-demangle \
hello \
libbabeltrace \
liberty \
liberty-z \
libunwind-debug-frame
FEATURE_TESTS ?= $(FEATURE_TESTS_BASIC)
ifeq ($(FEATURE_TESTS),all)
FEATURE_TESTS := $(FEATURE_TESTS_BASIC) $(FEATURE_TESTS_EXTRA)
endif
FEATURE_DISPLAY ?= \
dwarf \
glibc \
@ -68,6 +88,7 @@ FEATURE_DISPLAY ?= \
libperl \
libpython \
libslang \
libcrypto \
libunwind \
libdw-dwarf-unwind \
zlib \
@ -100,6 +121,14 @@ ifeq ($(feature-all), 1)
# test-all.c passed - just set all the core feature flags to 1:
#
$(foreach feat,$(FEATURE_TESTS),$(call feature_set,$(feat)))
#
# test-all.c does not comprise these tests, so we need to
# for this case to get features proper values
#
$(call feature_check,compile-32)
$(call feature_check,compile-x32)
$(call feature_check,bionic)
$(call feature_check,libbabeltrace)
else
$(foreach feat,$(FEATURE_TESTS),$(call feature_check,$(feat)))
endif

View File

@ -23,6 +23,7 @@ FILES= \
test-libpython.bin \
test-libpython-version.bin \
test-libslang.bin \
test-libcrypto.bin \
test-libunwind.bin \
test-libunwind-debug-frame.bin \
test-pthread-attr-setaffinity-np.bin \
@ -105,6 +106,9 @@ $(OUTPUT)test-libaudit.bin:
$(OUTPUT)test-libslang.bin:
$(BUILD) -I/usr/include/slang -lslang
$(OUTPUT)test-libcrypto.bin:
$(BUILD) -lcrypto
$(OUTPUT)test-gtk2.bin:
$(BUILD) $(shell $(PKG_CONFIG) --libs --cflags gtk+-2.0 2>/dev/null)

View File

@ -129,6 +129,10 @@
# include "test-bpf.c"
#undef main
#define main main_test_libcrypto
# include "test-libcrypto.c"
#undef main
int main(int argc, char *argv[])
{
main_test_libpython();
@ -158,6 +162,7 @@ int main(int argc, char *argv[])
main_test_lzma();
main_test_get_cpuid();
main_test_bpf();
main_test_libcrypto();
return 0;
}

View File

@ -1,4 +1,6 @@
#include <stdio.h>
int main(void)
{
printf("Hello World!\n");
return 0;
}

View File

@ -0,0 +1,17 @@
#include <openssl/sha.h>
#include <openssl/md5.h>
int main(void)
{
MD5_CTX context;
unsigned char md[MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH];
unsigned char dat[] = "12345";
MD5_Init(&context);
MD5_Update(&context, &dat[0], sizeof(dat));
MD5_Final(&md[0], &context);
SHA1(&dat[0], sizeof(dat), &md[0]);
return 0;
}

View File

@ -1,3 +1,4 @@
libapi-y += fd/
libapi-y += fs/
libapi-y += cpu.o
libapi-y += debug.o

View File

@ -18,6 +18,7 @@ LIBFILE = $(OUTPUT)libapi.a
CFLAGS := $(EXTRA_WARNINGS) $(EXTRA_CFLAGS)
CFLAGS += -ggdb3 -Wall -Wextra -std=gnu99 -Werror -O6 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -fPIC
CFLAGS += -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64
CFLAGS += -I$(srctree)/tools/lib/api
RM = rm -f

View File

@ -0,0 +1,20 @@
#ifndef __API_DEBUG_INTERNAL_H__
#define __API_DEBUG_INTERNAL_H__
#include "debug.h"
#define __pr(func, fmt, ...) \
do { \
if ((func)) \
(func)("libapi: " fmt, ##__VA_ARGS__); \
} while (0)
extern libapi_print_fn_t __pr_warning;
extern libapi_print_fn_t __pr_info;
extern libapi_print_fn_t __pr_debug;
#define pr_warning(fmt, ...) __pr(__pr_warning, fmt, ##__VA_ARGS__)
#define pr_info(fmt, ...) __pr(__pr_info, fmt, ##__VA_ARGS__)
#define pr_debug(fmt, ...) __pr(__pr_debug, fmt, ##__VA_ARGS__)
#endif /* __API_DEBUG_INTERNAL_H__ */

28
tools/lib/api/debug.c Normal file
View File

@ -0,0 +1,28 @@
#include <stdio.h>
#include <stdarg.h>
#include "debug.h"
#include "debug-internal.h"
static int __base_pr(const char *format, ...)
{
va_list args;
int err;
va_start(args, format);
err = vfprintf(stderr, format, args);
va_end(args);
return err;
}
libapi_print_fn_t __pr_warning = __base_pr;
libapi_print_fn_t __pr_info = __base_pr;
libapi_print_fn_t __pr_debug;
void libapi_set_print(libapi_print_fn_t warn,
libapi_print_fn_t info,
libapi_print_fn_t debug)
{
__pr_warning = warn;
__pr_info = info;
__pr_debug = debug;
}

10
tools/lib/api/debug.h Normal file
View File

@ -0,0 +1,10 @@
#ifndef __API_DEBUG_H__
#define __API_DEBUG_H__
typedef int (*libapi_print_fn_t)(const char *, ...);
void libapi_set_print(libapi_print_fn_t warn,
libapi_print_fn_t info,
libapi_print_fn_t debug);
#endif /* __API_DEBUG_H__ */

View File

@ -13,6 +13,7 @@
#include <sys/mount.h>
#include "fs.h"
#include "debug-internal.h"
#define _STR(x) #x
#define STR(x) _STR(x)
@ -300,6 +301,56 @@ int filename__read_ull(const char *filename, unsigned long long *value)
return err;
}
#define STRERR_BUFSIZE 128 /* For the buffer size of strerror_r */
int filename__read_str(const char *filename, char **buf, size_t *sizep)
{
size_t size = 0, alloc_size = 0;
void *bf = NULL, *nbf;
int fd, n, err = 0;
char sbuf[STRERR_BUFSIZE];
fd = open(filename, O_RDONLY);
if (fd < 0)
return -errno;
do {
if (size == alloc_size) {
alloc_size += BUFSIZ;
nbf = realloc(bf, alloc_size);
if (!nbf) {
err = -ENOMEM;
break;
}
bf = nbf;
}
n = read(fd, bf + size, alloc_size - size);
if (n < 0) {
if (size) {
pr_warning("read failed %d: %s\n", errno,
strerror_r(errno, sbuf, sizeof(sbuf)));
err = 0;
} else
err = -errno;
break;
}
size += n;
} while (n > 0);
if (!err) {
*sizep = size;
*buf = bf;
} else
free(bf);
close(fd);
return err;
}
int sysfs__read_ull(const char *entry, unsigned long long *value)
{
char path[PATH_MAX];
@ -326,6 +377,19 @@ int sysfs__read_int(const char *entry, int *value)
return filename__read_int(path, value);
}
int sysfs__read_str(const char *entry, char **buf, size_t *sizep)
{
char path[PATH_MAX];
const char *sysfs = sysfs__mountpoint();
if (!sysfs)
return -1;
snprintf(path, sizeof(path), "%s/%s", sysfs, entry);
return filename__read_str(path, buf, sizep);
}
int sysctl__read_int(const char *sysctl, int *value)
{
char path[PATH_MAX];

View File

@ -2,6 +2,7 @@
#define __API_FS__
#include <stdbool.h>
#include <unistd.h>
/*
* On most systems <limits.h> would have given us this, but not on some systems
@ -26,8 +27,10 @@ FS(tracefs)
int filename__read_int(const char *filename, int *value);
int filename__read_ull(const char *filename, unsigned long long *value);
int filename__read_str(const char *filename, char **buf, size_t *sizep);
int sysctl__read_int(const char *sysctl, int *value);
int sysfs__read_int(const char *entry, int *value);
int sysfs__read_ull(const char *entry, unsigned long long *value);
int sysfs__read_str(const char *entry, char **buf, size_t *sizep);
#endif /* __API_FS__ */

View File

@ -201,6 +201,7 @@ struct bpf_object {
Elf_Data *data;
} *reloc;
int nr_reloc;
int maps_shndx;
} efile;
/*
* All loaded bpf_object is linked in a list, which is
@ -350,6 +351,7 @@ static struct bpf_object *bpf_object__new(const char *path,
*/
obj->efile.obj_buf = obj_buf;
obj->efile.obj_buf_sz = obj_buf_sz;
obj->efile.maps_shndx = -1;
obj->loaded = false;
@ -529,12 +531,12 @@ bpf_object__init_maps(struct bpf_object *obj, void *data,
}
static int
bpf_object__init_maps_name(struct bpf_object *obj, int maps_shndx)
bpf_object__init_maps_name(struct bpf_object *obj)
{
int i;
Elf_Data *symbols = obj->efile.symbols;
if (!symbols || maps_shndx < 0)
if (!symbols || obj->efile.maps_shndx < 0)
return -EINVAL;
for (i = 0; i < symbols->d_size / sizeof(GElf_Sym); i++) {
@ -544,7 +546,7 @@ bpf_object__init_maps_name(struct bpf_object *obj, int maps_shndx)
if (!gelf_getsym(symbols, i, &sym))
continue;
if (sym.st_shndx != maps_shndx)
if (sym.st_shndx != obj->efile.maps_shndx)
continue;
map_name = elf_strptr(obj->efile.elf,
@ -572,7 +574,7 @@ static int bpf_object__elf_collect(struct bpf_object *obj)
Elf *elf = obj->efile.elf;
GElf_Ehdr *ep = &obj->efile.ehdr;
Elf_Scn *scn = NULL;
int idx = 0, err = 0, maps_shndx = -1;
int idx = 0, err = 0;
/* Elf is corrupted/truncated, avoid calling elf_strptr. */
if (!elf_rawdata(elf_getscn(elf, ep->e_shstrndx), NULL)) {
@ -625,7 +627,7 @@ static int bpf_object__elf_collect(struct bpf_object *obj)
else if (strcmp(name, "maps") == 0) {
err = bpf_object__init_maps(obj, data->d_buf,
data->d_size);
maps_shndx = idx;
obj->efile.maps_shndx = idx;
} else if (sh.sh_type == SHT_SYMTAB) {
if (obj->efile.symbols) {
pr_warning("bpf: multiple SYMTAB in %s\n",
@ -674,8 +676,8 @@ static int bpf_object__elf_collect(struct bpf_object *obj)
pr_warning("Corrupted ELF file: index of strtab invalid\n");
return LIBBPF_ERRNO__FORMAT;
}
if (maps_shndx >= 0)
err = bpf_object__init_maps_name(obj, maps_shndx);
if (obj->efile.maps_shndx >= 0)
err = bpf_object__init_maps_name(obj);
out:
return err;
}
@ -697,7 +699,8 @@ bpf_object__find_prog_by_idx(struct bpf_object *obj, int idx)
static int
bpf_program__collect_reloc(struct bpf_program *prog,
size_t nr_maps, GElf_Shdr *shdr,
Elf_Data *data, Elf_Data *symbols)
Elf_Data *data, Elf_Data *symbols,
int maps_shndx)
{
int i, nrels;
@ -724,9 +727,6 @@ bpf_program__collect_reloc(struct bpf_program *prog,
return -LIBBPF_ERRNO__FORMAT;
}
insn_idx = rel.r_offset / sizeof(struct bpf_insn);
pr_debug("relocation: insn_idx=%u\n", insn_idx);
if (!gelf_getsym(symbols,
GELF_R_SYM(rel.r_info),
&sym)) {
@ -735,6 +735,15 @@ bpf_program__collect_reloc(struct bpf_program *prog,
return -LIBBPF_ERRNO__FORMAT;
}
if (sym.st_shndx != maps_shndx) {
pr_warning("Program '%s' contains non-map related relo data pointing to section %u\n",
prog->section_name, sym.st_shndx);
return -LIBBPF_ERRNO__RELOC;
}
insn_idx = rel.r_offset / sizeof(struct bpf_insn);
pr_debug("relocation: insn_idx=%u\n", insn_idx);
if (insns[insn_idx].code != (BPF_LD | BPF_IMM | BPF_DW)) {
pr_warning("bpf: relocation: invalid relo for insns[%d].code 0x%x\n",
insn_idx, insns[insn_idx].code);
@ -863,7 +872,8 @@ static int bpf_object__collect_reloc(struct bpf_object *obj)
err = bpf_program__collect_reloc(prog, nr_maps,
shdr, data,
obj->efile.symbols);
obj->efile.symbols,
obj->efile.maps_shndx);
if (err)
return err;
}

View File

@ -1951,6 +1951,7 @@ process_op(struct event_format *event, struct print_arg *arg, char **tok)
strcmp(token, "*") == 0 ||
strcmp(token, "^") == 0 ||
strcmp(token, "/") == 0 ||
strcmp(token, "%") == 0 ||
strcmp(token, "<") == 0 ||
strcmp(token, ">") == 0 ||
strcmp(token, "<=") == 0 ||
@ -2397,6 +2398,12 @@ static int arg_num_eval(struct print_arg *arg, long long *val)
break;
*val = left + right;
break;
case '~':
ret = arg_num_eval(arg->op.right, &right);
if (!ret)
break;
*val = ~right;
break;
default:
do_warning("unknown op '%s'", arg->op.op);
ret = 0;
@ -2634,6 +2641,7 @@ process_hex(struct event_format *event, struct print_arg *arg, char **tok)
free_field:
free_arg(arg->hex.field);
arg->hex.field = NULL;
out:
*tok = NULL;
return EVENT_ERROR;
@ -2658,8 +2666,10 @@ process_int_array(struct event_format *event, struct print_arg *arg, char **tok)
free_size:
free_arg(arg->int_array.count);
arg->int_array.count = NULL;
free_field:
free_arg(arg->int_array.field);
arg->int_array.field = NULL;
out:
*tok = NULL;
return EVENT_ERROR;
@ -3689,6 +3699,9 @@ eval_num_arg(void *data, int size, struct event_format *event, struct print_arg
case '/':
val = left / right;
break;
case '%':
val = left % right;
break;
case '*':
val = left * right;
break;
@ -4971,7 +4984,7 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct event
break;
}
}
if (pevent->long_size == 8 && ls &&
if (pevent->long_size == 8 && ls == 1 &&
sizeof(long) != 8) {
char *p;
@ -5335,19 +5348,74 @@ static bool is_timestamp_in_us(char *trace_clock, bool use_trace_clock)
return false;
}
void pevent_print_event(struct pevent *pevent, struct trace_seq *s,
struct pevent_record *record, bool use_trace_clock)
/**
* pevent_find_event_by_record - return the event from a given record
* @pevent: a handle to the pevent
* @record: The record to get the event from
*
* Returns the associated event for a given record, or NULL if non is
* is found.
*/
struct event_format *
pevent_find_event_by_record(struct pevent *pevent, struct pevent_record *record)
{
int type;
if (record->size < 0) {
do_warning("ug! negative record size %d", record->size);
return NULL;
}
type = trace_parse_common_type(pevent, record->data);
return pevent_find_event(pevent, type);
}
/**
* pevent_print_event_task - Write the event task comm, pid and CPU
* @pevent: a handle to the pevent
* @s: the trace_seq to write to
* @event: the handle to the record's event
* @record: The record to get the event from
*
* Writes the tasks comm, pid and CPU to @s.
*/
void pevent_print_event_task(struct pevent *pevent, struct trace_seq *s,
struct event_format *event,
struct pevent_record *record)
{
void *data = record->data;
const char *comm;
int pid;
pid = parse_common_pid(pevent, data);
comm = find_cmdline(pevent, pid);
if (pevent->latency_format) {
trace_seq_printf(s, "%8.8s-%-5d %3d",
comm, pid, record->cpu);
} else
trace_seq_printf(s, "%16s-%-5d [%03d]", comm, pid, record->cpu);
}
/**
* pevent_print_event_time - Write the event timestamp
* @pevent: a handle to the pevent
* @s: the trace_seq to write to
* @event: the handle to the record's event
* @record: The record to get the event from
* @use_trace_clock: Set to parse according to the @pevent->trace_clock
*
* Writes the timestamp of the record into @s.
*/
void pevent_print_event_time(struct pevent *pevent, struct trace_seq *s,
struct event_format *event,
struct pevent_record *record,
bool use_trace_clock)
{
static const char *spaces = " "; /* 20 spaces */
struct event_format *event;
unsigned long secs;
unsigned long usecs;
unsigned long nsecs;
const char *comm;
void *data = record->data;
int type;
int pid;
int len;
int p;
bool use_usec_format;
@ -5358,28 +5426,11 @@ void pevent_print_event(struct pevent *pevent, struct trace_seq *s,
nsecs = record->ts - secs * NSECS_PER_SEC;
}
if (record->size < 0) {
do_warning("ug! negative record size %d", record->size);
return;
}
type = trace_parse_common_type(pevent, data);
event = pevent_find_event(pevent, type);
if (!event) {
do_warning("ug! no event found for type %d", type);
return;
}
pid = parse_common_pid(pevent, data);
comm = find_cmdline(pevent, pid);
if (pevent->latency_format) {
trace_seq_printf(s, "%8.8s-%-5d %3d",
comm, pid, record->cpu);
trace_seq_printf(s, " %3d", record->cpu);
pevent_data_lat_fmt(pevent, s, record);
} else
trace_seq_printf(s, "%16s-%-5d [%03d]", comm, pid, record->cpu);
trace_seq_printf(s, " [%03d]", record->cpu);
if (use_usec_format) {
if (pevent->flags & PEVENT_NSEC_OUTPUT) {
@ -5387,14 +5438,36 @@ void pevent_print_event(struct pevent *pevent, struct trace_seq *s,
p = 9;
} else {
usecs = (nsecs + 500) / NSECS_PER_USEC;
/* To avoid usecs larger than 1 sec */
if (usecs >= 1000000) {
usecs -= 1000000;
secs++;
}
p = 6;
}
trace_seq_printf(s, " %5lu.%0*lu: %s: ",
secs, p, usecs, event->name);
trace_seq_printf(s, " %5lu.%0*lu:", secs, p, usecs);
} else
trace_seq_printf(s, " %12llu: %s: ",
record->ts, event->name);
trace_seq_printf(s, " %12llu:", record->ts);
}
/**
* pevent_print_event_data - Write the event data section
* @pevent: a handle to the pevent
* @s: the trace_seq to write to
* @event: the handle to the record's event
* @record: The record to get the event from
*
* Writes the parsing of the record's data to @s.
*/
void pevent_print_event_data(struct pevent *pevent, struct trace_seq *s,
struct event_format *event,
struct pevent_record *record)
{
static const char *spaces = " "; /* 20 spaces */
int len;
trace_seq_printf(s, " %s: ", event->name);
/* Space out the event names evenly. */
len = strlen(event->name);
@ -5404,6 +5477,23 @@ void pevent_print_event(struct pevent *pevent, struct trace_seq *s,
pevent_event_info(s, event, record);
}
void pevent_print_event(struct pevent *pevent, struct trace_seq *s,
struct pevent_record *record, bool use_trace_clock)
{
struct event_format *event;
event = pevent_find_event_by_record(pevent, record);
if (!event) {
do_warning("ug! no event found for type %d",
trace_parse_common_type(pevent, record->data));
return;
}
pevent_print_event_task(pevent, s, event, record);
pevent_print_event_time(pevent, s, event, record, use_trace_clock);
pevent_print_event_data(pevent, s, event, record);
}
static int events_id_cmp(const void *a, const void *b)
{
struct event_format * const * ea = a;

View File

@ -628,6 +628,16 @@ int pevent_register_print_string(struct pevent *pevent, const char *fmt,
unsigned long long addr);
int pevent_pid_is_registered(struct pevent *pevent, int pid);
void pevent_print_event_task(struct pevent *pevent, struct trace_seq *s,
struct event_format *event,
struct pevent_record *record);
void pevent_print_event_time(struct pevent *pevent, struct trace_seq *s,
struct event_format *event,
struct pevent_record *record,
bool use_trace_clock);
void pevent_print_event_data(struct pevent *pevent, struct trace_seq *s,
struct event_format *event,
struct pevent_record *record);
void pevent_print_event(struct pevent *pevent, struct trace_seq *s,
struct pevent_record *record, bool use_trace_clock);
@ -694,6 +704,9 @@ struct event_format *pevent_find_event(struct pevent *pevent, int id);
struct event_format *
pevent_find_event_by_name(struct pevent *pevent, const char *sys, const char *name);
struct event_format *
pevent_find_event_by_record(struct pevent *pevent, struct pevent_record *record);
void pevent_data_lat_fmt(struct pevent *pevent,
struct trace_seq *s, struct pevent_record *record);
int pevent_data_type(struct pevent *pevent, struct pevent_record *rec);

View File

@ -8,7 +8,7 @@ perf-config - Get and set variables in a configuration file.
SYNOPSIS
--------
[verse]
'perf config' -l | --list
'perf config' [<file-option>] -l | --list
DESCRIPTION
-----------
@ -21,6 +21,14 @@ OPTIONS
--list::
Show current config variables, name and value, for all sections.
--user::
For writing and reading options: write to user
'$HOME/.perfconfig' file or read it.
--system::
For writing and reading options: write to system-wide
'$(sysconfdir)/perfconfig' or read it.
CONFIGURATION FILE
------------------
@ -30,6 +38,10 @@ The '$HOME/.perfconfig' file is used to store a per-user configuration.
The file '$(sysconfdir)/perfconfig' can be used to
store a system-wide default configuration.
When reading or writing, the values are read from the system and user
configuration files by default, and options '--system' and '--user'
can be used to tell the command to read from or write to only that location.
Syntax
~~~~~~
@ -62,7 +74,7 @@ Given a $HOME/.perfconfig like this:
medium = green, default
normal = lightgray, default
selected = white, lightgray
code = blue, default
jump_arrows = blue, default
addr = magenta, default
root = white, blue
@ -98,6 +110,347 @@ Given a $HOME/.perfconfig like this:
order = caller
sort-key = function
Variables
~~~~~~~~~
colors.*::
The variables for customizing the colors used in the output for the
'report', 'top' and 'annotate' in the TUI. They should specify the
foreground and background colors, separated by a comma, for example:
medium = green, lightgray
If you want to use the color configured for you terminal, just leave it
as 'default', for example:
medium = default, lightgray
Available colors:
red, yellow, green, cyan, gray, black, blue,
white, default, magenta, lightgray
colors.top::
'top' means a overhead percentage which is more than 5%.
And values of this variable specify percentage colors.
Basic key values are foreground-color 'red' and
background-color 'default'.
colors.medium::
'medium' means a overhead percentage which has more than 0.5%.
Default values are 'green' and 'default'.
colors.normal::
'normal' means the rest of overhead percentages
except 'top', 'medium', 'selected'.
Default values are 'lightgray' and 'default'.
colors.selected::
This selects the colors for the current entry in a list of entries
from sub-commands (top, report, annotate).
Default values are 'black' and 'lightgray'.
colors.jump_arrows::
Colors for jump arrows on assembly code listings
such as 'jns', 'jmp', 'jane', etc.
Default values are 'blue', 'default'.
colors.addr::
This selects colors for addresses from 'annotate'.
Default values are 'magenta', 'default'.
colors.root::
Colors for headers in the output of a sub-commands (top, report).
Default values are 'white', 'blue'.
tui.*, gtk.*::
Subcommands that can be configured here are 'top', 'report' and 'annotate'.
These values are booleans, for example:
[tui]
top = true
will make the TUI be the default for the 'top' subcommand. Those will be
available if the required libs were detected at tool build time.
buildid.*::
buildid.dir::
Each executable and shared library in modern distributions comes with a
content based identifier that, if available, will be inserted in a
'perf.data' file header to, at analysis time find what is needed to do
symbol resolution, code annotation, etc.
The recording tools also stores a hard link or copy in a per-user
directory, $HOME/.debug/, of binaries, shared libraries, /proc/kallsyms
and /proc/kcore files to be used at analysis time.
The buildid.dir variable can be used to either change this directory
cache location, or to disable it altogether. If you want to disable it,
set buildid.dir to /dev/null. The default is $HOME/.debug
annotate.*::
These options work only for TUI.
These are in control of addresses, jump function, source code
in lines of assembly code from a specific program.
annotate.hide_src_code::
If a program which is analyzed has source code,
this option lets 'annotate' print a list of assembly code with the source code.
For example, let's see a part of a program. There're four lines.
If this option is 'true', they can be printed
without source code from a program as below.
│ push %rbp
│ mov %rsp,%rbp
│ sub $0x10,%rsp
│ mov (%rdi),%rdx
But if this option is 'false', source code of the part
can be also printed as below. Default is 'false'.
│ struct rb_node *rb_next(const struct rb_node *node)
│ {
│ push %rbp
│ mov %rsp,%rbp
│ sub $0x10,%rsp
│ struct rb_node *parent;
│ if (RB_EMPTY_NODE(node))
│ mov (%rdi),%rdx
│ return n;
annotate.use_offset::
Basing on a first address of a loaded function, offset can be used.
Instead of using original addresses of assembly code,
addresses subtracted from a base address can be printed.
Let's illustrate an example.
If a base address is 0XFFFFFFFF81624d50 as below,
ffffffff81624d50 <load0>
an address on assembly code has a specific absolute address as below
ffffffff816250b8:│ mov 0x8(%r14),%rdi
but if use_offset is 'true', an address subtracted from a base address is printed.
Default is true. This option is only applied to TUI.
368:│ mov 0x8(%r14),%rdi
annotate.jump_arrows::
There can be jump instruction among assembly code.
Depending on a boolean value of jump_arrows,
arrows can be printed or not which represent
where do the instruction jump into as below.
│ ┌──jmp 1333
│ │ xchg %ax,%ax
│1330:│ mov %r15,%r10
│1333:└─→cmp %r15,%r14
If jump_arrow is 'false', the arrows isn't printed as below.
Default is 'false'.
│ ↓ jmp 1333
│ xchg %ax,%ax
│1330: mov %r15,%r10
│1333: cmp %r15,%r14
annotate.show_linenr::
When showing source code if this option is 'true',
line numbers are printed as below.
│1628 if (type & PERF_SAMPLE_IDENTIFIER) {
│ ↓ jne 508
│1628 data->id = *array;
│1629 array++;
│1630 }
However if this option is 'false', they aren't printed as below.
Default is 'false'.
│ if (type & PERF_SAMPLE_IDENTIFIER) {
│ ↓ jne 508
│ data->id = *array;
│ array++;
│ }
annotate.show_nr_jumps::
Let's see a part of assembly code.
│1382: movb $0x1,-0x270(%rbp)
If use this, the number of branches jumping to that address can be printed as below.
Default is 'false'.
│1 1382: movb $0x1,-0x270(%rbp)
annotate.show_total_period::
To compare two records on an instruction base, with this option
provided, display total number of samples that belong to a line
in assembly code. If this option is 'true', total periods are printed
instead of percent values as below.
302 │ mov %eax,%eax
But if this option is 'false', percent values for overhead are printed i.e.
Default is 'false'.
99.93 │ mov %eax,%eax
hist.*::
hist.percentage::
This option control the way to calculate overhead of filtered entries -
that means the value of this option is effective only if there's a
filter (by comm, dso or symbol name). Suppose a following example:
Overhead Symbols
........ .......
33.33% foo
33.33% bar
33.33% baz
This is an original overhead and we'll filter out the first 'foo'
entry. The value of 'relative' would increase the overhead of 'bar'
and 'baz' to 50.00% for each, while 'absolute' would show their
current overhead (33.33%).
ui.*::
ui.show-headers::
This option controls display of column headers (like 'Overhead' and 'Symbol')
in 'report' and 'top'. If this option is false, they are hidden.
This option is only applied to TUI.
call-graph.*::
When sub-commands 'top' and 'report' work with -g/—-children
there're options in control of call-graph.
call-graph.record-mode::
The record-mode can be 'fp' (frame pointer), 'dwarf' and 'lbr'.
The value of 'dwarf' is effective only if perf detect needed library
(libunwind or a recent version of libdw).
'lbr' only work for cpus that support it.
call-graph.dump-size::
The size of stack to dump in order to do post-unwinding. Default is 8192 (byte).
When using dwarf into record-mode, the default size will be used if omitted.
call-graph.print-type::
The print-types can be graph (graph absolute), fractal (graph relative),
flat and folded. This option controls a way to show overhead for each callchain
entry. Suppose a following example.
Overhead Symbols
........ .......
40.00% foo
|
---foo
|
|--50.00%--bar
| main
|
--50.00%--baz
main
This output is a 'fractal' format. The 'foo' came from 'bar' and 'baz' exactly
half and half so 'fractal' shows 50.00% for each
(meaning that it assumes 100% total overhead of 'foo').
The 'graph' uses absolute overhead value of 'foo' as total so each of
'bar' and 'baz' callchain will have 20.00% of overhead.
If 'flat' is used, single column and linear exposure of call chains.
'folded' mean call chains are displayed in a line, separated by semicolons.
call-graph.order::
This option controls print order of callchains. The default is
'callee' which means callee is printed at top and then followed by its
caller and so on. The 'caller' prints it in reverse order.
If this option is not set and report.children or top.children is
set to true (or the equivalent command line option is given),
the default value of this option is changed to 'caller' for the
execution of 'perf report' or 'perf top'. Other commands will
still default to 'callee'.
call-graph.sort-key::
The callchains are merged if they contain same information.
The sort-key option determines a way to compare the callchains.
A value of 'sort-key' can be 'function' or 'address'.
The default is 'function'.
call-graph.threshold::
When there're many callchains it'd print tons of lines. So perf omits
small callchains under a certain overhead (threshold) and this option
control the threshold. Default is 0.5 (%). The overhead is calculated
by value depends on call-graph.print-type.
call-graph.print-limit::
This is a maximum number of lines of callchain printed for a single
histogram entry. Default is 0 which means no limitation.
report.*::
report.percent-limit::
This one is mostly the same as call-graph.threshold but works for
histogram entries. Entries having an overhead lower than this
percentage will not be printed. Default is '0'. If percent-limit
is '10', only entries which have more than 10% of overhead will be
printed.
report.queue-size::
This option sets up the maximum allocation size of the internal
event queue for ordering events. Default is 0, meaning no limit.
report.children::
'Children' means functions called from another function.
If this option is true, 'perf report' cumulates callchains of children
and show (accumulated) total overhead as well as 'Self' overhead.
Please refer to the 'perf report' manual. The default is 'true'.
report.group::
This option is to show event group information together.
Example output with this turned on, notice that there is one column
per event in the group, ref-cycles and cycles:
# group: {ref-cycles,cycles}
# ========
#
# Samples: 7K of event 'anon group { ref-cycles, cycles }'
# Event count (approx.): 6876107743
#
# Overhead Command Shared Object Symbol
# ................ ....... ................. ...................
#
99.84% 99.76% noploop noploop [.] main
0.07% 0.00% noploop ld-2.15.so [.] strcmp
0.03% 0.00% noploop [kernel.kallsyms] [k] timerqueue_del
top.*::
top.children::
Same as 'report.children'. So if it is enabled, the output of 'top'
command will have 'Children' overhead column as well as 'Self' overhead
column by default.
The default is 'true'.
man.*::
man.viewer::
This option can assign a tool to view manual pages when 'help'
subcommand was invoked. Supported tools are 'man', 'woman'
(with emacs client) and 'konqueror'. Default is 'man'.
New man viewer tool can be also added using 'man.<tool>.cmd'
or use different path using 'man.<tool>.path' config option.
pager.*::
pager.<subcommand>::
When the subcommand is run on stdio, determine whether it uses
pager or not based on this value. Default is 'unspecified'.
kmem.*::
kmem.default::
This option decides which allocator is to be analyzed if neither
'--slab' nor '--page' option is used. Default is 'slab'.
record.*::
record.build-id::
This option can be 'cache', 'no-cache' or 'skip'.
'cache' is to post-process data and save/update the binaries into
the build-id cache (in ~/.debug). This is the default.
But if this option is 'no-cache', it will not update the build-id cache.
'skip' skips post-processing and does not update the cache.
SEE ALSO
--------
linkperf:perf[1]

View File

@ -53,6 +53,13 @@ include::itrace.txt[]
--strip::
Use with --itrace to strip out non-synthesized events.
-j::
--jit::
Process jitdump files by injecting the mmap records corresponding to jitted
functions. This option also generates the ELF images for each jitted function
found in the jitdumps files captured in the input perf.data file. Use this option
if you are monitoring environment using JIT runtimes, such as Java, DART or V8.
SEE ALSO
--------
linkperf:perf-record[1], linkperf:perf-report[1], linkperf:perf-archive[1]

View File

@ -341,6 +341,12 @@ Specify vmlinux path which has debuginfo.
--buildid-all::
Record build-id of all DSOs regardless whether it's actually hit or not.
--all-kernel::
Configure all used events to run in kernel space.
--all-user::
Configure all used events to run in user space.
SEE ALSO
--------
linkperf:perf-stat[1], linkperf:perf-list[1]

View File

@ -117,6 +117,22 @@ OPTIONS
And default sort keys are changed to comm, dso_from, symbol_from, dso_to
and symbol_to, see '--branch-stack'.
If the --mem-mode option is used, the following sort keys are also available
(incompatible with --branch-stack):
symbol_daddr, dso_daddr, locked, tlb, mem, snoop, dcacheline.
- symbol_daddr: name of data symbol being executed on at the time of sample
- dso_daddr: name of library or module containing the data being executed
on at the time of the sample
- locked: whether the bus was locked at the time of the sample
- tlb: type of tlb access for the data at the time of the sample
- mem: type of memory access for the data at the time of the sample
- snoop: type of snoop (if any) for the data at the time of the sample
- dcacheline: the cacheline the data address is on at the time of the sample
And the default sort keys are changed to local_weight, mem, sym, dso,
symbol_daddr, dso_daddr, snoop, tlb, locked, see '--mem-mode'.
If the data file has tracepoint event(s), following (dynamic) sort keys
are also available:
trace, trace_fields, [<event>.]<field>[/raw]
@ -151,22 +167,6 @@ OPTIONS
By default, every sort keys not specified in -F will be appended
automatically.
If --mem-mode option is used, following sort keys are also available
(incompatible with --branch-stack):
symbol_daddr, dso_daddr, locked, tlb, mem, snoop, dcacheline.
- symbol_daddr: name of data symbol being executed on at the time of sample
- dso_daddr: name of library or module containing the data being executed
on at the time of sample
- locked: whether the bus was locked at the time of sample
- tlb: type of tlb access for the data at the time of sample
- mem: type of memory access for the data at the time of sample
- snoop: type of snoop (if any) for the data at the time of sample
- dcacheline: the cacheline the data address is on at the time of sample
And default sort keys are changed to local_weight, mem, sym, dso,
symbol_daddr, dso_daddr, snoop, tlb, locked, see '--mem-mode'.
-p::
--parent=<regex>::
A regex filter to identify parent. The parent is a caller of this
@ -351,7 +351,10 @@ OPTIONS
--percent-limit::
Do not show entries which have an overhead under that percent.
(Default: 0).
(Default: 0). Note that this option also sets the percent limit (threshold)
of callchains. However the default value of callchain threshold is
different than the default value of hist entries. Please see the
--call-graph option for details.
--percentage::
Determine how to display the overhead percentage of filtered entries.
@ -398,6 +401,9 @@ include::itrace.txt[]
--raw-trace::
When displaying traceevent output, do not use print fmt or plugins.
--hierarchy::
Enable hierarchical output.
include::callchain-overhead-calculation.txt[]
SEE ALSO

View File

@ -69,6 +69,14 @@ report::
--scale::
scale/normalize counter values
-d::
--detailed::
print more detailed statistics, can be specified up to 3 times
-d: detailed events, L1 and LLC data cache
-d -d: more detailed events, dTLB and iTLB events
-d -d -d: very detailed events, adding prefetch events
-r::
--repeat=<n>::
repeat command and print average + stddev (max: 100). 0 means forever.
@ -139,6 +147,10 @@ Print count deltas every N milliseconds (minimum: 10ms)
The overhead percentage could be high in some cases, for instance with small, sub 100ms intervals. Use with caution.
example: 'perf stat -I 1000 -e cycles -a sleep 5'
--metric-only::
Only print computed metrics. Print them in a single line.
Don't show any raw values. Not supported with --per-thread.
--per-socket::
Aggregate counts per processor socket for system-wide mode measurements. This
is a useful mode to detect imbalance between sockets. To enable this mode,
@ -211,6 +223,29 @@ $ perf stat -- make -j
Wall-clock time elapsed: 719.554352 msecs
CSV FORMAT
----------
With -x, perf stat is able to output a not-quite-CSV format output
Commas in the output are not put into "". To make it easy to parse
it is recommended to use a different character like -x \;
The fields are in this order:
- optional usec time stamp in fractions of second (with -I xxx)
- optional CPU, core, or socket identifier
- optional number of logical CPUs aggregated
- counter value
- unit of the counter value or empty
- event name
- run time of counter
- percentage of measurement time the counter was running
- optional variance if multiple values are collected with -r
- optional metric value
- optional unit of metric
Additional metrics may be printed with all earlier fields being empty.
SEE ALSO
--------
linkperf:perf-top[1], linkperf:perf-list[1]

View File

@ -233,6 +233,9 @@ Default is to monitor all CPUS.
--raw-trace::
When displaying traceevent output, do not use print fmt or plugins.
--hierarchy::
Enable hierarchy output.
INTERACTIVE PROMPTING KEYS
--------------------------

View File

@ -5,7 +5,7 @@
medium = green, lightgray
normal = black, lightgray
selected = lightgray, magenta
code = blue, lightgray
jump_arrows = blue, lightgray
addr = magenta, lightgray
[tui]

View File

@ -27,3 +27,4 @@ Skip collecing build-id when recording: perf record -B
To change sampling frequency to 100 Hz: perf record -F 100
See assembly instructions with percentage: perf annotate <symbol>
If you prefer Intel style assembly, try: perf annotate -M intel
For hierarchical output, try: perf report --hierarchy

View File

@ -68,6 +68,20 @@ all tags TAGS:
$(print_msg)
$(make)
ifdef MAKECMDGOALS
has_clean := 0
ifneq ($(filter clean,$(MAKECMDGOALS)),)
has_clean := 1
endif # clean
ifeq ($(has_clean),1)
rest := $(filter-out clean,$(MAKECMDGOALS))
ifneq ($(rest),)
$(rest): clean
endif # rest
endif # has_clean
endif # MAKECMDGOALS
#
# The clean target is not really parallel, don't print the jobs info:
#
@ -75,10 +89,17 @@ clean:
$(make)
#
# The build-test target is not really parallel, don't print the jobs info:
# The build-test target is not really parallel, don't print the jobs info,
# it also uses only the tests/make targets that don't pollute the source
# repository, i.e. that uses O= or builds the tarpkg outside the source
# repo directories.
#
# For a full test, use:
#
# make -C tools/perf -f tests/make
#
build-test:
@$(MAKE) SHUF=1 -f tests/make --no-print-directory
@$(MAKE) SHUF=1 -f tests/make REUSE_FEATURES_DUMP=1 MK=Makefile SET_PARALLEL=1 --no-print-directory tarpkg out
#
# All other targets get passed through:

View File

@ -58,6 +58,9 @@ include config/utilities.mak
#
# Define NO_LIBBIONIC if you do not want bionic support
#
# Define NO_LIBCRYPTO if you do not want libcrypto (openssl) support
# used for generating build-ids for ELFs generated by jitdump.
#
# Define NO_LIBDW_DWARF_UNWIND if you do not want libdw support
# for dwarf backtrace post unwind.
#
@ -136,6 +139,8 @@ $(call allow-override,CC,$(CROSS_COMPILE)gcc)
$(call allow-override,AR,$(CROSS_COMPILE)ar)
$(call allow-override,LD,$(CROSS_COMPILE)ld)
LD += $(EXTRA_LDFLAGS)
PKG_CONFIG = $(CROSS_COMPILE)pkg-config
RM = rm -f
@ -165,7 +170,16 @@ ifeq ($(filter-out $(NON_CONFIG_TARGETS),$(MAKECMDGOALS)),)
endif
endif
# Set FEATURE_TESTS to 'all' so all possible feature checkers are executed.
# Without this setting the output feature dump file misses some features, for
# example, liberty. Select all checkers so we won't get an incomplete feature
# dump file.
ifeq ($(config),1)
ifdef MAKECMDGOALS
ifeq ($(filter feature-dump,$(MAKECMDGOALS)),feature-dump)
FEATURE_TESTS := all
endif
endif
include config/Makefile
endif
@ -618,7 +632,7 @@ clean: $(LIBTRACEEVENT)-clean $(LIBAPI)-clean $(LIBBPF)-clean $(LIBSUBCMD)-clean
$(call QUIET_CLEAN, core-progs) $(RM) $(ALL_PROGRAMS) perf perf-read-vdso32 perf-read-vdsox32
$(call QUIET_CLEAN, core-gen) $(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo $(OUTPUT)common-cmds.h TAGS tags cscope* $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)FEATURE-DUMP $(OUTPUT)util/*-bison* $(OUTPUT)util/*-flex* \
$(OUTPUT)util/intel-pt-decoder/inat-tables.c $(OUTPUT)fixdep \
$(OUTPUT)tests/llvm-src-{base,kbuild,prologue}.c
$(OUTPUT)tests/llvm-src-{base,kbuild,prologue,relocation}.c
$(QUIET_SUBDIR0)Documentation $(QUIET_SUBDIR1) clean
$(python-clean)

View File

@ -1,3 +1,4 @@
ifndef NO_DWARF
PERF_HAVE_DWARF_REGS := 1
endif
PERF_HAVE_JITDUMP := 1

View File

@ -1,3 +1,4 @@
ifndef NO_DWARF
PERF_HAVE_DWARF_REGS := 1
endif
PERF_HAVE_JITDUMP := 1

View File

@ -1,3 +1,6 @@
ifndef NO_DWARF
PERF_HAVE_DWARF_REGS := 1
endif
HAVE_KVM_STAT_SUPPORT := 1
PERF_HAVE_JITDUMP := 1

View File

@ -1,5 +1,6 @@
libperf-y += header.o
libperf-y += sym-handling.o
libperf-y += kvm-stat.o
libperf-$(CONFIG_DWARF) += dwarf-regs.o
libperf-$(CONFIG_DWARF) += skip-callchain-idx.o

View File

@ -0,0 +1,123 @@
#ifndef ARCH_PERF_BOOK3S_HV_HCALLS_H
#define ARCH_PERF_BOOK3S_HV_HCALLS_H
/*
* PowerPC HCALL codes : hcall code to name mapping
*/
#define kvm_trace_symbol_hcall \
{0x4, "H_REMOVE"}, \
{0x8, "H_ENTER"}, \
{0xc, "H_READ"}, \
{0x10, "H_CLEAR_MOD"}, \
{0x14, "H_CLEAR_REF"}, \
{0x18, "H_PROTECT"}, \
{0x1c, "H_GET_TCE"}, \
{0x20, "H_PUT_TCE"}, \
{0x24, "H_SET_SPRG0"}, \
{0x28, "H_SET_DABR"}, \
{0x2c, "H_PAGE_INIT"}, \
{0x30, "H_SET_ASR"}, \
{0x34, "H_ASR_ON"}, \
{0x38, "H_ASR_OFF"}, \
{0x3c, "H_LOGICAL_CI_LOAD"}, \
{0x40, "H_LOGICAL_CI_STORE"}, \
{0x44, "H_LOGICAL_CACHE_LOAD"}, \
{0x48, "H_LOGICAL_CACHE_STORE"}, \
{0x4c, "H_LOGICAL_ICBI"}, \
{0x50, "H_LOGICAL_DCBF"}, \
{0x54, "H_GET_TERM_CHAR"}, \
{0x58, "H_PUT_TERM_CHAR"}, \
{0x5c, "H_REAL_TO_LOGICAL"}, \
{0x60, "H_HYPERVISOR_DATA"}, \
{0x64, "H_EOI"}, \
{0x68, "H_CPPR"}, \
{0x6c, "H_IPI"}, \
{0x70, "H_IPOLL"}, \
{0x74, "H_XIRR"}, \
{0x78, "H_MIGRATE_DMA"}, \
{0x7c, "H_PERFMON"}, \
{0xdc, "H_REGISTER_VPA"}, \
{0xe0, "H_CEDE"}, \
{0xe4, "H_CONFER"}, \
{0xe8, "H_PROD"}, \
{0xec, "H_GET_PPP"}, \
{0xf0, "H_SET_PPP"}, \
{0xf4, "H_PURR"}, \
{0xf8, "H_PIC"}, \
{0xfc, "H_REG_CRQ"}, \
{0x100, "H_FREE_CRQ"}, \
{0x104, "H_VIO_SIGNAL"}, \
{0x108, "H_SEND_CRQ"}, \
{0x110, "H_COPY_RDMA"}, \
{0x114, "H_REGISTER_LOGICAL_LAN"}, \
{0x118, "H_FREE_LOGICAL_LAN"}, \
{0x11c, "H_ADD_LOGICAL_LAN_BUFFER"}, \
{0x120, "H_SEND_LOGICAL_LAN"}, \
{0x124, "H_BULK_REMOVE"}, \
{0x130, "H_MULTICAST_CTRL"}, \
{0x134, "H_SET_XDABR"}, \
{0x138, "H_STUFF_TCE"}, \
{0x13c, "H_PUT_TCE_INDIRECT"}, \
{0x14c, "H_CHANGE_LOGICAL_LAN_MAC"}, \
{0x150, "H_VTERM_PARTNER_INFO"}, \
{0x154, "H_REGISTER_VTERM"}, \
{0x158, "H_FREE_VTERM"}, \
{0x15c, "H_RESET_EVENTS"}, \
{0x160, "H_ALLOC_RESOURCE"}, \
{0x164, "H_FREE_RESOURCE"}, \
{0x168, "H_MODIFY_QP"}, \
{0x16c, "H_QUERY_QP"}, \
{0x170, "H_REREGISTER_PMR"}, \
{0x174, "H_REGISTER_SMR"}, \
{0x178, "H_QUERY_MR"}, \
{0x17c, "H_QUERY_MW"}, \
{0x180, "H_QUERY_HCA"}, \
{0x184, "H_QUERY_PORT"}, \
{0x188, "H_MODIFY_PORT"}, \
{0x18c, "H_DEFINE_AQP1"}, \
{0x190, "H_GET_TRACE_BUFFER"}, \
{0x194, "H_DEFINE_AQP0"}, \
{0x198, "H_RESIZE_MR"}, \
{0x19c, "H_ATTACH_MCQP"}, \
{0x1a0, "H_DETACH_MCQP"}, \
{0x1a4, "H_CREATE_RPT"}, \
{0x1a8, "H_REMOVE_RPT"}, \
{0x1ac, "H_REGISTER_RPAGES"}, \
{0x1b0, "H_DISABLE_AND_GETC"}, \
{0x1b4, "H_ERROR_DATA"}, \
{0x1b8, "H_GET_HCA_INFO"}, \
{0x1bc, "H_GET_PERF_COUNT"}, \
{0x1c0, "H_MANAGE_TRACE"}, \
{0x1d4, "H_FREE_LOGICAL_LAN_BUFFER"}, \
{0x1d8, "H_POLL_PENDING"}, \
{0x1e4, "H_QUERY_INT_STATE"}, \
{0x244, "H_ILLAN_ATTRIBUTES"}, \
{0x250, "H_MODIFY_HEA_QP"}, \
{0x254, "H_QUERY_HEA_QP"}, \
{0x258, "H_QUERY_HEA"}, \
{0x25c, "H_QUERY_HEA_PORT"}, \
{0x260, "H_MODIFY_HEA_PORT"}, \
{0x264, "H_REG_BCMC"}, \
{0x268, "H_DEREG_BCMC"}, \
{0x26c, "H_REGISTER_HEA_RPAGES"}, \
{0x270, "H_DISABLE_AND_GET_HEA"}, \
{0x274, "H_GET_HEA_INFO"}, \
{0x278, "H_ALLOC_HEA_RESOURCE"}, \
{0x284, "H_ADD_CONN"}, \
{0x288, "H_DEL_CONN"}, \
{0x298, "H_JOIN"}, \
{0x2a4, "H_VASI_STATE"}, \
{0x2b0, "H_ENABLE_CRQ"}, \
{0x2b8, "H_GET_EM_PARMS"}, \
{0x2d0, "H_SET_MPP"}, \
{0x2d4, "H_GET_MPP"}, \
{0x2ec, "H_HOME_NODE_ASSOCIATIVITY"}, \
{0x2f4, "H_BEST_ENERGY"}, \
{0x2fc, "H_XIRR_X"}, \
{0x300, "H_RANDOM"}, \
{0x304, "H_COP"}, \
{0x314, "H_GET_MPP_X"}, \
{0x31c, "H_SET_MODE"}, \
{0xf000, "H_RTAS"} \
#endif

Some files were not shown because too many files have changed in this diff Show More