Skip to content

Commit 9aae178

Browse files
kliang2Ingo Molnar
authored andcommitted
perf/x86/intel/uncore: Clean up client IMC uncore
The counters in client IMC uncore are free running counters, not fixed counters. It should be corrected. The new infrastructure for free running counter should be applied. Introducing a new type SNB_PCI_UNCORE_IMC_DATA for client IMC free running counters. Keeping the customized event_init() function to be compatible with old event encoding. Clean up other customized event_*() functions. Signed-off-by: Kan Liang <[email protected]> Signed-off-by: Peter Zijlstra (Intel) <[email protected]> Reviewed-by: Thomas Gleixner <[email protected]> Cc: Linus Torvalds <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: [email protected] Cc: [email protected] Link: http://lkml.kernel.org/r/[email protected] Signed-off-by: Ingo Molnar <[email protected]>
1 parent 5a6c9d9 commit 9aae178

File tree

1 file changed

+20
-112
lines changed

1 file changed

+20
-112
lines changed

arch/x86/events/intel/uncore_snb.c

Lines changed: 20 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,15 @@ static struct uncore_event_desc snb_uncore_imc_events[] = {
285285
#define SNB_UNCORE_PCI_IMC_DATA_WRITES_BASE 0x5054
286286
#define SNB_UNCORE_PCI_IMC_CTR_BASE SNB_UNCORE_PCI_IMC_DATA_READS_BASE
287287

288+
enum perf_snb_uncore_imc_freerunning_types {
289+
SNB_PCI_UNCORE_IMC_DATA = 0,
290+
SNB_PCI_UNCORE_IMC_FREERUNNING_TYPE_MAX,
291+
};
292+
293+
static struct freerunning_counters snb_uncore_imc_freerunning[] = {
294+
[SNB_PCI_UNCORE_IMC_DATA] = { SNB_UNCORE_PCI_IMC_DATA_READS_BASE, 0x4, 0x0, 2, 32 },
295+
};
296+
288297
static struct attribute *snb_uncore_imc_formats_attr[] = {
289298
&format_attr_event.attr,
290299
NULL,
@@ -341,9 +350,8 @@ static u64 snb_uncore_imc_read_counter(struct intel_uncore_box *box, struct perf
341350
}
342351

343352
/*
344-
* custom event_init() function because we define our own fixed, free
345-
* running counters, so we do not want to conflict with generic uncore
346-
* logic. Also simplifies processing
353+
* Keep the custom event_init() function compatible with old event
354+
* encoding for free running counters.
347355
*/
348356
static int snb_uncore_imc_event_init(struct perf_event *event)
349357
{
@@ -405,11 +413,11 @@ static int snb_uncore_imc_event_init(struct perf_event *event)
405413
switch (cfg) {
406414
case SNB_UNCORE_PCI_IMC_DATA_READS:
407415
base = SNB_UNCORE_PCI_IMC_DATA_READS_BASE;
408-
idx = UNCORE_PMC_IDX_FIXED;
416+
idx = UNCORE_PMC_IDX_FREERUNNING;
409417
break;
410418
case SNB_UNCORE_PCI_IMC_DATA_WRITES:
411419
base = SNB_UNCORE_PCI_IMC_DATA_WRITES_BASE;
412-
idx = UNCORE_PMC_IDX_FIXED + 1;
420+
idx = UNCORE_PMC_IDX_FREERUNNING;
413421
break;
414422
default:
415423
return -EINVAL;
@@ -430,104 +438,6 @@ static int snb_uncore_imc_hw_config(struct intel_uncore_box *box, struct perf_ev
430438
return 0;
431439
}
432440

433-
static void snb_uncore_imc_event_start(struct perf_event *event, int flags)
434-
{
435-
struct intel_uncore_box *box = uncore_event_to_box(event);
436-
u64 count;
437-
438-
if (WARN_ON_ONCE(!(event->hw.state & PERF_HES_STOPPED)))
439-
return;
440-
441-
event->hw.state = 0;
442-
box->n_active++;
443-
444-
list_add_tail(&event->active_entry, &box->active_list);
445-
446-
count = snb_uncore_imc_read_counter(box, event);
447-
local64_set(&event->hw.prev_count, count);
448-
449-
if (box->n_active == 1)
450-
uncore_pmu_start_hrtimer(box);
451-
}
452-
453-
static void snb_uncore_imc_event_read(struct perf_event *event)
454-
{
455-
struct intel_uncore_box *box = uncore_event_to_box(event);
456-
u64 prev_count, new_count, delta;
457-
int shift;
458-
459-
/*
460-
* There are two free running counters in IMC.
461-
* The index for the second one is hardcoded to
462-
* UNCORE_PMC_IDX_FIXED + 1.
463-
*/
464-
if (event->hw.idx >= UNCORE_PMC_IDX_FIXED)
465-
shift = 64 - uncore_fixed_ctr_bits(box);
466-
else
467-
shift = 64 - uncore_perf_ctr_bits(box);
468-
469-
/* the hrtimer might modify the previous event value */
470-
again:
471-
prev_count = local64_read(&event->hw.prev_count);
472-
new_count = uncore_read_counter(box, event);
473-
if (local64_xchg(&event->hw.prev_count, new_count) != prev_count)
474-
goto again;
475-
476-
delta = (new_count << shift) - (prev_count << shift);
477-
delta >>= shift;
478-
479-
local64_add(delta, &event->count);
480-
}
481-
482-
static void snb_uncore_imc_event_stop(struct perf_event *event, int flags)
483-
{
484-
struct intel_uncore_box *box = uncore_event_to_box(event);
485-
struct hw_perf_event *hwc = &event->hw;
486-
487-
if (!(hwc->state & PERF_HES_STOPPED)) {
488-
box->n_active--;
489-
490-
WARN_ON_ONCE(hwc->state & PERF_HES_STOPPED);
491-
hwc->state |= PERF_HES_STOPPED;
492-
493-
list_del(&event->active_entry);
494-
495-
if (box->n_active == 0)
496-
uncore_pmu_cancel_hrtimer(box);
497-
}
498-
499-
if ((flags & PERF_EF_UPDATE) && !(hwc->state & PERF_HES_UPTODATE)) {
500-
/*
501-
* Drain the remaining delta count out of a event
502-
* that we are disabling:
503-
*/
504-
snb_uncore_imc_event_read(event);
505-
hwc->state |= PERF_HES_UPTODATE;
506-
}
507-
}
508-
509-
static int snb_uncore_imc_event_add(struct perf_event *event, int flags)
510-
{
511-
struct intel_uncore_box *box = uncore_event_to_box(event);
512-
struct hw_perf_event *hwc = &event->hw;
513-
514-
if (!box)
515-
return -ENODEV;
516-
517-
hwc->state = PERF_HES_UPTODATE | PERF_HES_STOPPED;
518-
if (!(flags & PERF_EF_START))
519-
hwc->state |= PERF_HES_ARCH;
520-
521-
snb_uncore_imc_event_start(event, 0);
522-
523-
return 0;
524-
}
525-
526-
static void snb_uncore_imc_event_del(struct perf_event *event, int flags)
527-
{
528-
snb_uncore_imc_event_stop(event, PERF_EF_UPDATE);
529-
}
530-
531441
int snb_pci2phy_map_init(int devid)
532442
{
533443
struct pci_dev *dev = NULL;
@@ -559,11 +469,11 @@ int snb_pci2phy_map_init(int devid)
559469
static struct pmu snb_uncore_imc_pmu = {
560470
.task_ctx_nr = perf_invalid_context,
561471
.event_init = snb_uncore_imc_event_init,
562-
.add = snb_uncore_imc_event_add,
563-
.del = snb_uncore_imc_event_del,
564-
.start = snb_uncore_imc_event_start,
565-
.stop = snb_uncore_imc_event_stop,
566-
.read = snb_uncore_imc_event_read,
472+
.add = uncore_pmu_event_add,
473+
.del = uncore_pmu_event_del,
474+
.start = uncore_pmu_event_start,
475+
.stop = uncore_pmu_event_stop,
476+
.read = uncore_pmu_event_read,
567477
};
568478

569479
static struct intel_uncore_ops snb_uncore_imc_ops = {
@@ -581,12 +491,10 @@ static struct intel_uncore_type snb_uncore_imc = {
581491
.name = "imc",
582492
.num_counters = 2,
583493
.num_boxes = 1,
584-
.fixed_ctr_bits = 32,
585-
.fixed_ctr = SNB_UNCORE_PCI_IMC_CTR_BASE,
494+
.num_freerunning_types = SNB_PCI_UNCORE_IMC_FREERUNNING_TYPE_MAX,
495+
.freerunning = snb_uncore_imc_freerunning,
586496
.event_descs = snb_uncore_imc_events,
587497
.format_group = &snb_uncore_imc_format_group,
588-
.perf_ctr = SNB_UNCORE_PCI_IMC_DATA_READS_BASE,
589-
.event_mask = SNB_UNCORE_PCI_IMC_EVENT_MASK,
590498
.ops = &snb_uncore_imc_ops,
591499
.pmu = &snb_uncore_imc_pmu,
592500
};

0 commit comments

Comments
 (0)