* [PATCH 1/2] perf/x86/intel/uncore: correct num_boxes for IIO and IRP @ 2017-09-11 17:10 kan.liang 2017-09-11 17:10 ` [PATCH 2/2] perf/x86/intel/uncore: support IIO freerunning counter for SKX kan.liang 2017-09-25 10:48 ` [tip:x86/urgent] perf/x86/intel/uncore: Correct num_boxes for IIO and IRP tip-bot for Kan Liang 0 siblings, 2 replies; 5+ messages in thread From: kan.liang @ 2017-09-11 17:10 UTC (permalink / raw) To: peterz, tglx, mingo, linux-kernel; +Cc: acme, eranian, ak, Kan Liang From: Kan Liang <Kan.liang@intel.com> There are 6 IIO/IRP boxes for CBDMA, PCIe0-2, MCP 0 and MCP 1 separately. Correct the num_boxes. Signed-off-by: Kan Liang <Kan.liang@intel.com> --- arch/x86/events/intel/uncore_snbep.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/x86/events/intel/uncore_snbep.c b/arch/x86/events/intel/uncore_snbep.c index db1fe37..a719681 100644 --- a/arch/x86/events/intel/uncore_snbep.c +++ b/arch/x86/events/intel/uncore_snbep.c @@ -3462,7 +3462,7 @@ static struct intel_uncore_ops skx_uncore_iio_ops = { static struct intel_uncore_type skx_uncore_iio = { .name = "iio", .num_counters = 4, - .num_boxes = 5, + .num_boxes = 6, .perf_ctr_bits = 48, .event_ctl = SKX_IIO0_MSR_PMON_CTL0, .perf_ctr = SKX_IIO0_MSR_PMON_CTR0, @@ -3492,7 +3492,7 @@ static const struct attribute_group skx_uncore_format_group = { static struct intel_uncore_type skx_uncore_irp = { .name = "irp", .num_counters = 2, - .num_boxes = 5, + .num_boxes = 6, .perf_ctr_bits = 48, .event_ctl = SKX_IRP0_MSR_PMON_CTL0, .perf_ctr = SKX_IRP0_MSR_PMON_CTR0, -- 2.7.4 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 2/2] perf/x86/intel/uncore: support IIO freerunning counter for SKX 2017-09-11 17:10 [PATCH 1/2] perf/x86/intel/uncore: correct num_boxes for IIO and IRP kan.liang @ 2017-09-11 17:10 ` kan.liang 2017-10-17 1:20 ` Liang, Kan 2017-10-18 15:29 ` Thomas Gleixner 2017-09-25 10:48 ` [tip:x86/urgent] perf/x86/intel/uncore: Correct num_boxes for IIO and IRP tip-bot for Kan Liang 1 sibling, 2 replies; 5+ messages in thread From: kan.liang @ 2017-09-11 17:10 UTC (permalink / raw) To: peterz, tglx, mingo, linux-kernel; +Cc: acme, eranian, ak, Kan Liang From: Kan Liang <Kan.liang@intel.com> As of Skylake Server, there are a number of free-running counters in each IIO Box that collect counts for per box IO clocks and per Port Input/Output x BW/Utilization. The event code of free running event is shared with fixed event, which is 0xff. The umask of free running event starts from 0x10. The umask less than 0x10 is reserved for fixed event. The Free running counters could have different MSR location and offset. Accordingly, they are divided into different types. Each type is limited to only have at most 16 events. So the umask of the first free running events type starts from 0x10. The umask of the second starts from 0x20. The rest can be done in the same manner. Freerunning counters cannot be written by SW. Counting will be suspended only when the IIO Box is powered down. They are specially handled in uncore_pmu_event_add/del/start/stop and not added in box->events list. The bit width of freerunning counter is 36-bit. Signed-off-by: Kan Liang <Kan.liang@intel.com> --- arch/x86/events/intel/uncore.c | 33 +++++++++++++++++- arch/x86/events/intel/uncore.h | 67 +++++++++++++++++++++++++++++++++++- arch/x86/events/intel/uncore_snbep.c | 58 +++++++++++++++++++++++++++++++ 3 files changed, 156 insertions(+), 2 deletions(-) diff --git a/arch/x86/events/intel/uncore.c b/arch/x86/events/intel/uncore.c index 1c5390f..8d3e46c 100644 --- a/arch/x86/events/intel/uncore.c +++ b/arch/x86/events/intel/uncore.c @@ -218,7 +218,9 @@ void uncore_perf_event_update(struct intel_uncore_box *box, struct perf_event *e u64 prev_count, new_count, delta; int shift; - if (event->hw.idx >= UNCORE_PMC_IDX_FIXED) + if (event->hw.idx >= UNCORE_PMC_IDX_FREERUNNING) + shift = 64 - uncore_free_running_bits(box, event); + else if (event->hw.idx == UNCORE_PMC_IDX_FIXED) shift = 64 - uncore_fixed_ctr_bits(box); else shift = 64 - uncore_perf_ctr_bits(box); @@ -362,6 +364,9 @@ uncore_collect_events(struct intel_uncore_box *box, struct perf_event *leader, if (n >= max_count) return -EINVAL; + if (event->hw.idx == UNCORE_PMC_IDX_FREERUNNING) + continue; + box->event_list[n] = event; n++; } @@ -454,6 +459,12 @@ static void uncore_pmu_event_start(struct perf_event *event, int flags) struct intel_uncore_box *box = uncore_event_to_box(event); int idx = event->hw.idx; + if (event->hw.idx == UNCORE_PMC_IDX_FREERUNNING) { + local64_set(&event->hw.prev_count, + uncore_read_counter(box, event)); + return; + } + if (WARN_ON_ONCE(!(event->hw.state & PERF_HES_STOPPED))) return; @@ -479,6 +490,11 @@ static void uncore_pmu_event_stop(struct perf_event *event, int flags) struct intel_uncore_box *box = uncore_event_to_box(event); struct hw_perf_event *hwc = &event->hw; + if (hwc->idx == UNCORE_PMC_IDX_FREERUNNING) { + uncore_perf_event_update(box, event); + return; + } + if (__test_and_clear_bit(hwc->idx, box->active_mask)) { uncore_disable_event(box, event); box->n_active--; @@ -512,6 +528,13 @@ static int uncore_pmu_event_add(struct perf_event *event, int flags) if (!box) return -ENODEV; + if (hwc->idx == UNCORE_PMC_IDX_FREERUNNING) { + event->hw.event_base = uncore_free_running_msr(box, event); + if (flags & PERF_EF_START) + uncore_pmu_event_start(event, 0); + return 0; + } + ret = n = uncore_collect_events(box, event, false); if (ret < 0) return ret; @@ -570,6 +593,9 @@ static void uncore_pmu_event_del(struct perf_event *event, int flags) uncore_pmu_event_stop(event, PERF_EF_UPDATE); + if (event->hw.idx == UNCORE_PMC_IDX_FREERUNNING) + return; + for (i = 0; i < box->n_events; i++) { if (event == box->event_list[i]) { uncore_put_event_constraint(box, event); @@ -690,6 +716,11 @@ static int uncore_pmu_event_init(struct perf_event *event) /* fixed counters have event field hardcoded to zero */ hwc->config = 0ULL; + } else if (is_free_running_event(event)) { + if (UNCORE_FREE_RUNNING_MSR_IDX(event->attr.config) > + uncore_num_free_running(box, event)) + return -EINVAL; + event->hw.idx = UNCORE_PMC_IDX_FREERUNNING; } else { hwc->config = event->attr.config & (pmu->type->event_mask | ((u64)pmu->type->event_mask_ext << 32)); diff --git a/arch/x86/events/intel/uncore.h b/arch/x86/events/intel/uncore.h index df5989f..3e60686 100644 --- a/arch/x86/events/intel/uncore.h +++ b/arch/x86/events/intel/uncore.h @@ -12,7 +12,25 @@ #define UNCORE_FIXED_EVENT 0xff #define UNCORE_PMC_IDX_MAX_GENERIC 8 #define UNCORE_PMC_IDX_FIXED UNCORE_PMC_IDX_MAX_GENERIC -#define UNCORE_PMC_IDX_MAX (UNCORE_PMC_IDX_FIXED + 1) +#define UNCORE_PMC_IDX_FREERUNNING (UNCORE_PMC_IDX_FIXED + 1) +#define UNCORE_PMC_IDX_MAX (UNCORE_PMC_IDX_FREERUNNING + 1) + +/* + * Free running MSR events have the same event code 0xff as fixed events. + * The Free running events umask starts from 0x10. + * The umask which is less than 0x10 is reserved for fixed events. + * + * The Free running events are divided into different types according to + * MSR location, bit width or definition. Each type is limited to only have + * at most 16 events. + * So the umask of first type starts from 0x10, the second starts from 0x20, + * the rest can be done in the same manner. + */ +#define UNCORE_FREE_RUNNING_MSR_START 0x10 +#define UNCORE_FREE_RUNNING_MSR_IDX(config) ((config >> 8) & 0xf) +#define UNCORE_FREE_RUNNING_MSR_TYPE_IDX(config) \ + ((((config >> 8) - UNCORE_FREE_RUNNING_MSR_START) >> 4) & 0xf) + #define UNCORE_PCI_DEV_FULL_DATA(dev, func, type, idx) \ ((dev << 24) | (func << 16) | (type << 8) | idx) @@ -34,6 +52,7 @@ struct intel_uncore_ops; struct intel_uncore_pmu; struct intel_uncore_box; struct uncore_event_desc; +struct free_running_msr; struct intel_uncore_type { const char *name; @@ -41,6 +60,7 @@ struct intel_uncore_type { int num_boxes; int perf_ctr_bits; int fixed_ctr_bits; + int num_free_running_type; unsigned perf_ctr; unsigned event_ctl; unsigned event_mask; @@ -58,6 +78,7 @@ struct intel_uncore_type { struct intel_uncore_pmu *pmus; struct intel_uncore_ops *ops; struct uncore_event_desc *event_descs; + struct free_running_msr *free_running; const struct attribute_group *attr_groups[4]; struct pmu *pmu; /* for custom pmu ops */ }; @@ -128,6 +149,13 @@ struct uncore_event_desc { const char *config; }; +struct free_running_msr { + unsigned msr_base; + unsigned msr_off; + unsigned num_counters; + unsigned bits; +}; + struct pci2phy_map { struct list_head list; int segment; @@ -214,6 +242,18 @@ static inline unsigned uncore_msr_fixed_ctr(struct intel_uncore_box *box) } static inline +unsigned uncore_free_running_msr(struct intel_uncore_box *box, + struct perf_event *event) +{ + unsigned type = UNCORE_FREE_RUNNING_MSR_TYPE_IDX(event->attr.config); + unsigned idx = UNCORE_FREE_RUNNING_MSR_IDX(event->attr.config); + struct intel_uncore_pmu *pmu = box->pmu; + + return pmu->type->free_running[type].msr_base + idx + + pmu->type->free_running[type].msr_off * pmu->pmu_idx; +} + +static inline unsigned uncore_msr_event_ctl(struct intel_uncore_box *box, int idx) { return box->pmu->type->event_ctl + @@ -275,11 +315,36 @@ static inline int uncore_fixed_ctr_bits(struct intel_uncore_box *box) return box->pmu->type->fixed_ctr_bits; } +static inline unsigned +uncore_free_running_bits(struct intel_uncore_box *box, + struct perf_event *event) +{ + unsigned idx = UNCORE_FREE_RUNNING_MSR_TYPE_IDX(event->attr.config); + + return box->pmu->type->free_running[idx].bits; +} + +static inline int uncore_num_free_running(struct intel_uncore_box *box, + struct perf_event *event) +{ + unsigned idx = UNCORE_FREE_RUNNING_MSR_TYPE_IDX(event->attr.config); + + return box->pmu->type->free_running[idx].num_counters; +} + static inline int uncore_num_counters(struct intel_uncore_box *box) { return box->pmu->type->num_counters; } +static inline bool is_free_running_event(struct perf_event *event) +{ + u64 cfg = event->attr.config; + + return (((cfg & UNCORE_FIXED_EVENT) == UNCORE_FIXED_EVENT) && + (((cfg >> 8) & 0xff) >= UNCORE_FREE_RUNNING_MSR_START)); +} + static inline void uncore_disable_box(struct intel_uncore_box *box) { if (box->pmu->type->ops->disable_box) diff --git a/arch/x86/events/intel/uncore_snbep.c b/arch/x86/events/intel/uncore_snbep.c index a719681..cbd6061 100644 --- a/arch/x86/events/intel/uncore_snbep.c +++ b/arch/x86/events/intel/uncore_snbep.c @@ -3459,6 +3459,61 @@ static struct intel_uncore_ops skx_uncore_iio_ops = { .read_counter = uncore_msr_read_counter, }; +enum perf_uncore_iio_free_running_msr_type_id { + SKX_IIO_MSR_IOCLK = 0, + SKX_IIO_MSR_BW = 1, + SKX_IIO_MSR_UTIL = 2, + + SKX_IIO_FREE_RUNNING_MSR_TYPE_MAX, +}; + + +static struct free_running_msr skx_iio_free_running_msr[] = { + [SKX_IIO_MSR_IOCLK] = { 0xa45, 0x20, 1, 36 }, + [SKX_IIO_MSR_BW] = { 0xb00, 0x10, 8, 36 }, + [SKX_IIO_MSR_UTIL] = { 0xb08, 0x10, 8, 36 }, +}; + +static struct uncore_event_desc skx_uncore_iio_events[] = { + /* Free-Running IO CLOCKS Counter */ + INTEL_UNCORE_EVENT_DESC(ioclk, "event=0xff,umask=0x10"), + /* Free-Running IIO Bandwidth Counters */ + INTEL_UNCORE_EVENT_DESC(bw_in_port0, "event=0xff,umask=0x20"), + INTEL_UNCORE_EVENT_DESC(bw_in_port0.scale, "3.814697266e-6"), + INTEL_UNCORE_EVENT_DESC(bw_in_port0.unit, "MiB"), + INTEL_UNCORE_EVENT_DESC(bw_in_port1, "event=0xff,umask=0x21"), + INTEL_UNCORE_EVENT_DESC(bw_in_port1.scale, "3.814697266e-6"), + INTEL_UNCORE_EVENT_DESC(bw_in_port1.unit, "MiB"), + INTEL_UNCORE_EVENT_DESC(bw_in_port2, "event=0xff,umask=0x22"), + INTEL_UNCORE_EVENT_DESC(bw_in_port2.scale, "3.814697266e-6"), + INTEL_UNCORE_EVENT_DESC(bw_in_port2.unit, "MiB"), + INTEL_UNCORE_EVENT_DESC(bw_in_port3, "event=0xff,umask=0x23"), + INTEL_UNCORE_EVENT_DESC(bw_in_port3.scale, "3.814697266e-6"), + INTEL_UNCORE_EVENT_DESC(bw_in_port3.unit, "MiB"), + INTEL_UNCORE_EVENT_DESC(bw_out_port0, "event=0xff,umask=0x24"), + INTEL_UNCORE_EVENT_DESC(bw_out_port0.scale, "3.814697266e-6"), + INTEL_UNCORE_EVENT_DESC(bw_out_port0.unit, "MiB"), + INTEL_UNCORE_EVENT_DESC(bw_out_port1, "event=0xff,umask=0x25"), + INTEL_UNCORE_EVENT_DESC(bw_out_port1.scale, "3.814697266e-6"), + INTEL_UNCORE_EVENT_DESC(bw_out_port1.unit, "MiB"), + INTEL_UNCORE_EVENT_DESC(bw_out_port2, "event=0xff,umask=0x26"), + INTEL_UNCORE_EVENT_DESC(bw_out_port2.scale, "3.814697266e-6"), + INTEL_UNCORE_EVENT_DESC(bw_out_port2.unit, "MiB"), + INTEL_UNCORE_EVENT_DESC(bw_out_port3, "event=0xff,umask=0x27"), + INTEL_UNCORE_EVENT_DESC(bw_out_port3.scale, "3.814697266e-6"), + INTEL_UNCORE_EVENT_DESC(bw_out_port3.unit, "MiB"), + /* Free-running IIO Utilization Counters */ + INTEL_UNCORE_EVENT_DESC(util_in_port0, "event=0xff,umask=0x30"), + INTEL_UNCORE_EVENT_DESC(util_out_port0, "event=0xff,umask=0x31"), + INTEL_UNCORE_EVENT_DESC(util_in_port1, "event=0xff,umask=0x32"), + INTEL_UNCORE_EVENT_DESC(util_out_port1, "event=0xff,umask=0x33"), + INTEL_UNCORE_EVENT_DESC(util_in_port2, "event=0xff,umask=0x34"), + INTEL_UNCORE_EVENT_DESC(util_out_port2, "event=0xff,umask=0x35"), + INTEL_UNCORE_EVENT_DESC(util_in_port3, "event=0xff,umask=0x36"), + INTEL_UNCORE_EVENT_DESC(util_out_port3, "event=0xff,umask=0x37"), + { /* end: all zeroes */ }, +}; + static struct intel_uncore_type skx_uncore_iio = { .name = "iio", .num_counters = 4, @@ -3470,8 +3525,11 @@ static struct intel_uncore_type skx_uncore_iio = { .event_mask_ext = SKX_IIO_PMON_RAW_EVENT_MASK_EXT, .box_ctl = SKX_IIO0_MSR_PMON_BOX_CTL, .msr_offset = SKX_IIO_MSR_OFFSET, + .num_free_running_type = SKX_IIO_FREE_RUNNING_MSR_TYPE_MAX, + .free_running = skx_iio_free_running_msr, .constraints = skx_uncore_iio_constraints, .ops = &skx_uncore_iio_ops, + .event_descs = skx_uncore_iio_events, .format_group = &skx_uncore_iio_format_group, }; -- 2.7.4 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* RE: [PATCH 2/2] perf/x86/intel/uncore: support IIO freerunning counter for SKX 2017-09-11 17:10 ` [PATCH 2/2] perf/x86/intel/uncore: support IIO freerunning counter for SKX kan.liang @ 2017-10-17 1:20 ` Liang, Kan 2017-10-18 15:29 ` Thomas Gleixner 1 sibling, 0 replies; 5+ messages in thread From: Liang, Kan @ 2017-10-17 1:20 UTC (permalink / raw) To: peterz@infradead.org, tglx@linutronix.de, mingo@redhat.com, linux-kernel@vger.kernel.org Cc: acme@kernel.org, eranian@google.com, ak@linux.intel.com Ping. Any comments for this patch? Thanks, Kan > > From: Kan Liang <Kan.liang@intel.com> > > As of Skylake Server, there are a number of free-running counters in > each IIO Box that collect counts for per box IO clocks and per Port > Input/Output x BW/Utilization. > > The event code of free running event is shared with fixed event, which > is 0xff. > The umask of free running event starts from 0x10. The umask less than > 0x10 is reserved for fixed event. > > The Free running counters could have different MSR location and offset. > Accordingly, they are divided into different types. Each type is limited > to only have at most 16 events. > So the umask of the first free running events type starts from 0x10. The > umask of the second starts from 0x20. The rest can be done in the same > manner. > > Freerunning counters cannot be written by SW. Counting will be suspended > only when the IIO Box is powered down. They are specially handled in > uncore_pmu_event_add/del/start/stop and not added in box->events list. > > The bit width of freerunning counter is 36-bit. > > Signed-off-by: Kan Liang <Kan.liang@intel.com> > --- > arch/x86/events/intel/uncore.c | 33 +++++++++++++++++- > arch/x86/events/intel/uncore.h | 67 > +++++++++++++++++++++++++++++++++++- > arch/x86/events/intel/uncore_snbep.c | 58 > +++++++++++++++++++++++++++++++ > 3 files changed, 156 insertions(+), 2 deletions(-) > > diff --git a/arch/x86/events/intel/uncore.c b/arch/x86/events/intel/uncore.c > index 1c5390f..8d3e46c 100644 > --- a/arch/x86/events/intel/uncore.c > +++ b/arch/x86/events/intel/uncore.c > @@ -218,7 +218,9 @@ void uncore_perf_event_update(struct > intel_uncore_box *box, struct perf_event *e > u64 prev_count, new_count, delta; > int shift; > > - if (event->hw.idx >= UNCORE_PMC_IDX_FIXED) > + if (event->hw.idx >= UNCORE_PMC_IDX_FREERUNNING) > + shift = 64 - uncore_free_running_bits(box, event); > + else if (event->hw.idx == UNCORE_PMC_IDX_FIXED) > shift = 64 - uncore_fixed_ctr_bits(box); > else > shift = 64 - uncore_perf_ctr_bits(box); > @@ -362,6 +364,9 @@ uncore_collect_events(struct intel_uncore_box *box, > struct perf_event *leader, > if (n >= max_count) > return -EINVAL; > > + if (event->hw.idx == UNCORE_PMC_IDX_FREERUNNING) > + continue; > + > box->event_list[n] = event; > n++; > } > @@ -454,6 +459,12 @@ static void uncore_pmu_event_start(struct > perf_event *event, int flags) > struct intel_uncore_box *box = uncore_event_to_box(event); > int idx = event->hw.idx; > > + if (event->hw.idx == UNCORE_PMC_IDX_FREERUNNING) { > + local64_set(&event->hw.prev_count, > + uncore_read_counter(box, event)); > + return; > + } > + > if (WARN_ON_ONCE(!(event->hw.state & PERF_HES_STOPPED))) > return; > > @@ -479,6 +490,11 @@ static void uncore_pmu_event_stop(struct > perf_event *event, int flags) > struct intel_uncore_box *box = uncore_event_to_box(event); > struct hw_perf_event *hwc = &event->hw; > > + if (hwc->idx == UNCORE_PMC_IDX_FREERUNNING) { > + uncore_perf_event_update(box, event); > + return; > + } > + > if (__test_and_clear_bit(hwc->idx, box->active_mask)) { > uncore_disable_event(box, event); > box->n_active--; > @@ -512,6 +528,13 @@ static int uncore_pmu_event_add(struct perf_event > *event, int flags) > if (!box) > return -ENODEV; > > + if (hwc->idx == UNCORE_PMC_IDX_FREERUNNING) { > + event->hw.event_base = uncore_free_running_msr(box, > event); > + if (flags & PERF_EF_START) > + uncore_pmu_event_start(event, 0); > + return 0; > + } > + > ret = n = uncore_collect_events(box, event, false); > if (ret < 0) > return ret; > @@ -570,6 +593,9 @@ static void uncore_pmu_event_del(struct perf_event > *event, int flags) > > uncore_pmu_event_stop(event, PERF_EF_UPDATE); > > + if (event->hw.idx == UNCORE_PMC_IDX_FREERUNNING) > + return; > + > for (i = 0; i < box->n_events; i++) { > if (event == box->event_list[i]) { > uncore_put_event_constraint(box, event); > @@ -690,6 +716,11 @@ static int uncore_pmu_event_init(struct perf_event > *event) > > /* fixed counters have event field hardcoded to zero */ > hwc->config = 0ULL; > + } else if (is_free_running_event(event)) { > + if (UNCORE_FREE_RUNNING_MSR_IDX(event->attr.config) > > + uncore_num_free_running(box, event)) > + return -EINVAL; > + event->hw.idx = UNCORE_PMC_IDX_FREERUNNING; > } else { > hwc->config = event->attr.config & > (pmu->type->event_mask | ((u64)pmu->type- > >event_mask_ext << 32)); > diff --git a/arch/x86/events/intel/uncore.h b/arch/x86/events/intel/uncore.h > index df5989f..3e60686 100644 > --- a/arch/x86/events/intel/uncore.h > +++ b/arch/x86/events/intel/uncore.h > @@ -12,7 +12,25 @@ > #define UNCORE_FIXED_EVENT 0xff > #define UNCORE_PMC_IDX_MAX_GENERIC 8 > #define UNCORE_PMC_IDX_FIXED > UNCORE_PMC_IDX_MAX_GENERIC > -#define UNCORE_PMC_IDX_MAX (UNCORE_PMC_IDX_FIXED + > 1) > +#define UNCORE_PMC_IDX_FREERUNNING (UNCORE_PMC_IDX_FIXED + > 1) > +#define UNCORE_PMC_IDX_MAX > (UNCORE_PMC_IDX_FREERUNNING + 1) > + > +/* > + * Free running MSR events have the same event code 0xff as fixed events. > + * The Free running events umask starts from 0x10. > + * The umask which is less than 0x10 is reserved for fixed events. > + * > + * The Free running events are divided into different types according to > + * MSR location, bit width or definition. Each type is limited to only have > + * at most 16 events. > + * So the umask of first type starts from 0x10, the second starts from 0x20, > + * the rest can be done in the same manner. > + */ > +#define UNCORE_FREE_RUNNING_MSR_START 0x10 > +#define UNCORE_FREE_RUNNING_MSR_IDX(config) ((config >> 8) > & 0xf) > +#define UNCORE_FREE_RUNNING_MSR_TYPE_IDX(config) \ > + ((((config >> 8) - UNCORE_FREE_RUNNING_MSR_START) >> 4) > & 0xf) > + > > #define UNCORE_PCI_DEV_FULL_DATA(dev, func, type, idx) \ > ((dev << 24) | (func << 16) | (type << 8) | idx) > @@ -34,6 +52,7 @@ struct intel_uncore_ops; > struct intel_uncore_pmu; > struct intel_uncore_box; > struct uncore_event_desc; > +struct free_running_msr; > > struct intel_uncore_type { > const char *name; > @@ -41,6 +60,7 @@ struct intel_uncore_type { > int num_boxes; > int perf_ctr_bits; > int fixed_ctr_bits; > + int num_free_running_type; > unsigned perf_ctr; > unsigned event_ctl; > unsigned event_mask; > @@ -58,6 +78,7 @@ struct intel_uncore_type { > struct intel_uncore_pmu *pmus; > struct intel_uncore_ops *ops; > struct uncore_event_desc *event_descs; > + struct free_running_msr *free_running; > const struct attribute_group *attr_groups[4]; > struct pmu *pmu; /* for custom pmu ops */ > }; > @@ -128,6 +149,13 @@ struct uncore_event_desc { > const char *config; > }; > > +struct free_running_msr { > + unsigned msr_base; > + unsigned msr_off; > + unsigned num_counters; > + unsigned bits; > +}; > + > struct pci2phy_map { > struct list_head list; > int segment; > @@ -214,6 +242,18 @@ static inline unsigned uncore_msr_fixed_ctr(struct > intel_uncore_box *box) > } > > static inline > +unsigned uncore_free_running_msr(struct intel_uncore_box *box, > + struct perf_event *event) > +{ > + unsigned type = UNCORE_FREE_RUNNING_MSR_TYPE_IDX(event- > >attr.config); > + unsigned idx = UNCORE_FREE_RUNNING_MSR_IDX(event- > >attr.config); > + struct intel_uncore_pmu *pmu = box->pmu; > + > + return pmu->type->free_running[type].msr_base + idx + > + pmu->type->free_running[type].msr_off * pmu->pmu_idx; > +} > + > +static inline > unsigned uncore_msr_event_ctl(struct intel_uncore_box *box, int idx) > { > return box->pmu->type->event_ctl + > @@ -275,11 +315,36 @@ static inline int uncore_fixed_ctr_bits(struct > intel_uncore_box *box) > return box->pmu->type->fixed_ctr_bits; > } > > +static inline unsigned > +uncore_free_running_bits(struct intel_uncore_box *box, > + struct perf_event *event) > +{ > + unsigned idx = UNCORE_FREE_RUNNING_MSR_TYPE_IDX(event- > >attr.config); > + > + return box->pmu->type->free_running[idx].bits; > +} > + > +static inline int uncore_num_free_running(struct intel_uncore_box *box, > + struct perf_event *event) > +{ > + unsigned idx = UNCORE_FREE_RUNNING_MSR_TYPE_IDX(event- > >attr.config); > + > + return box->pmu->type->free_running[idx].num_counters; > +} > + > static inline int uncore_num_counters(struct intel_uncore_box *box) > { > return box->pmu->type->num_counters; > } > > +static inline bool is_free_running_event(struct perf_event *event) > +{ > + u64 cfg = event->attr.config; > + > + return (((cfg & UNCORE_FIXED_EVENT) == UNCORE_FIXED_EVENT) > && > + (((cfg >> 8) & 0xff) >= > UNCORE_FREE_RUNNING_MSR_START)); > +} > + > static inline void uncore_disable_box(struct intel_uncore_box *box) > { > if (box->pmu->type->ops->disable_box) > diff --git a/arch/x86/events/intel/uncore_snbep.c > b/arch/x86/events/intel/uncore_snbep.c > index a719681..cbd6061 100644 > --- a/arch/x86/events/intel/uncore_snbep.c > +++ b/arch/x86/events/intel/uncore_snbep.c > @@ -3459,6 +3459,61 @@ static struct intel_uncore_ops > skx_uncore_iio_ops = { > .read_counter = uncore_msr_read_counter, > }; > > +enum perf_uncore_iio_free_running_msr_type_id { > + SKX_IIO_MSR_IOCLK = 0, > + SKX_IIO_MSR_BW = 1, > + SKX_IIO_MSR_UTIL = 2, > + > + SKX_IIO_FREE_RUNNING_MSR_TYPE_MAX, > +}; > + > + > +static struct free_running_msr skx_iio_free_running_msr[] = { > + [SKX_IIO_MSR_IOCLK] = { 0xa45, 0x20, 1, 36 }, > + [SKX_IIO_MSR_BW] = { 0xb00, 0x10, 8, 36 }, > + [SKX_IIO_MSR_UTIL] = { 0xb08, 0x10, 8, 36 }, > +}; > + > +static struct uncore_event_desc skx_uncore_iio_events[] = { > + /* Free-Running IO CLOCKS Counter */ > + INTEL_UNCORE_EVENT_DESC(ioclk, > "event=0xff,umask=0x10"), > + /* Free-Running IIO Bandwidth Counters */ > + INTEL_UNCORE_EVENT_DESC(bw_in_port0, > "event=0xff,umask=0x20"), > + INTEL_UNCORE_EVENT_DESC(bw_in_port0.scale, > "3.814697266e-6"), > + INTEL_UNCORE_EVENT_DESC(bw_in_port0.unit, "MiB"), > + INTEL_UNCORE_EVENT_DESC(bw_in_port1, > "event=0xff,umask=0x21"), > + INTEL_UNCORE_EVENT_DESC(bw_in_port1.scale, > "3.814697266e-6"), > + INTEL_UNCORE_EVENT_DESC(bw_in_port1.unit, "MiB"), > + INTEL_UNCORE_EVENT_DESC(bw_in_port2, > "event=0xff,umask=0x22"), > + INTEL_UNCORE_EVENT_DESC(bw_in_port2.scale, > "3.814697266e-6"), > + INTEL_UNCORE_EVENT_DESC(bw_in_port2.unit, "MiB"), > + INTEL_UNCORE_EVENT_DESC(bw_in_port3, > "event=0xff,umask=0x23"), > + INTEL_UNCORE_EVENT_DESC(bw_in_port3.scale, > "3.814697266e-6"), > + INTEL_UNCORE_EVENT_DESC(bw_in_port3.unit, "MiB"), > + INTEL_UNCORE_EVENT_DESC(bw_out_port0, > "event=0xff,umask=0x24"), > + INTEL_UNCORE_EVENT_DESC(bw_out_port0.scale, > "3.814697266e-6"), > + INTEL_UNCORE_EVENT_DESC(bw_out_port0.unit, "MiB"), > + INTEL_UNCORE_EVENT_DESC(bw_out_port1, > "event=0xff,umask=0x25"), > + INTEL_UNCORE_EVENT_DESC(bw_out_port1.scale, > "3.814697266e-6"), > + INTEL_UNCORE_EVENT_DESC(bw_out_port1.unit, "MiB"), > + INTEL_UNCORE_EVENT_DESC(bw_out_port2, > "event=0xff,umask=0x26"), > + INTEL_UNCORE_EVENT_DESC(bw_out_port2.scale, > "3.814697266e-6"), > + INTEL_UNCORE_EVENT_DESC(bw_out_port2.unit, "MiB"), > + INTEL_UNCORE_EVENT_DESC(bw_out_port3, > "event=0xff,umask=0x27"), > + INTEL_UNCORE_EVENT_DESC(bw_out_port3.scale, > "3.814697266e-6"), > + INTEL_UNCORE_EVENT_DESC(bw_out_port3.unit, "MiB"), > + /* Free-running IIO Utilization Counters */ > + INTEL_UNCORE_EVENT_DESC(util_in_port0, > "event=0xff,umask=0x30"), > + INTEL_UNCORE_EVENT_DESC(util_out_port0, > "event=0xff,umask=0x31"), > + INTEL_UNCORE_EVENT_DESC(util_in_port1, > "event=0xff,umask=0x32"), > + INTEL_UNCORE_EVENT_DESC(util_out_port1, > "event=0xff,umask=0x33"), > + INTEL_UNCORE_EVENT_DESC(util_in_port2, > "event=0xff,umask=0x34"), > + INTEL_UNCORE_EVENT_DESC(util_out_port2, > "event=0xff,umask=0x35"), > + INTEL_UNCORE_EVENT_DESC(util_in_port3, > "event=0xff,umask=0x36"), > + INTEL_UNCORE_EVENT_DESC(util_out_port3, > "event=0xff,umask=0x37"), > + { /* end: all zeroes */ }, > +}; > + > static struct intel_uncore_type skx_uncore_iio = { > .name = "iio", > .num_counters = 4, > @@ -3470,8 +3525,11 @@ static struct intel_uncore_type skx_uncore_iio = { > .event_mask_ext = > SKX_IIO_PMON_RAW_EVENT_MASK_EXT, > .box_ctl = SKX_IIO0_MSR_PMON_BOX_CTL, > .msr_offset = SKX_IIO_MSR_OFFSET, > + .num_free_running_type = > SKX_IIO_FREE_RUNNING_MSR_TYPE_MAX, > + .free_running = skx_iio_free_running_msr, > .constraints = skx_uncore_iio_constraints, > .ops = &skx_uncore_iio_ops, > + .event_descs = skx_uncore_iio_events, > .format_group = &skx_uncore_iio_format_group, > }; > > -- > 2.7.4 ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH 2/2] perf/x86/intel/uncore: support IIO freerunning counter for SKX 2017-09-11 17:10 ` [PATCH 2/2] perf/x86/intel/uncore: support IIO freerunning counter for SKX kan.liang 2017-10-17 1:20 ` Liang, Kan @ 2017-10-18 15:29 ` Thomas Gleixner 1 sibling, 0 replies; 5+ messages in thread From: Thomas Gleixner @ 2017-10-18 15:29 UTC (permalink / raw) To: Kan Liang; +Cc: peterz, mingo, linux-kernel, acme, eranian, ak On Mon, 11 Sep 2017, kan.liang@intel.com wrote: > - if (event->hw.idx >= UNCORE_PMC_IDX_FIXED) > + if (event->hw.idx >= UNCORE_PMC_IDX_FREERUNNING) > + shift = 64 - uncore_free_running_bits(box, event); > + else if (event->hw.idx == UNCORE_PMC_IDX_FIXED) I have no idea why the original check was event->hw.idx >= UNCORE_PMC_IDX_FIXED and why the new one is event->hw.idx >= UNCORE_PMC_IDX_FREERUNNING when you check in the next conditional: > + if (event->hw.idx == UNCORE_PMC_IDX_FREERUNNING) > + continue; This stinks. Anything > UNCORE_PMC_IDX_FREERUNNING is bogus. > @@ -454,6 +459,12 @@ static void uncore_pmu_event_start(struct perf_event *event, int flags) > struct intel_uncore_box *box = uncore_event_to_box(event); > int idx = event->hw.idx; > > + if (event->hw.idx == UNCORE_PMC_IDX_FREERUNNING) { > + local64_set(&event->hw.prev_count, > + uncore_read_counter(box, event)); A comment why this has special treatment would be helpful. Here and in other places. > +/* > + * Free running MSR events have the same event code 0xff as fixed events. > + * The Free running events umask starts from 0x10. > + * The umask which is less than 0x10 is reserved for fixed events. > + * > + * The Free running events are divided into different types according to > + * MSR location, bit width or definition. Each type is limited to only have > + * at most 16 events. > + * So the umask of first type starts from 0x10, the second starts from 0x20, > + * the rest can be done in the same manner. > + */ > +#define UNCORE_FREE_RUNNING_MSR_START 0x10 > +#define UNCORE_FREE_RUNNING_MSR_IDX(config) ((config >> 8) & 0xf) > +#define UNCORE_FREE_RUNNING_MSR_TYPE_IDX(config) \ > + ((((config >> 8) - UNCORE_FREE_RUNNING_MSR_START) >> 4) & 0xf) > + Any reason why these two need to be fugly macros instead of inlines which simply take an event or an attribute pointer? > @@ -34,6 +52,7 @@ struct intel_uncore_ops; > struct intel_uncore_pmu; > struct intel_uncore_box; > struct uncore_event_desc; > +struct free_running_msr; > > struct intel_uncore_type { > const char *name; > @@ -41,6 +60,7 @@ struct intel_uncore_type { > int num_boxes; > int perf_ctr_bits; > int fixed_ctr_bits; > + int num_free_running_type; s/type/types/ > @@ -128,6 +149,13 @@ struct uncore_event_desc { > const char *config; > }; > > +struct free_running_msr { > + unsigned msr_base; unsigned int please > + unsigned msr_off; > + unsigned num_counters; > + unsigned bits; > +}; > + > struct pci2phy_map { > struct list_head list; > int segment; > @@ -214,6 +242,18 @@ static inline unsigned uncore_msr_fixed_ctr(struct intel_uncore_box *box) > } > +enum perf_uncore_iio_free_running_msr_type_id { > + SKX_IIO_MSR_IOCLK = 0, > + SKX_IIO_MSR_BW = 1, > + SKX_IIO_MSR_UTIL = 2, > + > + SKX_IIO_FREE_RUNNING_MSR_TYPE_MAX, > +}; Please split the patch in two parts: 1) Add infrastructure for free running counters 2) Add SKX support Thanks, tglx ^ permalink raw reply [flat|nested] 5+ messages in thread
* [tip:x86/urgent] perf/x86/intel/uncore: Correct num_boxes for IIO and IRP 2017-09-11 17:10 [PATCH 1/2] perf/x86/intel/uncore: correct num_boxes for IIO and IRP kan.liang 2017-09-11 17:10 ` [PATCH 2/2] perf/x86/intel/uncore: support IIO freerunning counter for SKX kan.liang @ 2017-09-25 10:48 ` tip-bot for Kan Liang 1 sibling, 0 replies; 5+ messages in thread From: tip-bot for Kan Liang @ 2017-09-25 10:48 UTC (permalink / raw) To: linux-tip-commits; +Cc: mingo, linux-kernel, hpa, tglx, Kan.liang Commit-ID: 29b46dfb136cdbeece542b3f01115237e43f2855 Gitweb: http://git.kernel.org/tip/29b46dfb136cdbeece542b3f01115237e43f2855 Author: Kan Liang <Kan.liang@intel.com> AuthorDate: Mon, 11 Sep 2017 10:10:15 -0700 Committer: Thomas Gleixner <tglx@linutronix.de> CommitDate: Mon, 25 Sep 2017 12:43:56 +0200 perf/x86/intel/uncore: Correct num_boxes for IIO and IRP There are 6 IIO/IRP boxes for CBDMA, PCIe0-2, MCP 0 and MCP 1 separately. Correct the num_boxes. Signed-off-by: Kan Liang <Kan.liang@intel.com> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Cc: ak@linux.intel.com Cc: peterz@infradead.org Cc: eranian@google.com Cc: acme@kernel.org Link: http://lkml.kernel.org/r/1505149816-12580-1-git-send-email-kan.liang@intel.com --- arch/x86/events/intel/uncore_snbep.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/x86/events/intel/uncore_snbep.c b/arch/x86/events/intel/uncore_snbep.c index db1fe37..a719681 100644 --- a/arch/x86/events/intel/uncore_snbep.c +++ b/arch/x86/events/intel/uncore_snbep.c @@ -3462,7 +3462,7 @@ static struct intel_uncore_ops skx_uncore_iio_ops = { static struct intel_uncore_type skx_uncore_iio = { .name = "iio", .num_counters = 4, - .num_boxes = 5, + .num_boxes = 6, .perf_ctr_bits = 48, .event_ctl = SKX_IIO0_MSR_PMON_CTL0, .perf_ctr = SKX_IIO0_MSR_PMON_CTR0, @@ -3492,7 +3492,7 @@ static const struct attribute_group skx_uncore_format_group = { static struct intel_uncore_type skx_uncore_irp = { .name = "irp", .num_counters = 2, - .num_boxes = 5, + .num_boxes = 6, .perf_ctr_bits = 48, .event_ctl = SKX_IRP0_MSR_PMON_CTL0, .perf_ctr = SKX_IRP0_MSR_PMON_CTR0, ^ permalink raw reply related [flat|nested] 5+ messages in thread
end of thread, other threads:[~2017-10-18 15:29 UTC | newest] Thread overview: 5+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2017-09-11 17:10 [PATCH 1/2] perf/x86/intel/uncore: correct num_boxes for IIO and IRP kan.liang 2017-09-11 17:10 ` [PATCH 2/2] perf/x86/intel/uncore: support IIO freerunning counter for SKX kan.liang 2017-10-17 1:20 ` Liang, Kan 2017-10-18 15:29 ` Thomas Gleixner 2017-09-25 10:48 ` [tip:x86/urgent] perf/x86/intel/uncore: Correct num_boxes for IIO and IRP tip-bot for Kan Liang
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox