Skip to content

Commit b1d9ea2

Browse files
Kan LiangPeter Zijlstra
authored andcommitted
perf/x86/uncore: Apply the unit control RB tree to MSR uncore units
The unit control RB tree has the unit control and unit ID information for all the MSR units. Use them to replace the box_ctl and uncore_msr_box_ctl() to get an accurate unit control address for MSR uncore units. Add intel_generic_uncore_assign_hw_event(), which utilizes the accurate unit control address from the unit control RB tree to calculate the config_base and event_base. The unit id related information should be retrieved from the unit control RB tree as well. 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 80580da commit b1d9ea2

File tree

4 files changed

+59
-11
lines changed

4 files changed

+59
-11
lines changed

arch/x86/events/intel/uncore.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,9 @@ static void uncore_assign_hw_event(struct intel_uncore_box *box,
263263
return;
264264
}
265265

266+
if (intel_generic_uncore_assign_hw_event(event, box))
267+
return;
268+
266269
hwc->config_base = uncore_event_ctl(box, hwc->idx);
267270
hwc->event_base = uncore_perf_ctr(box, hwc->idx);
268271
}

arch/x86/events/intel/uncore_discovery.c

Lines changed: 44 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -499,19 +499,31 @@ static const struct attribute_group generic_uncore_format_group = {
499499
.attrs = generic_uncore_formats_attr,
500500
};
501501

502+
static u64 intel_generic_uncore_box_ctl(struct intel_uncore_box *box)
503+
{
504+
struct intel_uncore_discovery_unit *unit;
505+
506+
unit = intel_uncore_find_discovery_unit(box->pmu->type->boxes,
507+
-1, box->pmu->pmu_idx);
508+
if (WARN_ON_ONCE(!unit))
509+
return 0;
510+
511+
return unit->addr;
512+
}
513+
502514
void intel_generic_uncore_msr_init_box(struct intel_uncore_box *box)
503515
{
504-
wrmsrl(uncore_msr_box_ctl(box), GENERIC_PMON_BOX_CTL_INT);
516+
wrmsrl(intel_generic_uncore_box_ctl(box), GENERIC_PMON_BOX_CTL_INT);
505517
}
506518

507519
void intel_generic_uncore_msr_disable_box(struct intel_uncore_box *box)
508520
{
509-
wrmsrl(uncore_msr_box_ctl(box), GENERIC_PMON_BOX_CTL_FRZ);
521+
wrmsrl(intel_generic_uncore_box_ctl(box), GENERIC_PMON_BOX_CTL_FRZ);
510522
}
511523

512524
void intel_generic_uncore_msr_enable_box(struct intel_uncore_box *box)
513525
{
514-
wrmsrl(uncore_msr_box_ctl(box), 0);
526+
wrmsrl(intel_generic_uncore_box_ctl(box), 0);
515527
}
516528

517529
static void intel_generic_uncore_msr_enable_event(struct intel_uncore_box *box,
@@ -539,6 +551,31 @@ static struct intel_uncore_ops generic_uncore_msr_ops = {
539551
.read_counter = uncore_msr_read_counter,
540552
};
541553

554+
bool intel_generic_uncore_assign_hw_event(struct perf_event *event,
555+
struct intel_uncore_box *box)
556+
{
557+
struct hw_perf_event *hwc = &event->hw;
558+
u64 box_ctl;
559+
560+
if (!box->pmu->type->boxes)
561+
return false;
562+
563+
if (box->pci_dev || box->io_addr) {
564+
hwc->config_base = uncore_pci_event_ctl(box, hwc->idx);
565+
hwc->event_base = uncore_pci_perf_ctr(box, hwc->idx);
566+
return true;
567+
}
568+
569+
box_ctl = intel_generic_uncore_box_ctl(box);
570+
if (!box_ctl)
571+
return false;
572+
573+
hwc->config_base = box_ctl + box->pmu->type->event_ctl + hwc->idx;
574+
hwc->event_base = box_ctl + box->pmu->type->perf_ctr + hwc->idx;
575+
576+
return true;
577+
}
578+
542579
void intel_generic_uncore_pci_init_box(struct intel_uncore_box *box)
543580
{
544581
struct pci_dev *pdev = box->pci_dev;
@@ -697,10 +734,12 @@ static bool uncore_update_uncore_type(enum uncore_access_type type_id,
697734
switch (type_id) {
698735
case UNCORE_ACCESS_MSR:
699736
uncore->ops = &generic_uncore_msr_ops;
700-
uncore->perf_ctr = (unsigned int)type->box_ctrl + type->ctr_offset;
701-
uncore->event_ctl = (unsigned int)type->box_ctrl + type->ctl_offset;
737+
uncore->perf_ctr = (unsigned int)type->ctr_offset;
738+
uncore->event_ctl = (unsigned int)type->ctl_offset;
702739
uncore->box_ctl = (unsigned int)type->box_ctrl;
703740
uncore->msr_offsets = type->box_offset;
741+
uncore->boxes = &type->units;
742+
uncore->num_boxes = type->num_units;
704743
break;
705744
case UNCORE_ACCESS_PCI:
706745
uncore->ops = &generic_uncore_pci_ops;

arch/x86/events/intel/uncore_discovery.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,3 +169,5 @@ intel_uncore_generic_init_uncores(enum uncore_access_type type_id, int num_extra
169169

170170
int intel_uncore_find_discovery_unit_id(struct rb_root *units, int die,
171171
unsigned int pmu_idx);
172+
bool intel_generic_uncore_assign_hw_event(struct perf_event *event,
173+
struct intel_uncore_box *box);

arch/x86/events/intel/uncore_snbep.c

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5933,10 +5933,11 @@ static int spr_cha_hw_config(struct intel_uncore_box *box, struct perf_event *ev
59335933
struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
59345934
bool tie_en = !!(event->hw.config & SPR_CHA_PMON_CTL_TID_EN);
59355935
struct intel_uncore_type *type = box->pmu->type;
5936+
int id = intel_uncore_find_discovery_unit_id(type->boxes, -1, box->pmu->pmu_idx);
59365937

59375938
if (tie_en) {
59385939
reg1->reg = SPR_C0_MSR_PMON_BOX_FILTER0 +
5939-
HSWEP_CBO_MSR_OFFSET * type->box_ids[box->pmu->pmu_idx];
5940+
HSWEP_CBO_MSR_OFFSET * id;
59405941
reg1->config = event->attr.config1 & SPR_CHA_PMON_BOX_FILTER_TID;
59415942
reg1->idx = 0;
59425943
}
@@ -6460,18 +6461,21 @@ uncore_find_type_by_id(struct intel_uncore_type **types, int type_id)
64606461
static int uncore_type_max_boxes(struct intel_uncore_type **types,
64616462
int type_id)
64626463
{
6464+
struct intel_uncore_discovery_unit *unit;
64636465
struct intel_uncore_type *type;
6464-
int i, max = 0;
6466+
struct rb_node *node;
6467+
int max = 0;
64656468

64666469
type = uncore_find_type_by_id(types, type_id);
64676470
if (!type)
64686471
return 0;
64696472

6470-
for (i = 0; i < type->num_boxes; i++) {
6471-
if (type->box_ids[i] > max)
6472-
max = type->box_ids[i];
6473-
}
6473+
for (node = rb_first(type->boxes); node; node = rb_next(node)) {
6474+
unit = rb_entry(node, struct intel_uncore_discovery_unit, node);
64746475

6476+
if (unit->id > max)
6477+
max = unit->id;
6478+
}
64756479
return max + 1;
64766480
}
64776481

0 commit comments

Comments
 (0)