Skip to content

Commit 9110089

Browse files
committed
perf/x86/uncore: Apply the unit control RB tree to PCI uncore units
jira LE-2177 Rebuild_History Non-Buildable kernel-5.14.0-503.19.1.el9_5 commit-author Kan Liang <kan.liang@linux.intel.com> commit f76a842 The unit control RB tree has the unit control and unit ID information for all the PCI units. Use them to replace the box_ctls/pci_offsets to get an accurate unit control address for PCI uncore units. The UPI/M3UPI units in the discovery table are ignored. Please see the commit 65248a9 ("perf/x86/uncore: Add a quirk for UPI on SPR"). Manually allocate a unit control RB tree for UPI/M3UPI. Add cleanup_extra_boxes to release such manual allocation. Signed-off-by: Kan Liang <kan.liang@linux.intel.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Tested-by: Yunying Sun <yunying.sun@intel.com> Link: https://lore.kernel.org/r/20240614134631.1092359-7-kan.liang@linux.intel.com (cherry picked from commit f76a842) Signed-off-by: Jonathan Maple <jmaple@ciq.com>
1 parent 60e8c06 commit 9110089

File tree

5 files changed

+94
-48
lines changed

5 files changed

+94
-48
lines changed

arch/x86/events/intel/uncore.c

Lines changed: 25 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -969,6 +969,9 @@ static void uncore_type_exit(struct intel_uncore_type *type)
969969
if (type->cleanup_mapping)
970970
type->cleanup_mapping(type);
971971

972+
if (type->cleanup_extra_boxes)
973+
type->cleanup_extra_boxes(type);
974+
972975
if (pmu) {
973976
for (i = 0; i < type->num_boxes; i++, pmu++) {
974977
uncore_pmu_unregister(pmu);
@@ -1084,22 +1087,19 @@ static struct intel_uncore_pmu *
10841087
uncore_pci_find_dev_pmu_from_types(struct pci_dev *pdev)
10851088
{
10861089
struct intel_uncore_type **types = uncore_pci_uncores;
1090+
struct intel_uncore_discovery_unit *unit;
10871091
struct intel_uncore_type *type;
1088-
u64 box_ctl;
1089-
int i, die;
1092+
struct rb_node *node;
10901093

10911094
for (; *types; types++) {
10921095
type = *types;
1093-
for (die = 0; die < __uncore_max_dies; die++) {
1094-
for (i = 0; i < type->num_boxes; i++) {
1095-
if (!type->box_ctls[die])
1096-
continue;
1097-
box_ctl = type->box_ctls[die] + type->pci_offsets[i];
1098-
if (pdev->devfn == UNCORE_DISCOVERY_PCI_DEVFN(box_ctl) &&
1099-
pdev->bus->number == UNCORE_DISCOVERY_PCI_BUS(box_ctl) &&
1100-
pci_domain_nr(pdev->bus) == UNCORE_DISCOVERY_PCI_DOMAIN(box_ctl))
1101-
return &type->pmus[i];
1102-
}
1096+
1097+
for (node = rb_first(type->boxes); node; node = rb_next(node)) {
1098+
unit = rb_entry(node, struct intel_uncore_discovery_unit, node);
1099+
if (pdev->devfn == UNCORE_DISCOVERY_PCI_DEVFN(unit->addr) &&
1100+
pdev->bus->number == UNCORE_DISCOVERY_PCI_BUS(unit->addr) &&
1101+
pci_domain_nr(pdev->bus) == UNCORE_DISCOVERY_PCI_DOMAIN(unit->addr))
1102+
return &type->pmus[unit->pmu_idx];
11031103
}
11041104
}
11051105

@@ -1375,28 +1375,25 @@ static struct notifier_block uncore_pci_notifier = {
13751375
static void uncore_pci_pmus_register(void)
13761376
{
13771377
struct intel_uncore_type **types = uncore_pci_uncores;
1378+
struct intel_uncore_discovery_unit *unit;
13781379
struct intel_uncore_type *type;
13791380
struct intel_uncore_pmu *pmu;
1381+
struct rb_node *node;
13801382
struct pci_dev *pdev;
1381-
u64 box_ctl;
1382-
int i, die;
13831383

13841384
for (; *types; types++) {
13851385
type = *types;
1386-
for (die = 0; die < __uncore_max_dies; die++) {
1387-
for (i = 0; i < type->num_boxes; i++) {
1388-
if (!type->box_ctls[die])
1389-
continue;
1390-
box_ctl = type->box_ctls[die] + type->pci_offsets[i];
1391-
pdev = pci_get_domain_bus_and_slot(UNCORE_DISCOVERY_PCI_DOMAIN(box_ctl),
1392-
UNCORE_DISCOVERY_PCI_BUS(box_ctl),
1393-
UNCORE_DISCOVERY_PCI_DEVFN(box_ctl));
1394-
if (!pdev)
1395-
continue;
1396-
pmu = &type->pmus[i];
1397-
1398-
uncore_pci_pmu_register(pdev, type, pmu, die);
1399-
}
1386+
1387+
for (node = rb_first(type->boxes); node; node = rb_next(node)) {
1388+
unit = rb_entry(node, struct intel_uncore_discovery_unit, node);
1389+
pdev = pci_get_domain_bus_and_slot(UNCORE_DISCOVERY_PCI_DOMAIN(unit->addr),
1390+
UNCORE_DISCOVERY_PCI_BUS(unit->addr),
1391+
UNCORE_DISCOVERY_PCI_DEVFN(unit->addr));
1392+
1393+
if (!pdev)
1394+
continue;
1395+
pmu = &type->pmus[unit->pmu_idx];
1396+
uncore_pci_pmu_register(pdev, type, pmu, unit->die);
14001397
}
14011398
}
14021399

arch/x86/events/intel/uncore.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,10 @@ struct intel_uncore_type {
9999
int (*get_topology)(struct intel_uncore_type *type);
100100
void (*set_mapping)(struct intel_uncore_type *type);
101101
void (*cleanup_mapping)(struct intel_uncore_type *type);
102+
/*
103+
* Optional callbacks for extra uncore units cleanup
104+
*/
105+
void (*cleanup_extra_boxes)(struct intel_uncore_type *type);
102106
};
103107

104108
#define pmu_group attr_groups[0]

arch/x86/events/intel/uncore_discovery.c

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -215,8 +215,8 @@ uncore_find_unit(struct rb_root *root, unsigned int id)
215215
return NULL;
216216
}
217217

218-
static void uncore_find_add_unit(struct intel_uncore_discovery_unit *node,
219-
struct rb_root *root, u16 *num_units)
218+
void uncore_find_add_unit(struct intel_uncore_discovery_unit *node,
219+
struct rb_root *root, u16 *num_units)
220220
{
221221
struct intel_uncore_discovery_unit *unit = uncore_find_unit(root, node->id);
222222

@@ -560,7 +560,7 @@ bool intel_generic_uncore_assign_hw_event(struct perf_event *event,
560560
if (!box->pmu->type->boxes)
561561
return false;
562562

563-
if (box->pci_dev || box->io_addr) {
563+
if (box->io_addr) {
564564
hwc->config_base = uncore_pci_event_ctl(box, hwc->idx);
565565
hwc->event_base = uncore_pci_perf_ctr(box, hwc->idx);
566566
return true;
@@ -570,16 +570,28 @@ bool intel_generic_uncore_assign_hw_event(struct perf_event *event,
570570
if (!box_ctl)
571571
return false;
572572

573+
if (box->pci_dev) {
574+
box_ctl = UNCORE_DISCOVERY_PCI_BOX_CTRL(box_ctl);
575+
hwc->config_base = box_ctl + uncore_pci_event_ctl(box, hwc->idx);
576+
hwc->event_base = box_ctl + uncore_pci_perf_ctr(box, hwc->idx);
577+
return true;
578+
}
579+
573580
hwc->config_base = box_ctl + box->pmu->type->event_ctl + hwc->idx;
574581
hwc->event_base = box_ctl + box->pmu->type->perf_ctr + hwc->idx;
575582

576583
return true;
577584
}
578585

586+
static inline int intel_pci_uncore_box_ctl(struct intel_uncore_box *box)
587+
{
588+
return UNCORE_DISCOVERY_PCI_BOX_CTRL(intel_generic_uncore_box_ctl(box));
589+
}
590+
579591
void intel_generic_uncore_pci_init_box(struct intel_uncore_box *box)
580592
{
581593
struct pci_dev *pdev = box->pci_dev;
582-
int box_ctl = uncore_pci_box_ctl(box);
594+
int box_ctl = intel_pci_uncore_box_ctl(box);
583595

584596
__set_bit(UNCORE_BOX_FLAG_CTL_OFFS8, &box->flags);
585597
pci_write_config_dword(pdev, box_ctl, GENERIC_PMON_BOX_CTL_INT);
@@ -588,15 +600,15 @@ void intel_generic_uncore_pci_init_box(struct intel_uncore_box *box)
588600
void intel_generic_uncore_pci_disable_box(struct intel_uncore_box *box)
589601
{
590602
struct pci_dev *pdev = box->pci_dev;
591-
int box_ctl = uncore_pci_box_ctl(box);
603+
int box_ctl = intel_pci_uncore_box_ctl(box);
592604

593605
pci_write_config_dword(pdev, box_ctl, GENERIC_PMON_BOX_CTL_FRZ);
594606
}
595607

596608
void intel_generic_uncore_pci_enable_box(struct intel_uncore_box *box)
597609
{
598610
struct pci_dev *pdev = box->pci_dev;
599-
int box_ctl = uncore_pci_box_ctl(box);
611+
int box_ctl = intel_pci_uncore_box_ctl(box);
600612

601613
pci_write_config_dword(pdev, box_ctl, 0);
602614
}
@@ -748,6 +760,8 @@ static bool uncore_update_uncore_type(enum uncore_access_type type_id,
748760
uncore->box_ctl = (unsigned int)UNCORE_DISCOVERY_PCI_BOX_CTRL(type->box_ctrl);
749761
uncore->box_ctls = type->box_ctrl_die;
750762
uncore->pci_offsets = type->box_offset;
763+
uncore->boxes = &type->units;
764+
uncore->num_boxes = type->num_units;
751765
break;
752766
case UNCORE_ACCESS_MMIO:
753767
uncore->ops = &generic_uncore_mmio_ops;

arch/x86/events/intel/uncore_discovery.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,3 +171,5 @@ int intel_uncore_find_discovery_unit_id(struct rb_root *units, int die,
171171
unsigned int pmu_idx);
172172
bool intel_generic_uncore_assign_hw_event(struct perf_event *event,
173173
struct intel_uncore_box *box);
174+
void uncore_find_add_unit(struct intel_uncore_discovery_unit *node,
175+
struct rb_root *root, u16 *num_units);

arch/x86/events/intel/uncore_snbep.c

Lines changed: 43 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6199,6 +6199,24 @@ static u64 spr_upi_pci_offsets[SPR_UNCORE_UPI_NUM_BOXES] = {
61996199
0, 0x8000, 0x10000, 0x18000
62006200
};
62016201

6202+
static void spr_extra_boxes_cleanup(struct intel_uncore_type *type)
6203+
{
6204+
struct intel_uncore_discovery_unit *pos;
6205+
struct rb_node *node;
6206+
6207+
if (!type->boxes)
6208+
return;
6209+
6210+
while (!RB_EMPTY_ROOT(type->boxes)) {
6211+
node = rb_first(type->boxes);
6212+
pos = rb_entry(node, struct intel_uncore_discovery_unit, node);
6213+
rb_erase(node, type->boxes);
6214+
kfree(pos);
6215+
}
6216+
kfree(type->boxes);
6217+
type->boxes = NULL;
6218+
}
6219+
62026220
static struct intel_uncore_type spr_uncore_upi = {
62036221
.event_mask = SNBEP_PMON_RAW_EVENT_MASK,
62046222
.event_mask_ext = SPR_RAW_EVENT_MASK_EXT,
@@ -6213,10 +6231,11 @@ static struct intel_uncore_type spr_uncore_upi = {
62136231
.num_counters = 4,
62146232
.num_boxes = SPR_UNCORE_UPI_NUM_BOXES,
62156233
.perf_ctr_bits = 48,
6216-
.perf_ctr = ICX_UPI_PCI_PMON_CTR0,
6217-
.event_ctl = ICX_UPI_PCI_PMON_CTL0,
6234+
.perf_ctr = ICX_UPI_PCI_PMON_CTR0 - ICX_UPI_PCI_PMON_BOX_CTL,
6235+
.event_ctl = ICX_UPI_PCI_PMON_CTL0 - ICX_UPI_PCI_PMON_BOX_CTL,
62186236
.box_ctl = ICX_UPI_PCI_PMON_BOX_CTL,
62196237
.pci_offsets = spr_upi_pci_offsets,
6238+
.cleanup_extra_boxes = spr_extra_boxes_cleanup,
62206239
};
62216240

62226241
static struct intel_uncore_type spr_uncore_m3upi = {
@@ -6226,11 +6245,12 @@ static struct intel_uncore_type spr_uncore_m3upi = {
62266245
.num_counters = 4,
62276246
.num_boxes = SPR_UNCORE_UPI_NUM_BOXES,
62286247
.perf_ctr_bits = 48,
6229-
.perf_ctr = ICX_M3UPI_PCI_PMON_CTR0,
6230-
.event_ctl = ICX_M3UPI_PCI_PMON_CTL0,
6248+
.perf_ctr = ICX_M3UPI_PCI_PMON_CTR0 - ICX_M3UPI_PCI_PMON_BOX_CTL,
6249+
.event_ctl = ICX_M3UPI_PCI_PMON_CTL0 - ICX_M3UPI_PCI_PMON_BOX_CTL,
62316250
.box_ctl = ICX_M3UPI_PCI_PMON_BOX_CTL,
62326251
.pci_offsets = spr_upi_pci_offsets,
62336252
.constraints = icx_uncore_m3upi_constraints,
6253+
.cleanup_extra_boxes = spr_extra_boxes_cleanup,
62346254
};
62356255

62366256
enum perf_uncore_spr_iio_freerunning_type_id {
@@ -6517,10 +6537,11 @@ void spr_uncore_cpu_init(void)
65176537

65186538
static void spr_update_device_location(int type_id)
65196539
{
6540+
struct intel_uncore_discovery_unit *unit;
65206541
struct intel_uncore_type *type;
65216542
struct pci_dev *dev = NULL;
6543+
struct rb_root *root;
65226544
u32 device, devfn;
6523-
u64 *ctls;
65246545
int die;
65256546

65266547
if (type_id == UNCORE_SPR_UPI) {
@@ -6534,27 +6555,35 @@ static void spr_update_device_location(int type_id)
65346555
} else
65356556
return;
65366557

6537-
ctls = kcalloc(__uncore_max_dies, sizeof(u64), GFP_KERNEL);
6538-
if (!ctls) {
6558+
root = kzalloc(sizeof(struct rb_root), GFP_KERNEL);
6559+
if (!root) {
65396560
type->num_boxes = 0;
65406561
return;
65416562
}
6563+
*root = RB_ROOT;
65426564

65436565
while ((dev = pci_get_device(PCI_VENDOR_ID_INTEL, device, dev)) != NULL) {
6544-
if (devfn != dev->devfn)
6545-
continue;
65466566

65476567
die = uncore_device_to_die(dev);
65486568
if (die < 0)
65496569
continue;
65506570

6551-
ctls[die] = pci_domain_nr(dev->bus) << UNCORE_DISCOVERY_PCI_DOMAIN_OFFSET |
6552-
dev->bus->number << UNCORE_DISCOVERY_PCI_BUS_OFFSET |
6553-
devfn << UNCORE_DISCOVERY_PCI_DEVFN_OFFSET |
6554-
type->box_ctl;
6571+
unit = kzalloc(sizeof(*unit), GFP_KERNEL);
6572+
if (!unit)
6573+
continue;
6574+
unit->die = die;
6575+
unit->id = PCI_SLOT(dev->devfn) - PCI_SLOT(devfn);
6576+
unit->addr = pci_domain_nr(dev->bus) << UNCORE_DISCOVERY_PCI_DOMAIN_OFFSET |
6577+
dev->bus->number << UNCORE_DISCOVERY_PCI_BUS_OFFSET |
6578+
devfn << UNCORE_DISCOVERY_PCI_DEVFN_OFFSET |
6579+
type->box_ctl;
6580+
6581+
unit->pmu_idx = unit->id;
6582+
6583+
uncore_find_add_unit(unit, root, NULL);
65556584
}
65566585

6557-
type->box_ctls = ctls;
6586+
type->boxes = root;
65586587
}
65596588

65606589
int spr_uncore_pci_init(void)

0 commit comments

Comments
 (0)