Skip to content

Commit f76a842

Browse files
Kan LiangPeter Zijlstra
authored andcommitted
perf/x86/uncore: Apply the unit control RB tree to PCI uncore units
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 <[email protected]> Signed-off-by: Peter Zijlstra (Intel) <[email protected]> Tested-by: Yunying Sun <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent b1d9ea2 commit f76a842

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)