Commit cf6d445f authored by Thomas Gleixner's avatar Thomas Gleixner Committed by Ingo Molnar

perf/x86/uncore: Track packages, not per CPU data

Uncore is a per package facility, but the code tries to mimick a per CPU
facility with completely convoluted constructs.

Simplify the whole machinery by tracking per package information. While at it,
avoid the kfree/alloc dance when a CPU goes offline and online again. There is
no point in freeing the box after it was allocated. We just keep proper
refcounting and the first CPU which comes online in a package does the
initialization/activation of the box.
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
Signed-off-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
Cc: Andi Kleen <andi.kleen@intel.com>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Harish Chegondi <harish.chegondi@intel.com>
Cc: Jacob Pan <jacob.jun.pan@linux.intel.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Kan Liang <kan.liang@intel.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Vince Weaver <vincent.weaver@maine.edu>
Cc: linux-kernel@vger.kernel.org
Link: http://lkml.kernel.org/r/20160222221011.622258933@linutronix.deSigned-off-by: default avatarIngo Molnar <mingo@kernel.org>
parent 1f12e32f
This diff is collapsed.
...@@ -19,11 +19,12 @@ ...@@ -19,11 +19,12 @@
#define UNCORE_EXTRA_PCI_DEV 0xff #define UNCORE_EXTRA_PCI_DEV 0xff
#define UNCORE_EXTRA_PCI_DEV_MAX 3 #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) #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_ops;
struct intel_uncore_pmu; struct intel_uncore_pmu;
struct intel_uncore_box; struct intel_uncore_box;
...@@ -79,9 +80,9 @@ struct intel_uncore_pmu { ...@@ -79,9 +80,9 @@ struct intel_uncore_pmu {
int pmu_idx; int pmu_idx;
int func_id; int func_id;
bool registered; bool registered;
atomic_t activeboxes;
struct intel_uncore_type *type; struct intel_uncore_type *type;
struct intel_uncore_box ** __percpu box; struct intel_uncore_box **boxes;
struct list_head box_list;
}; };
struct intel_uncore_extra_reg { struct intel_uncore_extra_reg {
...@@ -91,7 +92,8 @@ struct intel_uncore_extra_reg { ...@@ -91,7 +92,8 @@ struct intel_uncore_extra_reg {
}; };
struct intel_uncore_box { struct intel_uncore_box {
int phys_id; int pci_phys_id;
int pkgid;
int n_active; /* number of active events */ int n_active; /* number of active events */
int n_events; int n_events;
int cpu; /* cpu to collect events */ int cpu; /* cpu to collect events */
...@@ -316,7 +318,7 @@ static inline void uncore_box_exit(struct intel_uncore_box *box) ...@@ -316,7 +318,7 @@ static inline void uncore_box_exit(struct intel_uncore_box *box)
static inline bool uncore_box_is_fake(struct intel_uncore_box *box) static inline bool uncore_box_is_fake(struct intel_uncore_box *box)
{ {
return (box->phys_id < 0); return (box->pkgid < 0);
} }
static inline struct intel_uncore_pmu *uncore_event_to_pmu(struct perf_event *event) static inline struct intel_uncore_pmu *uncore_event_to_pmu(struct perf_event *event)
...@@ -345,7 +347,7 @@ extern struct intel_uncore_type **uncore_pci_uncores; ...@@ -345,7 +347,7 @@ extern struct intel_uncore_type **uncore_pci_uncores;
extern struct pci_driver *uncore_pci_driver; extern struct pci_driver *uncore_pci_driver;
extern raw_spinlock_t pci2phy_map_lock; extern raw_spinlock_t pci2phy_map_lock;
extern struct list_head pci2phy_map_head; 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; extern struct event_constraint uncore_constraint_empty;
/* perf_event_intel_uncore_snb.c */ /* perf_event_intel_uncore_snb.c */
......
...@@ -986,7 +986,9 @@ static void snbep_qpi_enable_event(struct intel_uncore_box *box, struct perf_eve ...@@ -986,7 +986,9 @@ static void snbep_qpi_enable_event(struct intel_uncore_box *box, struct perf_eve
if (reg1->idx != EXTRA_REG_NONE) { if (reg1->idx != EXTRA_REG_NONE) {
int idx = box->pmu->pmu_idx + SNBEP_PCI_QPI_PORT0_FILTER; 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) { if (filter_pdev) {
pci_write_config_dword(filter_pdev, reg1->reg, pci_write_config_dword(filter_pdev, reg1->reg,
(u32)reg1->config); (u32)reg1->config);
...@@ -2520,14 +2522,16 @@ static struct intel_uncore_type *hswep_msr_uncores[] = { ...@@ -2520,14 +2522,16 @@ static struct intel_uncore_type *hswep_msr_uncores[] = {
void hswep_uncore_cpu_init(void) 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) if (hswep_uncore_cbox.num_boxes > boot_cpu_data.x86_max_cores)
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 */ /* 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; 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); 0x94, &capid4);
if (((capid4 >> 6) & 0x3) == 0) if (((capid4 >> 6) & 0x3) == 0)
hswep_uncore_sbox.num_boxes = 2; hswep_uncore_sbox.num_boxes = 2;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment