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:
commit
e71c2c1eeb
|
@ -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:
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
|
||||
obj-y += entry/
|
||||
|
||||
obj-$(CONFIG_PERF_EVENTS) += events/
|
||||
|
||||
obj-$(CONFIG_KVM) += kvm/
|
||||
|
||||
# Xen paravirtualization support
|
||||
|
|
|
@ -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
|
|
@ -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]
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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);
|
|
@ -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;
|
|
@ -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;
|
|
@ -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,
|
|
@ -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, \
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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,
|
|
@ -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
|
||||
/*
|
|
@ -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
|
|
@ -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);
|
||||
|
|
@ -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);
|
File diff suppressed because it is too large
Load Diff
|
@ -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 */
|
|
@ -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, \
|
|
@ -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,
|
|
@ -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 = {
|
|
@ -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);
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 ||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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, <ype);
|
||||
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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -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++) {
|
||||
|
|
|
@ -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;
|
||||
/*
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
#include <stdio.h>
|
||||
int main(void)
|
||||
{
|
||||
printf("Hello World!\n");
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -1,3 +1,4 @@
|
|||
libapi-y += fd/
|
||||
libapi-y += fs/
|
||||
libapi-y += cpu.o
|
||||
libapi-y += debug.o
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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__ */
|
|
@ -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;
|
||||
}
|
|
@ -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__ */
|
|
@ -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];
|
||||
|
|
|
@ -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__ */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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
|
||||
--------------------------
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
medium = green, lightgray
|
||||
normal = black, lightgray
|
||||
selected = lightgray, magenta
|
||||
code = blue, lightgray
|
||||
jump_arrows = blue, lightgray
|
||||
addr = magenta, lightgray
|
||||
|
||||
[tui]
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
ifndef NO_DWARF
|
||||
PERF_HAVE_DWARF_REGS := 1
|
||||
endif
|
||||
PERF_HAVE_JITDUMP := 1
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
ifndef NO_DWARF
|
||||
PERF_HAVE_DWARF_REGS := 1
|
||||
endif
|
||||
PERF_HAVE_JITDUMP := 1
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
ifndef NO_DWARF
|
||||
PERF_HAVE_DWARF_REGS := 1
|
||||
endif
|
||||
|
||||
HAVE_KVM_STAT_SUPPORT := 1
|
||||
PERF_HAVE_JITDUMP := 1
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
Loading…
Reference in New Issue