[RESEND PATCH v4 0/4] Add perf interface to expose nvdimm
Patchset adds performance stats reporting support for nvdimm. Added interface includes support for pmu register/unregister functions. A structure is added called nvdimm_pmu to be used for adding arch/platform specific data such as supported events, cpumask pmu event functions like event_init/add/read/del. User could use the standard perf tool to access perf events exposed via pmu. Added implementation to expose IBM pseries platform nmem* device performance stats using this interface. Result from power9 pseries lpar with 2 nvdimm device: command:# perf list nmem nmem0/cchrhcnt/[Kernel PMU event] nmem0/cchwhcnt/[Kernel PMU event] nmem0/critrscu/[Kernel PMU event] nmem0/ctlresct/[Kernel PMU event] nmem0/ctlrestm/[Kernel PMU event] nmem0/fastwcnt/[Kernel PMU event] nmem0/hostlcnt/[Kernel PMU event] nmem0/hostldur/[Kernel PMU event] nmem0/hostscnt/[Kernel PMU event] nmem0/hostsdur/[Kernel PMU event] nmem0/medrcnt/ [Kernel PMU event] nmem0/medrdur/ [Kernel PMU event] nmem0/medwcnt/ [Kernel PMU event] nmem0/medwdur/ [Kernel PMU event] nmem0/memlife/ [Kernel PMU event] nmem0/noopstat/[Kernel PMU event] nmem0/ponsecs/ [Kernel PMU event] nmem1/cchrhcnt/[Kernel PMU event] nmem1/cchwhcnt/[Kernel PMU event] nmem1/critrscu/[Kernel PMU event] ... nmem1/noopstat/[Kernel PMU event] nmem1/ponsecs/ [Kernel PMU event] Patch1: Introduces the nvdimm_pmu structure Patch2: Adds common interface to add arch/platform specific data includes supported events, pmu event functions. It also adds code for cpu hotplug support. Patch3: Add code in arch/powerpc/platform/pseries/papr_scm.c to expose nmem* pmu. It fills in the nvdimm_pmu structure with event attrs cpumask andevent functions and then registers the pmu by adding callbacks to register_nvdimm_pmu. Patch4: Sysfs documentation patch Changelog --- v3 -> v4 - Rebase code on top of current papr_scm code without any logical changes. - Added Acked-by tag from Peter Zijlstra and Reviewed by tag from Madhavan Srinivasan. - Link to the patchset v3: https://lkml.org/lkml/2021/6/17/605 v2 -> v3 - Added Tested-by tag. - Fix nvdimm mailing list in the ABI Documentation. - Link to the patchset v2: https://lkml.org/lkml/2021/6/14/25 v1 -> v2 - Fix hotplug code by adding pmu migration call incase current designated cpu got offline. As pointed by Peter Zijlstra. - Removed the retun -1 part from cpu hotplug offline function. - Link to the patchset v1: https://lkml.org/lkml/2021/6/8/500 Kajol Jain (4): drivers/nvdimm: Add nvdimm pmu structure drivers/nvdimm: Add perf interface to expose nvdimm performance stats powerpc/papr_scm: Add perf interface support powerpc/papr_scm: Document papr_scm sysfs event format entries Documentation/ABI/testing/sysfs-bus-papr-pmem | 31 ++ arch/powerpc/include/asm/device.h | 5 + arch/powerpc/platforms/pseries/papr_scm.c | 365 ++ drivers/nvdimm/Makefile | 1 + drivers/nvdimm/nd_perf.c | 230 +++ include/linux/nd.h| 46 +++ 6 files changed, 678 insertions(+) create mode 100644 drivers/nvdimm/nd_perf.c -- 2.26.2
[RESEND PATCH v4 1/4] drivers/nvdimm: Add nvdimm pmu structure
A structure is added, called nvdimm_pmu, for performance stats reporting support of nvdimm devices. It can be used to add nvdimm pmu data such as supported events and pmu event functions like event_init/add/read/del with cpu hotplug support. Acked-by: Peter Zijlstra (Intel) Reviewed-by: Madhavan Srinivasan Tested-by: Nageswara R Sastry Signed-off-by: Kajol Jain --- include/linux/nd.h | 43 +++ 1 file changed, 43 insertions(+) diff --git a/include/linux/nd.h b/include/linux/nd.h index ee9ad76afbba..712499cf7335 100644 --- a/include/linux/nd.h +++ b/include/linux/nd.h @@ -8,6 +8,8 @@ #include #include #include +#include +#include enum nvdimm_event { NVDIMM_REVALIDATE_POISON, @@ -23,6 +25,47 @@ enum nvdimm_claim_class { NVDIMM_CCLASS_UNKNOWN, }; +/* Event attribute array index */ +#define NVDIMM_PMU_FORMAT_ATTR 0 +#define NVDIMM_PMU_EVENT_ATTR 1 +#define NVDIMM_PMU_CPUMASK_ATTR2 +#define NVDIMM_PMU_NULL_ATTR 3 + +/** + * struct nvdimm_pmu - data structure for nvdimm perf driver + * + * @name: name of the nvdimm pmu device. + * @pmu: pmu data structure for nvdimm performance stats. + * @dev: nvdimm device pointer. + * @functions(event_init/add/del/read): platform specific pmu functions. + * @attr_groups: data structure for events, formats and cpumask + * @cpu: designated cpu for counter access. + * @node: node for cpu hotplug notifier link. + * @cpuhp_state: state for cpu hotplug notification. + * @arch_cpumask: cpumask to get designated cpu for counter access. + */ +struct nvdimm_pmu { + const char *name; + struct pmu pmu; + struct device *dev; + int (*event_init)(struct perf_event *event); + int (*add)(struct perf_event *event, int flags); + void (*del)(struct perf_event *event, int flags); + void (*read)(struct perf_event *event); + /* +* Attribute groups for the nvdimm pmu. Index 0 used for +* format attribute, index 1 used for event attribute, +* index 2 used for cpusmask attribute and index 3 kept as NULL. +*/ + const struct attribute_group *attr_groups[4]; + int cpu; + struct hlist_node node; + enum cpuhp_state cpuhp_state; + + /* cpumask provided by arch/platform specific code */ + struct cpumask arch_cpumask; +}; + struct nd_device_driver { struct device_driver drv; unsigned long type; -- 2.26.2
[RESEND PATCH v4 2/4] drivers/nvdimm: Add perf interface to expose nvdimm performance stats
A common interface is added to get performance stats reporting support for nvdimm devices. Added interface includes support for pmu register/unregister functions, cpu hotplug and pmu event functions like event_init/add/read/del. User could use the standard perf tool to access perf events exposed via pmu. Acked-by: Peter Zijlstra (Intel) Reviewed-by: Madhavan Srinivasan Tested-by: Nageswara R Sastry Signed-off-by: Kajol Jain --- drivers/nvdimm/Makefile | 1 + drivers/nvdimm/nd_perf.c | 230 +++ include/linux/nd.h | 3 + 3 files changed, 234 insertions(+) create mode 100644 drivers/nvdimm/nd_perf.c diff --git a/drivers/nvdimm/Makefile b/drivers/nvdimm/Makefile index 29203f3d3069..25dba6095612 100644 --- a/drivers/nvdimm/Makefile +++ b/drivers/nvdimm/Makefile @@ -18,6 +18,7 @@ nd_e820-y := e820.o libnvdimm-y := core.o libnvdimm-y += bus.o libnvdimm-y += dimm_devs.o +libnvdimm-y += nd_perf.o libnvdimm-y += dimm.o libnvdimm-y += region_devs.o libnvdimm-y += region.o diff --git a/drivers/nvdimm/nd_perf.c b/drivers/nvdimm/nd_perf.c new file mode 100644 index ..4c49d1bc2a3c --- /dev/null +++ b/drivers/nvdimm/nd_perf.c @@ -0,0 +1,230 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * nd_perf.c: NVDIMM Device Performance Monitoring Unit support + * + * Perf interface to expose nvdimm performance stats. + * + * Copyright (C) 2021 IBM Corporation + */ + +#define pr_fmt(fmt) "nvdimm_pmu: " fmt + +#include + +static ssize_t nvdimm_pmu_cpumask_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct pmu *pmu = dev_get_drvdata(dev); + struct nvdimm_pmu *nd_pmu; + + nd_pmu = container_of(pmu, struct nvdimm_pmu, pmu); + + return cpumap_print_to_pagebuf(true, buf, cpumask_of(nd_pmu->cpu)); +} + +static int nvdimm_pmu_cpu_offline(unsigned int cpu, struct hlist_node *node) +{ + struct nvdimm_pmu *nd_pmu; + u32 target; + int nodeid; + const struct cpumask *cpumask; + + nd_pmu = hlist_entry_safe(node, struct nvdimm_pmu, node); + + /* Clear it, incase given cpu is set in nd_pmu->arch_cpumask */ + cpumask_test_and_clear_cpu(cpu, &nd_pmu->arch_cpumask); + + /* +* If given cpu is not same as current designated cpu for +* counter access, just return. +*/ + if (cpu != nd_pmu->cpu) + return 0; + + /* Check for any active cpu in nd_pmu->arch_cpumask */ + target = cpumask_any(&nd_pmu->arch_cpumask); + + /* +* Incase we don't have any active cpu in nd_pmu->arch_cpumask, +* check in given cpu's numa node list. +*/ + if (target >= nr_cpu_ids) { + nodeid = cpu_to_node(cpu); + cpumask = cpumask_of_node(nodeid); + target = cpumask_any_but(cpumask, cpu); + } + nd_pmu->cpu = target; + + /* Migrate nvdimm pmu events to the new target cpu if valid */ + if (target >= 0 && target < nr_cpu_ids) + perf_pmu_migrate_context(&nd_pmu->pmu, cpu, target); + + return 0; +} + +static int nvdimm_pmu_cpu_online(unsigned int cpu, struct hlist_node *node) +{ + struct nvdimm_pmu *nd_pmu; + + nd_pmu = hlist_entry_safe(node, struct nvdimm_pmu, node); + + if (nd_pmu->cpu >= nr_cpu_ids) + nd_pmu->cpu = cpu; + + return 0; +} + +static int create_cpumask_attr_group(struct nvdimm_pmu *nd_pmu) +{ + struct perf_pmu_events_attr *attr; + struct attribute **attrs; + struct attribute_group *nvdimm_pmu_cpumask_group; + + attr = kzalloc(sizeof(*attr), GFP_KERNEL); + if (!attr) + return -ENOMEM; + + attrs = kzalloc(2 * sizeof(struct attribute *), GFP_KERNEL); + if (!attrs) { + kfree(attr); + return -ENOMEM; + } + + /* Allocate memory for cpumask attribute group */ + nvdimm_pmu_cpumask_group = kzalloc(sizeof(*nvdimm_pmu_cpumask_group), GFP_KERNEL); + if (!nvdimm_pmu_cpumask_group) { + kfree(attr); + kfree(attrs); + return -ENOMEM; + } + + sysfs_attr_init(&attr->attr.attr); + attr->attr.attr.name = "cpumask"; + attr->attr.attr.mode = 0444; + attr->attr.show = nvdimm_pmu_cpumask_show; + attrs[0] = &attr->attr.attr; + attrs[1] = NULL; + + nvdimm_pmu_cpumask_group->attrs = attrs; + nd_pmu->attr_groups[NVDIMM_PMU_CPUMASK_ATTR] = nvdimm_pmu_cpumask_group; + return 0; +} + +static int nvdimm_pmu_cpu_hotplug_init(struct nvdimm_pmu *nd_pmu) +{ + int nodeid, rc; + const struct cpumask *cpumask; + + /* +* Incase cpu hotplug is not handled by arch specific code +* they can still provide required cpumask which
[RESEND PATCH v4 3/4] powerpc/papr_scm: Add perf interface support
Performance monitoring support for papr-scm nvdimm devices via perf interface is added which includes addition of pmu functions like add/del/read/event_init for nvdimm_pmu struture. A new parameter 'priv' in added to the pdev_archdata structure to save nvdimm_pmu device pointer, to handle the unregistering of pmu device. papr_scm_pmu_register function populates the nvdimm_pmu structure with events, cpumask, attribute groups along with event handling functions. Finally the populated nvdimm_pmu structure is passed to register the pmu device. Event handling functions internally uses hcall to get events and counter data. Result in power9 machine with 2 nvdimm device: Ex: List all event by perf list command:# perf list nmem nmem0/cchrhcnt/[Kernel PMU event] nmem0/cchwhcnt/[Kernel PMU event] nmem0/critrscu/[Kernel PMU event] nmem0/ctlresct/[Kernel PMU event] nmem0/ctlrestm/[Kernel PMU event] nmem0/fastwcnt/[Kernel PMU event] nmem0/hostlcnt/[Kernel PMU event] nmem0/hostldur/[Kernel PMU event] nmem0/hostscnt/[Kernel PMU event] nmem0/hostsdur/[Kernel PMU event] nmem0/medrcnt/ [Kernel PMU event] nmem0/medrdur/ [Kernel PMU event] nmem0/medwcnt/ [Kernel PMU event] nmem0/medwdur/ [Kernel PMU event] nmem0/memlife/ [Kernel PMU event] nmem0/noopstat/[Kernel PMU event] nmem0/ponsecs/ [Kernel PMU event] nmem1/cchrhcnt/[Kernel PMU event] nmem1/cchwhcnt/[Kernel PMU event] nmem1/critrscu/[Kernel PMU event] ... nmem1/noopstat/[Kernel PMU event] nmem1/ponsecs/ [Kernel PMU event] Acked-by: Peter Zijlstra (Intel) Reviewed-by: Madhavan Srinivasan Tested-by: Nageswara R Sastry Signed-off-by: Kajol Jain --- arch/powerpc/include/asm/device.h | 5 + arch/powerpc/platforms/pseries/papr_scm.c | 365 ++ 2 files changed, 370 insertions(+) diff --git a/arch/powerpc/include/asm/device.h b/arch/powerpc/include/asm/device.h index 219559d65864..47ed639f3b8f 100644 --- a/arch/powerpc/include/asm/device.h +++ b/arch/powerpc/include/asm/device.h @@ -48,6 +48,11 @@ struct dev_archdata { struct pdev_archdata { u64 dma_mask; + /* +* Pointer to nvdimm_pmu structure, to handle the unregistering +* of pmu device +*/ + void *priv; }; #endif /* _ASM_POWERPC_DEVICE_H */ diff --git a/arch/powerpc/platforms/pseries/papr_scm.c b/arch/powerpc/platforms/pseries/papr_scm.c index f48e87ac89c9..26900101e638 100644 --- a/arch/powerpc/platforms/pseries/papr_scm.c +++ b/arch/powerpc/platforms/pseries/papr_scm.c @@ -19,6 +19,8 @@ #include #include #include +#include +#include #define BIND_ANY_ADDR (~0ul) @@ -68,6 +70,8 @@ #define PAPR_SCM_PERF_STATS_EYECATCHER __stringify(SCMSTATS) #define PAPR_SCM_PERF_STATS_VERSION 0x1 +#define to_nvdimm_pmu(_pmu)container_of(_pmu, struct nvdimm_pmu, pmu) + /* Struct holding a single performance metric */ struct papr_scm_perf_stat { u8 stat_id[8]; @@ -120,6 +124,12 @@ struct papr_scm_priv { /* length of the stat buffer as expected by phyp */ size_t stat_buffer_len; + +/* array to have event_code and stat_id mappings */ + char **nvdimm_events_map; + + /* count of supported events */ + u32 total_events; }; static int papr_scm_pmem_flush(struct nd_region *nd_region, @@ -340,6 +350,354 @@ static ssize_t drc_pmem_query_stats(struct papr_scm_priv *p, return 0; } +PMU_FORMAT_ATTR(event, "config:0-4"); + +static struct attribute *nvdimm_pmu_format_attr[] = { + &format_attr_event.attr, + NULL, +}; + +static struct attribute_group nvdimm_pmu_format_group = { + .name = "format", + .attrs = nvdimm_pmu_format_attr, +}; + +static int papr_scm_pmu_get_value(struct perf_event *event, struct device *dev, u64 *count) +{ + struct papr_scm_perf_stat *stat; + struct papr_scm_perf_stats *stats; + struct papr_scm_priv *p = (struct papr_scm_priv *)dev->driver_data; + int rc, size; + + /* Allocate request buffer enough to hold single performance stat */ + size = sizeof(struct papr_scm_perf_stats) + + sizeof(struct papr_scm_perf_stat); + +
[RESEND PATCH v4 4/4] powerpc/papr_scm: Document papr_scm sysfs event format entries
Details is added for the event, cpumask and format attributes in the ABI documentation. Acked-by: Peter Zijlstra (Intel) Reviewed-by: Madhavan Srinivasan Tested-by: Nageswara R Sastry Signed-off-by: Kajol Jain --- Documentation/ABI/testing/sysfs-bus-papr-pmem | 31 +++ 1 file changed, 31 insertions(+) diff --git a/Documentation/ABI/testing/sysfs-bus-papr-pmem b/Documentation/ABI/testing/sysfs-bus-papr-pmem index 95254cec92bf..4d86252448f8 100644 --- a/Documentation/ABI/testing/sysfs-bus-papr-pmem +++ b/Documentation/ABI/testing/sysfs-bus-papr-pmem @@ -61,3 +61,34 @@ Description: * "CchRHCnt" : Cache Read Hit Count * "CchWHCnt" : Cache Write Hit Count * "FastWCnt" : Fast Write Count + +What: /sys/devices/nmemX/format +Date: June 2021 +Contact: linuxppc-dev , nvd...@lists.linux.dev, +Description: (RO) Attribute group to describe the magic bits +that go into perf_event_attr.config for a particular pmu. +(See ABI/testing/sysfs-bus-event_source-devices-format). + +Each attribute under this group defines a bit range of the +perf_event_attr.config. Supported attribute is listed +below:: + + event = "config:0-4" - event ID + + For example:: + noopstat = "event=0x1" + +What: /sys/devices/nmemX/events +Date: June 2021 +Contact: linuxppc-dev , nvd...@lists.linux.dev, +Description:(RO) Attribute group to describe performance monitoring +events specific to papr-scm. Each attribute in this group describes +a single performance monitoring event supported by this nvdimm pmu. +The name of the file is the name of the event. +(See ABI/testing/sysfs-bus-event_source-devices-events). + +What: /sys/devices/nmemX/cpumask +Date: June 2021 +Contact: linuxppc-dev , nvd...@lists.linux.dev, +Description: (RO) This sysfs file exposes the cpumask which is designated to make +HCALLs to retrieve nvdimm pmu event counter data. -- 2.26.2
[PATCH v5 1/4] drivers/nvdimm: Add nvdimm pmu structure
A structure is added called nvdimm_pmu, for performance stats reporting support of nvdimm devices. It can be used to add device pmu data such as pmu data structure for performance stats, nvdimm device pointer along with cpumask attributes. Signed-off-by: Kajol Jain --- include/linux/nd.h | 20 1 file changed, 20 insertions(+) diff --git a/include/linux/nd.h b/include/linux/nd.h index ee9ad76afbba..f5ed4db2d859 100644 --- a/include/linux/nd.h +++ b/include/linux/nd.h @@ -8,6 +8,7 @@ #include #include #include +#include enum nvdimm_event { NVDIMM_REVALIDATE_POISON, @@ -23,6 +24,25 @@ enum nvdimm_claim_class { NVDIMM_CCLASS_UNKNOWN, }; +/** + * struct nvdimm_pmu - data structure for nvdimm perf driver + * @pmu: pmu data structure for nvdimm performance stats. + * @dev: nvdimm device pointer. + * @cpu: designated cpu for counter access. + * @node: node for cpu hotplug notifier link. + * @cpuhp_state: state for cpu hotplug notification. + * @arch_cpumask: cpumask to get designated cpu for counter access. + */ +struct nvdimm_pmu { + struct pmu pmu; + struct device *dev; + int cpu; + struct hlist_node node; + enum cpuhp_state cpuhp_state; + /* cpumask provided by arch/platform specific code */ + struct cpumask arch_cpumask; +}; + struct nd_device_driver { struct device_driver drv; unsigned long type; -- 2.26.2
[PATCH v5 2/4] drivers/nvdimm: Add perf interface to expose nvdimm performance stats
A common interface is added to get performance stats reporting support for nvdimm devices. Added interface defines supported event list, config fields for the event attributes and their corresponding bit values which are exported via sysfs. Interface also added support for pmu register/unregister functions, cpu hotplug feature along with macros for handling events addition via sysfs. It adds attribute groups for format, cpumask and events to the pmu structure. User could use the standard perf tool to access perf events exposed via nvdimm pmu. Signed-off-by: Kajol Jain [Make hotplug function static as reported by kernel test rorbot] Reported-by: kernel test robot --- drivers/nvdimm/Makefile | 1 + drivers/nvdimm/nd_perf.c | 328 +++ include/linux/nd.h | 21 +++ 3 files changed, 350 insertions(+) create mode 100644 drivers/nvdimm/nd_perf.c diff --git a/drivers/nvdimm/Makefile b/drivers/nvdimm/Makefile index 29203f3d3069..25dba6095612 100644 --- a/drivers/nvdimm/Makefile +++ b/drivers/nvdimm/Makefile @@ -18,6 +18,7 @@ nd_e820-y := e820.o libnvdimm-y := core.o libnvdimm-y += bus.o libnvdimm-y += dimm_devs.o +libnvdimm-y += nd_perf.o libnvdimm-y += dimm.o libnvdimm-y += region_devs.o libnvdimm-y += region.o diff --git a/drivers/nvdimm/nd_perf.c b/drivers/nvdimm/nd_perf.c new file mode 100644 index ..314415894acf --- /dev/null +++ b/drivers/nvdimm/nd_perf.c @@ -0,0 +1,328 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * nd_perf.c: NVDIMM Device Performance Monitoring Unit support + * + * Perf interface to expose nvdimm performance stats. + * + * Copyright (C) 2021 IBM Corporation + */ + +#define pr_fmt(fmt) "nvdimm_pmu: " fmt + +#include + +#define EVENT(_name, _code) enum{_name = _code} + +/* + * NVDIMM Events codes. + */ + +/* Controller Reset Count */ +EVENT(CTL_RES_CNT, 0x1); +/* Controller Reset Elapsed Time */ +EVENT(CTL_RES_TM, 0x2); +/* Power-on Seconds */ +EVENT(POWERON_SECS,0x3); +/* Life Remaining */ +EVENT(MEM_LIFE,0x4); +/* Critical Resource Utilization */ +EVENT(CRI_RES_UTIL,0x5); +/* Host Load Count */ +EVENT(HOST_L_CNT, 0x6); +/* Host Store Count */ +EVENT(HOST_S_CNT, 0x7); +/* Host Store Duration */ +EVENT(HOST_S_DUR, 0x8); +/* Host Load Duration */ +EVENT(HOST_L_DUR, 0x9); +/* Media Read Count */ +EVENT(MED_R_CNT, 0xa); +/* Media Write Count */ +EVENT(MED_W_CNT, 0xb); +/* Media Read Duration */ +EVENT(MED_R_DUR, 0xc); +/* Media Write Duration */ +EVENT(MED_W_DUR, 0xd); +/* Cache Read Hit Count */ +EVENT(CACHE_RH_CNT,0xe); +/* Cache Write Hit Count */ +EVENT(CACHE_WH_CNT,0xf); +/* Fast Write Count */ +EVENT(FAST_W_CNT, 0x10); + +NVDIMM_EVENT_ATTR(ctl_res_cnt, CTL_RES_CNT); +NVDIMM_EVENT_ATTR(ctl_res_tm, CTL_RES_TM); +NVDIMM_EVENT_ATTR(poweron_secs,POWERON_SECS); +NVDIMM_EVENT_ATTR(mem_life,MEM_LIFE); +NVDIMM_EVENT_ATTR(cri_res_util,CRI_RES_UTIL); +NVDIMM_EVENT_ATTR(host_l_cnt, HOST_L_CNT); +NVDIMM_EVENT_ATTR(host_s_cnt, HOST_S_CNT); +NVDIMM_EVENT_ATTR(host_s_dur, HOST_S_DUR); +NVDIMM_EVENT_ATTR(host_l_dur, HOST_L_DUR); +NVDIMM_EVENT_ATTR(med_r_cnt, MED_R_CNT); +NVDIMM_EVENT_ATTR(med_w_cnt, MED_W_CNT); +NVDIMM_EVENT_ATTR(med_r_dur, MED_R_DUR); +NVDIMM_EVENT_ATTR(med_w_dur, MED_W_DUR); +NVDIMM_EVENT_ATTR(cache_rh_cnt,CACHE_RH_CNT); +NVDIMM_EVENT_ATTR(cache_wh_cnt,CACHE_WH_CNT); +NVDIMM_EVENT_ATTR(fast_w_cnt, FAST_W_CNT); + +static struct attribute *nvdimm_events_attr[] = { + NVDIMM_EVENT_PTR(CTL_RES_CNT), + NVDIMM_EVENT_PTR(CTL_RES_TM), + NVDIMM_EVENT_PTR(POWERON_SECS), + NVDIMM_EVENT_PTR(MEM_LIFE), + NVDIMM_EVENT_PTR(CRI_RES_UTIL), + NVDIMM_EVENT_PTR(HOST_L_CNT), + NVDIMM_EVENT_PTR(HOST_S_CNT), + NVDIMM_EVENT_PTR(HOST_S_DUR), + NVDIMM_EVENT_PTR(HOST_L_DUR), + NVDIMM_EVENT_PTR(MED_R_CNT), + NVDIMM_EVENT_PTR(MED_W_CNT), + NVDIMM_EVENT_PTR(MED_R_DUR), + NVDIMM_EVENT_PTR(MED_W_DUR), + NVDIMM_EVENT_PTR(CACHE_RH_CNT), + NVDIMM_EVENT_PTR(CACHE_WH_CNT), + NVDIMM_EVENT_PTR(FAST_W_CNT), + NULL +}; + +static struct attribute_group nvdimm_pmu_events_group = { + .name = "events", + .attrs = nvdimm_events_attr, +}; + +PMU_FORMAT_ATTR(event, "config:0-4"); + +static struct attribute *nvdimm_pmu_format_attr[] = { + &format_attr_event.attr, + NULL, +}; + +static struct attribute_group nvdimm_pmu_format_group = { + .name = "format", + .attrs = nvdimm_pmu_format_attr, +}; + +ssize_t nvdimm_events_sysfs_show(struct device *dev, +
[PATCH v5 3/4] powerpc/papr_scm: Add perf interface support
Performance monitoring support for papr-scm nvdimm devices via perf interface is added which includes addition of pmu functions like add/del/read/event_init for nvdimm_pmu struture. A new parameter 'priv' in added to the pdev_archdata structure to save nvdimm_pmu device pointer, to handle the unregistering of pmu device. papr_scm_pmu_register function populates the nvdimm_pmu structure with name, capabilities, cpumask along with event handling functions. Finally the populated nvdimm_pmu structure is passed to register the pmu device. Event handling functions internally uses hcall to get events and counter data. Result in power9 machine with 2 nvdimm device: Ex: List all event by perf list command:# perf list nmem nmem0/cache_rh_cnt/[Kernel PMU event] nmem0/cache_wh_cnt/[Kernel PMU event] nmem0/cri_res_util/[Kernel PMU event] nmem0/ctl_res_cnt/ [Kernel PMU event] nmem0/ctl_res_tm/ [Kernel PMU event] nmem0/fast_w_cnt/ [Kernel PMU event] nmem0/host_l_cnt/ [Kernel PMU event] nmem0/host_l_dur/ [Kernel PMU event] nmem0/host_s_cnt/ [Kernel PMU event] nmem0/host_s_dur/ [Kernel PMU event] nmem0/med_r_cnt/ [Kernel PMU event] nmem0/med_r_dur/ [Kernel PMU event] nmem0/med_w_cnt/ [Kernel PMU event] nmem0/med_w_dur/ [Kernel PMU event] nmem0/mem_life/[Kernel PMU event] nmem0/poweron_secs/[Kernel PMU event] ... nmem1/mem_life/[Kernel PMU event] nmem1/poweron_secs/[Kernel PMU event] Signed-off-by: Kajol Jain --- arch/powerpc/include/asm/device.h | 5 + arch/powerpc/platforms/pseries/papr_scm.c | 225 ++ 2 files changed, 230 insertions(+) diff --git a/arch/powerpc/include/asm/device.h b/arch/powerpc/include/asm/device.h index 219559d65864..47ed639f3b8f 100644 --- a/arch/powerpc/include/asm/device.h +++ b/arch/powerpc/include/asm/device.h @@ -48,6 +48,11 @@ struct dev_archdata { struct pdev_archdata { u64 dma_mask; + /* +* Pointer to nvdimm_pmu structure, to handle the unregistering +* of pmu device +*/ + void *priv; }; #endif /* _ASM_POWERPC_DEVICE_H */ diff --git a/arch/powerpc/platforms/pseries/papr_scm.c b/arch/powerpc/platforms/pseries/papr_scm.c index f48e87ac89c9..bdf2620db461 100644 --- a/arch/powerpc/platforms/pseries/papr_scm.c +++ b/arch/powerpc/platforms/pseries/papr_scm.c @@ -19,6 +19,7 @@ #include #include #include +#include #define BIND_ANY_ADDR (~0ul) @@ -68,6 +69,8 @@ #define PAPR_SCM_PERF_STATS_EYECATCHER __stringify(SCMSTATS) #define PAPR_SCM_PERF_STATS_VERSION 0x1 +#define to_nvdimm_pmu(_pmu)container_of(_pmu, struct nvdimm_pmu, pmu) + /* Struct holding a single performance metric */ struct papr_scm_perf_stat { u8 stat_id[8]; @@ -120,6 +123,9 @@ struct papr_scm_priv { /* length of the stat buffer as expected by phyp */ size_t stat_buffer_len; + +/* array to have event_code and stat_id mappings */ + char **nvdimm_events_map; }; static int papr_scm_pmem_flush(struct nd_region *nd_region, @@ -340,6 +346,218 @@ static ssize_t drc_pmem_query_stats(struct papr_scm_priv *p, return 0; } +static int papr_scm_pmu_get_value(struct perf_event *event, struct device *dev, u64 *count) +{ + struct papr_scm_perf_stat *stat; + struct papr_scm_perf_stats *stats; + struct papr_scm_priv *p = (struct papr_scm_priv *)dev->driver_data; + int rc, size; + + /* Allocate request buffer enough to hold single performance stat */ + size = sizeof(struct papr_scm_perf_stats) + + sizeof(struct papr_scm_perf_stat); + + if (!p || !p->nvdimm_events_map) + return -EINVAL; + + stats = kzalloc(size, GFP_KERNEL); + if (!stats) + return -ENOMEM; + + stat = &stats->scm_statistic[0]; + memcpy(&stat->stat_id, + p->nvdimm_events_map[event->attr.config], + sizeof(stat->stat_id)); + stat->stat_val = 0; + + rc = drc_pmem_query_stats(p, stats, 1); + if (rc < 0) { + kfree(stats); + return rc; + } + + *count = be64_to_cpu(stat->stat_val); + kfree(stats); + return 0; +} + +static int papr_scm_pmu_event_init(struct perf_event *event) +{ + struct nvdimm_pmu *nd_pmu = to_nvdimm_pmu(event->pmu); +
[PATCH v5 4/4] docs: ABI: sysfs-bus-nvdimm: Document sysfs event format entries for nvdimm pmu
Details are added for the event, cpumask and format attributes in the ABI documentation. Signed-off-by: Kajol Jain --- Documentation/ABI/testing/sysfs-bus-nvdimm | 35 ++ 1 file changed, 35 insertions(+) diff --git a/Documentation/ABI/testing/sysfs-bus-nvdimm b/Documentation/ABI/testing/sysfs-bus-nvdimm index bff84a16812a..64004d5e4840 100644 --- a/Documentation/ABI/testing/sysfs-bus-nvdimm +++ b/Documentation/ABI/testing/sysfs-bus-nvdimm @@ -6,3 +6,38 @@ Description: The libnvdimm sub-system implements a common sysfs interface for platform nvdimm resources. See Documentation/driver-api/nvdimm/. + +What: /sys/bus/event_source/devices/nmemX/format +Date: September 2021 +KernelVersion: 5.16 +Contact:Kajol Jain +Description: (RO) Attribute group to describe the magic bits + that go into perf_event_attr.config for a particular pmu. + (See ABI/testing/sysfs-bus-event_source-devices-format). + + Each attribute under this group defines a bit range of the + perf_event_attr.config. Supported attribute is listed + below:: + event = "config:0-4" - event ID + + For example:: + ctl_res_cnt = "event=0x1" + +What: /sys/bus/event_source/devices/nmemX/events +Date: September 2021 +KernelVersion: 5.16 +Contact:Kajol Jain +Description: (RO) Attribute group to describe performance monitoring events +for the nvdimm memory device. Each attribute in this group +describes a single performance monitoring event supported by +this nvdimm pmu. The name of the file is the name of the event. +(See ABI/testing/sysfs-bus-event_source-devices-events). A +listing of the events supported by a given nvdimm provider type +can be found in Documentation/driver-api/nvdimm/$provider. + +What: /sys/bus/event_source/devices/nmemX/cpumask +Date: September 2021 +KernelVersion: 5.16 +Contact:Kajol Jain +Description: (RO) This sysfs file exposes the cpumask which is designated to + to retrieve nvdimm pmu event counter data. -- 2.26.2
[PATCH v5 0/4] Add perf interface to expose nvdimm
Patchset adds performance stats reporting support for nvdimm. Added interface includes support for pmu register/unregister functions. A structure is added called nvdimm_pmu to be used for adding arch/platform specific data such as cpumask, nvdimm device pointer and pmu event functions like event_init/add/read/del. User could use the standard perf tool to access perf events exposed via pmu. Interface also defines supported event list, config fields for the event attributes and their corresponding bit values which are exported via sysfs. Patch 3 exposes IBM pseries platform nmem* device performance stats using this interface. Result from power9 pseries lpar with 2 nvdimm device: Ex: List all event by perf list command:# perf list nmem nmem0/cache_rh_cnt/[Kernel PMU event] nmem0/cache_wh_cnt/[Kernel PMU event] nmem0/cri_res_util/[Kernel PMU event] nmem0/ctl_res_cnt/ [Kernel PMU event] nmem0/ctl_res_tm/ [Kernel PMU event] nmem0/fast_w_cnt/ [Kernel PMU event] nmem0/host_l_cnt/ [Kernel PMU event] nmem0/host_l_dur/ [Kernel PMU event] nmem0/host_s_cnt/ [Kernel PMU event] nmem0/host_s_dur/ [Kernel PMU event] nmem0/med_r_cnt/ [Kernel PMU event] nmem0/med_r_dur/ [Kernel PMU event] nmem0/med_w_cnt/ [Kernel PMU event] nmem0/med_w_dur/ [Kernel PMU event] nmem0/mem_life/[Kernel PMU event] nmem0/poweron_secs/[Kernel PMU event] ... nmem1/mem_life/[Kernel PMU event] nmem1/poweron_secs/[Kernel PMU event] Patch1: Introduces the nvdimm_pmu structure Patch2: Adds common interface to add arch/platform specific data includes nvdimm device pointer, pmu data along with pmu event functions. It also defines supported event list and adds attribute groups for format, events and cpumask. It also adds code for cpu hotplug support. Patch3: Add code in arch/powerpc/platform/pseries/papr_scm.c to expose nmem* pmu. It fills in the nvdimm_pmu structure with pmu name, capabilities, cpumask and event functions and then registers the pmu by adding callbacks to register_nvdimm_pmu. Patch4: Sysfs documentation patch Changelog --- v4 -> v5: - Remove multiple variables defined in nvdimm_pmu structure include name and pmu functions(event_int/add/del/read) as they are just used to copy them again in pmu variable. Now we are directly doing this step in arch specific code as suggested by Dan Williams. - Remove attribute group field from nvdimm pmu structure and defined these attribute groups in common interface which includes format, event list along with cpumask as suggested by Dan Williams. Since we added static defination for attrbute groups needed in common interface, removes corresponding code from papr. - Add nvdimm pmu event list with event codes in the common interface. - Remove Acked-by/Reviewed-by/Tested-by tags as code is refactored to handle review comments from Dan. - Make nvdimm_pmu_free_hotplug_memory function static as reported by kernel test robot, also add corresponding Reported-by tag. - Link to the patchset v4: https://lkml.org/lkml/2021/9/3/45 v3 -> v4 - Rebase code on top of current papr_scm code without any logical changes. - Added Acked-by tag from Peter Zijlstra and Reviewed by tag from Madhavan Srinivasan. - Link to the patchset v3: https://lkml.org/lkml/2021/6/17/605 v2 -> v3 - Added Tested-by tag. - Fix nvdimm mailing list in the ABI Documentation. - Link to the patchset v2: https://lkml.org/lkml/2021/6/14/25 v1 -> v2 - Fix hotplug code by adding pmu migration call incase current designated cpu got offline. As pointed by Peter Zijlstra. - Removed the retun -1 part from cpu hotplug offline function. - Link to the patchset v1: https://lkml.org/lkml/2021/6/8/500 Kajol Jain (4): drivers/nvdimm: Add nvdimm pmu structure drivers/nvdimm: Add perf interface to expose nvdimm performance stats powerpc/papr_scm: Add perf interface support docs: ABI: sysfs-bus-nvdimm: Document sysfs event format entries for nvdimm pmu Documentation/ABI/testing/sysfs-bus-nvdimm | 35 +++ arch/powerpc/include/asm/device.h | 5 + arch/powerpc/platforms/pseries/papr_scm.c | 225 ++ drivers/nvdimm/Makefile| 1 + drivers/nvdimm/nd_perf.c | 328 + include/linux/nd.h
[RESEND PATCH v5 2/4] drivers/nvdimm: Add perf interface to expose nvdimm performance stats
A common interface is added to get performance stats reporting support for nvdimm devices. Added interface defines supported event list, config fields for the event attributes and their corresponding bit values which are exported via sysfs. Interface also added support for pmu register/unregister functions, cpu hotplug feature along with macros for handling events addition via sysfs. It adds attribute groups for format, cpumask and events to the pmu structure. User could use the standard perf tool to access perf events exposed via nvdimm pmu. Signed-off-by: Kajol Jain [Make hotplug function static as reported by kernel test rorbot] Reported-by: kernel test robot --- drivers/nvdimm/Makefile | 1 + drivers/nvdimm/nd_perf.c | 328 +++ include/linux/nd.h | 21 +++ 3 files changed, 350 insertions(+) create mode 100644 drivers/nvdimm/nd_perf.c diff --git a/drivers/nvdimm/Makefile b/drivers/nvdimm/Makefile index 29203f3d3069..25dba6095612 100644 --- a/drivers/nvdimm/Makefile +++ b/drivers/nvdimm/Makefile @@ -18,6 +18,7 @@ nd_e820-y := e820.o libnvdimm-y := core.o libnvdimm-y += bus.o libnvdimm-y += dimm_devs.o +libnvdimm-y += nd_perf.o libnvdimm-y += dimm.o libnvdimm-y += region_devs.o libnvdimm-y += region.o diff --git a/drivers/nvdimm/nd_perf.c b/drivers/nvdimm/nd_perf.c new file mode 100644 index ..314415894acf --- /dev/null +++ b/drivers/nvdimm/nd_perf.c @@ -0,0 +1,328 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * nd_perf.c: NVDIMM Device Performance Monitoring Unit support + * + * Perf interface to expose nvdimm performance stats. + * + * Copyright (C) 2021 IBM Corporation + */ + +#define pr_fmt(fmt) "nvdimm_pmu: " fmt + +#include + +#define EVENT(_name, _code) enum{_name = _code} + +/* + * NVDIMM Events codes. + */ + +/* Controller Reset Count */ +EVENT(CTL_RES_CNT, 0x1); +/* Controller Reset Elapsed Time */ +EVENT(CTL_RES_TM, 0x2); +/* Power-on Seconds */ +EVENT(POWERON_SECS,0x3); +/* Life Remaining */ +EVENT(MEM_LIFE,0x4); +/* Critical Resource Utilization */ +EVENT(CRI_RES_UTIL,0x5); +/* Host Load Count */ +EVENT(HOST_L_CNT, 0x6); +/* Host Store Count */ +EVENT(HOST_S_CNT, 0x7); +/* Host Store Duration */ +EVENT(HOST_S_DUR, 0x8); +/* Host Load Duration */ +EVENT(HOST_L_DUR, 0x9); +/* Media Read Count */ +EVENT(MED_R_CNT, 0xa); +/* Media Write Count */ +EVENT(MED_W_CNT, 0xb); +/* Media Read Duration */ +EVENT(MED_R_DUR, 0xc); +/* Media Write Duration */ +EVENT(MED_W_DUR, 0xd); +/* Cache Read Hit Count */ +EVENT(CACHE_RH_CNT,0xe); +/* Cache Write Hit Count */ +EVENT(CACHE_WH_CNT,0xf); +/* Fast Write Count */ +EVENT(FAST_W_CNT, 0x10); + +NVDIMM_EVENT_ATTR(ctl_res_cnt, CTL_RES_CNT); +NVDIMM_EVENT_ATTR(ctl_res_tm, CTL_RES_TM); +NVDIMM_EVENT_ATTR(poweron_secs,POWERON_SECS); +NVDIMM_EVENT_ATTR(mem_life,MEM_LIFE); +NVDIMM_EVENT_ATTR(cri_res_util,CRI_RES_UTIL); +NVDIMM_EVENT_ATTR(host_l_cnt, HOST_L_CNT); +NVDIMM_EVENT_ATTR(host_s_cnt, HOST_S_CNT); +NVDIMM_EVENT_ATTR(host_s_dur, HOST_S_DUR); +NVDIMM_EVENT_ATTR(host_l_dur, HOST_L_DUR); +NVDIMM_EVENT_ATTR(med_r_cnt, MED_R_CNT); +NVDIMM_EVENT_ATTR(med_w_cnt, MED_W_CNT); +NVDIMM_EVENT_ATTR(med_r_dur, MED_R_DUR); +NVDIMM_EVENT_ATTR(med_w_dur, MED_W_DUR); +NVDIMM_EVENT_ATTR(cache_rh_cnt,CACHE_RH_CNT); +NVDIMM_EVENT_ATTR(cache_wh_cnt,CACHE_WH_CNT); +NVDIMM_EVENT_ATTR(fast_w_cnt, FAST_W_CNT); + +static struct attribute *nvdimm_events_attr[] = { + NVDIMM_EVENT_PTR(CTL_RES_CNT), + NVDIMM_EVENT_PTR(CTL_RES_TM), + NVDIMM_EVENT_PTR(POWERON_SECS), + NVDIMM_EVENT_PTR(MEM_LIFE), + NVDIMM_EVENT_PTR(CRI_RES_UTIL), + NVDIMM_EVENT_PTR(HOST_L_CNT), + NVDIMM_EVENT_PTR(HOST_S_CNT), + NVDIMM_EVENT_PTR(HOST_S_DUR), + NVDIMM_EVENT_PTR(HOST_L_DUR), + NVDIMM_EVENT_PTR(MED_R_CNT), + NVDIMM_EVENT_PTR(MED_W_CNT), + NVDIMM_EVENT_PTR(MED_R_DUR), + NVDIMM_EVENT_PTR(MED_W_DUR), + NVDIMM_EVENT_PTR(CACHE_RH_CNT), + NVDIMM_EVENT_PTR(CACHE_WH_CNT), + NVDIMM_EVENT_PTR(FAST_W_CNT), + NULL +}; + +static struct attribute_group nvdimm_pmu_events_group = { + .name = "events", + .attrs = nvdimm_events_attr, +}; + +PMU_FORMAT_ATTR(event, "config:0-4"); + +static struct attribute *nvdimm_pmu_format_attr[] = { + &format_attr_event.attr, + NULL, +}; + +static struct attribute_group nvdimm_pmu_format_group = { + .name = "format", + .attrs = nvdimm_pmu_format_attr, +}; + +ssize_t nvdimm_events_sysfs_show(struct device *dev, +
[RESEND PATCH v5 3/4] powerpc/papr_scm: Add perf interface support
Performance monitoring support for papr-scm nvdimm devices via perf interface is added which includes addition of pmu functions like add/del/read/event_init for nvdimm_pmu struture. A new parameter 'priv' in added to the pdev_archdata structure to save nvdimm_pmu device pointer, to handle the unregistering of pmu device. papr_scm_pmu_register function populates the nvdimm_pmu structure with name, capabilities, cpumask along with event handling functions. Finally the populated nvdimm_pmu structure is passed to register the pmu device. Event handling functions internally uses hcall to get events and counter data. Result in power9 machine with 2 nvdimm device: Ex: List all event by perf list command:# perf list nmem nmem0/cache_rh_cnt/[Kernel PMU event] nmem0/cache_wh_cnt/[Kernel PMU event] nmem0/cri_res_util/[Kernel PMU event] nmem0/ctl_res_cnt/ [Kernel PMU event] nmem0/ctl_res_tm/ [Kernel PMU event] nmem0/fast_w_cnt/ [Kernel PMU event] nmem0/host_l_cnt/ [Kernel PMU event] nmem0/host_l_dur/ [Kernel PMU event] nmem0/host_s_cnt/ [Kernel PMU event] nmem0/host_s_dur/ [Kernel PMU event] nmem0/med_r_cnt/ [Kernel PMU event] nmem0/med_r_dur/ [Kernel PMU event] nmem0/med_w_cnt/ [Kernel PMU event] nmem0/med_w_dur/ [Kernel PMU event] nmem0/mem_life/[Kernel PMU event] nmem0/poweron_secs/[Kernel PMU event] ... nmem1/mem_life/[Kernel PMU event] nmem1/poweron_secs/[Kernel PMU event] Signed-off-by: Kajol Jain --- arch/powerpc/include/asm/device.h | 5 + arch/powerpc/platforms/pseries/papr_scm.c | 225 ++ 2 files changed, 230 insertions(+) diff --git a/arch/powerpc/include/asm/device.h b/arch/powerpc/include/asm/device.h index 219559d65864..47ed639f3b8f 100644 --- a/arch/powerpc/include/asm/device.h +++ b/arch/powerpc/include/asm/device.h @@ -48,6 +48,11 @@ struct dev_archdata { struct pdev_archdata { u64 dma_mask; + /* +* Pointer to nvdimm_pmu structure, to handle the unregistering +* of pmu device +*/ + void *priv; }; #endif /* _ASM_POWERPC_DEVICE_H */ diff --git a/arch/powerpc/platforms/pseries/papr_scm.c b/arch/powerpc/platforms/pseries/papr_scm.c index f48e87ac89c9..bdf2620db461 100644 --- a/arch/powerpc/platforms/pseries/papr_scm.c +++ b/arch/powerpc/platforms/pseries/papr_scm.c @@ -19,6 +19,7 @@ #include #include #include +#include #define BIND_ANY_ADDR (~0ul) @@ -68,6 +69,8 @@ #define PAPR_SCM_PERF_STATS_EYECATCHER __stringify(SCMSTATS) #define PAPR_SCM_PERF_STATS_VERSION 0x1 +#define to_nvdimm_pmu(_pmu)container_of(_pmu, struct nvdimm_pmu, pmu) + /* Struct holding a single performance metric */ struct papr_scm_perf_stat { u8 stat_id[8]; @@ -120,6 +123,9 @@ struct papr_scm_priv { /* length of the stat buffer as expected by phyp */ size_t stat_buffer_len; + +/* array to have event_code and stat_id mappings */ + char **nvdimm_events_map; }; static int papr_scm_pmem_flush(struct nd_region *nd_region, @@ -340,6 +346,218 @@ static ssize_t drc_pmem_query_stats(struct papr_scm_priv *p, return 0; } +static int papr_scm_pmu_get_value(struct perf_event *event, struct device *dev, u64 *count) +{ + struct papr_scm_perf_stat *stat; + struct papr_scm_perf_stats *stats; + struct papr_scm_priv *p = (struct papr_scm_priv *)dev->driver_data; + int rc, size; + + /* Allocate request buffer enough to hold single performance stat */ + size = sizeof(struct papr_scm_perf_stats) + + sizeof(struct papr_scm_perf_stat); + + if (!p || !p->nvdimm_events_map) + return -EINVAL; + + stats = kzalloc(size, GFP_KERNEL); + if (!stats) + return -ENOMEM; + + stat = &stats->scm_statistic[0]; + memcpy(&stat->stat_id, + p->nvdimm_events_map[event->attr.config], + sizeof(stat->stat_id)); + stat->stat_val = 0; + + rc = drc_pmem_query_stats(p, stats, 1); + if (rc < 0) { + kfree(stats); + return rc; + } + + *count = be64_to_cpu(stat->stat_val); + kfree(stats); + return 0; +} + +static int papr_scm_pmu_event_init(struct perf_event *event) +{ + struct nvdimm_pmu *nd_pmu = to_nvdimm_pmu(event->pmu); +
[RESEND PATCH v5 4/4] docs: ABI: sysfs-bus-nvdimm: Document sysfs event format entries for nvdimm pmu
Details are added for the event, cpumask and format attributes in the ABI documentation. Signed-off-by: Kajol Jain --- Documentation/ABI/testing/sysfs-bus-nvdimm | 35 ++ 1 file changed, 35 insertions(+) diff --git a/Documentation/ABI/testing/sysfs-bus-nvdimm b/Documentation/ABI/testing/sysfs-bus-nvdimm index bff84a16812a..64004d5e4840 100644 --- a/Documentation/ABI/testing/sysfs-bus-nvdimm +++ b/Documentation/ABI/testing/sysfs-bus-nvdimm @@ -6,3 +6,38 @@ Description: The libnvdimm sub-system implements a common sysfs interface for platform nvdimm resources. See Documentation/driver-api/nvdimm/. + +What: /sys/bus/event_source/devices/nmemX/format +Date: September 2021 +KernelVersion: 5.16 +Contact:Kajol Jain +Description: (RO) Attribute group to describe the magic bits + that go into perf_event_attr.config for a particular pmu. + (See ABI/testing/sysfs-bus-event_source-devices-format). + + Each attribute under this group defines a bit range of the + perf_event_attr.config. Supported attribute is listed + below:: + event = "config:0-4" - event ID + + For example:: + ctl_res_cnt = "event=0x1" + +What: /sys/bus/event_source/devices/nmemX/events +Date: September 2021 +KernelVersion: 5.16 +Contact:Kajol Jain +Description: (RO) Attribute group to describe performance monitoring events +for the nvdimm memory device. Each attribute in this group +describes a single performance monitoring event supported by +this nvdimm pmu. The name of the file is the name of the event. +(See ABI/testing/sysfs-bus-event_source-devices-events). A +listing of the events supported by a given nvdimm provider type +can be found in Documentation/driver-api/nvdimm/$provider. + +What: /sys/bus/event_source/devices/nmemX/cpumask +Date: September 2021 +KernelVersion: 5.16 +Contact:Kajol Jain +Description: (RO) This sysfs file exposes the cpumask which is designated to + to retrieve nvdimm pmu event counter data. -- 2.26.2
[RESEND PATCH v5 1/4] drivers/nvdimm: Add nvdimm pmu structure
A structure is added called nvdimm_pmu, for performance stats reporting support of nvdimm devices. It can be used to add device pmu data such as pmu data structure for performance stats, nvdimm device pointer along with cpumask attributes. Signed-off-by: Kajol Jain --- include/linux/nd.h | 20 1 file changed, 20 insertions(+) diff --git a/include/linux/nd.h b/include/linux/nd.h index ee9ad76afbba..f5ed4db2d859 100644 --- a/include/linux/nd.h +++ b/include/linux/nd.h @@ -8,6 +8,7 @@ #include #include #include +#include enum nvdimm_event { NVDIMM_REVALIDATE_POISON, @@ -23,6 +24,25 @@ enum nvdimm_claim_class { NVDIMM_CCLASS_UNKNOWN, }; +/** + * struct nvdimm_pmu - data structure for nvdimm perf driver + * @pmu: pmu data structure for nvdimm performance stats. + * @dev: nvdimm device pointer. + * @cpu: designated cpu for counter access. + * @node: node for cpu hotplug notifier link. + * @cpuhp_state: state for cpu hotplug notification. + * @arch_cpumask: cpumask to get designated cpu for counter access. + */ +struct nvdimm_pmu { + struct pmu pmu; + struct device *dev; + int cpu; + struct hlist_node node; + enum cpuhp_state cpuhp_state; + /* cpumask provided by arch/platform specific code */ + struct cpumask arch_cpumask; +}; + struct nd_device_driver { struct device_driver drv; unsigned long type; -- 2.26.2
[RESEND PATCH v5 0/4] Add perf interface to expose nvdimm
Patchset adds performance stats reporting support for nvdimm. Added interface includes support for pmu register/unregister functions. A structure is added called nvdimm_pmu to be used for adding arch/platform specific data such as cpumask, nvdimm device pointer and pmu event functions like event_init/add/read/del. User could use the standard perf tool to access perf events exposed via pmu. Interface also defines supported event list, config fields for the event attributes and their corresponding bit values which are exported via sysfs. Patch 3 exposes IBM pseries platform nmem* device performance stats using this interface. Result from power9 pseries lpar with 2 nvdimm device: Ex: List all event by perf list command:# perf list nmem nmem0/cache_rh_cnt/[Kernel PMU event] nmem0/cache_wh_cnt/[Kernel PMU event] nmem0/cri_res_util/[Kernel PMU event] nmem0/ctl_res_cnt/ [Kernel PMU event] nmem0/ctl_res_tm/ [Kernel PMU event] nmem0/fast_w_cnt/ [Kernel PMU event] nmem0/host_l_cnt/ [Kernel PMU event] nmem0/host_l_dur/ [Kernel PMU event] nmem0/host_s_cnt/ [Kernel PMU event] nmem0/host_s_dur/ [Kernel PMU event] nmem0/med_r_cnt/ [Kernel PMU event] nmem0/med_r_dur/ [Kernel PMU event] nmem0/med_w_cnt/ [Kernel PMU event] nmem0/med_w_dur/ [Kernel PMU event] nmem0/mem_life/[Kernel PMU event] nmem0/poweron_secs/[Kernel PMU event] ... nmem1/mem_life/[Kernel PMU event] nmem1/poweron_secs/[Kernel PMU event] Patch1: Introduces the nvdimm_pmu structure Patch2: Adds common interface to add arch/platform specific data includes nvdimm device pointer, pmu data along with pmu event functions. It also defines supported event list and adds attribute groups for format, events and cpumask. It also adds code for cpu hotplug support. Patch3: Add code in arch/powerpc/platform/pseries/papr_scm.c to expose nmem* pmu. It fills in the nvdimm_pmu structure with pmu name, capabilities, cpumask and event functions and then registers the pmu by adding callbacks to register_nvdimm_pmu. Patch4: Sysfs documentation patch Changelog --- v4 -> v5: - Remove multiple variables defined in nvdimm_pmu structure include name and pmu functions(event_int/add/del/read) as they are just used to copy them again in pmu variable. Now we are directly doing this step in arch specific code as suggested by Dan Williams. - Remove attribute group field from nvdimm pmu structure and defined these attribute groups in common interface which includes format, event list along with cpumask as suggested by Dan Williams. Since we added static defination for attrbute groups needed in common interface, removes corresponding code from papr. - Add nvdimm pmu event list with event codes in the common interface. - Remove Acked-by/Reviewed-by/Tested-by tags as code is refactored to handle review comments from Dan. - Make nvdimm_pmu_free_hotplug_memory function static as reported by kernel test robot, also add corresponding Reported-by tag. - Link to the patchset v4: https://lkml.org/lkml/2021/9/3/45 v3 -> v4 - Rebase code on top of current papr_scm code without any logical changes. - Added Acked-by tag from Peter Zijlstra and Reviewed by tag from Madhavan Srinivasan. - Link to the patchset v3: https://lkml.org/lkml/2021/6/17/605 v2 -> v3 - Added Tested-by tag. - Fix nvdimm mailing list in the ABI Documentation. - Link to the patchset v2: https://lkml.org/lkml/2021/6/14/25 v1 -> v2 - Fix hotplug code by adding pmu migration call incase current designated cpu got offline. As pointed by Peter Zijlstra. - Removed the retun -1 part from cpu hotplug offline function. - Link to the patchset v1: https://lkml.org/lkml/2021/6/8/500 Kajol Jain (4): drivers/nvdimm: Add nvdimm pmu structure drivers/nvdimm: Add perf interface to expose nvdimm performance stats powerpc/papr_scm: Add perf interface support docs: ABI: sysfs-bus-nvdimm: Document sysfs event format entries for nvdimm pmu Documentation/ABI/testing/sysfs-bus-nvdimm | 35 +++ arch/powerpc/include/asm/device.h | 5 + arch/powerpc/platforms/pseries/papr_scm.c | 225 ++ drivers/nvdimm/Makefile| 1 + drivers/nvdimm/nd_perf.c | 328 + include/linux/nd.h
[PATCH v6 1/4] drivers/nvdimm: Add nvdimm pmu structure
A structure is added called nvdimm_pmu, for performance stats reporting support of nvdimm devices. It can be used to add device pmu data such as pmu data structure for performance stats, nvdimm device pointer along with cpumask attributes. Signed-off-by: Kajol Jain --- Changelog: Resend v5 -> v6 - No logic change, just a rebase to latest upstream and tested the patch. - Link to the patchset Resend v5: https://lkml.org/lkml/2021/11/15/3979 include/linux/nd.h | 20 1 file changed, 20 insertions(+) diff --git a/include/linux/nd.h b/include/linux/nd.h index 8a8c63edb1b2..ad186e828263 100644 --- a/include/linux/nd.h +++ b/include/linux/nd.h @@ -8,6 +8,7 @@ #include #include #include +#include enum nvdimm_event { NVDIMM_REVALIDATE_POISON, @@ -23,6 +24,25 @@ enum nvdimm_claim_class { NVDIMM_CCLASS_UNKNOWN, }; +/** + * struct nvdimm_pmu - data structure for nvdimm perf driver + * @pmu: pmu data structure for nvdimm performance stats. + * @dev: nvdimm device pointer. + * @cpu: designated cpu for counter access. + * @node: node for cpu hotplug notifier link. + * @cpuhp_state: state for cpu hotplug notification. + * @arch_cpumask: cpumask to get designated cpu for counter access. + */ +struct nvdimm_pmu { + struct pmu pmu; + struct device *dev; + int cpu; + struct hlist_node node; + enum cpuhp_state cpuhp_state; + /* cpumask provided by arch/platform specific code */ + struct cpumask arch_cpumask; +}; + struct nd_device_driver { struct device_driver drv; unsigned long type; -- 2.31.1
[PATCH v6 0/4] Add perf interface to expose nvdimm
Patchset adds performance stats reporting support for nvdimm. Added interface includes support for pmu register/unregister functions. A structure is added called nvdimm_pmu to be used for adding arch/platform specific data such as cpumask, nvdimm device pointer and pmu event functions like event_init/add/read/del. User could use the standard perf tool to access perf events exposed via pmu. Interface also defines supported event list, config fields for the event attributes and their corresponding bit values which are exported via sysfs. Patch 3 exposes IBM pseries platform nmem* device performance stats using this interface. Result from power9 pseries lpar with 2 nvdimm device: Ex: List all event by perf list command:# perf list nmem nmem0/cache_rh_cnt/[Kernel PMU event] nmem0/cache_wh_cnt/[Kernel PMU event] nmem0/cri_res_util/[Kernel PMU event] nmem0/ctl_res_cnt/ [Kernel PMU event] nmem0/ctl_res_tm/ [Kernel PMU event] nmem0/fast_w_cnt/ [Kernel PMU event] nmem0/host_l_cnt/ [Kernel PMU event] nmem0/host_l_dur/ [Kernel PMU event] nmem0/host_s_cnt/ [Kernel PMU event] nmem0/host_s_dur/ [Kernel PMU event] nmem0/med_r_cnt/ [Kernel PMU event] nmem0/med_r_dur/ [Kernel PMU event] nmem0/med_w_cnt/ [Kernel PMU event] nmem0/med_w_dur/ [Kernel PMU event] nmem0/mem_life/[Kernel PMU event] nmem0/poweron_secs/[Kernel PMU event] ... nmem1/mem_life/[Kernel PMU event] nmem1/poweron_secs/[Kernel PMU event] Patch1: Introduces the nvdimm_pmu structure Patch2: Adds common interface to add arch/platform specific data includes nvdimm device pointer, pmu data along with pmu event functions. It also defines supported event list and adds attribute groups for format, events and cpumask. It also adds code for cpu hotplug support. Patch3: Add code in arch/powerpc/platform/pseries/papr_scm.c to expose nmem* pmu. It fills in the nvdimm_pmu structure with pmu name, capabilities, cpumask and event functions and then registers the pmu by adding callbacks to register_nvdimm_pmu. Patch4: Sysfs documentation patch Changelog --- Resend v5 -> v6 - No logic change, just a rebase to latest upstream and tested the patchset. - Link to the patchset Resend v5: https://lkml.org/lkml/2021/11/15/3979 v5 -> Resend v5 - Resend the patchset - Link to the patchset v5: https://lkml.org/lkml/2021/9/28/643 v4 -> v5: - Remove multiple variables defined in nvdimm_pmu structure include name and pmu functions(event_int/add/del/read) as they are just used to copy them again in pmu variable. Now we are directly doing this step in arch specific code as suggested by Dan Williams. - Remove attribute group field from nvdimm pmu structure and defined these attribute groups in common interface which includes format, event list along with cpumask as suggested by Dan Williams. Since we added static defination for attrbute groups needed in common interface, removes corresponding code from papr. - Add nvdimm pmu event list with event codes in the common interface. - Remove Acked-by/Reviewed-by/Tested-by tags as code is refactored to handle review comments from Dan. - Make nvdimm_pmu_free_hotplug_memory function static as reported by kernel test robot, also add corresponding Reported-by tag. - Link to the patchset v4: https://lkml.org/lkml/2021/9/3/45 v3 -> v4 - Rebase code on top of current papr_scm code without any logical changes. - Added Acked-by tag from Peter Zijlstra and Reviewed by tag from Madhavan Srinivasan. - Link to the patchset v3: https://lkml.org/lkml/2021/6/17/605 v2 -> v3 - Added Tested-by tag. - Fix nvdimm mailing list in the ABI Documentation. - Link to the patchset v2: https://lkml.org/lkml/2021/6/14/25 v1 -> v2 - Fix hotplug code by adding pmu migration call incase current designated cpu got offline. As pointed by Peter Zijlstra. - Removed the retun -1 part from cpu hotplug offline function. - Link to the patchset v1: https://lkml.org/lkml/2021/6/8/500 Kajol Jain (4): drivers/nvdimm: Add nvdimm pmu structure drivers/nvdimm: Add perf interface to expose nvdimm performance stats powerpc/papr_scm: Add perf interface support docs: ABI: sysfs-bus-nvdimm: Document sysfs event format entries for nvdimm pmu Documentation/ABI/testing/sysfs-bus-nvdimm | 35 +++ arch/p
[PATCH v6 4/4] docs: ABI: sysfs-bus-nvdimm: Document sysfs event format entries for nvdimm pmu
Details are added for the event, cpumask and format attributes in the ABI documentation. Signed-off-by: Kajol Jain --- Changelog: Resend v5 -> v6 - No logic change, just a rebase to latest upstream. - Link to the patchset Resend v5: https://lkml.org/lkml/2021/11/15/3979 Documentation/ABI/testing/sysfs-bus-nvdimm | 35 ++ 1 file changed, 35 insertions(+) diff --git a/Documentation/ABI/testing/sysfs-bus-nvdimm b/Documentation/ABI/testing/sysfs-bus-nvdimm index bff84a16812a..64004d5e4840 100644 --- a/Documentation/ABI/testing/sysfs-bus-nvdimm +++ b/Documentation/ABI/testing/sysfs-bus-nvdimm @@ -6,3 +6,38 @@ Description: The libnvdimm sub-system implements a common sysfs interface for platform nvdimm resources. See Documentation/driver-api/nvdimm/. + +What: /sys/bus/event_source/devices/nmemX/format +Date: February 2022 +KernelVersion: 5.18 +Contact: Kajol Jain +Description: (RO) Attribute group to describe the magic bits + that go into perf_event_attr.config for a particular pmu. + (See ABI/testing/sysfs-bus-event_source-devices-format). + + Each attribute under this group defines a bit range of the + perf_event_attr.config. Supported attribute is listed + below:: + event = "config:0-4" - event ID + + For example:: + ctl_res_cnt = "event=0x1" + +What: /sys/bus/event_source/devices/nmemX/events +Date: February 2022 +KernelVersion: 5.18 +Contact:Kajol Jain +Description: (RO) Attribute group to describe performance monitoring events +for the nvdimm memory device. Each attribute in this group +describes a single performance monitoring event supported by +this nvdimm pmu. The name of the file is the name of the event. +(See ABI/testing/sysfs-bus-event_source-devices-events). A +listing of the events supported by a given nvdimm provider type +can be found in Documentation/driver-api/nvdimm/$provider. + +What: /sys/bus/event_source/devices/nmemX/cpumask +Date: February 2022 +KernelVersion: 5.18 +Contact:Kajol Jain +Description: (RO) This sysfs file exposes the cpumask which is designated to + to retrieve nvdimm pmu event counter data. -- 2.31.1
[PATCH v6 3/4] powerpc/papr_scm: Add perf interface support
Performance monitoring support for papr-scm nvdimm devices via perf interface is added which includes addition of pmu functions like add/del/read/event_init for nvdimm_pmu struture. A new parameter 'priv' in added to the pdev_archdata structure to save nvdimm_pmu device pointer, to handle the unregistering of pmu device. papr_scm_pmu_register function populates the nvdimm_pmu structure with name, capabilities, cpumask along with event handling functions. Finally the populated nvdimm_pmu structure is passed to register the pmu device. Event handling functions internally uses hcall to get events and counter data. Result in power9 machine with 2 nvdimm device: Ex: List all event by perf list command:# perf list nmem nmem0/cache_rh_cnt/[Kernel PMU event] nmem0/cache_wh_cnt/[Kernel PMU event] nmem0/cri_res_util/[Kernel PMU event] nmem0/ctl_res_cnt/ [Kernel PMU event] nmem0/ctl_res_tm/ [Kernel PMU event] nmem0/fast_w_cnt/ [Kernel PMU event] nmem0/host_l_cnt/ [Kernel PMU event] nmem0/host_l_dur/ [Kernel PMU event] nmem0/host_s_cnt/ [Kernel PMU event] nmem0/host_s_dur/ [Kernel PMU event] nmem0/med_r_cnt/ [Kernel PMU event] nmem0/med_r_dur/ [Kernel PMU event] nmem0/med_w_cnt/ [Kernel PMU event] nmem0/med_w_dur/ [Kernel PMU event] nmem0/mem_life/[Kernel PMU event] nmem0/poweron_secs/[Kernel PMU event] ... nmem1/mem_life/[Kernel PMU event] nmem1/poweron_secs/[Kernel PMU event] Signed-off-by: Kajol Jain --- Changelog: Resend v5 -> v6 - No logic change, just a rebase to latest upstream and tested the patch. - Link to the patchset Resend v5: https://lkml.org/lkml/2021/11/15/3979 arch/powerpc/include/asm/device.h | 5 + arch/powerpc/platforms/pseries/papr_scm.c | 225 ++ 2 files changed, 230 insertions(+) diff --git a/arch/powerpc/include/asm/device.h b/arch/powerpc/include/asm/device.h index 219559d65864..47ed639f3b8f 100644 --- a/arch/powerpc/include/asm/device.h +++ b/arch/powerpc/include/asm/device.h @@ -48,6 +48,11 @@ struct dev_archdata { struct pdev_archdata { u64 dma_mask; + /* +* Pointer to nvdimm_pmu structure, to handle the unregistering +* of pmu device +*/ + void *priv; }; #endif /* _ASM_POWERPC_DEVICE_H */ diff --git a/arch/powerpc/platforms/pseries/papr_scm.c b/arch/powerpc/platforms/pseries/papr_scm.c index f48e87ac89c9..bdf2620db461 100644 --- a/arch/powerpc/platforms/pseries/papr_scm.c +++ b/arch/powerpc/platforms/pseries/papr_scm.c @@ -19,6 +19,7 @@ #include #include #include +#include #define BIND_ANY_ADDR (~0ul) @@ -68,6 +69,8 @@ #define PAPR_SCM_PERF_STATS_EYECATCHER __stringify(SCMSTATS) #define PAPR_SCM_PERF_STATS_VERSION 0x1 +#define to_nvdimm_pmu(_pmu)container_of(_pmu, struct nvdimm_pmu, pmu) + /* Struct holding a single performance metric */ struct papr_scm_perf_stat { u8 stat_id[8]; @@ -120,6 +123,9 @@ struct papr_scm_priv { /* length of the stat buffer as expected by phyp */ size_t stat_buffer_len; + +/* array to have event_code and stat_id mappings */ + char **nvdimm_events_map; }; static int papr_scm_pmem_flush(struct nd_region *nd_region, @@ -340,6 +346,218 @@ static ssize_t drc_pmem_query_stats(struct papr_scm_priv *p, return 0; } +static int papr_scm_pmu_get_value(struct perf_event *event, struct device *dev, u64 *count) +{ + struct papr_scm_perf_stat *stat; + struct papr_scm_perf_stats *stats; + struct papr_scm_priv *p = (struct papr_scm_priv *)dev->driver_data; + int rc, size; + + /* Allocate request buffer enough to hold single performance stat */ + size = sizeof(struct papr_scm_perf_stats) + + sizeof(struct papr_scm_perf_stat); + + if (!p || !p->nvdimm_events_map) + return -EINVAL; + + stats = kzalloc(size, GFP_KERNEL); + if (!stats) + return -ENOMEM; + + stat = &stats->scm_statistic[0]; + memcpy(&stat->stat_id, + p->nvdimm_events_map[event->attr.config], + sizeof(stat->stat_id)); + stat->stat_val = 0; + + rc = drc_pmem_query_stats(p, stats, 1); + if (rc < 0) { + kfree(stats); + return rc; + } + + *count = be64_to_cpu(stat->stat_val); +
[PATCH v6 2/4] drivers/nvdimm: Add perf interface to expose nvdimm performance stats
A common interface is added to get performance stats reporting support for nvdimm devices. Added interface defines supported event list, config fields for the event attributes and their corresponding bit values which are exported via sysfs. Interface also added support for pmu register/unregister functions, cpu hotplug feature along with macros for handling events addition via sysfs. It adds attribute groups for format, cpumask and events to the pmu structure. User could use the standard perf tool to access perf events exposed via nvdimm pmu. Signed-off-by: Kajol Jain [Make hotplug function static as reported by kernel test rorbot] Reported-by: kernel test robot --- Changelog: Resend v5 -> v6 - No logic change, just a rebase to latest upstream and tested the patch. - Link to the patchset Resend v5: https://lkml.org/lkml/2021/11/15/3979 drivers/nvdimm/Makefile | 1 + drivers/nvdimm/nd_perf.c | 328 +++ include/linux/nd.h | 21 +++ 3 files changed, 350 insertions(+) create mode 100644 drivers/nvdimm/nd_perf.c diff --git a/drivers/nvdimm/Makefile b/drivers/nvdimm/Makefile index 29203f3d3069..25dba6095612 100644 --- a/drivers/nvdimm/Makefile +++ b/drivers/nvdimm/Makefile @@ -18,6 +18,7 @@ nd_e820-y := e820.o libnvdimm-y := core.o libnvdimm-y += bus.o libnvdimm-y += dimm_devs.o +libnvdimm-y += nd_perf.o libnvdimm-y += dimm.o libnvdimm-y += region_devs.o libnvdimm-y += region.o diff --git a/drivers/nvdimm/nd_perf.c b/drivers/nvdimm/nd_perf.c new file mode 100644 index ..314415894acf --- /dev/null +++ b/drivers/nvdimm/nd_perf.c @@ -0,0 +1,328 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * nd_perf.c: NVDIMM Device Performance Monitoring Unit support + * + * Perf interface to expose nvdimm performance stats. + * + * Copyright (C) 2021 IBM Corporation + */ + +#define pr_fmt(fmt) "nvdimm_pmu: " fmt + +#include + +#define EVENT(_name, _code) enum{_name = _code} + +/* + * NVDIMM Events codes. + */ + +/* Controller Reset Count */ +EVENT(CTL_RES_CNT, 0x1); +/* Controller Reset Elapsed Time */ +EVENT(CTL_RES_TM, 0x2); +/* Power-on Seconds */ +EVENT(POWERON_SECS,0x3); +/* Life Remaining */ +EVENT(MEM_LIFE,0x4); +/* Critical Resource Utilization */ +EVENT(CRI_RES_UTIL,0x5); +/* Host Load Count */ +EVENT(HOST_L_CNT, 0x6); +/* Host Store Count */ +EVENT(HOST_S_CNT, 0x7); +/* Host Store Duration */ +EVENT(HOST_S_DUR, 0x8); +/* Host Load Duration */ +EVENT(HOST_L_DUR, 0x9); +/* Media Read Count */ +EVENT(MED_R_CNT, 0xa); +/* Media Write Count */ +EVENT(MED_W_CNT, 0xb); +/* Media Read Duration */ +EVENT(MED_R_DUR, 0xc); +/* Media Write Duration */ +EVENT(MED_W_DUR, 0xd); +/* Cache Read Hit Count */ +EVENT(CACHE_RH_CNT,0xe); +/* Cache Write Hit Count */ +EVENT(CACHE_WH_CNT,0xf); +/* Fast Write Count */ +EVENT(FAST_W_CNT, 0x10); + +NVDIMM_EVENT_ATTR(ctl_res_cnt, CTL_RES_CNT); +NVDIMM_EVENT_ATTR(ctl_res_tm, CTL_RES_TM); +NVDIMM_EVENT_ATTR(poweron_secs,POWERON_SECS); +NVDIMM_EVENT_ATTR(mem_life,MEM_LIFE); +NVDIMM_EVENT_ATTR(cri_res_util,CRI_RES_UTIL); +NVDIMM_EVENT_ATTR(host_l_cnt, HOST_L_CNT); +NVDIMM_EVENT_ATTR(host_s_cnt, HOST_S_CNT); +NVDIMM_EVENT_ATTR(host_s_dur, HOST_S_DUR); +NVDIMM_EVENT_ATTR(host_l_dur, HOST_L_DUR); +NVDIMM_EVENT_ATTR(med_r_cnt, MED_R_CNT); +NVDIMM_EVENT_ATTR(med_w_cnt, MED_W_CNT); +NVDIMM_EVENT_ATTR(med_r_dur, MED_R_DUR); +NVDIMM_EVENT_ATTR(med_w_dur, MED_W_DUR); +NVDIMM_EVENT_ATTR(cache_rh_cnt,CACHE_RH_CNT); +NVDIMM_EVENT_ATTR(cache_wh_cnt,CACHE_WH_CNT); +NVDIMM_EVENT_ATTR(fast_w_cnt, FAST_W_CNT); + +static struct attribute *nvdimm_events_attr[] = { + NVDIMM_EVENT_PTR(CTL_RES_CNT), + NVDIMM_EVENT_PTR(CTL_RES_TM), + NVDIMM_EVENT_PTR(POWERON_SECS), + NVDIMM_EVENT_PTR(MEM_LIFE), + NVDIMM_EVENT_PTR(CRI_RES_UTIL), + NVDIMM_EVENT_PTR(HOST_L_CNT), + NVDIMM_EVENT_PTR(HOST_S_CNT), + NVDIMM_EVENT_PTR(HOST_S_DUR), + NVDIMM_EVENT_PTR(HOST_L_DUR), + NVDIMM_EVENT_PTR(MED_R_CNT), + NVDIMM_EVENT_PTR(MED_W_CNT), + NVDIMM_EVENT_PTR(MED_R_DUR), + NVDIMM_EVENT_PTR(MED_W_DUR), + NVDIMM_EVENT_PTR(CACHE_RH_CNT), + NVDIMM_EVENT_PTR(CACHE_WH_CNT), + NVDIMM_EVENT_PTR(FAST_W_CNT), + NULL +}; + +static struct attribute_group nvdimm_pmu_events_group = { + .name = "events", + .attrs = nvdimm_events_attr, +}; + +PMU_FORMAT_ATTR(event, "config:0-4"); + +static struct attribute *nvdimm_pmu_format_attr[] = { + &format_attr_event.attr, + NULL, +}; + +static struct attribute_group nvdimm_pmu_for
[PATCH v7 1/4] drivers/nvdimm: Add nvdimm pmu structure
A structure is added called nvdimm_pmu, for performance stats reporting support of nvdimm devices. It can be used to add device pmu data such as pmu data structure for performance stats, nvdimm device pointer along with cpumask attributes. Acked-by: Peter Zijlstra (Intel) Tested-by: Nageswara R Sastry Signed-off-by: Kajol Jain --- Changelog: v6 -> v7 - Add Acked-by and Tested-by tag from Peter Zijlstra and Nageswara R Sastry. include/linux/nd.h | 20 1 file changed, 20 insertions(+) diff --git a/include/linux/nd.h b/include/linux/nd.h index 8a8c63edb1b2..ad186e828263 100644 --- a/include/linux/nd.h +++ b/include/linux/nd.h @@ -8,6 +8,7 @@ #include #include #include +#include enum nvdimm_event { NVDIMM_REVALIDATE_POISON, @@ -23,6 +24,25 @@ enum nvdimm_claim_class { NVDIMM_CCLASS_UNKNOWN, }; +/** + * struct nvdimm_pmu - data structure for nvdimm perf driver + * @pmu: pmu data structure for nvdimm performance stats. + * @dev: nvdimm device pointer. + * @cpu: designated cpu for counter access. + * @node: node for cpu hotplug notifier link. + * @cpuhp_state: state for cpu hotplug notification. + * @arch_cpumask: cpumask to get designated cpu for counter access. + */ +struct nvdimm_pmu { + struct pmu pmu; + struct device *dev; + int cpu; + struct hlist_node node; + enum cpuhp_state cpuhp_state; + /* cpumask provided by arch/platform specific code */ + struct cpumask arch_cpumask; +}; + struct nd_device_driver { struct device_driver drv; unsigned long type; -- 2.31.1
[PATCH v7 2/4] drivers/nvdimm: Add perf interface to expose nvdimm performance stats
A common interface is added to get performance stats reporting support for nvdimm devices. Added interface defines supported event list, config fields for the event attributes and their corresponding bit values which are exported via sysfs. Interface also added support for pmu register/unregister functions, cpu hotplug feature along with macros for handling events addition via sysfs. It adds attribute groups for format, cpumask and events to the pmu structure. User could use the standard perf tool to access perf events exposed via nvdimm pmu. Acked-by: Peter Zijlstra (Intel) Tested-by: Nageswara R Sastry Signed-off-by: Kajol Jain [Declare pmu functions in nd.h file to resolve implicit-function-declaration warning and make hotplug function static as reported by kernel test robot] Link: https://lore.kernel.org/all/202202241242.zqzgkguy-...@intel.com/ Reported-by: kernel test robot --- Changelog: v6 -> v7 - Add function declaration of perf_pmu_register, perf_pmu_unregister and perf_pmu_migrate_context functions in nd.h file to resolve the implicit-function-declaration warning as reported by kernel test robot. - Add Acked-by and Tested-by tag from Peter Zijlstra and Nageswara R Sastry. drivers/nvdimm/Makefile | 1 + drivers/nvdimm/nd_perf.c | 328 +++ include/linux/nd.h | 24 +++ 3 files changed, 353 insertions(+) create mode 100644 drivers/nvdimm/nd_perf.c diff --git a/drivers/nvdimm/Makefile b/drivers/nvdimm/Makefile index 29203f3d3069..25dba6095612 100644 --- a/drivers/nvdimm/Makefile +++ b/drivers/nvdimm/Makefile @@ -18,6 +18,7 @@ nd_e820-y := e820.o libnvdimm-y := core.o libnvdimm-y += bus.o libnvdimm-y += dimm_devs.o +libnvdimm-y += nd_perf.o libnvdimm-y += dimm.o libnvdimm-y += region_devs.o libnvdimm-y += region.o diff --git a/drivers/nvdimm/nd_perf.c b/drivers/nvdimm/nd_perf.c new file mode 100644 index ..314415894acf --- /dev/null +++ b/drivers/nvdimm/nd_perf.c @@ -0,0 +1,328 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * nd_perf.c: NVDIMM Device Performance Monitoring Unit support + * + * Perf interface to expose nvdimm performance stats. + * + * Copyright (C) 2021 IBM Corporation + */ + +#define pr_fmt(fmt) "nvdimm_pmu: " fmt + +#include + +#define EVENT(_name, _code) enum{_name = _code} + +/* + * NVDIMM Events codes. + */ + +/* Controller Reset Count */ +EVENT(CTL_RES_CNT, 0x1); +/* Controller Reset Elapsed Time */ +EVENT(CTL_RES_TM, 0x2); +/* Power-on Seconds */ +EVENT(POWERON_SECS,0x3); +/* Life Remaining */ +EVENT(MEM_LIFE,0x4); +/* Critical Resource Utilization */ +EVENT(CRI_RES_UTIL,0x5); +/* Host Load Count */ +EVENT(HOST_L_CNT, 0x6); +/* Host Store Count */ +EVENT(HOST_S_CNT, 0x7); +/* Host Store Duration */ +EVENT(HOST_S_DUR, 0x8); +/* Host Load Duration */ +EVENT(HOST_L_DUR, 0x9); +/* Media Read Count */ +EVENT(MED_R_CNT, 0xa); +/* Media Write Count */ +EVENT(MED_W_CNT, 0xb); +/* Media Read Duration */ +EVENT(MED_R_DUR, 0xc); +/* Media Write Duration */ +EVENT(MED_W_DUR, 0xd); +/* Cache Read Hit Count */ +EVENT(CACHE_RH_CNT,0xe); +/* Cache Write Hit Count */ +EVENT(CACHE_WH_CNT,0xf); +/* Fast Write Count */ +EVENT(FAST_W_CNT, 0x10); + +NVDIMM_EVENT_ATTR(ctl_res_cnt, CTL_RES_CNT); +NVDIMM_EVENT_ATTR(ctl_res_tm, CTL_RES_TM); +NVDIMM_EVENT_ATTR(poweron_secs,POWERON_SECS); +NVDIMM_EVENT_ATTR(mem_life,MEM_LIFE); +NVDIMM_EVENT_ATTR(cri_res_util,CRI_RES_UTIL); +NVDIMM_EVENT_ATTR(host_l_cnt, HOST_L_CNT); +NVDIMM_EVENT_ATTR(host_s_cnt, HOST_S_CNT); +NVDIMM_EVENT_ATTR(host_s_dur, HOST_S_DUR); +NVDIMM_EVENT_ATTR(host_l_dur, HOST_L_DUR); +NVDIMM_EVENT_ATTR(med_r_cnt, MED_R_CNT); +NVDIMM_EVENT_ATTR(med_w_cnt, MED_W_CNT); +NVDIMM_EVENT_ATTR(med_r_dur, MED_R_DUR); +NVDIMM_EVENT_ATTR(med_w_dur, MED_W_DUR); +NVDIMM_EVENT_ATTR(cache_rh_cnt,CACHE_RH_CNT); +NVDIMM_EVENT_ATTR(cache_wh_cnt,CACHE_WH_CNT); +NVDIMM_EVENT_ATTR(fast_w_cnt, FAST_W_CNT); + +static struct attribute *nvdimm_events_attr[] = { + NVDIMM_EVENT_PTR(CTL_RES_CNT), + NVDIMM_EVENT_PTR(CTL_RES_TM), + NVDIMM_EVENT_PTR(POWERON_SECS), + NVDIMM_EVENT_PTR(MEM_LIFE), + NVDIMM_EVENT_PTR(CRI_RES_UTIL), + NVDIMM_EVENT_PTR(HOST_L_CNT), + NVDIMM_EVENT_PTR(HOST_S_CNT), + NVDIMM_EVENT_PTR(HOST_S_DUR), + NVDIMM_EVENT_PTR(HOST_L_DUR), + NVDIMM_EVENT_PTR(MED_R_CNT), + NVDIMM_EVENT_PTR(MED_W_CNT), + NVDIMM_EVENT_PTR(MED_R_DUR), + NVDIMM_EVENT_PTR(MED_W_DUR), + NVDIMM_EVENT_PTR(CACHE_RH_CNT), + NVDIMM_EVENT_PTR(CACHE_WH_CNT), + NVDIMM_EVENT_PTR(FAST_W_CNT), + NULL +}; + +
[PATCH v7 0/4] Add perf interface to expose nvdimm
tag. - Fix nvdimm mailing list in the ABI Documentation. - Link to the patchset v2: https://lkml.org/lkml/2021/6/14/25 v1 -> v2 - Fix hotplug code by adding pmu migration call incase current designated cpu got offline. As pointed by Peter Zijlstra. - Removed the retun -1 part from cpu hotplug offline function. - Link to the patchset v1: https://lkml.org/lkml/2021/6/8/500 Kajol Jain (4): drivers/nvdimm: Add nvdimm pmu structure drivers/nvdimm: Add perf interface to expose nvdimm performance stats powerpc/papr_scm: Add perf interface support docs: ABI: sysfs-bus-nvdimm: Document sysfs event format entries for nvdimm pmu Documentation/ABI/testing/sysfs-bus-nvdimm | 35 +++ arch/powerpc/include/asm/device.h | 5 + arch/powerpc/platforms/pseries/papr_scm.c | 225 ++ drivers/nvdimm/Makefile| 1 + drivers/nvdimm/nd_perf.c | 328 + include/linux/nd.h | 44 +++ 6 files changed, 638 insertions(+) create mode 100644 drivers/nvdimm/nd_perf.c -- 2.31.1
[PATCH v7 3/4] powerpc/papr_scm: Add perf interface support
Performance monitoring support for papr-scm nvdimm devices via perf interface is added which includes addition of pmu functions like add/del/read/event_init for nvdimm_pmu struture. A new parameter 'priv' in added to the pdev_archdata structure to save nvdimm_pmu device pointer, to handle the unregistering of pmu device. papr_scm_pmu_register function populates the nvdimm_pmu structure with name, capabilities, cpumask along with event handling functions. Finally the populated nvdimm_pmu structure is passed to register the pmu device. Event handling functions internally uses hcall to get events and counter data. Result in power9 machine with 2 nvdimm device: Ex: List all event by perf list command:# perf list nmem nmem0/cache_rh_cnt/[Kernel PMU event] nmem0/cache_wh_cnt/[Kernel PMU event] nmem0/cri_res_util/[Kernel PMU event] nmem0/ctl_res_cnt/ [Kernel PMU event] nmem0/ctl_res_tm/ [Kernel PMU event] nmem0/fast_w_cnt/ [Kernel PMU event] nmem0/host_l_cnt/ [Kernel PMU event] nmem0/host_l_dur/ [Kernel PMU event] nmem0/host_s_cnt/ [Kernel PMU event] nmem0/host_s_dur/ [Kernel PMU event] nmem0/med_r_cnt/ [Kernel PMU event] nmem0/med_r_dur/ [Kernel PMU event] nmem0/med_w_cnt/ [Kernel PMU event] nmem0/med_w_dur/ [Kernel PMU event] nmem0/mem_life/[Kernel PMU event] nmem0/poweron_secs/[Kernel PMU event] ... nmem1/mem_life/[Kernel PMU event] nmem1/poweron_secs/[Kernel PMU event] Acked-by: Peter Zijlstra (Intel) Tested-by: Nageswara R Sastry Signed-off-by: Kajol Jain [Add numa_map_to_online_node function call to get online node id] Reported-by: Nageswara R Sastry --- Changelog: Resend v6 -> v7 - Add function call to numa_map_to_online_node function inorder to get online numa node. As the node id returned by function dev_to_node can be offline in some scenarios and create issue in hotplug code. - Add Acked-by, Tested-by and Reported-by tags from Peter Zijlstra and Nageswara R Sastry. arch/powerpc/include/asm/device.h | 5 + arch/powerpc/platforms/pseries/papr_scm.c | 225 ++ 2 files changed, 230 insertions(+) diff --git a/arch/powerpc/include/asm/device.h b/arch/powerpc/include/asm/device.h index 219559d65864..47ed639f3b8f 100644 --- a/arch/powerpc/include/asm/device.h +++ b/arch/powerpc/include/asm/device.h @@ -48,6 +48,11 @@ struct dev_archdata { struct pdev_archdata { u64 dma_mask; + /* +* Pointer to nvdimm_pmu structure, to handle the unregistering +* of pmu device +*/ + void *priv; }; #endif /* _ASM_POWERPC_DEVICE_H */ diff --git a/arch/powerpc/platforms/pseries/papr_scm.c b/arch/powerpc/platforms/pseries/papr_scm.c index f48e87ac89c9..4dd513d7c029 100644 --- a/arch/powerpc/platforms/pseries/papr_scm.c +++ b/arch/powerpc/platforms/pseries/papr_scm.c @@ -19,6 +19,7 @@ #include #include #include +#include #define BIND_ANY_ADDR (~0ul) @@ -68,6 +69,8 @@ #define PAPR_SCM_PERF_STATS_EYECATCHER __stringify(SCMSTATS) #define PAPR_SCM_PERF_STATS_VERSION 0x1 +#define to_nvdimm_pmu(_pmu)container_of(_pmu, struct nvdimm_pmu, pmu) + /* Struct holding a single performance metric */ struct papr_scm_perf_stat { u8 stat_id[8]; @@ -120,6 +123,9 @@ struct papr_scm_priv { /* length of the stat buffer as expected by phyp */ size_t stat_buffer_len; + +/* array to have event_code and stat_id mappings */ + char **nvdimm_events_map; }; static int papr_scm_pmem_flush(struct nd_region *nd_region, @@ -340,6 +346,218 @@ static ssize_t drc_pmem_query_stats(struct papr_scm_priv *p, return 0; } +static int papr_scm_pmu_get_value(struct perf_event *event, struct device *dev, u64 *count) +{ + struct papr_scm_perf_stat *stat; + struct papr_scm_perf_stats *stats; + struct papr_scm_priv *p = (struct papr_scm_priv *)dev->driver_data; + int rc, size; + + /* Allocate request buffer enough to hold single performance stat */ + size = sizeof(struct papr_scm_perf_stats) + + sizeof(struct papr_scm_perf_stat); + + if (!p || !p->nvdimm_events_map) + return -EINVAL; + + stats = kzalloc(size, GFP_KERNEL); + if (!stats) + return -ENOMEM; + + stat = &stats->scm_statistic[0]; + memcpy(&stat->stat_id, + p->
[PATCH v7 4/4] docs: ABI: sysfs-bus-nvdimm: Document sysfs event format entries for nvdimm pmu
Details are added for the event, cpumask and format attributes in the ABI documentation. Acked-by: Peter Zijlstra (Intel) Tested-by: Nageswara R Sastry Signed-off-by: Kajol Jain --- Changelog: v6 -> v7 - Add Acked-by and Tested-by tag from Peter Zijlstra and Nageswara R Sastry. Documentation/ABI/testing/sysfs-bus-nvdimm | 35 ++ 1 file changed, 35 insertions(+) diff --git a/Documentation/ABI/testing/sysfs-bus-nvdimm b/Documentation/ABI/testing/sysfs-bus-nvdimm index bff84a16812a..1c1f5acbf53d 100644 --- a/Documentation/ABI/testing/sysfs-bus-nvdimm +++ b/Documentation/ABI/testing/sysfs-bus-nvdimm @@ -6,3 +6,38 @@ Description: The libnvdimm sub-system implements a common sysfs interface for platform nvdimm resources. See Documentation/driver-api/nvdimm/. + +What: /sys/bus/event_source/devices/nmemX/format +Date: February 2022 +KernelVersion: 5.18 +Contact: Kajol Jain +Description: (RO) Attribute group to describe the magic bits + that go into perf_event_attr.config for a particular pmu. + (See ABI/testing/sysfs-bus-event_source-devices-format). + + Each attribute under this group defines a bit range of the + perf_event_attr.config. Supported attribute is listed + below:: + event = "config:0-4" - event ID + + For example:: + ctl_res_cnt = "event=0x1" + +What: /sys/bus/event_source/devices/nmemX/events +Date: February 2022 +KernelVersion: 5.18 +Contact:Kajol Jain +Description: (RO) Attribute group to describe performance monitoring events +for the nvdimm memory device. Each attribute in this group +describes a single performance monitoring event supported by +this nvdimm pmu. The name of the file is the name of the event. +(See ABI/testing/sysfs-bus-event_source-devices-events). A +listing of the events supported by a given nvdimm provider type +can be found in Documentation/driver-api/nvdimm/$provider. + +What: /sys/bus/event_source/devices/nmemX/cpumask +Date: February 2022 +KernelVersion: 5.18 +Contact:Kajol Jain +Description: (RO) This sysfs file exposes the cpumask which is designated to + to retrieve nvdimm pmu event counter data. -- 2.31.1
[PATCH 1/2] drivers/nvdimm: Fix build failure when CONFIG_PERF_EVENTS is not set
The following build failure occures when CONFIG_PERF_EVENTS is not set as generic pmu functions are not visible in that scenario. |-- s390-randconfig-r044-20220313 | |-- nd_perf.c:(.text):undefined-reference-to-perf_pmu_migrate_context | |-- nd_perf.c:(.text):undefined-reference-to-perf_pmu_register | `-- nd_perf.c:(.text):undefined-reference-to-perf_pmu_unregister Similar build failure in nds32 architecture: nd_perf.c:(.text+0x21e): undefined reference to `perf_pmu_migrate_context' nd_perf.c:(.text+0x434): undefined reference to `perf_pmu_register' nd_perf.c:(.text+0x57c): undefined reference to `perf_pmu_unregister' Fix this issue by adding check for CONFIG_PERF_EVENTS config option and disabling the nvdimm perf interface incase this config is not set. Also removed function declaration of perf_pmu_migrate_context, perf_pmu_register, perf_pmu_unregister functions from nd.h as these are common pmu functions which are part of perf_event.h and since we are disabling nvdimm perf interface incase CONFIG_PERF_EVENTS option is not set, we not need to declare them in nd.h Fixes: 0fab1ba6ad6b ("drivers/nvdimm: Add perf interface to expose nvdimm performance stats") (Commit id based on linux-next tree) Signed-off-by: Kajol Jain Link: https://lore.kernel.org/all/62317124.ybqfu33+s%2fwdvwgj%25...@intel.com/ Reported-by: kernel test robot --- drivers/nvdimm/Makefile | 2 +- include/linux/nd.h | 7 --- 2 files changed, 5 insertions(+), 4 deletions(-) --- - This fix patch changes are added and tested on top of linux-next tree on the 'next-20220315' branch. --- diff --git a/drivers/nvdimm/Makefile b/drivers/nvdimm/Makefile index 3fb806748716..ba0296dca9db 100644 --- a/drivers/nvdimm/Makefile +++ b/drivers/nvdimm/Makefile @@ -15,7 +15,7 @@ nd_e820-y := e820.o libnvdimm-y := core.o libnvdimm-y += bus.o libnvdimm-y += dimm_devs.o -libnvdimm-y += nd_perf.o +libnvdimm-$(CONFIG_PERF_EVENTS) += nd_perf.o libnvdimm-y += dimm.o libnvdimm-y += region_devs.o libnvdimm-y += region.o diff --git a/include/linux/nd.h b/include/linux/nd.h index 7b2ccbdc1cbc..a4265eaf5ae8 100644 --- a/include/linux/nd.h +++ b/include/linux/nd.h @@ -8,8 +8,10 @@ #include #include #include +#ifdef CONFIG_PERF_EVENTS #include #include +#endif enum nvdimm_event { NVDIMM_REVALIDATE_POISON, @@ -25,6 +27,7 @@ enum nvdimm_claim_class { NVDIMM_CCLASS_UNKNOWN, }; +#ifdef CONFIG_PERF_EVENTS #define NVDIMM_EVENT_VAR(_id) event_attr_##_id #define NVDIMM_EVENT_PTR(_id) (&event_attr_##_id.attr.attr) @@ -63,9 +66,7 @@ extern ssize_t nvdimm_events_sysfs_show(struct device *dev, int register_nvdimm_pmu(struct nvdimm_pmu *nvdimm, struct platform_device *pdev); void unregister_nvdimm_pmu(struct nvdimm_pmu *nd_pmu); -void perf_pmu_migrate_context(struct pmu *pmu, int src_cpu, int dst_cpu); -int perf_pmu_register(struct pmu *pmu, const char *name, int type); -void perf_pmu_unregister(struct pmu *pmu); +#endif struct nd_device_driver { struct device_driver drv; -- 2.31.1
[PATCH 2/2] powerpc/papr_scm: Fix build failure when CONFIG_PERF_EVENTS is not set
The following build failure occures when CONFIG_PERF_EVENTS is not set as generic pmu functions are not visible in that scenario. arch/powerpc/platforms/pseries/papr_scm.c:372:35: error: ‘struct perf_event’ has no member named ‘attr’ p->nvdimm_events_map[event->attr.config], ^~ In file included from ./include/linux/list.h:5, from ./include/linux/kobject.h:19, from ./include/linux/of.h:17, from arch/powerpc/platforms/pseries/papr_scm.c:5: arch/powerpc/platforms/pseries/papr_scm.c: In function ‘papr_scm_pmu_event_init’: arch/powerpc/platforms/pseries/papr_scm.c:389:49: error: ‘struct perf_event’ has no member named ‘pmu’ struct nvdimm_pmu *nd_pmu = to_nvdimm_pmu(event->pmu); ^~ ./include/linux/container_of.h:18:26: note: in definition of macro ‘container_of’ void *__mptr = (void *)(ptr); \ ^~~ arch/powerpc/platforms/pseries/papr_scm.c:389:30: note: in expansion of macro ‘to_nvdimm_pmu’ struct nvdimm_pmu *nd_pmu = to_nvdimm_pmu(event->pmu); ^ In file included from ./include/linux/bits.h:22, from ./include/linux/bitops.h:6, from ./include/linux/of.h:15, from arch/powerpc/platforms/pseries/papr_scm.c:5: Fix the build issue by adding check for CONFIG_PERF_EVENTS config option and disabling the papr_scm perf interface support incase this config is not set Fixes: 4c08d4bbc089 ("powerpc/papr_scm: Add perf interface support") (Commit id based on linux-next tree) Signed-off-by: Kajol Jain --- arch/powerpc/platforms/pseries/papr_scm.c | 15 +++ 1 file changed, 15 insertions(+) --- - This fix patch changes are added and tested on top of linux-next tree on the 'next-20220315' branch. --- diff --git a/arch/powerpc/platforms/pseries/papr_scm.c b/arch/powerpc/platforms/pseries/papr_scm.c index 4f65bc0fb861..ffe85aeb4127 100644 --- a/arch/powerpc/platforms/pseries/papr_scm.c +++ b/arch/powerpc/platforms/pseries/papr_scm.c @@ -19,7 +19,10 @@ #include #include #include + +#ifdef CONFIG_PERF_EVENTS #include +#endif #define BIND_ANY_ADDR (~0ul) @@ -69,7 +72,9 @@ #define PAPR_SCM_PERF_STATS_EYECATCHER __stringify(SCMSTATS) #define PAPR_SCM_PERF_STATS_VERSION 0x1 +#ifdef CONFIG_PERF_EVENTS #define to_nvdimm_pmu(_pmu)container_of(_pmu, struct nvdimm_pmu, pmu) +#endif /* Struct holding a single performance metric */ struct papr_scm_perf_stat { @@ -127,8 +132,10 @@ struct papr_scm_priv { /* The bits which needs to be overridden */ u64 health_bitmap_inject_mask; +#ifdef CONFIG_PERF_EVENTS /* array to have event_code and stat_id mappings */ char **nvdimm_events_map; +#endif }; static int papr_scm_pmem_flush(struct nd_region *nd_region, @@ -349,6 +356,7 @@ static ssize_t drc_pmem_query_stats(struct papr_scm_priv *p, return 0; } +#ifdef CONFIG_PERF_EVENTS static int papr_scm_pmu_get_value(struct perf_event *event, struct device *dev, u64 *count) { struct papr_scm_perf_stat *stat; @@ -560,6 +568,7 @@ static void papr_scm_pmu_register(struct papr_scm_priv *p) pmu_err_print: dev_info(&p->pdev->dev, "nvdimm pmu didn't register rc=%d\n", rc); } +#endif /* * Issue hcall to retrieve dimm health info and populate papr_scm_priv with the @@ -1537,7 +1546,10 @@ static int papr_scm_probe(struct platform_device *pdev) goto err2; platform_set_drvdata(pdev, p); + +#ifdef CONFIG_PERF_EVENTS papr_scm_pmu_register(p); +#endif return 0; @@ -1557,11 +1569,14 @@ static int papr_scm_remove(struct platform_device *pdev) nvdimm_bus_unregister(p->bus); drc_pmem_unbind(p); +#ifdef CONFIG_PERF_EVENTS if (pdev->archdata.priv) unregister_nvdimm_pmu(pdev->archdata.priv); pdev->archdata.priv = NULL; kfree(p->nvdimm_events_map); +#endif + kfree(p->bus_desc.provider_name); kfree(p); -- 2.31.1
[v2 PATCH 1/2] drivers/nvdimm: Fix build failure when CONFIG_PERF_EVENTS is not set
The following build failure occurs when CONFIG_PERF_EVENTS is not set as generic pmu functions are not visible in that scenario. |-- s390-randconfig-r044-20220313 | |-- nd_perf.c:(.text):undefined-reference-to-perf_pmu_migrate_context | |-- nd_perf.c:(.text):undefined-reference-to-perf_pmu_register | `-- nd_perf.c:(.text):undefined-reference-to-perf_pmu_unregister Similar build failure in nds32 architecture: nd_perf.c:(.text+0x21e): undefined reference to `perf_pmu_migrate_context' nd_perf.c:(.text+0x434): undefined reference to `perf_pmu_register' nd_perf.c:(.text+0x57c): undefined reference to `perf_pmu_unregister' Fix this issue by adding check for CONFIG_PERF_EVENTS config option and disabling the nvdimm perf interface incase this config is not set. Also remove function declaration of perf_pmu_migrate_context, perf_pmu_register, perf_pmu_unregister functions from nd.h as these are common pmu functions which are part of perf_event.h and since we are disabling nvdimm perf interface incase CONFIG_PERF_EVENTS option is not set, we not need to declare them in nd.h Also move the platform_device header file addition part from nd.h to nd_perf.c and add stub functions for register_nvdimm_pmu and unregister_nvdimm_pmu functions to handle CONFIG_PERF_EVENTS=n case. Fixes: 0fab1ba6ad6b ("drivers/nvdimm: Add perf interface to expose nvdimm performance stats") (Commit id based on libnvdimm-for-next tree) Signed-off-by: Kajol Jain Link: https://lore.kernel.org/all/62317124.ybqfu33+s%2fwdvwgj%25...@intel.com/ Reported-by: kernel test robot --- drivers/nvdimm/Makefile | 2 +- drivers/nvdimm/nd_perf.c | 1 + include/linux/nd.h | 16 3 files changed, 14 insertions(+), 5 deletions(-) --- Changelog: v1 -> v2 - Rebase and tested the fix patch changes on top of libnvdimm-for-next branch - Add stub functions for register_nvdimm_pmu and unregister_nvdimm_pmu functions to handle CONFIG_PERF_EVENTS=n case as suggested by Dan Williams - Move the platform_device header file addition part from nd.h to nd_perf.c and just forward declare struct platform_device in nd.h --- diff --git a/drivers/nvdimm/Makefile b/drivers/nvdimm/Makefile index 3fb806748716..ba0296dca9db 100644 --- a/drivers/nvdimm/Makefile +++ b/drivers/nvdimm/Makefile @@ -15,7 +15,7 @@ nd_e820-y := e820.o libnvdimm-y := core.o libnvdimm-y += bus.o libnvdimm-y += dimm_devs.o -libnvdimm-y += nd_perf.o +libnvdimm-$(CONFIG_PERF_EVENTS) += nd_perf.o libnvdimm-y += dimm.o libnvdimm-y += region_devs.o libnvdimm-y += region.o diff --git a/drivers/nvdimm/nd_perf.c b/drivers/nvdimm/nd_perf.c index 314415894acf..433bbb68ae64 100644 --- a/drivers/nvdimm/nd_perf.c +++ b/drivers/nvdimm/nd_perf.c @@ -10,6 +10,7 @@ #define pr_fmt(fmt) "nvdimm_pmu: " fmt #include +#include #define EVENT(_name, _code) enum{_name = _code} diff --git a/include/linux/nd.h b/include/linux/nd.h index 7b2ccbdc1cbc..f3e91c891cbc 100644 --- a/include/linux/nd.h +++ b/include/linux/nd.h @@ -9,7 +9,6 @@ #include #include #include -#include enum nvdimm_event { NVDIMM_REVALIDATE_POISON, @@ -57,15 +56,24 @@ struct nvdimm_pmu { struct cpumask arch_cpumask; }; +struct platform_device; + +#ifdef CONFIG_PERF_EVENTS extern ssize_t nvdimm_events_sysfs_show(struct device *dev, struct device_attribute *attr, char *page); int register_nvdimm_pmu(struct nvdimm_pmu *nvdimm, struct platform_device *pdev); void unregister_nvdimm_pmu(struct nvdimm_pmu *nd_pmu); -void perf_pmu_migrate_context(struct pmu *pmu, int src_cpu, int dst_cpu); -int perf_pmu_register(struct pmu *pmu, const char *name, int type); -void perf_pmu_unregister(struct pmu *pmu); + +#else +static inline int register_nvdimm_pmu(struct nvdimm_pmu *nvdimm, struct platform_device *pdev) +{ + return -ENXIO; +} + +static inline void unregister_nvdimm_pmu(struct nvdimm_pmu *nd_pmu) { } +#endif struct nd_device_driver { struct device_driver drv; -- 2.31.1
[v2 PATCH 2/2] powerpc/papr_scm: Fix build failure when
The following build failure occurs when CONFIG_PERF_EVENTS is not set as generic pmu functions are not visible in that scenario. arch/powerpc/platforms/pseries/papr_scm.c:372:35: error: ‘struct perf_event’ has no member named ‘attr’ p->nvdimm_events_map[event->attr.config], ^~ In file included from ./include/linux/list.h:5, from ./include/linux/kobject.h:19, from ./include/linux/of.h:17, from arch/powerpc/platforms/pseries/papr_scm.c:5: arch/powerpc/platforms/pseries/papr_scm.c: In function ‘papr_scm_pmu_event_init’: arch/powerpc/platforms/pseries/papr_scm.c:389:49: error: ‘struct perf_event’ has no member named ‘pmu’ struct nvdimm_pmu *nd_pmu = to_nvdimm_pmu(event->pmu); ^~ ./include/linux/container_of.h:18:26: note: in definition of macro ‘container_of’ void *__mptr = (void *)(ptr); \ ^~~ arch/powerpc/platforms/pseries/papr_scm.c:389:30: note: in expansion of macro ‘to_nvdimm_pmu’ struct nvdimm_pmu *nd_pmu = to_nvdimm_pmu(event->pmu); ^ In file included from ./include/linux/bits.h:22, from ./include/linux/bitops.h:6, from ./include/linux/of.h:15, from arch/powerpc/platforms/pseries/papr_scm.c:5: Fix the build issue by adding check for CONFIG_PERF_EVENTS config option and also add stub function for papr_scm_pmu_register to handle the CONFIG_PERF_EVENTS=n case. Also move the position of macro "to_nvdimm_pmu" inorder to merge it in CONFIG_PERF_EVENTS=y block. Fixes: 4c08d4bbc089 ("powerpc/papr_scm: Add perf interface support") (Commit id based on libnvdimm-for-next tree) Signed-off-by: Kajol Jain --- arch/powerpc/platforms/pseries/papr_scm.c | 9 +++-- 1 file changed, 7 insertions(+), 2 deletions(-) --- Changelog: v1 -> v2 - Rebase and tested the fix patch changes on top of libnvdimm-for-next branch - Add stub function for papr_scm_pmu_register function to handle the CONFIG_PERF_EVENTS=n case. - Move the position of macro "to_nvdimm_pmu" inorder to merge it in CONFIG_PERF_EVENTS=y block. - The initial part of arch/powerpc/platforms/pseries/papr_scm.c could be moved to a headerfile, will work on this in the follow up patchset. --- diff --git a/arch/powerpc/platforms/pseries/papr_scm.c b/arch/powerpc/platforms/pseries/papr_scm.c index 4dd513d7c029..9dba9e71fde9 100644 --- a/arch/powerpc/platforms/pseries/papr_scm.c +++ b/arch/powerpc/platforms/pseries/papr_scm.c @@ -69,8 +69,6 @@ #define PAPR_SCM_PERF_STATS_EYECATCHER __stringify(SCMSTATS) #define PAPR_SCM_PERF_STATS_VERSION 0x1 -#define to_nvdimm_pmu(_pmu)container_of(_pmu, struct nvdimm_pmu, pmu) - /* Struct holding a single performance metric */ struct papr_scm_perf_stat { u8 stat_id[8]; @@ -346,6 +344,9 @@ static ssize_t drc_pmem_query_stats(struct papr_scm_priv *p, return 0; } +#ifdef CONFIG_PERF_EVENTS +#define to_nvdimm_pmu(_pmu)container_of(_pmu, struct nvdimm_pmu, pmu) + static int papr_scm_pmu_get_value(struct perf_event *event, struct device *dev, u64 *count) { struct papr_scm_perf_stat *stat; @@ -558,6 +559,10 @@ static void papr_scm_pmu_register(struct papr_scm_priv *p) dev_info(&p->pdev->dev, "nvdimm pmu didn't register rc=%d\n", rc); } +#else +static void papr_scm_pmu_register(struct papr_scm_priv *p) { } +#endif + /* * Issue hcall to retrieve dimm health info and populate papr_scm_priv with the * health information. -- 2.31.1
[PATCH] perf vendor events: Initial json/events list for power10 platform
Patch adds initial json/events for POWER10. Signed-off-by: Kajol Jain --- .../perf/pmu-events/arch/powerpc/mapfile.csv | 1 + .../arch/powerpc/power10/cache.json | 47 +++ .../arch/powerpc/power10/floating_point.json | 7 + .../arch/powerpc/power10/frontend.json| 217 + .../arch/powerpc/power10/locks.json | 12 + .../arch/powerpc/power10/marked.json | 147 + .../arch/powerpc/power10/memory.json | 192 +++ .../arch/powerpc/power10/others.json | 297 ++ .../arch/powerpc/power10/pipeline.json| 297 ++ .../pmu-events/arch/powerpc/power10/pmc.json | 22 ++ .../arch/powerpc/power10/translation.json | 57 11 files changed, 1296 insertions(+) create mode 100644 tools/perf/pmu-events/arch/powerpc/power10/cache.json create mode 100644 tools/perf/pmu-events/arch/powerpc/power10/floating_point.json create mode 100644 tools/perf/pmu-events/arch/powerpc/power10/frontend.json create mode 100644 tools/perf/pmu-events/arch/powerpc/power10/locks.json create mode 100644 tools/perf/pmu-events/arch/powerpc/power10/marked.json create mode 100644 tools/perf/pmu-events/arch/powerpc/power10/memory.json create mode 100644 tools/perf/pmu-events/arch/powerpc/power10/others.json create mode 100644 tools/perf/pmu-events/arch/powerpc/power10/pipeline.json create mode 100644 tools/perf/pmu-events/arch/powerpc/power10/pmc.json create mode 100644 tools/perf/pmu-events/arch/powerpc/power10/translation.json diff --git a/tools/perf/pmu-events/arch/powerpc/mapfile.csv b/tools/perf/pmu-events/arch/powerpc/mapfile.csv index 229150e7ab7d..4abdfc3f9692 100644 --- a/tools/perf/pmu-events/arch/powerpc/mapfile.csv +++ b/tools/perf/pmu-events/arch/powerpc/mapfile.csv @@ -15,3 +15,4 @@ # Power8 entries 004[bcd][[:xdigit:]]{4},1,power8,core 004e[[:xdigit:]]{4},1,power9,core +0080[[:xdigit:]]{4},1,power10,core diff --git a/tools/perf/pmu-events/arch/powerpc/power10/cache.json b/tools/perf/pmu-events/arch/powerpc/power10/cache.json new file mode 100644 index ..95e33531fbc6 --- /dev/null +++ b/tools/perf/pmu-events/arch/powerpc/power10/cache.json @@ -0,0 +1,47 @@ +[ + { +"EventCode": "1003C", +"EventName": "PM_EXEC_STALL_DMISS_L2L3", +"BriefDescription": "Cycles in which the oldest instruction in the pipeline was waiting for a load miss to resolve from either the local L2 or local L3." + }, + { +"EventCode": "34056", +"EventName": "PM_EXEC_STALL_LOAD_FINISH", +"BriefDescription": "Cycles in which the oldest instruction in the pipeline was finishing a load after its data was reloaded from a data source beyond the local L1; cycles in which the LSU was processing an L1-hit; cycles in which the NTF instruction merged with another load in the LMQ." + }, + { +"EventCode": "3006C", +"EventName": "PM_RUN_CYC_SMT2_MODE", +"BriefDescription": "Cycles when this thread's run latch is set and the core is in SMT2 mode" + }, + { +"EventCode": "300F4", +"EventName": "PM_RUN_INST_CMPL_CONC", +"BriefDescription": "PowerPC instructions completed by this thread when all threads in the core had the run-latch set" + }, + { +"EventCode": "4C016", +"EventName": "PM_EXEC_STALL_DMISS_L2L3_CONFLICT", +"BriefDescription": "Cycles in which the oldest instruction in the pipeline was waiting for a load miss to resolve from the local L2 or local L3, with a dispatch conflict." + }, + { +"EventCode": "4D014", +"EventName": "PM_EXEC_STALL_LOAD", +"BriefDescription": "Cycles in which the oldest instruction in the pipeline was a load instruction executing in the Load Store Unit." + }, + { +"EventCode": "4D016", +"EventName": "PM_EXEC_STALL_PTESYNC", +"BriefDescription": "Cycles in which the oldest instruction in the pipeline was a PTESYNC instruction executing in the Load Store Unit." + }, + { +"EventCode": "401EA", +"EventName": "PM_THRESH_EXC_128", +"BriefDescription": "Threshold counter exceeded a value of 128" + }, + { +"EventCode": "400F6", +"EventName": "PM_BR_MPRED_CMPL", +"BriefDescription": "A mispredicted branch completed. Includes direction and target." + } +] diff --git a/tools/perf/pmu-events/arch/powerpc/power10/floating_point.json b/tools/perf/pmu-events/arch/powerpc/power10/floating_point.json new file mode 100644 index 00
[PATCH] powerpc/papr_scm: trivial: fix typo in a comment
There is a spelling mistake "byes" -> "bytes" in a comment of function drc_pmem_query_stats(). Fix that typo. Signed-off-by: Kajol Jain --- arch/powerpc/platforms/pseries/papr_scm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/platforms/pseries/papr_scm.c b/arch/powerpc/platforms/pseries/papr_scm.c index 835163f54244..ba4faa513a74 100644 --- a/arch/powerpc/platforms/pseries/papr_scm.c +++ b/arch/powerpc/platforms/pseries/papr_scm.c @@ -227,7 +227,7 @@ static int drc_pmem_query_n_bind(struct papr_scm_priv *p) * Query the Dimm performance stats from PHYP and copy them (if returned) to * provided struct papr_scm_perf_stats instance 'stats' that can hold atleast * (num_stats + header) bytes. - * - If buff_stats == NULL the return value is the size in byes of the buffer + * - If buff_stats == NULL the return value is the size in bytes of the buffer * needed to hold all supported performance-statistics. * - If buff_stats != NULL and num_stats == 0 then we copy all known * performance-statistics to 'buff_stat' and expect to be large enough to -- 2.27.0
[PATCH v2] perf vendor events: Initial json/events list for power10 platform
Patch adds initial json/events for POWER10. Signed-off-by: Kajol Jain Tested-by: Paul A. Clarke Reviewed-by: Paul A. Clarke --- .../perf/pmu-events/arch/powerpc/mapfile.csv | 1 + .../arch/powerpc/power10/cache.json | 47 +++ .../arch/powerpc/power10/floating_point.json | 7 + .../arch/powerpc/power10/frontend.json| 217 + .../arch/powerpc/power10/locks.json | 12 + .../arch/powerpc/power10/marked.json | 147 + .../arch/powerpc/power10/memory.json | 192 +++ .../arch/powerpc/power10/others.json | 297 ++ .../arch/powerpc/power10/pipeline.json| 297 ++ .../pmu-events/arch/powerpc/power10/pmc.json | 22 ++ .../arch/powerpc/power10/translation.json | 57 11 files changed, 1296 insertions(+) create mode 100644 tools/perf/pmu-events/arch/powerpc/power10/cache.json create mode 100644 tools/perf/pmu-events/arch/powerpc/power10/floating_point.json create mode 100644 tools/perf/pmu-events/arch/powerpc/power10/frontend.json create mode 100644 tools/perf/pmu-events/arch/powerpc/power10/locks.json create mode 100644 tools/perf/pmu-events/arch/powerpc/power10/marked.json create mode 100644 tools/perf/pmu-events/arch/powerpc/power10/memory.json create mode 100644 tools/perf/pmu-events/arch/powerpc/power10/others.json create mode 100644 tools/perf/pmu-events/arch/powerpc/power10/pipeline.json create mode 100644 tools/perf/pmu-events/arch/powerpc/power10/pmc.json create mode 100644 tools/perf/pmu-events/arch/powerpc/power10/translation.json --- Changelog: v1 -> v2 - Removed inconsistencies in "BriefDescription" field and make sure it will end with period without any space at the end. Suggested by : Paul A. Clarke - Added Tested-by and Reviewed-by tag. --- diff --git a/tools/perf/pmu-events/arch/powerpc/mapfile.csv b/tools/perf/pmu-events/arch/powerpc/mapfile.csv index 229150e7ab7d..4abdfc3f9692 100644 --- a/tools/perf/pmu-events/arch/powerpc/mapfile.csv +++ b/tools/perf/pmu-events/arch/powerpc/mapfile.csv @@ -15,3 +15,4 @@ # Power8 entries 004[bcd][[:xdigit:]]{4},1,power8,core 004e[[:xdigit:]]{4},1,power9,core +0080[[:xdigit:]]{4},1,power10,core diff --git a/tools/perf/pmu-events/arch/powerpc/power10/cache.json b/tools/perf/pmu-events/arch/powerpc/power10/cache.json new file mode 100644 index ..95e33531fbc6 --- /dev/null +++ b/tools/perf/pmu-events/arch/powerpc/power10/cache.json @@ -0,0 +1,47 @@ +[ + { +"EventCode": "1003C", +"EventName": "PM_EXEC_STALL_DMISS_L2L3", +"BriefDescription": "Cycles in which the oldest instruction in the pipeline was waiting for a load miss to resolve from either the local L2 or local L3." + }, + { +"EventCode": "34056", +"EventName": "PM_EXEC_STALL_LOAD_FINISH", +"BriefDescription": "Cycles in which the oldest instruction in the pipeline was finishing a load after its data was reloaded from a data source beyond the local L1; cycles in which the LSU was processing an L1-hit; cycles in which the NTF instruction merged with another load in the LMQ." + }, + { +"EventCode": "3006C", +"EventName": "PM_RUN_CYC_SMT2_MODE", +"BriefDescription": "Cycles when this thread's run latch is set and the core is in SMT2 mode." + }, + { +"EventCode": "300F4", +"EventName": "PM_RUN_INST_CMPL_CONC", +"BriefDescription": "PowerPC instructions completed by this thread when all threads in the core had the run-latch set." + }, + { +"EventCode": "4C016", +"EventName": "PM_EXEC_STALL_DMISS_L2L3_CONFLICT", +"BriefDescription": "Cycles in which the oldest instruction in the pipeline was waiting for a load miss to resolve from the local L2 or local L3, with a dispatch conflict." + }, + { +"EventCode": "4D014", +"EventName": "PM_EXEC_STALL_LOAD", +"BriefDescription": "Cycles in which the oldest instruction in the pipeline was a load instruction executing in the Load Store Unit." + }, + { +"EventCode": "4D016", +"EventName": "PM_EXEC_STALL_PTESYNC", +"BriefDescription": "Cycles in which the oldest instruction in the pipeline was a PTESYNC instruction executing in the Load Store Unit." + }, + { +"EventCode": "401EA", +"EventName": "PM_THRESH_EXC_128", +"BriefDescription": "Threshold counter exceeded a value of 128." + }, + { +"EventCode": "400F6", +"EventName": "PM_BR_MPRED_CMPL"
[PATCH] perf test: Skip test 68 for Powerpc
Commit ed21d6d7c48e6e ("perf tests: Add test for PE binary format support") adds a WINDOWS EXE file named tests/pe-file.exe, which is examined by the test case 'PE file support'. As powerpc doesn't support it, we are skipping this test. Result in power9 platform before this patach: [command]# ./perf test -F 68 68: PE file support : Failed! Result in power9 platform after this patch: [command]# ./perf test -F 68 68: PE file support : Skip Signed-off-by: Kajol Jain --- tools/perf/tests/pe-file-parsing.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/tests/pe-file-parsing.c b/tools/perf/tests/pe-file-parsing.c index 4e45178c50f6..14f675f5ffb2 100644 --- a/tools/perf/tests/pe-file-parsing.c +++ b/tools/perf/tests/pe-file-parsing.c @@ -18,7 +18,7 @@ #include "tests.h" -#if defined(HAVE_LIBBFD_SUPPORT) && !defined(__s390x__) +#if defined(HAVE_LIBBFD_SUPPORT) && !defined(__s390x__) && !defined(__powerpc__) static int run_dir(const char *d) { -- 2.27.0
[PATCH] perf test: Fix metric parsing test
Commit e1c92a7fbbc5 ("perf tests: Add another metric parsing test") add another test for metric parsing. The test goes through all metrics compiled for arch within pmu events and try to parse them. Right now this test is failing in powerpc machine. Result in power9 platform: [command]# ./perf test 10 10: PMU events : 10.1: PMU event table sanity: Ok 10.2: PMU event map aliases : Ok 10.3: Parsing of PMU event table metrics: Skip (some metrics failed) 10.4: Parsing of PMU event table metrics with fake PMUs : FAILED! Issue is we are passing different runtime parameter value in "expr__find_other" and "expr__parse" function which is called from function `metric_parse_fake`. And because of this parsing of hv-24x7 metrics is failing. [command]# ./perf test 10 -vv . hv_24x7/pm_mcs01_128b_rd_disp_port01,chip=1/ not found expr__parse failed test child finished with -1 end PMU events subtest 4: FAILED! This patch fix this issue and change runtime parameter value to '0' in expr__parse function. Result in power9 platform after this patch: [command]# ./perf test 10 10: PMU events : 10.1: PMU event table sanity: Ok 10.2: PMU event map aliases : Ok 10.3: Parsing of PMU event table metrics: Skip (some metrics failed) 10.4: Parsing of PMU event table metrics with fake PMUs : Ok Fixes: e1c92a7fbbc5 ("perf tests: Add another metric parsing test") Signed-off-by: Kajol Jain --- tools/perf/tests/pmu-events.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/tests/pmu-events.c b/tools/perf/tests/pmu-events.c index ad2b21591275..0ca6a5a53523 100644 --- a/tools/perf/tests/pmu-events.c +++ b/tools/perf/tests/pmu-events.c @@ -575,7 +575,7 @@ static int metric_parse_fake(const char *str) } } - if (expr__parse(&result, &ctx, str, 1)) + if (expr__parse(&result, &ctx, str, 0)) pr_err("expr__parse failed\n"); else ret = 0; -- 2.27.0
[PATCH] perf/tools/pmu-events/powerpc: Added nest imc metric events
Added nest imc metric events. Signed-off-by: Kajol Jain --- .../arch/powerpc/power9/nest_metrics.json | 35 +++ 1 file changed, 35 insertions(+) diff --git a/tools/perf/pmu-events/arch/powerpc/power9/nest_metrics.json b/tools/perf/pmu-events/arch/powerpc/power9/nest_metrics.json index c121e526442a..8383a37647ad 100644 --- a/tools/perf/pmu-events/arch/powerpc/power9/nest_metrics.json +++ b/tools/perf/pmu-events/arch/powerpc/power9/nest_metrics.json @@ -15,5 +15,40 @@ "MetricExpr": "(hv_24x7@PM_PB_CYC\\,chip\\=?@ )", "MetricName": "PowerBUS_Frequency", "ScaleUnit": "2.5e-7GHz" +}, +{ + "MetricExpr" : "nest_mcs01_imc@PM_MCS01_128B_RD_DISP_PORT01@ + nest_mcs01_imc@PM_MCS01_128B_RD_DISP_PORT23@", + "MetricName" : "mcs01-read", + "MetricGroup" : "memory_bw", + "ScaleUnit": "6.1e-5MB" +}, +{ + "MetricExpr" : "nest_mcs23_imc@PM_MCS23_128B_RD_DISP_PORT01@ + nest_mcs23_imc@PM_MCS23_128B_RD_DISP_PORT23@", + "MetricName" : "mcs23-read", + "MetricGroup" : "memory_bw", + "ScaleUnit": "6.1e-5MB" +}, +{ + "MetricExpr" : "nest_mcs01_imc@PM_MCS01_128B_WR_DISP_PORT01@ + nest_mcs01_imc@PM_MCS01_128B_WR_DISP_PORT23@", + "MetricName" : "mcs01-write", + "MetricGroup" : "memory_bw", + "ScaleUnit": "6.1e-5MB" +}, +{ + "MetricExpr" : "nest_mcs23_imc@PM_MCS23_128B_WR_DISP_PORT01@ + nest_mcs23_imc@PM_MCS23_128B_WR_DISP_PORT23@", + "MetricName" : "mcs23-write", + "MetricGroup" : "memory-bandwidth", + "ScaleUnit": "6.1e-5MB" +}, +{ + "MetricExpr" : "nest_powerbus0_imc@PM_PB_CYC@", + "MetricName" : "powerbus_freq", + "ScaleUnit": "1e-9GHz" +}, +{ + "MetricExpr" : "(nest_mcs01_imc@PM_MCS01_128B_RD_DISP_PORT01@ + nest_mcs01_imc@PM_MCS01_128B_RD_DISP_PORT23@ + nest_mcs23_imc@PM_MCS23_128B_RD_DISP_PORT01@ + nest_mcs23_imc@PM_MCS23_128B_RD_DISP_PORT23@ + nest_mcs01_imc@PM_MCS01_128B_WR_DISP_PORT01@ + nest_mcs01_imc@PM_MCS01_128B_WR_DISP_PORT23@ + nest_mcs23_imc@PM_MCS23_128B_WR_DISP_PORT01@ + nest_mcs23_imc@PM_MCS23_128B_WR_DISP_PORT23@)", + "MetricName" : "Memory-bandwidth-MCS", + "MetricGroup" : "memory_bw", + "ScaleUnit": "6.1e-5MB" } ] -- 2.17.1
[RFC 2/3] perf/tools: Pass pmu_event structure as a parameter for arch_get_runtimeparam
This patch adds passing of pmu_event as a parameter in function 'arch_get_runtimeparam' which can be used to get details like if the event is percore/perchip. Signed-off-by: Kajol Jain --- tools/perf/arch/powerpc/util/header.c | 7 +-- tools/perf/util/metricgroup.c | 5 ++--- tools/perf/util/metricgroup.h | 3 ++- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/tools/perf/arch/powerpc/util/header.c b/tools/perf/arch/powerpc/util/header.c index d4870074f14c..fe684e0af5b3 100644 --- a/tools/perf/arch/powerpc/util/header.c +++ b/tools/perf/arch/powerpc/util/header.c @@ -47,8 +47,11 @@ get_cpuid_str(struct perf_pmu *pmu __maybe_unused) return bufp; } -int arch_get_runtimeparam(void) +int arch_get_runtimeparam(struct pmu_event *pe) { int count; - return sysfs__read_int("/devices/hv_24x7/interface/sockets", &count) < 0 ? 1 : count; + char path[PATH_MAX] = "/devices/hv_24x7/interface/"; + + pe->perchip ? strcat(path, "sockets") : strcat(path, "coresperchip"); + return sysfs__read_int(path, &count) < 0 ? 1 : count; } diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c index 9e21aa767e41..c06166ec64d6 100644 --- a/tools/perf/util/metricgroup.c +++ b/tools/perf/util/metricgroup.c @@ -15,7 +15,6 @@ #include "rblist.h" #include #include -#include "pmu-events/pmu-events.h" #include "strlist.h" #include #include @@ -547,7 +546,7 @@ static bool metricgroup__has_constraint(struct pmu_event *pe) return false; } -int __weak arch_get_runtimeparam(void) +int __weak arch_get_runtimeparam(struct pmu_event *pe __maybe_unused) { return 1; } @@ -634,7 +633,7 @@ static int metricgroup__add_metric(const char *metric, bool metric_no_group, } else { int j, count; - count = arch_get_runtimeparam(); + count = arch_get_runtimeparam(pe); /* This loop is added to create multiple * events depend on count value and add diff --git a/tools/perf/util/metricgroup.h b/tools/perf/util/metricgroup.h index 287850bcdeca..c0bf77514343 100644 --- a/tools/perf/util/metricgroup.h +++ b/tools/perf/util/metricgroup.h @@ -5,6 +5,7 @@ #include #include #include +#include "pmu-events/pmu-events.h" struct evsel; struct option; @@ -37,5 +38,5 @@ int metricgroup__parse_groups(const struct option *opt, void metricgroup__print(bool metrics, bool groups, char *filter, bool raw, bool details); bool metricgroup__has_metric(const char *metric); -int arch_get_runtimeparam(void); +int arch_get_runtimeparam(struct pmu_event *pe __maybe_unused); #endif -- 2.26.2
[RFC 3/3] perf/tools/pmu_events/powerpc: Add hv_24x7 core level metric events
This patch adds hv_24x7 core level events in nest_metric.json file and also add PerChip/PerCore field in metric events. Result: power9 platform: command:# ./perf stat --metric-only -M PowerBUS_Frequency -C 0 -I 1000 1.706011.92.0 2.0002538812.01.9 3.0003648102.02.0 Signed-off-by: Kajol Jain --- .../arch/powerpc/power9/nest_metrics.json | 15 --- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/tools/perf/pmu-events/arch/powerpc/power9/nest_metrics.json b/tools/perf/pmu-events/arch/powerpc/power9/nest_metrics.json index c121e526442a..1f9c4ec12f67 100644 --- a/tools/perf/pmu-events/arch/powerpc/power9/nest_metrics.json +++ b/tools/perf/pmu-events/arch/powerpc/power9/nest_metrics.json @@ -3,17 +3,26 @@ "MetricExpr": "(hv_24x7@PM_MCS01_128B_RD_DISP_PORT01\\,chip\\=?@ + hv_24x7@PM_MCS01_128B_RD_DISP_PORT23\\,chip\\=?@ + hv_24x7@PM_MCS23_128B_RD_DISP_PORT01\\,chip\\=?@ + hv_24x7@PM_MCS23_128B_RD_DISP_PORT23\\,chip\\=?@)", "MetricName": "Memory_RD_BW_Chip", "MetricGroup": "Memory_BW", -"ScaleUnit": "1.6e-2MB" +"ScaleUnit": "1.6e-2MB", + "PerChip": "1" }, { "MetricExpr": "(hv_24x7@PM_MCS01_128B_WR_DISP_PORT01\\,chip\\=?@ + hv_24x7@PM_MCS01_128B_WR_DISP_PORT23\\,chip\\=?@ + hv_24x7@PM_MCS23_128B_WR_DISP_PORT01\\,chip\\=?@ + hv_24x7@PM_MCS23_128B_WR_DISP_PORT23\\,chip\\=?@ )", "MetricName": "Memory_WR_BW_Chip", "MetricGroup": "Memory_BW", -"ScaleUnit": "1.6e-2MB" +"ScaleUnit": "1.6e-2MB", + "PerChip": "1" }, { "MetricExpr": "(hv_24x7@PM_PB_CYC\\,chip\\=?@ )", "MetricName": "PowerBUS_Frequency", -"ScaleUnit": "2.5e-7GHz" +"ScaleUnit": "2.5e-7GHz", + "PerChip": "1" +}, +{ + "MetricExpr": "(hv_24x7@CPM_CS_32MHZ_CYC\\,domain\\=3\\,core\\=?@ )", +"MetricName": "CPM_CS_32MHZ_CYC", +"ScaleUnit": "1MHz", + "PerCore": "1" } ] -- 2.26.2
[RFC 0/3] powerpc/perf: Add json file support for hv_24x7 core level events
Patchset enhance current runtime parameter support. It introduces new fields like "PerChip" and "PerCore" similar to the field "PerPkg" which is used to specify perpkg events. The "PerCore" and "PerChip" specifies whether its core or chip events. Based on which we can decide which runtime parameter user want to access. Now character '?' can refers different parameter based on user requirement. Kajol Jain (3): perf jevents: Add support for parsing perchip/percore events perf/tools: Pass pmu_event structure as a parameter for arch_get_runtimeparam perf/tools/pmu_events/powerpc: Add hv_24x7 core level metric events tools/perf/arch/powerpc/util/header.c | 7 ++-- .../arch/powerpc/power9/nest_metrics.json | 15 ++-- tools/perf/pmu-events/jevents.c | 34 +++ tools/perf/pmu-events/jevents.h | 3 +- tools/perf/pmu-events/pmu-events.h| 2 ++ tools/perf/util/metricgroup.c | 5 ++- tools/perf/util/metricgroup.h | 3 +- 7 files changed, 53 insertions(+), 16 deletions(-) -- 2.26.2
[RFC 1/3] perf jevents: Add support for parsing perchip/percore events
Set up the "PerChip" field so that perf knows they are per chip events. Set up the "PerCore" field so that perf knows they are per core events and add these fields to pmu_event structure. Similar to the way we had "PerPkg field to specify perpkg events. Signed-off-by: Kajol Jain --- tools/perf/pmu-events/jevents.c| 34 -- tools/perf/pmu-events/jevents.h| 3 ++- tools/perf/pmu-events/pmu-events.h | 2 ++ 3 files changed, 32 insertions(+), 7 deletions(-) diff --git a/tools/perf/pmu-events/jevents.c b/tools/perf/pmu-events/jevents.c index fa86c5f997cc..21fd7990ded5 100644 --- a/tools/perf/pmu-events/jevents.c +++ b/tools/perf/pmu-events/jevents.c @@ -323,7 +323,8 @@ static int print_events_table_entry(void *data, char *name, char *event, char *pmu, char *unit, char *perpkg, char *metric_expr, char *metric_name, char *metric_group, - char *deprecated, char *metric_constraint) + char *deprecated, char *perchip, char *percore, + char *metric_constraint) { struct perf_entry_data *pd = data; FILE *outfp = pd->outfp; @@ -357,6 +358,10 @@ static int print_events_table_entry(void *data, char *name, char *event, fprintf(outfp, "\t.metric_group = \"%s\",\n", metric_group); if (deprecated) fprintf(outfp, "\t.deprecated = \"%s\",\n", deprecated); + if (perchip) + fprintf(outfp, "\t.perchip = \"%s\",\n", perchip); + if (percore) + fprintf(outfp, "\t.percore = \"%s\",\n", percore); if (metric_constraint) fprintf(outfp, "\t.metric_constraint = \"%s\",\n", metric_constraint); fprintf(outfp, "},\n"); @@ -378,6 +383,8 @@ struct event_struct { char *metric_group; char *deprecated; char *metric_constraint; + char *perchip; + char *percore; }; #define ADD_EVENT_FIELD(field) do { if (field) { \ @@ -406,6 +413,8 @@ struct event_struct { op(metric_name);\ op(metric_group); \ op(deprecated); \ + op(perchip);\ + op(percore);\ } while (0) static LIST_HEAD(arch_std_events); @@ -425,7 +434,8 @@ static int save_arch_std_events(void *data, char *name, char *event, char *desc, char *long_desc, char *pmu, char *unit, char *perpkg, char *metric_expr, char *metric_name, char *metric_group, - char *deprecated, char *metric_constraint) + char *deprecated, char *perchip, char *percore, + char *metric_constraint) { struct event_struct *es; @@ -489,7 +499,8 @@ try_fixup(const char *fn, char *arch_std, char **event, char **desc, char **name, char **long_desc, char **pmu, char **filter, char **perpkg, char **unit, char **metric_expr, char **metric_name, char **metric_group, unsigned long long eventcode, - char **deprecated, char **metric_constraint) + char **deprecated, char **perchip, char **percore, + char **metric_constraint) { /* try to find matching event from arch standard values */ struct event_struct *es; @@ -518,7 +529,8 @@ int json_events(const char *fn, char *pmu, char *unit, char *perpkg, char *metric_expr, char *metric_name, char *metric_group, - char *deprecated, char *metric_constraint), + char *deprecated, char *perchip, char *percore, + char *metric_constraint), void *data) { int err; @@ -548,6 +560,8 @@ int json_events(const char *fn, char *metric_name = NULL; char *metric_group = NULL; char *deprecated = NULL; + char *perchip = NULL; + char *percore = NULL; char *metric_constraint = NULL; char *arch_std = NULL; unsigned long long eventcode = 0; @@ -629,6 +643,10 @@ int json_events(const char *fn, addfield(map, &perpkg, "", "", val); } else if (json_streq(map, field, "Deprecated")) { addfield(map, &deprecated, "", "", val); +
[RFC v2 3/5] perf jevents: Add support for parsing perchip/percore events
Added the "PerChip" field in enum so that perf knows they are per chip events. Added the "PerCore" field in enum so that perf knows they are per core events and add these fields to pmu_event structure. Similar to the way we had "PerPkg field to specify perpkg events. Signed-off-by: Kajol Jain --- tools/perf/pmu-events/jevents.c| 8 +++- tools/perf/pmu-events/pmu-events.h | 4 +++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/tools/perf/pmu-events/jevents.c b/tools/perf/pmu-events/jevents.c index b2f59f0af63d..1f65047db000 100644 --- a/tools/perf/pmu-events/jevents.c +++ b/tools/perf/pmu-events/jevents.c @@ -54,13 +54,19 @@ int verbose; char *prog; enum aggr_mode_class { - PerPkg = 1 + PerChip = 0, + PerPkg = 1, + PerCore = 2 }; enum aggr_mode_class convert(const char *aggr_mode) { if (!strcmp(aggr_mode, "PerPkg")) return PerPkg; + else if (!strcmp(aggr_mode, "PerCore")) + return PerCore; + else if (!strcmp(aggr_mode, "PerChip")) + return PerChip; return -1; } diff --git a/tools/perf/pmu-events/pmu-events.h b/tools/perf/pmu-events/pmu-events.h index 71b7aa6278d0..114ae1559358 100644 --- a/tools/perf/pmu-events/pmu-events.h +++ b/tools/perf/pmu-events/pmu-events.h @@ -3,7 +3,9 @@ #define PMU_EVENTS_H enum aggr_mode_class { - PerPkg = 1 + PerChip = 0, + PerPkg = 1, + PerCore = 2 }; /* -- 2.26.2
[RFC v2 1/5] perf/pmu-events/jevents: Add enum to store aggregation like PerPkg
Initially, every time we want to add new terms like chip, core, thread etc, we need to create corrsponding fields in pmu_events and event struct. This patch adds an enum called 'aggr_mode_class' which store all these aggregation like perpkg/percore. It also adds new field 'aggr_mode' to capture these terms. Now, if user wants to add any new term, they just need to add it in the enum defined. Signed-off-by: Kajol Jain --- tools/perf/pmu-events/jevents.c| 39 +++--- tools/perf/pmu-events/jevents.h| 2 +- tools/perf/pmu-events/pmu-events.h | 6 - tools/perf/tests/pmu-events.c | 8 +++--- tools/perf/util/pmu.c | 6 ++--- 5 files changed, 38 insertions(+), 23 deletions(-) diff --git a/tools/perf/pmu-events/jevents.c b/tools/perf/pmu-events/jevents.c index fa86c5f997cc..b2f59f0af63d 100644 --- a/tools/perf/pmu-events/jevents.c +++ b/tools/perf/pmu-events/jevents.c @@ -53,6 +53,17 @@ int verbose; char *prog; +enum aggr_mode_class { + PerPkg = 1 +}; + +enum aggr_mode_class convert(const char *aggr_mode) +{ + if (!strcmp(aggr_mode, "PerPkg")) + return PerPkg; + return -1; +} + int eprintf(int level, int var, const char *fmt, ...) { @@ -320,7 +331,7 @@ static void print_events_table_prefix(FILE *fp, const char *tblname) static int print_events_table_entry(void *data, char *name, char *event, char *desc, char *long_desc, - char *pmu, char *unit, char *perpkg, + char *pmu, char *unit, char *aggr_mode, char *metric_expr, char *metric_name, char *metric_group, char *deprecated, char *metric_constraint) @@ -345,10 +356,10 @@ static int print_events_table_entry(void *data, char *name, char *event, fprintf(outfp, "\t.long_desc = \"%s\",\n", long_desc); if (pmu) fprintf(outfp, "\t.pmu = \"%s\",\n", pmu); + if (aggr_mode) + fprintf(outfp, "\t.aggr_mode = \"%d\",\n", convert(aggr_mode)); if (unit) fprintf(outfp, "\t.unit = \"%s\",\n", unit); - if (perpkg) - fprintf(outfp, "\t.perpkg = \"%s\",\n", perpkg); if (metric_expr) fprintf(outfp, "\t.metric_expr = \"%s\",\n", metric_expr); if (metric_name) @@ -372,7 +383,7 @@ struct event_struct { char *long_desc; char *pmu; char *unit; - char *perpkg; + char *aggr_mode; char *metric_expr; char *metric_name; char *metric_group; @@ -401,7 +412,7 @@ struct event_struct { op(long_desc); \ op(pmu);\ op(unit); \ - op(perpkg); \ + op(aggr_mode); \ op(metric_expr);\ op(metric_name);\ op(metric_group); \ @@ -423,7 +434,7 @@ static void free_arch_std_events(void) static int save_arch_std_events(void *data, char *name, char *event, char *desc, char *long_desc, char *pmu, - char *unit, char *perpkg, char *metric_expr, + char *unit, char *aggr_mode, char *metric_expr, char *metric_name, char *metric_group, char *deprecated, char *metric_constraint) { @@ -487,7 +498,7 @@ static char *real_event(const char *name, char *event) static int try_fixup(const char *fn, char *arch_std, char **event, char **desc, char **name, char **long_desc, char **pmu, char **filter, - char **perpkg, char **unit, char **metric_expr, char **metric_name, + char **aggr_mode, char **unit, char **metric_expr, char **metric_name, char **metric_group, unsigned long long eventcode, char **deprecated, char **metric_constraint) { @@ -515,7 +526,7 @@ try_fixup(const char *fn, char *arch_std, char **event, char **desc, int json_events(const char *fn, int (*func)(void *data, char *name, char *event, char *desc, char *long_desc, - char *pmu, char *unit, char *perpkg, + char *pmu, char *unit, char *aggr_mode, char *metric_expr, char *metric_name, char *metric_group, char *deprecated, char *metric_constraint), @@ -542,7 +553,7 @@ int json_events(const char *f
[RFC v2 0/5] tools/perf/pmu-events/jevents.c
Patchset enhance current runtime parameter support. It introduces new fields like "PerChip" and "PerCore" similar to the field "PerPkg" which is used to specify perpkg events. The "PerCore" and "PerChip" specifies whether its core or chip events. Based on which we can decide which runtime parameter user want to access. Now character '?' can refers different parameter based on user requirement. Initially, every time we want to add new terms like chip, core, thread etc, we need to create corrsponding fields in pmu_events and event struct. This patchset adds an enum called 'aggr_mode_class' which store all these aggregation like perpkg/percore. It also adds new field 'AggregationMode' to capture these terms. Now, if user wants to add any new term, they just need to add it in the enum defined. I try to test it with my current setup. I also need to replace PerPkg field to AggregationMode in all the x86 uncore json files. It will great if Andi and team can test it and let me know if they have any concerns. Changelog: v1 -> v2: - Rather then adding new field as PerCore/PerChip, created a new enum to get these fields. And new field as "AggregationMode" which can be used to capture these fields from json file. Kajol Jain (5): perf/pmu-events/jevents: Add enum to store aggregation like PerPkg pmu-events/x86/uncore: Replace PerPkg field to AggregationMode in x86 json files perf jevents: Add support for parsing perchip/percore events perf/tools: Pass pmu_event structure as a parameter for arch_get_runtimeparam perf/tools/pmu_events/powerpc: Add hv_24x7 core level metric events tools/perf/arch/powerpc/util/header.c | 7 +- .../arch/powerpc/power9/nest_metrics.json | 17 +- .../arch/x86/broadwellde/uncore-cache.json| 62 ++-- .../arch/x86/broadwellde/uncore-memory.json | 18 +- .../arch/x86/broadwellde/uncore-power.json| 18 +- .../arch/x86/broadwellx/uncore-cache.json | 62 ++-- .../x86/broadwellx/uncore-interconnect.json | 6 +- .../arch/x86/broadwellx/uncore-memory.json| 18 +- .../arch/x86/broadwellx/uncore-power.json | 18 +- .../arch/x86/cascadelakex/uncore-memory.json | 64 ++-- .../arch/x86/cascadelakex/uncore-other.json | 332 +- .../arch/x86/haswellx/uncore-cache.json | 62 ++-- .../x86/haswellx/uncore-interconnect.json | 6 +- .../arch/x86/haswellx/uncore-memory.json | 18 +- .../arch/x86/haswellx/uncore-power.json | 18 +- .../arch/x86/ivytown/uncore-cache.json| 62 ++-- .../arch/x86/ivytown/uncore-interconnect.json | 10 +- .../arch/x86/ivytown/uncore-memory.json | 16 +- .../arch/x86/ivytown/uncore-power.json| 52 +-- .../arch/x86/jaketown/uncore-cache.json | 40 +-- .../x86/jaketown/uncore-interconnect.json | 10 +- .../arch/x86/jaketown/uncore-memory.json | 18 +- .../arch/x86/jaketown/uncore-power.json | 52 +-- .../x86/knightslanding/uncore-memory.json | 8 +- .../arch/x86/skylakex/uncore-memory.json | 36 +- .../arch/x86/skylakex/uncore-other.json | 220 ++-- .../arch/x86/tremontx/uncore-memory.json | 14 +- .../arch/x86/tremontx/uncore-other.json | 70 ++-- .../arch/x86/tremontx/uncore-power.json | 2 +- tools/perf/pmu-events/jevents.c | 45 ++- tools/perf/pmu-events/jevents.h | 2 +- tools/perf/pmu-events/pmu-events.h| 8 +- tools/perf/tests/pmu-events.c | 8 +- tools/perf/util/metricgroup.c | 5 +- tools/perf/util/metricgroup.h | 3 +- tools/perf/util/pmu.c | 6 +- 36 files changed, 724 insertions(+), 689 deletions(-) -- 2.26.2
[RFC v2 4/5] perf/tools: Pass pmu_event structure as a parameter for arch_get_runtimeparam
This patch adds passing of pmu_event as a parameter in function 'arch_get_runtimeparam' which can be used to get details like if the event is percore/perchip. Signed-off-by: Kajol Jain --- tools/perf/arch/powerpc/util/header.c | 7 +-- tools/perf/util/metricgroup.c | 5 ++--- tools/perf/util/metricgroup.h | 3 ++- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/tools/perf/arch/powerpc/util/header.c b/tools/perf/arch/powerpc/util/header.c index d4870074f14c..c8a33120a7a3 100644 --- a/tools/perf/arch/powerpc/util/header.c +++ b/tools/perf/arch/powerpc/util/header.c @@ -47,8 +47,11 @@ get_cpuid_str(struct perf_pmu *pmu __maybe_unused) return bufp; } -int arch_get_runtimeparam(void) +int arch_get_runtimeparam(struct pmu_event *pe) { int count; - return sysfs__read_int("/devices/hv_24x7/interface/sockets", &count) < 0 ? 1 : count; + char path[PATH_MAX] = "/devices/hv_24x7/interface/"; + + atoi(pe->aggr_mode) == PerChip ? strcat(path, "sockets") : strcat(path, "coresperchip"); + return sysfs__read_int(path, &count) < 0 ? 1 : count; } diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c index 9e21aa767e41..c06166ec64d6 100644 --- a/tools/perf/util/metricgroup.c +++ b/tools/perf/util/metricgroup.c @@ -15,7 +15,6 @@ #include "rblist.h" #include #include -#include "pmu-events/pmu-events.h" #include "strlist.h" #include #include @@ -547,7 +546,7 @@ static bool metricgroup__has_constraint(struct pmu_event *pe) return false; } -int __weak arch_get_runtimeparam(void) +int __weak arch_get_runtimeparam(struct pmu_event *pe __maybe_unused) { return 1; } @@ -634,7 +633,7 @@ static int metricgroup__add_metric(const char *metric, bool metric_no_group, } else { int j, count; - count = arch_get_runtimeparam(); + count = arch_get_runtimeparam(pe); /* This loop is added to create multiple * events depend on count value and add diff --git a/tools/perf/util/metricgroup.h b/tools/perf/util/metricgroup.h index 287850bcdeca..c0bf77514343 100644 --- a/tools/perf/util/metricgroup.h +++ b/tools/perf/util/metricgroup.h @@ -5,6 +5,7 @@ #include #include #include +#include "pmu-events/pmu-events.h" struct evsel; struct option; @@ -37,5 +38,5 @@ int metricgroup__parse_groups(const struct option *opt, void metricgroup__print(bool metrics, bool groups, char *filter, bool raw, bool details); bool metricgroup__has_metric(const char *metric); -int arch_get_runtimeparam(void); +int arch_get_runtimeparam(struct pmu_event *pe __maybe_unused); #endif -- 2.26.2
[RFC v2 5/5] perf/tools/pmu_events/powerpc: Add hv_24x7 core level metric events
This patch adds hv_24x7 core level events in nest_metric.json file and also add PerChip/PerCore field in metric events. Result: power9 platform: command:# ./perf stat --metric-only -M PowerBUS_Frequency -C 0 -I 1000 1.706011.92.0 2.0002538812.01.9 3.0003648102.02.0 Signed-off-by: Kajol Jain --- .../arch/powerpc/power9/nest_metrics.json | 17 + 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/tools/perf/pmu-events/arch/powerpc/power9/nest_metrics.json b/tools/perf/pmu-events/arch/powerpc/power9/nest_metrics.json index c121e526442a..2a471cb5dd7a 100644 --- a/tools/perf/pmu-events/arch/powerpc/power9/nest_metrics.json +++ b/tools/perf/pmu-events/arch/powerpc/power9/nest_metrics.json @@ -3,17 +3,26 @@ "MetricExpr": "(hv_24x7@PM_MCS01_128B_RD_DISP_PORT01\\,chip\\=?@ + hv_24x7@PM_MCS01_128B_RD_DISP_PORT23\\,chip\\=?@ + hv_24x7@PM_MCS23_128B_RD_DISP_PORT01\\,chip\\=?@ + hv_24x7@PM_MCS23_128B_RD_DISP_PORT23\\,chip\\=?@)", "MetricName": "Memory_RD_BW_Chip", "MetricGroup": "Memory_BW", -"ScaleUnit": "1.6e-2MB" +"ScaleUnit": "1.6e-2MB", + "AggregationMode": "PerChip" }, { "MetricExpr": "(hv_24x7@PM_MCS01_128B_WR_DISP_PORT01\\,chip\\=?@ + hv_24x7@PM_MCS01_128B_WR_DISP_PORT23\\,chip\\=?@ + hv_24x7@PM_MCS23_128B_WR_DISP_PORT01\\,chip\\=?@ + hv_24x7@PM_MCS23_128B_WR_DISP_PORT23\\,chip\\=?@ )", "MetricName": "Memory_WR_BW_Chip", "MetricGroup": "Memory_BW", -"ScaleUnit": "1.6e-2MB" +"ScaleUnit": "1.6e-2MB", + "AggregationMode": "PerChip" }, { "MetricExpr": "(hv_24x7@PM_PB_CYC\\,chip\\=?@ )", "MetricName": "PowerBUS_Frequency", -"ScaleUnit": "2.5e-7GHz" -} +"ScaleUnit": "2.5e-7GHz", + "AggregationMode": "PerChip" +}, +{ + "MetricExpr": "(hv_24x7@CPM_CS_32MHZ_CYC\\,domain\\=3\\,core\\=?@ )", +"MetricName": "CPM_CS_32MHZ_CYC", +"ScaleUnit": "1MHz", + "AggregationMode": "PerCore" + } ] -- 2.26.2
[RFC] perf/core: Fixes hung issue on perf stat command during cpu hotplug
Commit 2ed6edd33a21 ("perf: Add cond_resched() to task_function_call()") added assignment of ret value as -EAGAIN in case function call to 'smp_call_function_single' fails. For non-zero ret value, it did 'ret = !ret ? data.ret : -EAGAIN;', which always assign -EAGAIN to ret and make second if condition useless. In scenarios like when executing a perf stat with --per-thread option, and if any of the monitoring cpu goes offline, the 'smp_call_function_single' function could return -ENXIO, and with the above check, task_function_call hung and increases CPU usage (because of repeated 'smp_call_function_single()') Recration scenario: # perf stat -a --per-thread && (offline a CPU ) Patch here removes the tertiary condition added as part of that commit and added a check for NULL and -EAGAIN. Fixes: 2ed6edd33a21("perf: Add cond_resched() to task_function_call()") Signed-off-by: Kajol Jain Reported-by: Srikar Dronamraju --- kernel/events/core.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/kernel/events/core.c b/kernel/events/core.c index 5bfe8e3c6e44..330c53f7df9c 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -115,9 +115,9 @@ task_function_call(struct task_struct *p, remote_function_f func, void *info) for (;;) { ret = smp_call_function_single(task_cpu(p), remote_function, &data, 1); - ret = !ret ? data.ret : -EAGAIN; - - if (ret != -EAGAIN) + if (!ret) + ret = data.ret; + else if (ret != -EAGAIN) break; cond_resched(); -- 2.26.2
[RFC v2] perf/core: Fixes hung issue on perf stat command during cpu hotplug
Commit 2ed6edd33a21 ("perf: Add cond_resched() to task_function_call()") added assignment of ret value as -EAGAIN in case function call to 'smp_call_function_single' fails. For non-zero ret value, it did 'ret = !ret ? data.ret : -EAGAIN;', which always assign -EAGAIN to ret and make second if condition useless. In scenarios like when executing a perf stat with --per-thread option, and if any of the monitoring cpu goes offline, the 'smp_call_function_single' function could return -ENXIO, and with the above check, task_function_call hung and increases CPU usage (because of repeated 'smp_call_function_single()') Recration scenario: # perf stat -a --per-thread && (offline a CPU ) Patch here removes the tertiary condition added as part of that commit and added a check for NULL and -EAGAIN. Fixes: 2ed6edd33a21("perf: Add cond_resched() to task_function_call()") Signed-off-by: Kajol Jain Reported-by: Srikar Dronamraju --- kernel/events/core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) Changelog: - Remove addition of else in the first patch for if(ret != -EAGAIN) condition. diff --git a/kernel/events/core.c b/kernel/events/core.c index 856d98c36f56..fe104fee097a 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -115,8 +115,8 @@ task_function_call(struct task_struct *p, remote_function_f func, void *info) for (;;) { ret = smp_call_function_single(task_cpu(p), remote_function, &data, 1); - ret = !ret ? data.ret : -EAGAIN; - + if(!ret) + ret = data.ret; if (ret != -EAGAIN) break; -- 2.26.2
[PATCH] perf/core: Fix hung issue on perf stat command during cpu hotplug
Commit 2ed6edd33a21 ("perf: Add cond_resched() to task_function_call()") added assignment of ret value as -EAGAIN in case function call to 'smp_call_function_single' fails. For non-zero ret value, it did 'ret = !ret ? data.ret : -EAGAIN;', which always assign -EAGAIN to ret and make second if condition useless. In scenarios like when executing a perf stat with --per-thread option, and if any of the monitoring cpu goes offline, the 'smp_call_function_single' function could return -ENXIO, and with the above check, task_function_call hung and increases CPU usage (because of repeated 'smp_call_function_single()') Recration scenario: # perf stat -a --per-thread && (offline a CPU ) Patch here removes the tertiary condition added as part of that commit and added a check for NULL and -EAGAIN. Fixes: 2ed6edd33a21("perf: Add cond_resched() to task_function_call()") Signed-off-by: Kajol Jain Reported-by: Srikar Dronamraju Reviewed-by: Barret Rhoden Tested-by: Srikar Dronamraju --- kernel/events/core.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) Changelog: - Remove RFC tag - Resolve some nits issues like space after if and added -ENXIO in comment msg of function 'task_function_call' as suggested by Barret Rhoden. Link to the RFC: https://lkml.org/lkml/2020/8/26/896 diff --git a/kernel/events/core.c b/kernel/events/core.c index 5bfe8e3c6e44..cef646084198 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -99,7 +99,7 @@ static void remote_function(void *data) * retry due to any failures in smp_call_function_single(), such as if the * task_cpu() goes offline concurrently. * - * returns @func return value or -ESRCH when the process isn't running + * returns @func return value or -ESRCH or -ENXIO when the process isn't running */ static int task_function_call(struct task_struct *p, remote_function_f func, void *info) @@ -115,7 +115,8 @@ task_function_call(struct task_struct *p, remote_function_f func, void *info) for (;;) { ret = smp_call_function_single(task_cpu(p), remote_function, &data, 1); - ret = !ret ? data.ret : -EAGAIN; + if (!ret) + ret = data.ret; if (ret != -EAGAIN) break; -- 2.26.2
[PATCH v6 3/5] perf jevents: Add support for parsing perchip/percore events
Initially, every time we want to add new terms like chip, core thread etc, we need to create corrsponding fields in pmu_events and event struct. This patch adds an enum called 'aggr_mode_class' which store all these aggregation like perchip/percore. It also adds new field 'aggr_mode' to capture these terms. Now, if user wants to add any new term, they just need to add it in the enum defined. Signed-off-by: Kajol Jain --- tools/perf/pmu-events/jevents.c| 16 tools/perf/pmu-events/pmu-events.h | 6 ++ 2 files changed, 22 insertions(+) diff --git a/tools/perf/pmu-events/jevents.c b/tools/perf/pmu-events/jevents.c index b205cd904a4f..f4ad2d403533 100644 --- a/tools/perf/pmu-events/jevents.c +++ b/tools/perf/pmu-events/jevents.c @@ -48,6 +48,7 @@ #include #include "jsmn.h" #include "json.h" +#include "pmu-events.h" int verbose; char *prog; @@ -60,6 +61,7 @@ struct json_event { char *pmu; char *unit; char *perpkg; + char *aggr_mode; char *metric_expr; char *metric_name; char *metric_group; @@ -74,6 +76,14 @@ struct json_event { (void)(&_min1 == &_min2); \ _min1 < _min2 ? _min1 : _min2; }) #endif +enum aggr_mode_class convert(const char *aggr_mode) +{ + if (!strcmp(aggr_mode, "PerCore")) + return PerCore; + else if (!strcmp(aggr_mode, "PerChip")) + return PerChip; + return -1; +} typedef int (*func)(void *data, struct json_event *je); @@ -368,6 +378,8 @@ static int print_events_table_entry(void *data, struct json_event *je) fprintf(outfp, "\t.unit = \"%s\",\n", je->unit); if (je->perpkg) fprintf(outfp, "\t.perpkg = \"%s\",\n", je->perpkg); + if (je->aggr_mode) + fprintf(outfp, "\t.aggr_mode = \"%d\",\n", convert(je->aggr_mode)); if (je->metric_expr) fprintf(outfp, "\t.metric_expr = \"%s\",\n", je->metric_expr); if (je->metric_name) @@ -392,6 +404,7 @@ struct event_struct { char *pmu; char *unit; char *perpkg; + char *aggr_mode; char *metric_expr; char *metric_name; char *metric_group; @@ -421,6 +434,7 @@ struct event_struct { op(pmu);\ op(unit); \ op(perpkg); \ + op(aggr_mode); \ op(metric_expr);\ op(metric_name);\ op(metric_group); \ @@ -627,6 +641,8 @@ int json_events(const char *fn, addfield(map, &je.unit, "", "", val); } else if (json_streq(map, field, "PerPkg")) { addfield(map, &je.perpkg, "", "", val); + } else if (json_streq(map, field, "AggregationMode")) { + addfield(map, &je.aggr_mode, "", "", val); } else if (json_streq(map, field, "Deprecated")) { addfield(map, &je.deprecated, "", "", val); } else if (json_streq(map, field, "MetricName")) { diff --git a/tools/perf/pmu-events/pmu-events.h b/tools/perf/pmu-events/pmu-events.h index c8f306b572f4..7da1a3743b77 100644 --- a/tools/perf/pmu-events/pmu-events.h +++ b/tools/perf/pmu-events/pmu-events.h @@ -2,6 +2,11 @@ #ifndef PMU_EVENTS_H #define PMU_EVENTS_H +enum aggr_mode_class { + PerChip = 1, + PerCore +}; + /* * Describe each PMU event. Each CPU has a table of PMU events. */ @@ -14,6 +19,7 @@ struct pmu_event { const char *pmu; const char *unit; const char *perpkg; + const char *aggr_mode; const char *metric_expr; const char *metric_name; const char *metric_group; -- 2.26.2
[PATCH v6 4/5] perf/tools: Pass pmu_event structure as a parameter for arch_get_runtimeparam
This patch adds passing of pmu_event as a parameter in function 'arch_get_runtimeparam' which can be used to get details like if the event is percore/perchip. Signed-off-by: Kajol Jain Acked-by: Ian Rogers --- tools/perf/arch/powerpc/util/header.c | 7 +-- tools/perf/util/metricgroup.c | 5 ++--- tools/perf/util/metricgroup.h | 3 ++- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/tools/perf/arch/powerpc/util/header.c b/tools/perf/arch/powerpc/util/header.c index 1a950171a66f..58b2d610aadb 100644 --- a/tools/perf/arch/powerpc/util/header.c +++ b/tools/perf/arch/powerpc/util/header.c @@ -40,8 +40,11 @@ get_cpuid_str(struct perf_pmu *pmu __maybe_unused) return bufp; } -int arch_get_runtimeparam(void) +int arch_get_runtimeparam(struct pmu_event *pe) { int count; - return sysfs__read_int("/devices/hv_24x7/interface/sockets", &count) < 0 ? 1 : count; + char path[PATH_MAX] = "/devices/hv_24x7/interface/"; + + atoi(pe->aggr_mode) == PerChip ? strcat(path, "sockets") : strcat(path, "coresperchip"); + return sysfs__read_int(path, &count) < 0 ? 1 : count; } diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c index 8831b964288f..c387aa1615ba 100644 --- a/tools/perf/util/metricgroup.c +++ b/tools/perf/util/metricgroup.c @@ -15,7 +15,6 @@ #include "rblist.h" #include #include -#include "pmu-events/pmu-events.h" #include "strlist.h" #include #include @@ -634,7 +633,7 @@ static bool metricgroup__has_constraint(struct pmu_event *pe) return false; } -int __weak arch_get_runtimeparam(void) +int __weak arch_get_runtimeparam(struct pmu_event *pe __maybe_unused) { return 1; } @@ -902,7 +901,7 @@ static int add_metric(struct list_head *metric_list, } else { int j, count; - count = arch_get_runtimeparam(); + count = arch_get_runtimeparam(pe); /* This loop is added to create multiple * events depend on count value and add diff --git a/tools/perf/util/metricgroup.h b/tools/perf/util/metricgroup.h index 62623a39cbec..491a5d78252d 100644 --- a/tools/perf/util/metricgroup.h +++ b/tools/perf/util/metricgroup.h @@ -5,6 +5,7 @@ #include #include #include +#include "pmu-events/pmu-events.h" struct evsel; struct evlist; @@ -52,6 +53,6 @@ int metricgroup__parse_groups_test(struct evlist *evlist, void metricgroup__print(bool metrics, bool groups, char *filter, bool raw, bool details); bool metricgroup__has_metric(const char *metric); -int arch_get_runtimeparam(void); +int arch_get_runtimeparam(struct pmu_event *pe __maybe_unused); void metricgroup__rblist_exit(struct rblist *metric_events); #endif -- 2.26.2
[PATCH v6 5/5] perf/tools/pmu_events/powerpc: Add hv_24x7 core level metric events
This patch adds hv_24x7 core level events in nest_metric.json file and also add PerChip/PerCore field in metric events. Result: power9 platform: command:# ./perf stat --metric-only -M PowerBUS_Frequency -C 0 -I 1000 1.706011.92.0 2.0002538812.01.9 3.0003648102.02.0 Signed-off-by: Kajol Jain Acked-by: Ian Rogers --- .../arch/powerpc/power9/nest_metrics.json | 35 --- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/tools/perf/pmu-events/arch/powerpc/power9/nest_metrics.json b/tools/perf/pmu-events/arch/powerpc/power9/nest_metrics.json index 8383a37647ad..7a5d1bf543f8 100644 --- a/tools/perf/pmu-events/arch/powerpc/power9/nest_metrics.json +++ b/tools/perf/pmu-events/arch/powerpc/power9/nest_metrics.json @@ -1,37 +1,46 @@ [ { -"MetricExpr": "(hv_24x7@PM_MCS01_128B_RD_DISP_PORT01\\,chip\\=?@ + hv_24x7@PM_MCS01_128B_RD_DISP_PORT23\\,chip\\=?@ + hv_24x7@PM_MCS23_128B_RD_DISP_PORT01\\,chip\\=?@ + hv_24x7@PM_MCS23_128B_RD_DISP_PORT23\\,chip\\=?@)", -"MetricName": "Memory_RD_BW_Chip", -"MetricGroup": "Memory_BW", -"ScaleUnit": "1.6e-2MB" + "MetricExpr": "(hv_24x7@PM_MCS01_128B_RD_DISP_PORT01\\,chip\\=?@ + hv_24x7@PM_MCS01_128B_RD_DISP_PORT23\\,chip\\=?@ + hv_24x7@PM_MCS23_128B_RD_DISP_PORT01\\,chip\\=?@ + hv_24x7@PM_MCS23_128B_RD_DISP_PORT23\\,chip\\=?@)", + "MetricName": "Memory_RD_BW_Chip", + "MetricGroup": "Memory_BW", + "ScaleUnit": "1.6e-2MB", + "AggregationMode": "PerChip" }, { "MetricExpr": "(hv_24x7@PM_MCS01_128B_WR_DISP_PORT01\\,chip\\=?@ + hv_24x7@PM_MCS01_128B_WR_DISP_PORT23\\,chip\\=?@ + hv_24x7@PM_MCS23_128B_WR_DISP_PORT01\\,chip\\=?@ + hv_24x7@PM_MCS23_128B_WR_DISP_PORT23\\,chip\\=?@ )", -"MetricName": "Memory_WR_BW_Chip", -"MetricGroup": "Memory_BW", -"ScaleUnit": "1.6e-2MB" + "MetricName": "Memory_WR_BW_Chip", + "MetricGroup": "Memory_BW", + "ScaleUnit": "1.6e-2MB", + "AggregationMode": "PerChip" }, { "MetricExpr": "(hv_24x7@PM_PB_CYC\\,chip\\=?@ )", -"MetricName": "PowerBUS_Frequency", -"ScaleUnit": "2.5e-7GHz" + "MetricName": "PowerBUS_Frequency", + "ScaleUnit": "2.5e-7GHz", + "AggregationMode": "PerChip" +}, +{ + "MetricExpr": "(hv_24x7@CPM_CS_32MHZ_CYC\\,domain\\=3\\,core\\=?@ )", + "MetricName": "CPM_CS_32MHZ_CYC", + "ScaleUnit": "1MHz", + "AggregationMode": "PerCore" }, { "MetricExpr" : "nest_mcs01_imc@PM_MCS01_128B_RD_DISP_PORT01@ + nest_mcs01_imc@PM_MCS01_128B_RD_DISP_PORT23@", "MetricName" : "mcs01-read", - "MetricGroup" : "memory_bw", + "MetricGroup" : "memory-bandwidth", "ScaleUnit": "6.1e-5MB" }, { "MetricExpr" : "nest_mcs23_imc@PM_MCS23_128B_RD_DISP_PORT01@ + nest_mcs23_imc@PM_MCS23_128B_RD_DISP_PORT23@", "MetricName" : "mcs23-read", - "MetricGroup" : "memory_bw", + "MetricGroup" : "memory-bandwidth", "ScaleUnit": "6.1e-5MB" }, { "MetricExpr" : "nest_mcs01_imc@PM_MCS01_128B_WR_DISP_PORT01@ + nest_mcs01_imc@PM_MCS01_128B_WR_DISP_PORT23@", "MetricName" : "mcs01-write", - "MetricGroup" : "memory_bw", + "MetricGroup" : "memory-bandwidth", "ScaleUnit": "6.1e-5MB" }, { @@ -48,7 +57,7 @@ { "MetricExpr" : "(nest_mcs01_imc@PM_MCS01_128B_RD_DISP_PORT01@ + nest_mcs01_imc@PM_MCS01_128B_RD_DISP_PORT23@ + nest_mcs23_imc@PM_MCS23_128B_RD_DISP_PORT01@ + nest_mcs23_imc@PM_MCS23_128B_RD_DISP_PORT23@ + nest_mcs01_imc@PM_MCS01_128B_WR_DISP_PORT01@ + nest_mcs01_imc@PM_MCS01_128B_WR_DISP_PORT23@ + nest_mcs23_imc@PM_MCS23_128B_WR_DISP_PORT01@ + nest_mcs23_imc@PM_MCS23_128B_WR_DISP_PORT23@)", "MetricName" : "Memory-bandwidth-MCS", - "MetricGroup" : "memory_bw", + "MetricGroup" : "memory-bandwidth", "ScaleUnit": "6.1e-5MB" } ] -- 2.26.2
[PATCH v6 2/5] perf/jevents: Add new structure to pass json fields.
This patch adds new structure called 'json_event' inside jevents.h file to improve the callback prototype inside jevent files. Initially, whenever user want to add new field, they need to update in all function callback which make it more and more complex with increased number of parmeters. With this change, we just need to add it in new structure 'json_event'. Signed-off-by: Kajol Jain Reviewed-by: Andi Kleen --- tools/perf/pmu-events/jevents.c | 222 +++- 1 file changed, 105 insertions(+), 117 deletions(-) diff --git a/tools/perf/pmu-events/jevents.c b/tools/perf/pmu-events/jevents.c index 1c55cc754b5a..b205cd904a4f 100644 --- a/tools/perf/pmu-events/jevents.c +++ b/tools/perf/pmu-events/jevents.c @@ -52,6 +52,21 @@ int verbose; char *prog; +struct json_event { + char *name; + char *event; + char *desc; + char *long_desc; + char *pmu; + char *unit; + char *perpkg; + char *metric_expr; + char *metric_name; + char *metric_group; + char *deprecated; + char *metric_constraint; +}; + #ifndef min #define min(x, y) ({ \ typeof(x) _min1 = (x); \ @@ -60,6 +75,8 @@ char *prog; _min1 < _min2 ? _min1 : _min2; }) #endif +typedef int (*func)(void *data, struct json_event *je); + int eprintf(int level, int var, const char *fmt, ...) { @@ -325,12 +342,7 @@ static void print_events_table_prefix(FILE *fp, const char *tblname) close_table = 1; } -static int print_events_table_entry(void *data, char *name, char *event, - char *desc, char *long_desc, - char *pmu, char *unit, char *perpkg, - char *metric_expr, - char *metric_name, char *metric_group, - char *deprecated, char *metric_constraint) +static int print_events_table_entry(void *data, struct json_event *je) { struct perf_entry_data *pd = data; FILE *outfp = pd->outfp; @@ -342,30 +354,30 @@ static int print_events_table_entry(void *data, char *name, char *event, */ fprintf(outfp, "{\n"); - if (name) - fprintf(outfp, "\t.name = \"%s\",\n", name); - if (event) - fprintf(outfp, "\t.event = \"%s\",\n", event); - fprintf(outfp, "\t.desc = \"%s\",\n", desc); + if (je->name) + fprintf(outfp, "\t.name = \"%s\",\n", je->name); + if (je->event) + fprintf(outfp, "\t.event = \"%s\",\n", je->event); + fprintf(outfp, "\t.desc = \"%s\",\n", je->desc); fprintf(outfp, "\t.topic = \"%s\",\n", topic); - if (long_desc && long_desc[0]) - fprintf(outfp, "\t.long_desc = \"%s\",\n", long_desc); - if (pmu) - fprintf(outfp, "\t.pmu = \"%s\",\n", pmu); - if (unit) - fprintf(outfp, "\t.unit = \"%s\",\n", unit); - if (perpkg) - fprintf(outfp, "\t.perpkg = \"%s\",\n", perpkg); - if (metric_expr) - fprintf(outfp, "\t.metric_expr = \"%s\",\n", metric_expr); - if (metric_name) - fprintf(outfp, "\t.metric_name = \"%s\",\n", metric_name); - if (metric_group) - fprintf(outfp, "\t.metric_group = \"%s\",\n", metric_group); - if (deprecated) - fprintf(outfp, "\t.deprecated = \"%s\",\n", deprecated); - if (metric_constraint) - fprintf(outfp, "\t.metric_constraint = \"%s\",\n", metric_constraint); + if (je->long_desc && je->long_desc[0]) + fprintf(outfp, "\t.long_desc = \"%s\",\n", je->long_desc); + if (je->pmu) + fprintf(outfp, "\t.pmu = \"%s\",\n", je->pmu); + if (je->unit) + fprintf(outfp, "\t.unit = \"%s\",\n", je->unit); + if (je->perpkg) + fprintf(outfp, "\t.perpkg = \"%s\",\n", je->perpkg); + if (je->metric_expr) + fprintf(outfp, "\t.metric_expr = \"%s\",\n", je->metric_expr); + if (je->metric_name) + fprintf(outfp, "\t.metric_name = \"%s\",\n", je->metric_name); + if (je->metric_group) + fprintf(outfp, "\t.metric_group = \"%s\",\n", je->metric_group); + if (je->deprecated) + fprintf(outfp, "\t.deprecated
[PATCH v6 0/5] powerpc/perf: Add json file support for hv_24x7 core level events
Patchset enhance current runtime parameter support. It introduces new fields like "PerChip" and "PerCore" similar to the field "PerPkg" which is used to specify perpkg events. The "PerCore" and "PerChip" specifies whether its core or chip events. Based on which we can decide which runtime parameter user want to access. Now character '?' can refers different parameter based on user requirement. Initially, every time we want to add new terms like chip, core, thread etc, we need to create corrsponding fields in pmu_events and event struct. This patchset adds an enum called 'aggr_mode_class' which store all these aggregation like perchip/percore. It also adds new field 'AggregationMode' to capture these terms. Now, if user wants to add any new term, they just need to add it in the enum defined. This patchset also adds changes of adding new structure called 'json_event' inside jevents.h file to improve the callback prototype inside jevent files. Initially, whenever user want to add new field, they need to update in all function callback which makes it more and more complex with increased number of parmeters. With this change, we just need to add it in new structure 'json_event'. link to the patch: https://lkml.org/lkml/2020/8/25/217 Changelog: v5 -> v6 - Made changes to improve callback prototype inside jevent file by adding new struture 'json_event' as suggested by Andi Kleen. - Added Reviewd-by tag from Andi Kleen - Made changes suggested by Jiri Olsa and John garry includes: - Removing jevents.h file. - Some nits like freeing je->event mem, adding typedef for func and not allocating mem for json_event structure. - Added free for each field in json_event as suggested by John Garry. - In real_event function, rather then returning fixed structure pointer, used strcpy to copy event to je->event field. - Also merge some changes in this patch set from the patch- https://lkml.org/lkml/2020/8/21/222. except nest event change which was using capability of defining metric using other metric. - Make power side changes as per new struture added. Link to the previous version patchset: https://lkml.org/lkml/2020/8/16/50 Kajol Jain (5): perf/jevents: Remove jevents.h file perf/jevents: Add new structure to pass json fields. perf jevents: Add support for parsing perchip/percore events perf/tools: Pass pmu_event structure as a parameter for arch_get_runtimeparam perf/tools/pmu_events/powerpc: Add hv_24x7 core level metric events tools/perf/arch/powerpc/util/header.c | 7 +- .../arch/powerpc/power9/nest_metrics.json | 35 ++- tools/perf/pmu-events/jevents.c | 247 +- tools/perf/pmu-events/jevents.h | 23 -- tools/perf/pmu-events/pmu-events.h| 6 + tools/perf/util/metricgroup.c | 5 +- tools/perf/util/metricgroup.h | 3 +- 7 files changed, 166 insertions(+), 160 deletions(-) delete mode 100644 tools/perf/pmu-events/jevents.h -- 2.26.2
[PATCH v6 1/5] perf/jevents: Remove jevents.h file
This patch removes jevents.h file and add its data inside jevents.c as this file is only included there. Signed-off-by: Kajol Jain --- tools/perf/pmu-events/jevents.c | 9 - tools/perf/pmu-events/jevents.h | 23 --- 2 files changed, 8 insertions(+), 24 deletions(-) delete mode 100644 tools/perf/pmu-events/jevents.h diff --git a/tools/perf/pmu-events/jevents.c b/tools/perf/pmu-events/jevents.c index fa86c5f997cc..1c55cc754b5a 100644 --- a/tools/perf/pmu-events/jevents.c +++ b/tools/perf/pmu-events/jevents.c @@ -48,11 +48,18 @@ #include #include "jsmn.h" #include "json.h" -#include "jevents.h" int verbose; char *prog; +#ifndef min +#define min(x, y) ({ \ + typeof(x) _min1 = (x); \ + typeof(y) _min2 = (y); \ + (void)(&_min1 == &_min2); \ + _min1 < _min2 ? _min1 : _min2; }) +#endif + int eprintf(int level, int var, const char *fmt, ...) { diff --git a/tools/perf/pmu-events/jevents.h b/tools/perf/pmu-events/jevents.h deleted file mode 100644 index 2afc8304529e.. --- a/tools/perf/pmu-events/jevents.h +++ /dev/null @@ -1,23 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef JEVENTS_H -#define JEVENTS_H 1 - -int json_events(const char *fn, - int (*func)(void *data, char *name, char *event, char *desc, - char *long_desc, - char *pmu, - char *unit, char *perpkg, char *metric_expr, - char *metric_name, char *metric_group, - char *deprecated, char *metric_constraint), - void *data); -char *get_cpu_str(void); - -#ifndef min -#define min(x, y) ({\ - typeof(x) _min1 = (x); \ - typeof(y) _min2 = (y); \ - (void) (&_min1 == &_min2); \ - _min1 < _min2 ? _min1 : _min2; }) -#endif - -#endif -- 2.26.2
[RFC] perf/jevents: Add new structure to pass json fields.
This patch adds new structure called 'json_event' inside jevents.h file to improve the callback prototype inside jevent files. Initially, whenever user want to add new field, they need to update in all function callback which make it more and more complex with increased number of parmeters. With this change, we just need to add it in new structure 'json_event'. Signed-off-by: Kajol Jain --- tools/perf/pmu-events/jevents.c | 188 +--- tools/perf/pmu-events/jevents.h | 28 +++-- 2 files changed, 94 insertions(+), 122 deletions(-) This is the initial prototype to include structure for passing json fileds. Please, Let me know if this is the right direction to go forward. This patch doen't include all the changes, like percore/perchip field addition. If this looks fine I can send new patch set with those changes. diff --git a/tools/perf/pmu-events/jevents.c b/tools/perf/pmu-events/jevents.c index fa86c5f997cc..606805af69fe 100644 --- a/tools/perf/pmu-events/jevents.c +++ b/tools/perf/pmu-events/jevents.c @@ -318,12 +318,7 @@ static void print_events_table_prefix(FILE *fp, const char *tblname) close_table = 1; } -static int print_events_table_entry(void *data, char *name, char *event, - char *desc, char *long_desc, - char *pmu, char *unit, char *perpkg, - char *metric_expr, - char *metric_name, char *metric_group, - char *deprecated, char *metric_constraint) +static int print_events_table_entry(void *data, struct json_event *je) { struct perf_entry_data *pd = data; FILE *outfp = pd->outfp; @@ -335,30 +330,30 @@ static int print_events_table_entry(void *data, char *name, char *event, */ fprintf(outfp, "{\n"); - if (name) - fprintf(outfp, "\t.name = \"%s\",\n", name); - if (event) - fprintf(outfp, "\t.event = \"%s\",\n", event); - fprintf(outfp, "\t.desc = \"%s\",\n", desc); + if (je->name) + fprintf(outfp, "\t.name = \"%s\",\n", je->name); + if (je->event) + fprintf(outfp, "\t.event = \"%s\",\n", je->event); + fprintf(outfp, "\t.desc = \"%s\",\n", je->desc); fprintf(outfp, "\t.topic = \"%s\",\n", topic); - if (long_desc && long_desc[0]) - fprintf(outfp, "\t.long_desc = \"%s\",\n", long_desc); - if (pmu) - fprintf(outfp, "\t.pmu = \"%s\",\n", pmu); - if (unit) - fprintf(outfp, "\t.unit = \"%s\",\n", unit); - if (perpkg) - fprintf(outfp, "\t.perpkg = \"%s\",\n", perpkg); - if (metric_expr) - fprintf(outfp, "\t.metric_expr = \"%s\",\n", metric_expr); - if (metric_name) - fprintf(outfp, "\t.metric_name = \"%s\",\n", metric_name); - if (metric_group) - fprintf(outfp, "\t.metric_group = \"%s\",\n", metric_group); - if (deprecated) - fprintf(outfp, "\t.deprecated = \"%s\",\n", deprecated); - if (metric_constraint) - fprintf(outfp, "\t.metric_constraint = \"%s\",\n", metric_constraint); + if (je->long_desc && je->long_desc[0]) + fprintf(outfp, "\t.long_desc = \"%s\",\n", je->long_desc); + if (je->pmu) + fprintf(outfp, "\t.pmu = \"%s\",\n", je->pmu); + if (je->unit) + fprintf(outfp, "\t.unit = \"%s\",\n", je->unit); + if (je->perpkg) + fprintf(outfp, "\t.perpkg = \"%s\",\n", je->perpkg); + if (je->metric_expr) + fprintf(outfp, "\t.metric_expr = \"%s\",\n", je->metric_expr); + if (je->metric_name) + fprintf(outfp, "\t.metric_name = \"%s\",\n", je->metric_name); + if (je->metric_group) + fprintf(outfp, "\t.metric_group = \"%s\",\n", je->metric_group); + if (je->deprecated) + fprintf(outfp, "\t.deprecated = \"%s\",\n", je->deprecated); + if (je->metric_constraint) + fprintf(outfp, "\t.metric_constraint = \"%s\",\n", je->metric_constraint); fprintf(outfp, "},\n"); return 0; @@ -380,17 +375,17 @@ struct event_struct { char *metr
[PATCH v7 0/5] powerpc/perf: Add json file support for hv_24x7 core level events
Patchset enhance current runtime parameter support. It introduces new fields like "PerChip" and "PerCore" similar to the field "PerPkg" which is used to specify perpkg events. The "PerCore" and "PerChip" specifies whether its core or chip events. Based on which we can decide which runtime parameter user want to access. Now character '?' can refers different parameter based on user requirement. Initially, every time we want to add new terms like chip, core, thread etc, we need to create corrsponding fields in pmu_events and event struct. This patchset adds an enum called 'aggr_mode_class' which store all these aggregation like perchip/percore. It also adds new field 'AggregationMode' to capture these terms. Now, if user wants to add any new term, they just need to add it in the enum defined. This patchset also adds changes of adding new structure called 'json_event' inside jevents.h file to improve the callback prototype inside jevent files. Initially, whenever user want to add new field, they need to update in all function callback which makes it more and more complex with increased number of parmeters. With this change, we just need to add it in new structure 'json_event'. link to the patch: https://lkml.org/lkml/2020/8/25/217 Changelog: v6 -> v7 - Remove min and get_cpu_str functions from jevents.c - Make json_events function static to solve warning part [John Garry]. - Add event attribute in json_events function to remove strcpy from real_event function, as suggested by Jiri Olsa. - Add warning while checking aggr_mode value [Jiri Olsa]. v5 -> v6 - Made changes to improve callback prototype inside jevent file by adding new struture 'json_event' as suggested by Andi Kleen. - Added Reviewd-by tag from Andi Kleen - Made changes suggested by Jiri Olsa and John garry includes: - Removing jevents.h file. - Some nits like freeing je->event mem, adding typedef for func and not allocating mem for json_event structure. - Added free for each field in json_event as suggested by John Garry. - In real_event function, rather then returning fixed structure pointer, used strcpy to copy event to je->event field. - Also merge some changes in this patch set from the patch- https://lkml.org/lkml/2020/8/21/222. except nest event change which was using capability of defining metric using other metric. - Make power side changes as per new struture added. Link to the previous version patchset: https://lkml.org/lkml/2020/8/27/799 Kajol Jain (5): perf/jevents: Remove jevents.h file perf/jevents: Add new structure to pass json fields. perf jevents: Add support for parsing perchip/percore events perf/tools: Pass pmu_event structure as a parameter for arch_get_runtimeparam perf/tools/pmu_events/powerpc: Add hv_24x7 core level metric events tools/perf/arch/powerpc/util/header.c | 7 +- .../arch/powerpc/power9/nest_metrics.json | 35 ++- tools/perf/pmu-events/jevents.c | 234 +- tools/perf/pmu-events/jevents.h | 23 -- tools/perf/pmu-events/pmu-events.h| 6 + tools/perf/util/metricgroup.c | 5 +- tools/perf/util/metricgroup.h | 3 +- 7 files changed, 154 insertions(+), 159 deletions(-) delete mode 100644 tools/perf/pmu-events/jevents.h -- 2.26.2
[PATCH v7 2/5] perf/jevents: Add new structure to pass json fields.
This patch adds new structure called 'json_event' inside jevents.h file to improve the callback prototype inside jevent files. Initially, whenever user want to add new field, they need to update in all function callback which make it more and more complex with increased number of parmeters. With this change, we just need to add it in new structure 'json_event'. Signed-off-by: Kajol Jain Reviewed-by: Andi Kleen --- tools/perf/pmu-events/jevents.c | 214 +++- 1 file changed, 98 insertions(+), 116 deletions(-) diff --git a/tools/perf/pmu-events/jevents.c b/tools/perf/pmu-events/jevents.c index 558b6b6270da..388dd287d736 100644 --- a/tools/perf/pmu-events/jevents.c +++ b/tools/perf/pmu-events/jevents.c @@ -52,6 +52,23 @@ int verbose; char *prog; +struct json_event { + char *name; + char *event; + char *desc; + char *long_desc; + char *pmu; + char *unit; + char *perpkg; + char *metric_expr; + char *metric_name; + char *metric_group; + char *deprecated; + char *metric_constraint; +}; + +typedef int (*func)(void *data, struct json_event *je); + int eprintf(int level, int var, const char *fmt, ...) { @@ -70,11 +87,6 @@ int eprintf(int level, int var, const char *fmt, ...) return ret; } -__attribute__((weak)) char *get_cpu_str(void) -{ - return NULL; -} - static void addfield(char *map, char **dst, const char *sep, const char *a, jsmntok_t *bt) { @@ -317,12 +329,7 @@ static void print_events_table_prefix(FILE *fp, const char *tblname) close_table = 1; } -static int print_events_table_entry(void *data, char *name, char *event, - char *desc, char *long_desc, - char *pmu, char *unit, char *perpkg, - char *metric_expr, - char *metric_name, char *metric_group, - char *deprecated, char *metric_constraint) +static int print_events_table_entry(void *data, struct json_event *je) { struct perf_entry_data *pd = data; FILE *outfp = pd->outfp; @@ -334,30 +341,30 @@ static int print_events_table_entry(void *data, char *name, char *event, */ fprintf(outfp, "{\n"); - if (name) - fprintf(outfp, "\t.name = \"%s\",\n", name); - if (event) - fprintf(outfp, "\t.event = \"%s\",\n", event); - fprintf(outfp, "\t.desc = \"%s\",\n", desc); + if (je->name) + fprintf(outfp, "\t.name = \"%s\",\n", je->name); + if (je->event) + fprintf(outfp, "\t.event = \"%s\",\n", je->event); + fprintf(outfp, "\t.desc = \"%s\",\n", je->desc); fprintf(outfp, "\t.topic = \"%s\",\n", topic); - if (long_desc && long_desc[0]) - fprintf(outfp, "\t.long_desc = \"%s\",\n", long_desc); - if (pmu) - fprintf(outfp, "\t.pmu = \"%s\",\n", pmu); - if (unit) - fprintf(outfp, "\t.unit = \"%s\",\n", unit); - if (perpkg) - fprintf(outfp, "\t.perpkg = \"%s\",\n", perpkg); - if (metric_expr) - fprintf(outfp, "\t.metric_expr = \"%s\",\n", metric_expr); - if (metric_name) - fprintf(outfp, "\t.metric_name = \"%s\",\n", metric_name); - if (metric_group) - fprintf(outfp, "\t.metric_group = \"%s\",\n", metric_group); - if (deprecated) - fprintf(outfp, "\t.deprecated = \"%s\",\n", deprecated); - if (metric_constraint) - fprintf(outfp, "\t.metric_constraint = \"%s\",\n", metric_constraint); + if (je->long_desc && je->long_desc[0]) + fprintf(outfp, "\t.long_desc = \"%s\",\n", je->long_desc); + if (je->pmu) + fprintf(outfp, "\t.pmu = \"%s\",\n", je->pmu); + if (je->unit) + fprintf(outfp, "\t.unit = \"%s\",\n", je->unit); + if (je->perpkg) + fprintf(outfp, "\t.perpkg = \"%s\",\n", je->perpkg); + if (je->metric_expr) + fprintf(outfp, "\t.metric_expr = \"%s\",\n", je->metric_expr); + if (je->metric_name) + fprintf(outfp, "\t.metric_name = \"%s\",\n", je->metric_name); + if (je->metric_group) + fprintf(outfp, "\t.metric_group = \"%s\",\n", je
[PATCH v7 4/5] perf/tools: Pass pmu_event structure as a parameter for arch_get_runtimeparam
This patch adds passing of pmu_event as a parameter in function 'arch_get_runtimeparam' which can be used to get details like if the event is percore/perchip. Signed-off-by: Kajol Jain Acked-by: Ian Rogers --- tools/perf/arch/powerpc/util/header.c | 7 +-- tools/perf/util/metricgroup.c | 5 ++--- tools/perf/util/metricgroup.h | 3 ++- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/tools/perf/arch/powerpc/util/header.c b/tools/perf/arch/powerpc/util/header.c index 1a950171a66f..58b2d610aadb 100644 --- a/tools/perf/arch/powerpc/util/header.c +++ b/tools/perf/arch/powerpc/util/header.c @@ -40,8 +40,11 @@ get_cpuid_str(struct perf_pmu *pmu __maybe_unused) return bufp; } -int arch_get_runtimeparam(void) +int arch_get_runtimeparam(struct pmu_event *pe) { int count; - return sysfs__read_int("/devices/hv_24x7/interface/sockets", &count) < 0 ? 1 : count; + char path[PATH_MAX] = "/devices/hv_24x7/interface/"; + + atoi(pe->aggr_mode) == PerChip ? strcat(path, "sockets") : strcat(path, "coresperchip"); + return sysfs__read_int(path, &count) < 0 ? 1 : count; } diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c index 8831b964288f..c387aa1615ba 100644 --- a/tools/perf/util/metricgroup.c +++ b/tools/perf/util/metricgroup.c @@ -15,7 +15,6 @@ #include "rblist.h" #include #include -#include "pmu-events/pmu-events.h" #include "strlist.h" #include #include @@ -634,7 +633,7 @@ static bool metricgroup__has_constraint(struct pmu_event *pe) return false; } -int __weak arch_get_runtimeparam(void) +int __weak arch_get_runtimeparam(struct pmu_event *pe __maybe_unused) { return 1; } @@ -902,7 +901,7 @@ static int add_metric(struct list_head *metric_list, } else { int j, count; - count = arch_get_runtimeparam(); + count = arch_get_runtimeparam(pe); /* This loop is added to create multiple * events depend on count value and add diff --git a/tools/perf/util/metricgroup.h b/tools/perf/util/metricgroup.h index 62623a39cbec..491a5d78252d 100644 --- a/tools/perf/util/metricgroup.h +++ b/tools/perf/util/metricgroup.h @@ -5,6 +5,7 @@ #include #include #include +#include "pmu-events/pmu-events.h" struct evsel; struct evlist; @@ -52,6 +53,6 @@ int metricgroup__parse_groups_test(struct evlist *evlist, void metricgroup__print(bool metrics, bool groups, char *filter, bool raw, bool details); bool metricgroup__has_metric(const char *metric); -int arch_get_runtimeparam(void); +int arch_get_runtimeparam(struct pmu_event *pe __maybe_unused); void metricgroup__rblist_exit(struct rblist *metric_events); #endif -- 2.26.2
[PATCH v7 1/5] perf/jevents: Remove jevents.h file
This patch removes jevents.h file. Signed-off-by: Kajol Jain --- tools/perf/pmu-events/jevents.c | 1 - tools/perf/pmu-events/jevents.h | 23 --- 2 files changed, 24 deletions(-) delete mode 100644 tools/perf/pmu-events/jevents.h diff --git a/tools/perf/pmu-events/jevents.c b/tools/perf/pmu-events/jevents.c index fa86c5f997cc..558b6b6270da 100644 --- a/tools/perf/pmu-events/jevents.c +++ b/tools/perf/pmu-events/jevents.c @@ -48,7 +48,6 @@ #include #include "jsmn.h" #include "json.h" -#include "jevents.h" int verbose; char *prog; diff --git a/tools/perf/pmu-events/jevents.h b/tools/perf/pmu-events/jevents.h deleted file mode 100644 index 2afc8304529e.. --- a/tools/perf/pmu-events/jevents.h +++ /dev/null @@ -1,23 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef JEVENTS_H -#define JEVENTS_H 1 - -int json_events(const char *fn, - int (*func)(void *data, char *name, char *event, char *desc, - char *long_desc, - char *pmu, - char *unit, char *perpkg, char *metric_expr, - char *metric_name, char *metric_group, - char *deprecated, char *metric_constraint), - void *data); -char *get_cpu_str(void); - -#ifndef min -#define min(x, y) ({\ - typeof(x) _min1 = (x); \ - typeof(y) _min2 = (y); \ - (void) (&_min1 == &_min2); \ - _min1 < _min2 ? _min1 : _min2; }) -#endif - -#endif -- 2.26.2
[PATCH v7 5/5] perf/tools/pmu_events/powerpc: Add hv_24x7 core level metric events
This patch adds hv_24x7 core level events in nest_metric.json file and also add PerChip/PerCore field in metric events. Result: power9 platform: command:# ./perf stat --metric-only -M PowerBUS_Frequency -C 0 -I 1000 1.706011.92.0 2.0002538812.01.9 3.0003648102.02.0 Signed-off-by: Kajol Jain Acked-by: Ian Rogers --- .../arch/powerpc/power9/nest_metrics.json | 35 --- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/tools/perf/pmu-events/arch/powerpc/power9/nest_metrics.json b/tools/perf/pmu-events/arch/powerpc/power9/nest_metrics.json index 8383a37647ad..7a5d1bf543f8 100644 --- a/tools/perf/pmu-events/arch/powerpc/power9/nest_metrics.json +++ b/tools/perf/pmu-events/arch/powerpc/power9/nest_metrics.json @@ -1,37 +1,46 @@ [ { -"MetricExpr": "(hv_24x7@PM_MCS01_128B_RD_DISP_PORT01\\,chip\\=?@ + hv_24x7@PM_MCS01_128B_RD_DISP_PORT23\\,chip\\=?@ + hv_24x7@PM_MCS23_128B_RD_DISP_PORT01\\,chip\\=?@ + hv_24x7@PM_MCS23_128B_RD_DISP_PORT23\\,chip\\=?@)", -"MetricName": "Memory_RD_BW_Chip", -"MetricGroup": "Memory_BW", -"ScaleUnit": "1.6e-2MB" + "MetricExpr": "(hv_24x7@PM_MCS01_128B_RD_DISP_PORT01\\,chip\\=?@ + hv_24x7@PM_MCS01_128B_RD_DISP_PORT23\\,chip\\=?@ + hv_24x7@PM_MCS23_128B_RD_DISP_PORT01\\,chip\\=?@ + hv_24x7@PM_MCS23_128B_RD_DISP_PORT23\\,chip\\=?@)", + "MetricName": "Memory_RD_BW_Chip", + "MetricGroup": "Memory_BW", + "ScaleUnit": "1.6e-2MB", + "AggregationMode": "PerChip" }, { "MetricExpr": "(hv_24x7@PM_MCS01_128B_WR_DISP_PORT01\\,chip\\=?@ + hv_24x7@PM_MCS01_128B_WR_DISP_PORT23\\,chip\\=?@ + hv_24x7@PM_MCS23_128B_WR_DISP_PORT01\\,chip\\=?@ + hv_24x7@PM_MCS23_128B_WR_DISP_PORT23\\,chip\\=?@ )", -"MetricName": "Memory_WR_BW_Chip", -"MetricGroup": "Memory_BW", -"ScaleUnit": "1.6e-2MB" + "MetricName": "Memory_WR_BW_Chip", + "MetricGroup": "Memory_BW", + "ScaleUnit": "1.6e-2MB", + "AggregationMode": "PerChip" }, { "MetricExpr": "(hv_24x7@PM_PB_CYC\\,chip\\=?@ )", -"MetricName": "PowerBUS_Frequency", -"ScaleUnit": "2.5e-7GHz" + "MetricName": "PowerBUS_Frequency", + "ScaleUnit": "2.5e-7GHz", + "AggregationMode": "PerChip" +}, +{ + "MetricExpr": "(hv_24x7@CPM_CS_32MHZ_CYC\\,domain\\=3\\,core\\=?@ )", + "MetricName": "CPM_CS_32MHZ_CYC", + "ScaleUnit": "1MHz", + "AggregationMode": "PerCore" }, { "MetricExpr" : "nest_mcs01_imc@PM_MCS01_128B_RD_DISP_PORT01@ + nest_mcs01_imc@PM_MCS01_128B_RD_DISP_PORT23@", "MetricName" : "mcs01-read", - "MetricGroup" : "memory_bw", + "MetricGroup" : "memory-bandwidth", "ScaleUnit": "6.1e-5MB" }, { "MetricExpr" : "nest_mcs23_imc@PM_MCS23_128B_RD_DISP_PORT01@ + nest_mcs23_imc@PM_MCS23_128B_RD_DISP_PORT23@", "MetricName" : "mcs23-read", - "MetricGroup" : "memory_bw", + "MetricGroup" : "memory-bandwidth", "ScaleUnit": "6.1e-5MB" }, { "MetricExpr" : "nest_mcs01_imc@PM_MCS01_128B_WR_DISP_PORT01@ + nest_mcs01_imc@PM_MCS01_128B_WR_DISP_PORT23@", "MetricName" : "mcs01-write", - "MetricGroup" : "memory_bw", + "MetricGroup" : "memory-bandwidth", "ScaleUnit": "6.1e-5MB" }, { @@ -48,7 +57,7 @@ { "MetricExpr" : "(nest_mcs01_imc@PM_MCS01_128B_RD_DISP_PORT01@ + nest_mcs01_imc@PM_MCS01_128B_RD_DISP_PORT23@ + nest_mcs23_imc@PM_MCS23_128B_RD_DISP_PORT01@ + nest_mcs23_imc@PM_MCS23_128B_RD_DISP_PORT23@ + nest_mcs01_imc@PM_MCS01_128B_WR_DISP_PORT01@ + nest_mcs01_imc@PM_MCS01_128B_WR_DISP_PORT23@ + nest_mcs23_imc@PM_MCS23_128B_WR_DISP_PORT01@ + nest_mcs23_imc@PM_MCS23_128B_WR_DISP_PORT23@)", "MetricName" : "Memory-bandwidth-MCS", - "MetricGroup" : "memory_bw", + "MetricGroup" : "memory-bandwidth", "ScaleUnit": "6.1e-5MB" } ] -- 2.26.2
[PATCH v7 3/5] perf jevents: Add support for parsing perchip/percore events
Initially, every time we want to add new terms like chip, core thread etc, we need to create corrsponding fields in pmu_events and event struct. This patch adds an enum called 'aggr_mode_class' which store all these aggregation like perchip/percore. It also adds new field 'aggr_mode' to capture these terms. Now, if user wants to add any new term, they just need to add it in the enum defined. Signed-off-by: Kajol Jain --- tools/perf/pmu-events/jevents.c| 19 +++ tools/perf/pmu-events/pmu-events.h | 6 ++ 2 files changed, 25 insertions(+) diff --git a/tools/perf/pmu-events/jevents.c b/tools/perf/pmu-events/jevents.c index 388dd287d736..767a6d59b07a 100644 --- a/tools/perf/pmu-events/jevents.c +++ b/tools/perf/pmu-events/jevents.c @@ -48,6 +48,7 @@ #include #include "jsmn.h" #include "json.h" +#include "pmu-events.h" int verbose; char *prog; @@ -60,6 +61,7 @@ struct json_event { char *pmu; char *unit; char *perpkg; + char *aggr_mode; char *metric_expr; char *metric_name; char *metric_group; @@ -67,6 +69,17 @@ struct json_event { char *metric_constraint; }; +enum aggr_mode_class convert(const char *aggr_mode) +{ + if (!strcmp(aggr_mode, "PerCore")) + return PerCore; + else if (!strcmp(aggr_mode, "PerChip")) + return PerChip; + + pr_err("%s: Wrong AggregationMode value '%s'\n", prog, aggr_mode); + return -1; +} + typedef int (*func)(void *data, struct json_event *je); int eprintf(int level, int var, const char *fmt, ...) @@ -355,6 +368,8 @@ static int print_events_table_entry(void *data, struct json_event *je) fprintf(outfp, "\t.unit = \"%s\",\n", je->unit); if (je->perpkg) fprintf(outfp, "\t.perpkg = \"%s\",\n", je->perpkg); + if (je->aggr_mode) + fprintf(outfp, "\t.aggr_mode = \"%d\",\n", convert(je->aggr_mode)); if (je->metric_expr) fprintf(outfp, "\t.metric_expr = \"%s\",\n", je->metric_expr); if (je->metric_name) @@ -379,6 +394,7 @@ struct event_struct { char *pmu; char *unit; char *perpkg; + char *aggr_mode; char *metric_expr; char *metric_name; char *metric_group; @@ -408,6 +424,7 @@ struct event_struct { op(pmu);\ op(unit); \ op(perpkg); \ + op(aggr_mode); \ op(metric_expr);\ op(metric_name);\ op(metric_group); \ @@ -613,6 +630,8 @@ static int json_events(const char *fn, addfield(map, &je.unit, "", "", val); } else if (json_streq(map, field, "PerPkg")) { addfield(map, &je.perpkg, "", "", val); + } else if (json_streq(map, field, "AggregationMode")) { + addfield(map, &je.aggr_mode, "", "", val); } else if (json_streq(map, field, "Deprecated")) { addfield(map, &je.deprecated, "", "", val); } else if (json_streq(map, field, "MetricName")) { diff --git a/tools/perf/pmu-events/pmu-events.h b/tools/perf/pmu-events/pmu-events.h index c8f306b572f4..7da1a3743b77 100644 --- a/tools/perf/pmu-events/pmu-events.h +++ b/tools/perf/pmu-events/pmu-events.h @@ -2,6 +2,11 @@ #ifndef PMU_EVENTS_H #define PMU_EVENTS_H +enum aggr_mode_class { + PerChip = 1, + PerCore +}; + /* * Describe each PMU event. Each CPU has a table of PMU events. */ @@ -14,6 +19,7 @@ struct pmu_event { const char *pmu; const char *unit; const char *perpkg; + const char *aggr_mode; const char *metric_expr; const char *metric_name; const char *metric_group; -- 2.26.2
[PATCH v8 0/5] powerpc/perf: Add json file support for hv_24x7 core level events
Patchset enhance current runtime parameter support. It introduces new fields like "PerChip" and "PerCore" similar to the field "PerPkg" which is used to specify perpkg events. The "PerCore" and "PerChip" specifies whether its core or chip events. Based on which we can decide which runtime parameter user want to access. Now character '?' can refers different parameter based on user requirement. Initially, every time we want to add new terms like chip, core, thread etc, we need to create corrsponding fields in pmu_events and event struct. This patchset adds an enum called 'aggr_mode_class' which store all these aggregation like perchip/percore. It also adds new field 'AggregationMode' to capture these terms. Now, if user wants to add any new term, they just need to add it in the enum defined. This patchset also adds changes of adding new structure called 'json_event' inside jevents.c file to improve the callback prototype inside jevent file. Initially, whenever user want to add new field, they need to update in all function callback which makes it more and more complex with increased number of parmeters. With this change, we just need to add it in new structure 'json_event'. link to the RFC patch: https://lkml.org/lkml/2020/8/25/217 Changelog: v7 -> v8 - Change commit typo from jevents.h to jevents.c - Make json_events function static in first patch. v6 -> v7 - Remove min and get_cpu_str functions from jevents.c - Make json_events function static to solve warning part [John Garry]. - Add event attribute in json_events function to remove strcpy from real_event function, as suggested by Jiri Olsa. - Add warning while checking aggr_mode value [Jiri Olsa]. Kajol Jain (5): perf/jevents: Remove jevents.h file perf/jevents: Add new structure to pass json fields. perf jevents: Add support for parsing perchip/percore events perf/tools: Pass pmu_event structure as a parameter for arch_get_runtimeparam perf/tools/pmu_events/powerpc: Add hv_24x7 core level metric events tools/perf/arch/powerpc/util/header.c | 7 +- .../arch/powerpc/power9/nest_metrics.json | 35 ++- tools/perf/pmu-events/jevents.c | 234 +- tools/perf/pmu-events/jevents.h | 23 -- tools/perf/pmu-events/pmu-events.h| 6 + tools/perf/util/metricgroup.c | 5 +- tools/perf/util/metricgroup.h | 3 +- 7 files changed, 154 insertions(+), 159 deletions(-) delete mode 100644 tools/perf/pmu-events/jevents.h -- 2.26.2
[PATCH v8 4/5] perf/tools: Pass pmu_event structure as a parameter for arch_get_runtimeparam
This patch adds passing of pmu_event as a parameter in function 'arch_get_runtimeparam' which can be used to get details like if the event is percore/perchip. Signed-off-by: Kajol Jain Acked-by: Ian Rogers --- tools/perf/arch/powerpc/util/header.c | 7 +-- tools/perf/util/metricgroup.c | 5 ++--- tools/perf/util/metricgroup.h | 3 ++- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/tools/perf/arch/powerpc/util/header.c b/tools/perf/arch/powerpc/util/header.c index 1a950171a66f..58b2d610aadb 100644 --- a/tools/perf/arch/powerpc/util/header.c +++ b/tools/perf/arch/powerpc/util/header.c @@ -40,8 +40,11 @@ get_cpuid_str(struct perf_pmu *pmu __maybe_unused) return bufp; } -int arch_get_runtimeparam(void) +int arch_get_runtimeparam(struct pmu_event *pe) { int count; - return sysfs__read_int("/devices/hv_24x7/interface/sockets", &count) < 0 ? 1 : count; + char path[PATH_MAX] = "/devices/hv_24x7/interface/"; + + atoi(pe->aggr_mode) == PerChip ? strcat(path, "sockets") : strcat(path, "coresperchip"); + return sysfs__read_int(path, &count) < 0 ? 1 : count; } diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c index 8831b964288f..c387aa1615ba 100644 --- a/tools/perf/util/metricgroup.c +++ b/tools/perf/util/metricgroup.c @@ -15,7 +15,6 @@ #include "rblist.h" #include #include -#include "pmu-events/pmu-events.h" #include "strlist.h" #include #include @@ -634,7 +633,7 @@ static bool metricgroup__has_constraint(struct pmu_event *pe) return false; } -int __weak arch_get_runtimeparam(void) +int __weak arch_get_runtimeparam(struct pmu_event *pe __maybe_unused) { return 1; } @@ -902,7 +901,7 @@ static int add_metric(struct list_head *metric_list, } else { int j, count; - count = arch_get_runtimeparam(); + count = arch_get_runtimeparam(pe); /* This loop is added to create multiple * events depend on count value and add diff --git a/tools/perf/util/metricgroup.h b/tools/perf/util/metricgroup.h index 62623a39cbec..491a5d78252d 100644 --- a/tools/perf/util/metricgroup.h +++ b/tools/perf/util/metricgroup.h @@ -5,6 +5,7 @@ #include #include #include +#include "pmu-events/pmu-events.h" struct evsel; struct evlist; @@ -52,6 +53,6 @@ int metricgroup__parse_groups_test(struct evlist *evlist, void metricgroup__print(bool metrics, bool groups, char *filter, bool raw, bool details); bool metricgroup__has_metric(const char *metric); -int arch_get_runtimeparam(void); +int arch_get_runtimeparam(struct pmu_event *pe __maybe_unused); void metricgroup__rblist_exit(struct rblist *metric_events); #endif -- 2.26.2
[PATCH v8 5/5] perf/tools/pmu_events/powerpc: Add hv_24x7 core level metric events
This patch adds hv_24x7 core level events in nest_metric.json file and also add PerChip/PerCore field in metric events. Result: power9 platform: command:# ./perf stat --metric-only -M PowerBUS_Frequency -C 0 -I 1000 1.706011.92.0 2.0002538812.01.9 3.0003648102.02.0 Signed-off-by: Kajol Jain Acked-by: Ian Rogers --- .../arch/powerpc/power9/nest_metrics.json | 35 --- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/tools/perf/pmu-events/arch/powerpc/power9/nest_metrics.json b/tools/perf/pmu-events/arch/powerpc/power9/nest_metrics.json index 8383a37647ad..7a5d1bf543f8 100644 --- a/tools/perf/pmu-events/arch/powerpc/power9/nest_metrics.json +++ b/tools/perf/pmu-events/arch/powerpc/power9/nest_metrics.json @@ -1,37 +1,46 @@ [ { -"MetricExpr": "(hv_24x7@PM_MCS01_128B_RD_DISP_PORT01\\,chip\\=?@ + hv_24x7@PM_MCS01_128B_RD_DISP_PORT23\\,chip\\=?@ + hv_24x7@PM_MCS23_128B_RD_DISP_PORT01\\,chip\\=?@ + hv_24x7@PM_MCS23_128B_RD_DISP_PORT23\\,chip\\=?@)", -"MetricName": "Memory_RD_BW_Chip", -"MetricGroup": "Memory_BW", -"ScaleUnit": "1.6e-2MB" + "MetricExpr": "(hv_24x7@PM_MCS01_128B_RD_DISP_PORT01\\,chip\\=?@ + hv_24x7@PM_MCS01_128B_RD_DISP_PORT23\\,chip\\=?@ + hv_24x7@PM_MCS23_128B_RD_DISP_PORT01\\,chip\\=?@ + hv_24x7@PM_MCS23_128B_RD_DISP_PORT23\\,chip\\=?@)", + "MetricName": "Memory_RD_BW_Chip", + "MetricGroup": "Memory_BW", + "ScaleUnit": "1.6e-2MB", + "AggregationMode": "PerChip" }, { "MetricExpr": "(hv_24x7@PM_MCS01_128B_WR_DISP_PORT01\\,chip\\=?@ + hv_24x7@PM_MCS01_128B_WR_DISP_PORT23\\,chip\\=?@ + hv_24x7@PM_MCS23_128B_WR_DISP_PORT01\\,chip\\=?@ + hv_24x7@PM_MCS23_128B_WR_DISP_PORT23\\,chip\\=?@ )", -"MetricName": "Memory_WR_BW_Chip", -"MetricGroup": "Memory_BW", -"ScaleUnit": "1.6e-2MB" + "MetricName": "Memory_WR_BW_Chip", + "MetricGroup": "Memory_BW", + "ScaleUnit": "1.6e-2MB", + "AggregationMode": "PerChip" }, { "MetricExpr": "(hv_24x7@PM_PB_CYC\\,chip\\=?@ )", -"MetricName": "PowerBUS_Frequency", -"ScaleUnit": "2.5e-7GHz" + "MetricName": "PowerBUS_Frequency", + "ScaleUnit": "2.5e-7GHz", + "AggregationMode": "PerChip" +}, +{ + "MetricExpr": "(hv_24x7@CPM_CS_32MHZ_CYC\\,domain\\=3\\,core\\=?@ )", + "MetricName": "CPM_CS_32MHZ_CYC", + "ScaleUnit": "1MHz", + "AggregationMode": "PerCore" }, { "MetricExpr" : "nest_mcs01_imc@PM_MCS01_128B_RD_DISP_PORT01@ + nest_mcs01_imc@PM_MCS01_128B_RD_DISP_PORT23@", "MetricName" : "mcs01-read", - "MetricGroup" : "memory_bw", + "MetricGroup" : "memory-bandwidth", "ScaleUnit": "6.1e-5MB" }, { "MetricExpr" : "nest_mcs23_imc@PM_MCS23_128B_RD_DISP_PORT01@ + nest_mcs23_imc@PM_MCS23_128B_RD_DISP_PORT23@", "MetricName" : "mcs23-read", - "MetricGroup" : "memory_bw", + "MetricGroup" : "memory-bandwidth", "ScaleUnit": "6.1e-5MB" }, { "MetricExpr" : "nest_mcs01_imc@PM_MCS01_128B_WR_DISP_PORT01@ + nest_mcs01_imc@PM_MCS01_128B_WR_DISP_PORT23@", "MetricName" : "mcs01-write", - "MetricGroup" : "memory_bw", + "MetricGroup" : "memory-bandwidth", "ScaleUnit": "6.1e-5MB" }, { @@ -48,7 +57,7 @@ { "MetricExpr" : "(nest_mcs01_imc@PM_MCS01_128B_RD_DISP_PORT01@ + nest_mcs01_imc@PM_MCS01_128B_RD_DISP_PORT23@ + nest_mcs23_imc@PM_MCS23_128B_RD_DISP_PORT01@ + nest_mcs23_imc@PM_MCS23_128B_RD_DISP_PORT23@ + nest_mcs01_imc@PM_MCS01_128B_WR_DISP_PORT01@ + nest_mcs01_imc@PM_MCS01_128B_WR_DISP_PORT23@ + nest_mcs23_imc@PM_MCS23_128B_WR_DISP_PORT01@ + nest_mcs23_imc@PM_MCS23_128B_WR_DISP_PORT23@)", "MetricName" : "Memory-bandwidth-MCS", - "MetricGroup" : "memory_bw", + "MetricGroup" : "memory-bandwidth", "ScaleUnit": "6.1e-5MB" } ] -- 2.26.2
[PATCH v8 2/5] perf/jevents: Add new structure to pass json fields.
This patch adds new structure called 'json_event' inside jevents.c file to improve the callback prototype inside jevent files. Initially, whenever user want to add new field, they need to update in all function callback which make it more and more complex with increased number of parmeters. With this change, we just need to add it in new structure 'json_event'. Signed-off-by: Kajol Jain Reviewed-by: Andi Kleen Reviewed-by: John Garry --- tools/perf/pmu-events/jevents.c | 212 +++- 1 file changed, 97 insertions(+), 115 deletions(-) diff --git a/tools/perf/pmu-events/jevents.c b/tools/perf/pmu-events/jevents.c index 1b1c3606f62e..388dd287d736 100644 --- a/tools/perf/pmu-events/jevents.c +++ b/tools/perf/pmu-events/jevents.c @@ -52,6 +52,23 @@ int verbose; char *prog; +struct json_event { + char *name; + char *event; + char *desc; + char *long_desc; + char *pmu; + char *unit; + char *perpkg; + char *metric_expr; + char *metric_name; + char *metric_group; + char *deprecated; + char *metric_constraint; +}; + +typedef int (*func)(void *data, struct json_event *je); + int eprintf(int level, int var, const char *fmt, ...) { @@ -70,11 +87,6 @@ int eprintf(int level, int var, const char *fmt, ...) return ret; } -__attribute__((weak)) char *get_cpu_str(void) -{ - return NULL; -} - static void addfield(char *map, char **dst, const char *sep, const char *a, jsmntok_t *bt) { @@ -317,12 +329,7 @@ static void print_events_table_prefix(FILE *fp, const char *tblname) close_table = 1; } -static int print_events_table_entry(void *data, char *name, char *event, - char *desc, char *long_desc, - char *pmu, char *unit, char *perpkg, - char *metric_expr, - char *metric_name, char *metric_group, - char *deprecated, char *metric_constraint) +static int print_events_table_entry(void *data, struct json_event *je) { struct perf_entry_data *pd = data; FILE *outfp = pd->outfp; @@ -334,30 +341,30 @@ static int print_events_table_entry(void *data, char *name, char *event, */ fprintf(outfp, "{\n"); - if (name) - fprintf(outfp, "\t.name = \"%s\",\n", name); - if (event) - fprintf(outfp, "\t.event = \"%s\",\n", event); - fprintf(outfp, "\t.desc = \"%s\",\n", desc); + if (je->name) + fprintf(outfp, "\t.name = \"%s\",\n", je->name); + if (je->event) + fprintf(outfp, "\t.event = \"%s\",\n", je->event); + fprintf(outfp, "\t.desc = \"%s\",\n", je->desc); fprintf(outfp, "\t.topic = \"%s\",\n", topic); - if (long_desc && long_desc[0]) - fprintf(outfp, "\t.long_desc = \"%s\",\n", long_desc); - if (pmu) - fprintf(outfp, "\t.pmu = \"%s\",\n", pmu); - if (unit) - fprintf(outfp, "\t.unit = \"%s\",\n", unit); - if (perpkg) - fprintf(outfp, "\t.perpkg = \"%s\",\n", perpkg); - if (metric_expr) - fprintf(outfp, "\t.metric_expr = \"%s\",\n", metric_expr); - if (metric_name) - fprintf(outfp, "\t.metric_name = \"%s\",\n", metric_name); - if (metric_group) - fprintf(outfp, "\t.metric_group = \"%s\",\n", metric_group); - if (deprecated) - fprintf(outfp, "\t.deprecated = \"%s\",\n", deprecated); - if (metric_constraint) - fprintf(outfp, "\t.metric_constraint = \"%s\",\n", metric_constraint); + if (je->long_desc && je->long_desc[0]) + fprintf(outfp, "\t.long_desc = \"%s\",\n", je->long_desc); + if (je->pmu) + fprintf(outfp, "\t.pmu = \"%s\",\n", je->pmu); + if (je->unit) + fprintf(outfp, "\t.unit = \"%s\",\n", je->unit); + if (je->perpkg) + fprintf(outfp, "\t.perpkg = \"%s\",\n", je->perpkg); + if (je->metric_expr) + fprintf(outfp, "\t.metric_expr = \"%s\",\n", je->metric_expr); + if (je->metric_name) + fprintf(outfp, "\t.metric_name = \"%s\",\n", je->metric_name); + if (je->metric_group) + fprintf(outfp, "\t.metric_group = \"%s\",\
[PATCH v8 3/5] perf jevents: Add support for parsing perchip/percore events
Initially, every time we want to add new terms like chip, core thread etc, we need to create corrsponding fields in pmu_events and event struct. This patch adds an enum called 'aggr_mode_class' which store all these aggregation like perchip/percore. It also adds new field 'aggr_mode' to capture these terms. Now, if user wants to add any new term, they just need to add it in the enum defined. Signed-off-by: Kajol Jain --- tools/perf/pmu-events/jevents.c| 19 +++ tools/perf/pmu-events/pmu-events.h | 6 ++ 2 files changed, 25 insertions(+) diff --git a/tools/perf/pmu-events/jevents.c b/tools/perf/pmu-events/jevents.c index 388dd287d736..ebfb295bba05 100644 --- a/tools/perf/pmu-events/jevents.c +++ b/tools/perf/pmu-events/jevents.c @@ -48,6 +48,7 @@ #include #include "jsmn.h" #include "json.h" +#include "pmu-events.h" int verbose; char *prog; @@ -60,6 +61,7 @@ struct json_event { char *pmu; char *unit; char *perpkg; + char *aggr_mode; char *metric_expr; char *metric_name; char *metric_group; @@ -67,6 +69,17 @@ struct json_event { char *metric_constraint; }; +enum aggr_mode_class convert(const char *aggr_mode) +{ + if (!strcmp(aggr_mode, "PerCore")) + return PerCore; + else if (!strcmp(aggr_mode, "PerChip")) + return PerChip; + + pr_err("%s: Wrong AggregationMode value '%s'\n", prog, aggr_mode); + return -1; +} + typedef int (*func)(void *data, struct json_event *je); int eprintf(int level, int var, const char *fmt, ...) @@ -355,6 +368,8 @@ static int print_events_table_entry(void *data, struct json_event *je) fprintf(outfp, "\t.unit = \"%s\",\n", je->unit); if (je->perpkg) fprintf(outfp, "\t.perpkg = \"%s\",\n", je->perpkg); + if (je->aggr_mode) + fprintf(outfp, "\t.aggr_mode = \"%d\",\n", convert(je->aggr_mode)); if (je->metric_expr) fprintf(outfp, "\t.metric_expr = \"%s\",\n", je->metric_expr); if (je->metric_name) @@ -379,6 +394,7 @@ struct event_struct { char *pmu; char *unit; char *perpkg; + char *aggr_mode; char *metric_expr; char *metric_name; char *metric_group; @@ -408,6 +424,7 @@ struct event_struct { op(pmu);\ op(unit); \ op(perpkg); \ + op(aggr_mode); \ op(metric_expr);\ op(metric_name);\ op(metric_group); \ @@ -613,6 +630,8 @@ static int json_events(const char *fn, addfield(map, &je.unit, "", "", val); } else if (json_streq(map, field, "PerPkg")) { addfield(map, &je.perpkg, "", "", val); + } else if (json_streq(map, field, "AggregationMode")) { + addfield(map, &je.aggr_mode, "", "", val); } else if (json_streq(map, field, "Deprecated")) { addfield(map, &je.deprecated, "", "", val); } else if (json_streq(map, field, "MetricName")) { diff --git a/tools/perf/pmu-events/pmu-events.h b/tools/perf/pmu-events/pmu-events.h index c8f306b572f4..7da1a3743b77 100644 --- a/tools/perf/pmu-events/pmu-events.h +++ b/tools/perf/pmu-events/pmu-events.h @@ -2,6 +2,11 @@ #ifndef PMU_EVENTS_H #define PMU_EVENTS_H +enum aggr_mode_class { + PerChip = 1, + PerCore +}; + /* * Describe each PMU event. Each CPU has a table of PMU events. */ @@ -14,6 +19,7 @@ struct pmu_event { const char *pmu; const char *unit; const char *perpkg; + const char *aggr_mode; const char *metric_expr; const char *metric_name; const char *metric_group; -- 2.26.2
[PATCH v8 1/5] perf/jevents: Remove jevents.h file
This patch removes jevents.h file. Signed-off-by: Kajol Jain Reviewed-by: John Garry --- tools/perf/pmu-events/jevents.c | 3 +-- tools/perf/pmu-events/jevents.h | 23 --- 2 files changed, 1 insertion(+), 25 deletions(-) delete mode 100644 tools/perf/pmu-events/jevents.h diff --git a/tools/perf/pmu-events/jevents.c b/tools/perf/pmu-events/jevents.c index fa86c5f997cc..1b1c3606f62e 100644 --- a/tools/perf/pmu-events/jevents.c +++ b/tools/perf/pmu-events/jevents.c @@ -48,7 +48,6 @@ #include #include "jsmn.h" #include "json.h" -#include "jevents.h" int verbose; char *prog; @@ -512,7 +511,7 @@ try_fixup(const char *fn, char *arch_std, char **event, char **desc, } /* Call func with each event in the json file */ -int json_events(const char *fn, +static int json_events(const char *fn, int (*func)(void *data, char *name, char *event, char *desc, char *long_desc, char *pmu, char *unit, char *perpkg, diff --git a/tools/perf/pmu-events/jevents.h b/tools/perf/pmu-events/jevents.h deleted file mode 100644 index 2afc8304529e.. --- a/tools/perf/pmu-events/jevents.h +++ /dev/null @@ -1,23 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef JEVENTS_H -#define JEVENTS_H 1 - -int json_events(const char *fn, - int (*func)(void *data, char *name, char *event, char *desc, - char *long_desc, - char *pmu, - char *unit, char *perpkg, char *metric_expr, - char *metric_name, char *metric_group, - char *deprecated, char *metric_constraint), - void *data); -char *get_cpu_str(void); - -#ifndef min -#define min(x, y) ({\ - typeof(x) _min1 = (x); \ - typeof(y) _min2 = (y); \ - (void) (&_min1 == &_min2); \ - _min1 < _min2 ? _min1 : _min2; }) -#endif - -#endif -- 2.26.2
[PATCH v9 0/5] powerpc/perf: Add json file support for hv_24x7 core level events
Patchset enhance current runtime parameter support. It introduces new fields like "PerChip" and "PerCore" similar to the field "PerPkg" which is used to specify perpkg events. The "PerCore" and "PerChip" specifies whether its core or chip events. Based on which we can decide which runtime parameter user want to access. Now character '?' can refers different parameter based on user requirement. Initially, every time we want to add new terms like chip, core, thread etc, we need to create corrsponding fields in pmu_events and event struct. This patchset adds an enum called 'aggr_mode_class' which store all these aggregation like perchip/percore. It also adds new field 'AggregationMode' to capture these terms. Now, if user wants to add any new term, they just need to add it in the enum defined. This patchset also adds changes of adding new structure called 'json_event' inside jevents.c file to improve the callback prototype inside jevent file. Initially, whenever user want to add new field, they need to update in all function callback which makes it more and more complex with increased number of parmeters. With this change, we just need to add it in new structure 'json_event'. link to the RFC patch: https://lkml.org/lkml/2020/8/25/217 Changelog: v8 -> v9 - Free aggr_mode memory [Jiri Olsa]. v7 -> v8 - Change commit typo from jevents.h to jevents.c - Make json_events function static in first patch. v6 -> v7 - Remove min and get_cpu_str functions from jevents.c - Make json_events function static to solve warning part [John Garry]. - Add event attribute in json_events function to remove strcpy from real_event function, as suggested by Jiri Olsa. - Add warning while checking aggr_mode value [Jiri Olsa]. Kajol Jain (5): perf/jevents: Remove jevents.h file perf/jevents: Add new structure to pass json fields. perf jevents: Add support for parsing perchip/percore events perf/tools: Pass pmu_event structure as a parameter for arch_get_runtimeparam perf/tools/pmu_events/powerpc: Add hv_24x7 core level metric events tools/perf/arch/powerpc/util/header.c | 7 +- .../arch/powerpc/power9/nest_metrics.json | 35 ++- tools/perf/pmu-events/jevents.c | 234 +- tools/perf/pmu-events/jevents.h | 23 -- tools/perf/pmu-events/pmu-events.h| 6 + tools/perf/util/metricgroup.c | 5 +- tools/perf/util/metricgroup.h | 3 +- 7 files changed, 154 insertions(+), 159 deletions(-) delete mode 100644 tools/perf/pmu-events/jevents.h -- 2.26.2
[PATCH v9 3/5] perf jevents: Add support for parsing perchip/percore events
Initially, every time we want to add new terms like chip, core thread etc, we need to create corrsponding fields in pmu_events and event struct. This patch adds an enum called 'aggr_mode_class' which store all these aggregation like perchip/percore. It also adds new field 'aggr_mode' to capture these terms. Now, if user wants to add any new term, they just need to add it in the enum defined. Signed-off-by: Kajol Jain --- tools/perf/pmu-events/jevents.c| 20 tools/perf/pmu-events/pmu-events.h | 6 ++ 2 files changed, 26 insertions(+) diff --git a/tools/perf/pmu-events/jevents.c b/tools/perf/pmu-events/jevents.c index db334b2fd896..b6f0c13ae8c0 100644 --- a/tools/perf/pmu-events/jevents.c +++ b/tools/perf/pmu-events/jevents.c @@ -48,6 +48,7 @@ #include #include "jsmn.h" #include "json.h" +#include "pmu-events.h" int verbose; char *prog; @@ -60,6 +61,7 @@ struct json_event { char *pmu; char *unit; char *perpkg; + char *aggr_mode; char *metric_expr; char *metric_name; char *metric_group; @@ -67,6 +69,17 @@ struct json_event { char *metric_constraint; }; +enum aggr_mode_class convert(const char *aggr_mode) +{ + if (!strcmp(aggr_mode, "PerCore")) + return PerCore; + else if (!strcmp(aggr_mode, "PerChip")) + return PerChip; + + pr_err("%s: Wrong AggregationMode value '%s'\n", prog, aggr_mode); + return -1; +} + typedef int (*func)(void *data, struct json_event *je); int eprintf(int level, int var, const char *fmt, ...) @@ -355,6 +368,8 @@ static int print_events_table_entry(void *data, struct json_event *je) fprintf(outfp, "\t.unit = \"%s\",\n", je->unit); if (je->perpkg) fprintf(outfp, "\t.perpkg = \"%s\",\n", je->perpkg); + if (je->aggr_mode) + fprintf(outfp, "\t.aggr_mode = \"%d\",\n", convert(je->aggr_mode)); if (je->metric_expr) fprintf(outfp, "\t.metric_expr = \"%s\",\n", je->metric_expr); if (je->metric_name) @@ -379,6 +394,7 @@ struct event_struct { char *pmu; char *unit; char *perpkg; + char *aggr_mode; char *metric_expr; char *metric_name; char *metric_group; @@ -408,6 +424,7 @@ struct event_struct { op(pmu);\ op(unit); \ op(perpkg); \ + op(aggr_mode); \ op(metric_expr);\ op(metric_name);\ op(metric_group); \ @@ -613,6 +630,8 @@ static int json_events(const char *fn, addfield(map, &je.unit, "", "", val); } else if (json_streq(map, field, "PerPkg")) { addfield(map, &je.perpkg, "", "", val); + } else if (json_streq(map, field, "AggregationMode")) { + addfield(map, &je.aggr_mode, "", "", val); } else if (json_streq(map, field, "Deprecated")) { addfield(map, &je.deprecated, "", "", val); } else if (json_streq(map, field, "MetricName")) { @@ -673,6 +692,7 @@ static int json_events(const char *fn, free(je.pmu); free(filter); free(je.perpkg); + free(je.aggr_mode); free(je.deprecated); free(je.unit); free(je.metric_expr); diff --git a/tools/perf/pmu-events/pmu-events.h b/tools/perf/pmu-events/pmu-events.h index c8f306b572f4..7da1a3743b77 100644 --- a/tools/perf/pmu-events/pmu-events.h +++ b/tools/perf/pmu-events/pmu-events.h @@ -2,6 +2,11 @@ #ifndef PMU_EVENTS_H #define PMU_EVENTS_H +enum aggr_mode_class { + PerChip = 1, + PerCore +}; + /* * Describe each PMU event. Each CPU has a table of PMU events. */ @@ -14,6 +19,7 @@ struct pmu_event { const char *pmu; const char *unit; const char *perpkg; + const char *aggr_mode; const char *metric_expr; const char *metric_name; const char *metric_group; -- 2.26.2
[PATCH v9 1/5] perf/jevents: Remove jevents.h file
This patch removes jevents.h and makes json_events function static. Signed-off-by: Kajol Jain Reviewed-by: John Garry --- tools/perf/pmu-events/jevents.c | 3 +-- tools/perf/pmu-events/jevents.h | 23 --- 2 files changed, 1 insertion(+), 25 deletions(-) delete mode 100644 tools/perf/pmu-events/jevents.h diff --git a/tools/perf/pmu-events/jevents.c b/tools/perf/pmu-events/jevents.c index fc9c158bfa13..b9b938aaff16 100644 --- a/tools/perf/pmu-events/jevents.c +++ b/tools/perf/pmu-events/jevents.c @@ -48,7 +48,6 @@ #include #include "jsmn.h" #include "json.h" -#include "jevents.h" int verbose; char *prog; @@ -512,7 +511,7 @@ try_fixup(const char *fn, char *arch_std, char **event, char **desc, } /* Call func with each event in the json file */ -int json_events(const char *fn, +static int json_events(const char *fn, int (*func)(void *data, char *name, char *event, char *desc, char *long_desc, char *pmu, char *unit, char *perpkg, diff --git a/tools/perf/pmu-events/jevents.h b/tools/perf/pmu-events/jevents.h deleted file mode 100644 index 2afc8304529e.. --- a/tools/perf/pmu-events/jevents.h +++ /dev/null @@ -1,23 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef JEVENTS_H -#define JEVENTS_H 1 - -int json_events(const char *fn, - int (*func)(void *data, char *name, char *event, char *desc, - char *long_desc, - char *pmu, - char *unit, char *perpkg, char *metric_expr, - char *metric_name, char *metric_group, - char *deprecated, char *metric_constraint), - void *data); -char *get_cpu_str(void); - -#ifndef min -#define min(x, y) ({\ - typeof(x) _min1 = (x); \ - typeof(y) _min2 = (y); \ - (void) (&_min1 == &_min2); \ - _min1 < _min2 ? _min1 : _min2; }) -#endif - -#endif -- 2.26.2
[PATCH v9 2/5] perf/jevents: Add new structure to pass json fields.
This patch adds new structure called 'json_event' inside jevents.c file to improve the callback prototype inside jevent files. Initially, whenever user want to add new field, they need to update in all function callback which make it more and more complex with increased number of parmeters. With this change, we just need to add it in new structure 'json_event'. Signed-off-by: Kajol Jain Reviewed-by: Andi Kleen Reviewed-by: John Garry --- tools/perf/pmu-events/jevents.c | 212 +++- 1 file changed, 97 insertions(+), 115 deletions(-) diff --git a/tools/perf/pmu-events/jevents.c b/tools/perf/pmu-events/jevents.c index b9b938aaff16..db334b2fd896 100644 --- a/tools/perf/pmu-events/jevents.c +++ b/tools/perf/pmu-events/jevents.c @@ -52,6 +52,23 @@ int verbose; char *prog; +struct json_event { + char *name; + char *event; + char *desc; + char *long_desc; + char *pmu; + char *unit; + char *perpkg; + char *metric_expr; + char *metric_name; + char *metric_group; + char *deprecated; + char *metric_constraint; +}; + +typedef int (*func)(void *data, struct json_event *je); + int eprintf(int level, int var, const char *fmt, ...) { @@ -70,11 +87,6 @@ int eprintf(int level, int var, const char *fmt, ...) return ret; } -__attribute__((weak)) char *get_cpu_str(void) -{ - return NULL; -} - static void addfield(char *map, char **dst, const char *sep, const char *a, jsmntok_t *bt) { @@ -317,12 +329,7 @@ static void print_events_table_prefix(FILE *fp, const char *tblname) close_table = 1; } -static int print_events_table_entry(void *data, char *name, char *event, - char *desc, char *long_desc, - char *pmu, char *unit, char *perpkg, - char *metric_expr, - char *metric_name, char *metric_group, - char *deprecated, char *metric_constraint) +static int print_events_table_entry(void *data, struct json_event *je) { struct perf_entry_data *pd = data; FILE *outfp = pd->outfp; @@ -334,30 +341,30 @@ static int print_events_table_entry(void *data, char *name, char *event, */ fprintf(outfp, "{\n"); - if (name) - fprintf(outfp, "\t.name = \"%s\",\n", name); - if (event) - fprintf(outfp, "\t.event = \"%s\",\n", event); - fprintf(outfp, "\t.desc = \"%s\",\n", desc); + if (je->name) + fprintf(outfp, "\t.name = \"%s\",\n", je->name); + if (je->event) + fprintf(outfp, "\t.event = \"%s\",\n", je->event); + fprintf(outfp, "\t.desc = \"%s\",\n", je->desc); fprintf(outfp, "\t.topic = \"%s\",\n", topic); - if (long_desc && long_desc[0]) - fprintf(outfp, "\t.long_desc = \"%s\",\n", long_desc); - if (pmu) - fprintf(outfp, "\t.pmu = \"%s\",\n", pmu); - if (unit) - fprintf(outfp, "\t.unit = \"%s\",\n", unit); - if (perpkg) - fprintf(outfp, "\t.perpkg = \"%s\",\n", perpkg); - if (metric_expr) - fprintf(outfp, "\t.metric_expr = \"%s\",\n", metric_expr); - if (metric_name) - fprintf(outfp, "\t.metric_name = \"%s\",\n", metric_name); - if (metric_group) - fprintf(outfp, "\t.metric_group = \"%s\",\n", metric_group); - if (deprecated) - fprintf(outfp, "\t.deprecated = \"%s\",\n", deprecated); - if (metric_constraint) - fprintf(outfp, "\t.metric_constraint = \"%s\",\n", metric_constraint); + if (je->long_desc && je->long_desc[0]) + fprintf(outfp, "\t.long_desc = \"%s\",\n", je->long_desc); + if (je->pmu) + fprintf(outfp, "\t.pmu = \"%s\",\n", je->pmu); + if (je->unit) + fprintf(outfp, "\t.unit = \"%s\",\n", je->unit); + if (je->perpkg) + fprintf(outfp, "\t.perpkg = \"%s\",\n", je->perpkg); + if (je->metric_expr) + fprintf(outfp, "\t.metric_expr = \"%s\",\n", je->metric_expr); + if (je->metric_name) + fprintf(outfp, "\t.metric_name = \"%s\",\n", je->metric_name); + if (je->metric_group) + fprintf(outfp, "\t.metric_group = \"%s\",\
[PATCH v9 4/5] perf/tools: Pass pmu_event structure as a parameter for arch_get_runtimeparam
This patch adds passing of pmu_event as a parameter in function 'arch_get_runtimeparam' which can be used to get details like if the event is percore/perchip. Signed-off-by: Kajol Jain Acked-by: Ian Rogers --- tools/perf/arch/powerpc/util/header.c | 7 +-- tools/perf/util/metricgroup.c | 5 ++--- tools/perf/util/metricgroup.h | 3 ++- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/tools/perf/arch/powerpc/util/header.c b/tools/perf/arch/powerpc/util/header.c index 1a950171a66f..58b2d610aadb 100644 --- a/tools/perf/arch/powerpc/util/header.c +++ b/tools/perf/arch/powerpc/util/header.c @@ -40,8 +40,11 @@ get_cpuid_str(struct perf_pmu *pmu __maybe_unused) return bufp; } -int arch_get_runtimeparam(void) +int arch_get_runtimeparam(struct pmu_event *pe) { int count; - return sysfs__read_int("/devices/hv_24x7/interface/sockets", &count) < 0 ? 1 : count; + char path[PATH_MAX] = "/devices/hv_24x7/interface/"; + + atoi(pe->aggr_mode) == PerChip ? strcat(path, "sockets") : strcat(path, "coresperchip"); + return sysfs__read_int(path, &count) < 0 ? 1 : count; } diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c index 8831b964288f..c387aa1615ba 100644 --- a/tools/perf/util/metricgroup.c +++ b/tools/perf/util/metricgroup.c @@ -15,7 +15,6 @@ #include "rblist.h" #include #include -#include "pmu-events/pmu-events.h" #include "strlist.h" #include #include @@ -634,7 +633,7 @@ static bool metricgroup__has_constraint(struct pmu_event *pe) return false; } -int __weak arch_get_runtimeparam(void) +int __weak arch_get_runtimeparam(struct pmu_event *pe __maybe_unused) { return 1; } @@ -902,7 +901,7 @@ static int add_metric(struct list_head *metric_list, } else { int j, count; - count = arch_get_runtimeparam(); + count = arch_get_runtimeparam(pe); /* This loop is added to create multiple * events depend on count value and add diff --git a/tools/perf/util/metricgroup.h b/tools/perf/util/metricgroup.h index 62623a39cbec..491a5d78252d 100644 --- a/tools/perf/util/metricgroup.h +++ b/tools/perf/util/metricgroup.h @@ -5,6 +5,7 @@ #include #include #include +#include "pmu-events/pmu-events.h" struct evsel; struct evlist; @@ -52,6 +53,6 @@ int metricgroup__parse_groups_test(struct evlist *evlist, void metricgroup__print(bool metrics, bool groups, char *filter, bool raw, bool details); bool metricgroup__has_metric(const char *metric); -int arch_get_runtimeparam(void); +int arch_get_runtimeparam(struct pmu_event *pe __maybe_unused); void metricgroup__rblist_exit(struct rblist *metric_events); #endif -- 2.26.2
[PATCH v9 5/5] perf/tools/pmu_events/powerpc: Add hv_24x7 core level metric events
This patch adds hv_24x7 core level events in nest_metric.json file and also add PerChip/PerCore field in metric events. Result: power9 platform: command:# ./perf stat --metric-only -M PowerBUS_Frequency -C 0 -I 1000 1.706011.92.0 2.0002538812.01.9 3.0003648102.02.0 Signed-off-by: Kajol Jain Acked-by: Ian Rogers --- .../arch/powerpc/power9/nest_metrics.json | 35 --- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/tools/perf/pmu-events/arch/powerpc/power9/nest_metrics.json b/tools/perf/pmu-events/arch/powerpc/power9/nest_metrics.json index 8383a37647ad..7a5d1bf543f8 100644 --- a/tools/perf/pmu-events/arch/powerpc/power9/nest_metrics.json +++ b/tools/perf/pmu-events/arch/powerpc/power9/nest_metrics.json @@ -1,37 +1,46 @@ [ { -"MetricExpr": "(hv_24x7@PM_MCS01_128B_RD_DISP_PORT01\\,chip\\=?@ + hv_24x7@PM_MCS01_128B_RD_DISP_PORT23\\,chip\\=?@ + hv_24x7@PM_MCS23_128B_RD_DISP_PORT01\\,chip\\=?@ + hv_24x7@PM_MCS23_128B_RD_DISP_PORT23\\,chip\\=?@)", -"MetricName": "Memory_RD_BW_Chip", -"MetricGroup": "Memory_BW", -"ScaleUnit": "1.6e-2MB" + "MetricExpr": "(hv_24x7@PM_MCS01_128B_RD_DISP_PORT01\\,chip\\=?@ + hv_24x7@PM_MCS01_128B_RD_DISP_PORT23\\,chip\\=?@ + hv_24x7@PM_MCS23_128B_RD_DISP_PORT01\\,chip\\=?@ + hv_24x7@PM_MCS23_128B_RD_DISP_PORT23\\,chip\\=?@)", + "MetricName": "Memory_RD_BW_Chip", + "MetricGroup": "Memory_BW", + "ScaleUnit": "1.6e-2MB", + "AggregationMode": "PerChip" }, { "MetricExpr": "(hv_24x7@PM_MCS01_128B_WR_DISP_PORT01\\,chip\\=?@ + hv_24x7@PM_MCS01_128B_WR_DISP_PORT23\\,chip\\=?@ + hv_24x7@PM_MCS23_128B_WR_DISP_PORT01\\,chip\\=?@ + hv_24x7@PM_MCS23_128B_WR_DISP_PORT23\\,chip\\=?@ )", -"MetricName": "Memory_WR_BW_Chip", -"MetricGroup": "Memory_BW", -"ScaleUnit": "1.6e-2MB" + "MetricName": "Memory_WR_BW_Chip", + "MetricGroup": "Memory_BW", + "ScaleUnit": "1.6e-2MB", + "AggregationMode": "PerChip" }, { "MetricExpr": "(hv_24x7@PM_PB_CYC\\,chip\\=?@ )", -"MetricName": "PowerBUS_Frequency", -"ScaleUnit": "2.5e-7GHz" + "MetricName": "PowerBUS_Frequency", + "ScaleUnit": "2.5e-7GHz", + "AggregationMode": "PerChip" +}, +{ + "MetricExpr": "(hv_24x7@CPM_CS_32MHZ_CYC\\,domain\\=3\\,core\\=?@ )", + "MetricName": "CPM_CS_32MHZ_CYC", + "ScaleUnit": "1MHz", + "AggregationMode": "PerCore" }, { "MetricExpr" : "nest_mcs01_imc@PM_MCS01_128B_RD_DISP_PORT01@ + nest_mcs01_imc@PM_MCS01_128B_RD_DISP_PORT23@", "MetricName" : "mcs01-read", - "MetricGroup" : "memory_bw", + "MetricGroup" : "memory-bandwidth", "ScaleUnit": "6.1e-5MB" }, { "MetricExpr" : "nest_mcs23_imc@PM_MCS23_128B_RD_DISP_PORT01@ + nest_mcs23_imc@PM_MCS23_128B_RD_DISP_PORT23@", "MetricName" : "mcs23-read", - "MetricGroup" : "memory_bw", + "MetricGroup" : "memory-bandwidth", "ScaleUnit": "6.1e-5MB" }, { "MetricExpr" : "nest_mcs01_imc@PM_MCS01_128B_WR_DISP_PORT01@ + nest_mcs01_imc@PM_MCS01_128B_WR_DISP_PORT23@", "MetricName" : "mcs01-write", - "MetricGroup" : "memory_bw", + "MetricGroup" : "memory-bandwidth", "ScaleUnit": "6.1e-5MB" }, { @@ -48,7 +57,7 @@ { "MetricExpr" : "(nest_mcs01_imc@PM_MCS01_128B_RD_DISP_PORT01@ + nest_mcs01_imc@PM_MCS01_128B_RD_DISP_PORT23@ + nest_mcs23_imc@PM_MCS23_128B_RD_DISP_PORT01@ + nest_mcs23_imc@PM_MCS23_128B_RD_DISP_PORT23@ + nest_mcs01_imc@PM_MCS01_128B_WR_DISP_PORT01@ + nest_mcs01_imc@PM_MCS01_128B_WR_DISP_PORT23@ + nest_mcs23_imc@PM_MCS23_128B_WR_DISP_PORT01@ + nest_mcs23_imc@PM_MCS23_128B_WR_DISP_PORT23@)", "MetricName" : "Memory-bandwidth-MCS", - "MetricGroup" : "memory_bw", + "MetricGroup" : "memory-bandwidth", "ScaleUnit": "6.1e-5MB" } ] -- 2.26.2
[PATCH v5 3/3] perf/tools/pmu_events/powerpc: Add hv_24x7 core level metric events
This patch adds hv_24x7 core level events in nest_metric.json file and also add PerChip/PerCore field in metric events. Result: power9 platform: command:# ./perf stat --metric-only -M PowerBUS_Frequency -C 0 -I 1000 1.706011.92.0 2.0002538812.01.9 3.0003648102.02.0 Signed-off-by: Kajol Jain Acked-by: Ian Rogers --- .../arch/powerpc/power9/nest_metrics.json | 35 --- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/tools/perf/pmu-events/arch/powerpc/power9/nest_metrics.json b/tools/perf/pmu-events/arch/powerpc/power9/nest_metrics.json index 8383a37647ad..7a5d1bf543f8 100644 --- a/tools/perf/pmu-events/arch/powerpc/power9/nest_metrics.json +++ b/tools/perf/pmu-events/arch/powerpc/power9/nest_metrics.json @@ -1,37 +1,46 @@ [ { -"MetricExpr": "(hv_24x7@PM_MCS01_128B_RD_DISP_PORT01\\,chip\\=?@ + hv_24x7@PM_MCS01_128B_RD_DISP_PORT23\\,chip\\=?@ + hv_24x7@PM_MCS23_128B_RD_DISP_PORT01\\,chip\\=?@ + hv_24x7@PM_MCS23_128B_RD_DISP_PORT23\\,chip\\=?@)", -"MetricName": "Memory_RD_BW_Chip", -"MetricGroup": "Memory_BW", -"ScaleUnit": "1.6e-2MB" + "MetricExpr": "(hv_24x7@PM_MCS01_128B_RD_DISP_PORT01\\,chip\\=?@ + hv_24x7@PM_MCS01_128B_RD_DISP_PORT23\\,chip\\=?@ + hv_24x7@PM_MCS23_128B_RD_DISP_PORT01\\,chip\\=?@ + hv_24x7@PM_MCS23_128B_RD_DISP_PORT23\\,chip\\=?@)", + "MetricName": "Memory_RD_BW_Chip", + "MetricGroup": "Memory_BW", + "ScaleUnit": "1.6e-2MB", + "AggregationMode": "PerChip" }, { "MetricExpr": "(hv_24x7@PM_MCS01_128B_WR_DISP_PORT01\\,chip\\=?@ + hv_24x7@PM_MCS01_128B_WR_DISP_PORT23\\,chip\\=?@ + hv_24x7@PM_MCS23_128B_WR_DISP_PORT01\\,chip\\=?@ + hv_24x7@PM_MCS23_128B_WR_DISP_PORT23\\,chip\\=?@ )", -"MetricName": "Memory_WR_BW_Chip", -"MetricGroup": "Memory_BW", -"ScaleUnit": "1.6e-2MB" + "MetricName": "Memory_WR_BW_Chip", + "MetricGroup": "Memory_BW", + "ScaleUnit": "1.6e-2MB", + "AggregationMode": "PerChip" }, { "MetricExpr": "(hv_24x7@PM_PB_CYC\\,chip\\=?@ )", -"MetricName": "PowerBUS_Frequency", -"ScaleUnit": "2.5e-7GHz" + "MetricName": "PowerBUS_Frequency", + "ScaleUnit": "2.5e-7GHz", + "AggregationMode": "PerChip" +}, +{ + "MetricExpr": "(hv_24x7@CPM_CS_32MHZ_CYC\\,domain\\=3\\,core\\=?@ )", + "MetricName": "CPM_CS_32MHZ_CYC", + "ScaleUnit": "1MHz", + "AggregationMode": "PerCore" }, { "MetricExpr" : "nest_mcs01_imc@PM_MCS01_128B_RD_DISP_PORT01@ + nest_mcs01_imc@PM_MCS01_128B_RD_DISP_PORT23@", "MetricName" : "mcs01-read", - "MetricGroup" : "memory_bw", + "MetricGroup" : "memory-bandwidth", "ScaleUnit": "6.1e-5MB" }, { "MetricExpr" : "nest_mcs23_imc@PM_MCS23_128B_RD_DISP_PORT01@ + nest_mcs23_imc@PM_MCS23_128B_RD_DISP_PORT23@", "MetricName" : "mcs23-read", - "MetricGroup" : "memory_bw", + "MetricGroup" : "memory-bandwidth", "ScaleUnit": "6.1e-5MB" }, { "MetricExpr" : "nest_mcs01_imc@PM_MCS01_128B_WR_DISP_PORT01@ + nest_mcs01_imc@PM_MCS01_128B_WR_DISP_PORT23@", "MetricName" : "mcs01-write", - "MetricGroup" : "memory_bw", + "MetricGroup" : "memory-bandwidth", "ScaleUnit": "6.1e-5MB" }, { @@ -48,7 +57,7 @@ { "MetricExpr" : "(nest_mcs01_imc@PM_MCS01_128B_RD_DISP_PORT01@ + nest_mcs01_imc@PM_MCS01_128B_RD_DISP_PORT23@ + nest_mcs23_imc@PM_MCS23_128B_RD_DISP_PORT01@ + nest_mcs23_imc@PM_MCS23_128B_RD_DISP_PORT23@ + nest_mcs01_imc@PM_MCS01_128B_WR_DISP_PORT01@ + nest_mcs01_imc@PM_MCS01_128B_WR_DISP_PORT23@ + nest_mcs23_imc@PM_MCS23_128B_WR_DISP_PORT01@ + nest_mcs23_imc@PM_MCS23_128B_WR_DISP_PORT23@)", "MetricName" : "Memory-bandwidth-MCS", - "MetricGroup" : "memory_bw", + "MetricGroup" : "memory-bandwidth", "ScaleUnit": "6.1e-5MB" } ] -- 2.26.2
[PATCH v5 2/3] perf/tools: Pass pmu_event structure as a parameter for arch_get_runtimeparam
This patch adds passing of pmu_event as a parameter in function 'arch_get_runtimeparam' which can be used to get details like if the event is percore/perchip. Signed-off-by: Kajol Jain Acked-by: Ian Rogers --- tools/perf/arch/powerpc/util/header.c | 7 +-- tools/perf/util/metricgroup.c | 5 ++--- tools/perf/util/metricgroup.h | 3 ++- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/tools/perf/arch/powerpc/util/header.c b/tools/perf/arch/powerpc/util/header.c index 1a950171a66f..58b2d610aadb 100644 --- a/tools/perf/arch/powerpc/util/header.c +++ b/tools/perf/arch/powerpc/util/header.c @@ -40,8 +40,11 @@ get_cpuid_str(struct perf_pmu *pmu __maybe_unused) return bufp; } -int arch_get_runtimeparam(void) +int arch_get_runtimeparam(struct pmu_event *pe) { int count; - return sysfs__read_int("/devices/hv_24x7/interface/sockets", &count) < 0 ? 1 : count; + char path[PATH_MAX] = "/devices/hv_24x7/interface/"; + + atoi(pe->aggr_mode) == PerChip ? strcat(path, "sockets") : strcat(path, "coresperchip"); + return sysfs__read_int(path, &count) < 0 ? 1 : count; } diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c index 8831b964288f..c387aa1615ba 100644 --- a/tools/perf/util/metricgroup.c +++ b/tools/perf/util/metricgroup.c @@ -15,7 +15,6 @@ #include "rblist.h" #include #include -#include "pmu-events/pmu-events.h" #include "strlist.h" #include #include @@ -634,7 +633,7 @@ static bool metricgroup__has_constraint(struct pmu_event *pe) return false; } -int __weak arch_get_runtimeparam(void) +int __weak arch_get_runtimeparam(struct pmu_event *pe __maybe_unused) { return 1; } @@ -902,7 +901,7 @@ static int add_metric(struct list_head *metric_list, } else { int j, count; - count = arch_get_runtimeparam(); + count = arch_get_runtimeparam(pe); /* This loop is added to create multiple * events depend on count value and add diff --git a/tools/perf/util/metricgroup.h b/tools/perf/util/metricgroup.h index 62623a39cbec..491a5d78252d 100644 --- a/tools/perf/util/metricgroup.h +++ b/tools/perf/util/metricgroup.h @@ -5,6 +5,7 @@ #include #include #include +#include "pmu-events/pmu-events.h" struct evsel; struct evlist; @@ -52,6 +53,6 @@ int metricgroup__parse_groups_test(struct evlist *evlist, void metricgroup__print(bool metrics, bool groups, char *filter, bool raw, bool details); bool metricgroup__has_metric(const char *metric); -int arch_get_runtimeparam(void); +int arch_get_runtimeparam(struct pmu_event *pe __maybe_unused); void metricgroup__rblist_exit(struct rblist *metric_events); #endif -- 2.26.2
[PATCH v5 0/3] powerpc/perf: Add json file support for hv_24x7 core level events
Patchset enhance current runtime parameter support. It introduces new fields like "PerChip" and "PerCore" similar to the field "PerPkg" which is used to specify perpkg events. The "PerCore" and "PerChip" specifies whether its core or chip events. Based on which we can decide which runtime parameter user want to access. Now character '?' can refers different parameter based on user requirement. Initially, every time we want to add new terms like chip, core, thread etc, we need to create corrsponding fields in pmu_events and event struct. This patchset adds an enum called 'aggr_mode_class' which store all these aggregation like perchip/percore. It also adds new field 'AggregationMode' to capture these terms. Now, if user wants to add any new term, they just need to add it in the enum defined. Changelog: v4 -> v5 - Remove intel side changes on uncore events by removing PerPkg field from enum "AggregationMode" and other corresponding changes. Link to previous patchset: https://lkml.org/lkml/2020/7/20/124 Kajol Jain (3): perf jevents: Add support for parsing perchip/percore events perf/tools: Pass pmu_event structure as a parameter for arch_get_runtimeparam perf/tools/pmu_events/powerpc: Add hv_24x7 core level metric events tools/perf/arch/powerpc/util/header.c | 7 ++-- .../arch/powerpc/power9/nest_metrics.json | 35 --- tools/perf/pmu-events/jevents.c | 32 + tools/perf/pmu-events/jevents.h | 2 +- tools/perf/pmu-events/pmu-events.h| 6 tools/perf/util/metricgroup.c | 5 ++- tools/perf/util/metricgroup.h | 3 +- 7 files changed, 63 insertions(+), 27 deletions(-) -- 2.26.2
[PATCH v5 1/3] perf jevents: Add support for parsing perchip/percore events
Initially, every time we want to add new terms like chip, core thread etc, we need to create corrsponding fields in pmu_events and event struct. This patch adds an enum called 'aggr_mode_class' which store all these aggregation like perchip/percore. It also adds new field 'aggr_mode' to capture these terms. Now, if user wants to add any new term, they just need to add it in the enum defined. Signed-off-by: Kajol Jain Acked-by: Ian Rogers --- tools/perf/pmu-events/jevents.c| 32 +++--- tools/perf/pmu-events/jevents.h| 2 +- tools/perf/pmu-events/pmu-events.h | 6 ++ 3 files changed, 32 insertions(+), 8 deletions(-) diff --git a/tools/perf/pmu-events/jevents.c b/tools/perf/pmu-events/jevents.c index fa86c5f997cc..f97394dac1db 100644 --- a/tools/perf/pmu-events/jevents.c +++ b/tools/perf/pmu-events/jevents.c @@ -49,10 +49,20 @@ #include "jsmn.h" #include "json.h" #include "jevents.h" +#include "pmu-events.h" int verbose; char *prog; +enum aggr_mode_class convert(const char *aggr_mode) +{ + if (!strcmp(aggr_mode, "PerCore")) + return PerCore; + else if (!strcmp(aggr_mode, "PerChip")) + return PerChip; + return -1; +} + int eprintf(int level, int var, const char *fmt, ...) { @@ -321,7 +331,7 @@ static void print_events_table_prefix(FILE *fp, const char *tblname) static int print_events_table_entry(void *data, char *name, char *event, char *desc, char *long_desc, char *pmu, char *unit, char *perpkg, - char *metric_expr, + char *metric_expr, char *aggr_mode, char *metric_name, char *metric_group, char *deprecated, char *metric_constraint) { @@ -345,6 +355,8 @@ static int print_events_table_entry(void *data, char *name, char *event, fprintf(outfp, "\t.long_desc = \"%s\",\n", long_desc); if (pmu) fprintf(outfp, "\t.pmu = \"%s\",\n", pmu); + if (aggr_mode) + fprintf(outfp, "\t.aggr_mode = \"%d\",\n", convert(aggr_mode)); if (unit) fprintf(outfp, "\t.unit = \"%s\",\n", unit); if (perpkg) @@ -372,6 +384,7 @@ struct event_struct { char *long_desc; char *pmu; char *unit; + char *aggr_mode; char *perpkg; char *metric_expr; char *metric_name; @@ -402,6 +415,7 @@ struct event_struct { op(pmu);\ op(unit); \ op(perpkg); \ + op(aggr_mode); \ op(metric_expr);\ op(metric_name);\ op(metric_group); \ @@ -424,7 +438,7 @@ static void free_arch_std_events(void) static int save_arch_std_events(void *data, char *name, char *event, char *desc, char *long_desc, char *pmu, char *unit, char *perpkg, char *metric_expr, - char *metric_name, char *metric_group, + char *aggr_mode, char *metric_name, char *metric_group, char *deprecated, char *metric_constraint) { struct event_struct *es; @@ -487,8 +501,8 @@ static char *real_event(const char *name, char *event) static int try_fixup(const char *fn, char *arch_std, char **event, char **desc, char **name, char **long_desc, char **pmu, char **filter, - char **perpkg, char **unit, char **metric_expr, char **metric_name, - char **metric_group, unsigned long long eventcode, + char **perpkg, char **unit, char **metric_expr, char **aggr_mode, + char **metric_name, char **metric_group, unsigned long long eventcode, char **deprecated, char **metric_constraint) { /* try to find matching event from arch standard values */ @@ -516,7 +530,7 @@ int json_events(const char *fn, int (*func)(void *data, char *name, char *event, char *desc, char *long_desc, char *pmu, char *unit, char *perpkg, - char *metric_expr, + char *metric_expr, char *aggr_mode, char *metric_name, char *metric_group, char *deprecated, char *metric_constraint), void *data) @@ -543,6 +557,7 @@ int json_events(const char *fn, char *pmu = NULL; char *filter = NULL;
[PATCH] perf/tools/pmu-events/powerpc: update nest metric event to utilize other metrics
This patch take advantage of the new capability added to use computed metrics in calculating other metrics. It also update metric group for nest events to make it consistent for all nest memory events. Signed-off-by: Kajol Jain --- .../arch/powerpc/power9/nest_metrics.json | 18 +- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/tools/perf/pmu-events/arch/powerpc/power9/nest_metrics.json b/tools/perf/pmu-events/arch/powerpc/power9/nest_metrics.json index 8383a37647ad..a21e179edaf9 100644 --- a/tools/perf/pmu-events/arch/powerpc/power9/nest_metrics.json +++ b/tools/perf/pmu-events/arch/powerpc/power9/nest_metrics.json @@ -18,25 +18,25 @@ }, { "MetricExpr" : "nest_mcs01_imc@PM_MCS01_128B_RD_DISP_PORT01@ + nest_mcs01_imc@PM_MCS01_128B_RD_DISP_PORT23@", - "MetricName" : "mcs01-read", - "MetricGroup" : "memory_bw", + "MetricName" : "mcs01_read", + "MetricGroup" : "memory-bandwidth", "ScaleUnit": "6.1e-5MB" }, { "MetricExpr" : "nest_mcs23_imc@PM_MCS23_128B_RD_DISP_PORT01@ + nest_mcs23_imc@PM_MCS23_128B_RD_DISP_PORT23@", - "MetricName" : "mcs23-read", - "MetricGroup" : "memory_bw", + "MetricName" : "mcs23_read", + "MetricGroup" : "memory-bandwidth", "ScaleUnit": "6.1e-5MB" }, { "MetricExpr" : "nest_mcs01_imc@PM_MCS01_128B_WR_DISP_PORT01@ + nest_mcs01_imc@PM_MCS01_128B_WR_DISP_PORT23@", - "MetricName" : "mcs01-write", - "MetricGroup" : "memory_bw", + "MetricName" : "mcs01_write", + "MetricGroup" : "memory-bandwidth", "ScaleUnit": "6.1e-5MB" }, { "MetricExpr" : "nest_mcs23_imc@PM_MCS23_128B_WR_DISP_PORT01@ + nest_mcs23_imc@PM_MCS23_128B_WR_DISP_PORT23@", - "MetricName" : "mcs23-write", + "MetricName" : "mcs23_write", "MetricGroup" : "memory-bandwidth", "ScaleUnit": "6.1e-5MB" }, @@ -46,9 +46,9 @@ "ScaleUnit": "1e-9GHz" }, { - "MetricExpr" : "(nest_mcs01_imc@PM_MCS01_128B_RD_DISP_PORT01@ + nest_mcs01_imc@PM_MCS01_128B_RD_DISP_PORT23@ + nest_mcs23_imc@PM_MCS23_128B_RD_DISP_PORT01@ + nest_mcs23_imc@PM_MCS23_128B_RD_DISP_PORT23@ + nest_mcs01_imc@PM_MCS01_128B_WR_DISP_PORT01@ + nest_mcs01_imc@PM_MCS01_128B_WR_DISP_PORT23@ + nest_mcs23_imc@PM_MCS23_128B_WR_DISP_PORT01@ + nest_mcs23_imc@PM_MCS23_128B_WR_DISP_PORT23@)", + "MetricExpr" : "mcs01_read + mcs23_read + mcs01_write + mcs23_write", "MetricName" : "Memory-bandwidth-MCS", - "MetricGroup" : "memory_bw", + "MetricGroup" : "memory-bandwidth", "ScaleUnit": "6.1e-5MB" } ] -- 2.17.1
[PATCH v4 0/5] powerpc/perf: Add json file support for hv_24x7 core level events
Patchset enhance current runtime parameter support. It introduces new fields like "PerChip" and "PerCore" similar to the field "PerPkg" which is used to specify perpkg events. The "PerCore" and "PerChip" specifies whether its core or chip events. Based on which we can decide which runtime parameter user want to access. Now character '?' can refers different parameter based on user requirement. Initially, every time we want to add new terms like chip, core, thread etc, we need to create corrsponding fields in pmu_events and event struct. This patchset adds an enum called 'aggr_mode_class' which store all these aggregation like perpkg/percore. It also adds new field 'AggregationMode' to capture these terms. Now, if user wants to add any new term, they just need to add it in the enum defined. I try to test it with my current setup. I also need to replace PerPkg field to AggregationMode in all the x86 uncore json files. It will great if Andi and team can test it and let me know if they have any concerns. Changelog: v3 -> v4: - Include pmu-events.h header file in jevents.c and remove redecalaration of enum aggr_mode_class as Suggested by Jiri. - Add Acked-by tag. v2 -> v3: - Did some nits changes suggested by Jiri include correction of indentation, and making PerCore/PerChip values forward after PerPkg as 1 in the enum. - Rebase the patchset on Arnaldo's tmp.perf/core branch. - Change RFC tag v1 -> v2: - Rather then adding new field as PerCore/PerChip, created a new enum to get these fields. And new field as "AggregationMode" which can be used to capture these fields from json file. - Suggested By Ian Rogers Kajol Jain (5): perf/pmu-events/jevents: Add enum to store aggregation like PerPkg pmu-events/x86/uncore: Replace PerPkg field to AggregationMode in x86 json files perf jevents: Add support for parsing perchip/percore events perf/tools: Pass pmu_event structure as a parameter for arch_get_runtimeparam perf/tools/pmu_events/powerpc: Add hv_24x7 core level metric events tools/perf/arch/powerpc/util/header.c | 7 +- .../arch/powerpc/power9/nest_metrics.json | 27 +- .../arch/x86/broadwellde/uncore-cache.json| 62 ++-- .../arch/x86/broadwellde/uncore-memory.json | 18 +- .../arch/x86/broadwellde/uncore-power.json| 18 +- .../arch/x86/broadwellx/uncore-cache.json | 62 ++-- .../x86/broadwellx/uncore-interconnect.json | 6 +- .../arch/x86/broadwellx/uncore-memory.json| 18 +- .../arch/x86/broadwellx/uncore-power.json | 18 +- .../arch/x86/cascadelakex/uncore-memory.json | 64 ++-- .../arch/x86/cascadelakex/uncore-other.json | 332 +- .../arch/x86/haswellx/uncore-cache.json | 62 ++-- .../x86/haswellx/uncore-interconnect.json | 6 +- .../arch/x86/haswellx/uncore-memory.json | 18 +- .../arch/x86/haswellx/uncore-power.json | 18 +- .../arch/x86/ivytown/uncore-cache.json| 62 ++-- .../arch/x86/ivytown/uncore-interconnect.json | 10 +- .../arch/x86/ivytown/uncore-memory.json | 16 +- .../arch/x86/ivytown/uncore-power.json| 52 +-- .../arch/x86/jaketown/uncore-cache.json | 40 +-- .../x86/jaketown/uncore-interconnect.json | 10 +- .../arch/x86/jaketown/uncore-memory.json | 18 +- .../arch/x86/jaketown/uncore-power.json | 52 +-- .../x86/knightslanding/uncore-memory.json | 8 +- .../arch/x86/skylakex/uncore-memory.json | 36 +- .../arch/x86/skylakex/uncore-other.json | 220 ++-- .../arch/x86/tremontx/uncore-memory.json | 14 +- .../arch/x86/tremontx/uncore-other.json | 70 ++-- .../arch/x86/tremontx/uncore-power.json | 2 +- tools/perf/pmu-events/jevents.c | 40 ++- tools/perf/pmu-events/jevents.h | 2 +- tools/perf/pmu-events/pmu-events.h| 8 +- tools/perf/tests/pmu-events.c | 8 +- tools/perf/util/metricgroup.c | 5 +- tools/perf/util/metricgroup.h | 3 +- tools/perf/util/pmu.c | 6 +- 36 files changed, 724 insertions(+), 694 deletions(-) -- 2.26.2
[PATCH v4 1/5] perf/pmu-events/jevents: Add enum to store aggregation like PerPkg
Initially, every time we want to add new terms like chip, core thread etc, we need to create corrsponding fields in pmu_events and event struct. This patch adds an enum called 'aggr_mode_class' which store all these aggregation like perpkg/percore. It also adds new field 'aggr_mode' to capture these terms. Now, if user wants to add any new term, they just need to add it in the enum defined. Signed-off-by: Kajol Jain Acked-by: Ian Rogers --- tools/perf/pmu-events/jevents.c| 36 ++ tools/perf/pmu-events/jevents.h| 2 +- tools/perf/pmu-events/pmu-events.h | 6 - tools/perf/tests/pmu-events.c | 8 +++ tools/perf/util/pmu.c | 6 ++--- 5 files changed, 35 insertions(+), 23 deletions(-) diff --git a/tools/perf/pmu-events/jevents.c b/tools/perf/pmu-events/jevents.c index fa86c5f997cc..6601f1fd2e80 100644 --- a/tools/perf/pmu-events/jevents.c +++ b/tools/perf/pmu-events/jevents.c @@ -49,10 +49,18 @@ #include "jsmn.h" #include "json.h" #include "jevents.h" +#include "pmu-events.h" int verbose; char *prog; +enum aggr_mode_class convert(const char *aggr_mode) +{ + if (!strcmp(aggr_mode, "PerPkg")) + return PerPkg; + return -1; +} + int eprintf(int level, int var, const char *fmt, ...) { @@ -320,7 +328,7 @@ static void print_events_table_prefix(FILE *fp, const char *tblname) static int print_events_table_entry(void *data, char *name, char *event, char *desc, char *long_desc, - char *pmu, char *unit, char *perpkg, + char *pmu, char *unit, char *aggr_mode, char *metric_expr, char *metric_name, char *metric_group, char *deprecated, char *metric_constraint) @@ -345,10 +353,10 @@ static int print_events_table_entry(void *data, char *name, char *event, fprintf(outfp, "\t.long_desc = \"%s\",\n", long_desc); if (pmu) fprintf(outfp, "\t.pmu = \"%s\",\n", pmu); + if (aggr_mode) + fprintf(outfp, "\t.aggr_mode = \"%d\",\n", convert(aggr_mode)); if (unit) fprintf(outfp, "\t.unit = \"%s\",\n", unit); - if (perpkg) - fprintf(outfp, "\t.perpkg = \"%s\",\n", perpkg); if (metric_expr) fprintf(outfp, "\t.metric_expr = \"%s\",\n", metric_expr); if (metric_name) @@ -372,7 +380,7 @@ struct event_struct { char *long_desc; char *pmu; char *unit; - char *perpkg; + char *aggr_mode; char *metric_expr; char *metric_name; char *metric_group; @@ -401,7 +409,7 @@ struct event_struct { op(long_desc); \ op(pmu);\ op(unit); \ - op(perpkg); \ + op(aggr_mode); \ op(metric_expr);\ op(metric_name);\ op(metric_group); \ @@ -423,7 +431,7 @@ static void free_arch_std_events(void) static int save_arch_std_events(void *data, char *name, char *event, char *desc, char *long_desc, char *pmu, - char *unit, char *perpkg, char *metric_expr, + char *unit, char *aggr_mode, char *metric_expr, char *metric_name, char *metric_group, char *deprecated, char *metric_constraint) { @@ -487,7 +495,7 @@ static char *real_event(const char *name, char *event) static int try_fixup(const char *fn, char *arch_std, char **event, char **desc, char **name, char **long_desc, char **pmu, char **filter, - char **perpkg, char **unit, char **metric_expr, char **metric_name, + char **aggr_mode, char **unit, char **metric_expr, char **metric_name, char **metric_group, unsigned long long eventcode, char **deprecated, char **metric_constraint) { @@ -515,7 +523,7 @@ try_fixup(const char *fn, char *arch_std, char **event, char **desc, int json_events(const char *fn, int (*func)(void *data, char *name, char *event, char *desc, char *long_desc, - char *pmu, char *unit, char *perpkg, + char *pmu, char *unit, char *aggr_mode, char *metric_expr, char *metric_name, char *metric_group,
[PATCH v4 4/5] perf/tools: Pass pmu_event structure as a parameter for arch_get_runtimeparam
This patch adds passing of pmu_event as a parameter in function 'arch_get_runtimeparam' which can be used to get details like if the event is percore/perchip. Signed-off-by: Kajol Jain Acked-by: Ian Rogers --- tools/perf/arch/powerpc/util/header.c | 7 +-- tools/perf/util/metricgroup.c | 5 ++--- tools/perf/util/metricgroup.h | 3 ++- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/tools/perf/arch/powerpc/util/header.c b/tools/perf/arch/powerpc/util/header.c index d4870074f14c..c8a33120a7a3 100644 --- a/tools/perf/arch/powerpc/util/header.c +++ b/tools/perf/arch/powerpc/util/header.c @@ -47,8 +47,11 @@ get_cpuid_str(struct perf_pmu *pmu __maybe_unused) return bufp; } -int arch_get_runtimeparam(void) +int arch_get_runtimeparam(struct pmu_event *pe) { int count; - return sysfs__read_int("/devices/hv_24x7/interface/sockets", &count) < 0 ? 1 : count; + char path[PATH_MAX] = "/devices/hv_24x7/interface/"; + + atoi(pe->aggr_mode) == PerChip ? strcat(path, "sockets") : strcat(path, "coresperchip"); + return sysfs__read_int(path, &count) < 0 ? 1 : count; } diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c index 82fecb5a302d..58054588f599 100644 --- a/tools/perf/util/metricgroup.c +++ b/tools/perf/util/metricgroup.c @@ -15,7 +15,6 @@ #include "rblist.h" #include #include -#include "pmu-events/pmu-events.h" #include "strlist.h" #include #include @@ -566,7 +565,7 @@ static bool metricgroup__has_constraint(struct pmu_event *pe) return false; } -int __weak arch_get_runtimeparam(void) +int __weak arch_get_runtimeparam(struct pmu_event *pe __maybe_unused) { return 1; } @@ -650,7 +649,7 @@ static int metricgroup__add_metric(const char *metric, bool metric_no_group, } else { int j, count; - count = arch_get_runtimeparam(); + count = arch_get_runtimeparam(pe); /* This loop is added to create multiple * events depend on count value and add diff --git a/tools/perf/util/metricgroup.h b/tools/perf/util/metricgroup.h index 8315bd1a7da4..3917b5e43ebb 100644 --- a/tools/perf/util/metricgroup.h +++ b/tools/perf/util/metricgroup.h @@ -5,6 +5,7 @@ #include #include #include +#include "pmu-events/pmu-events.h" struct evsel; struct evlist; @@ -46,6 +47,6 @@ int metricgroup__parse_groups_test(struct evlist *evlist, void metricgroup__print(bool metrics, bool groups, char *filter, bool raw, bool details); bool metricgroup__has_metric(const char *metric); -int arch_get_runtimeparam(void); +int arch_get_runtimeparam(struct pmu_event *pe __maybe_unused); void metricgroup__rblist_exit(struct rblist *metric_events); #endif -- 2.26.2
[PATCH v4 5/5] perf/tools/pmu_events/powerpc: Add hv_24x7 core level metric events
This patch adds hv_24x7 core level events in nest_metric.json file and also add PerChip/PerCore field in metric events. Result: power9 platform: command:# ./perf stat --metric-only -M PowerBUS_Frequency -C 0 -I 1000 1.706011.92.0 2.0002538812.01.9 3.0003648102.02.0 Signed-off-by: Kajol Jain Acked-by: Ian Rogers --- .../arch/powerpc/power9/nest_metrics.json | 27 --- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/tools/perf/pmu-events/arch/powerpc/power9/nest_metrics.json b/tools/perf/pmu-events/arch/powerpc/power9/nest_metrics.json index 8383a37647ad..4672e6d7e7cb 100644 --- a/tools/perf/pmu-events/arch/powerpc/power9/nest_metrics.json +++ b/tools/perf/pmu-events/arch/powerpc/power9/nest_metrics.json @@ -1,20 +1,29 @@ [ { -"MetricExpr": "(hv_24x7@PM_MCS01_128B_RD_DISP_PORT01\\,chip\\=?@ + hv_24x7@PM_MCS01_128B_RD_DISP_PORT23\\,chip\\=?@ + hv_24x7@PM_MCS23_128B_RD_DISP_PORT01\\,chip\\=?@ + hv_24x7@PM_MCS23_128B_RD_DISP_PORT23\\,chip\\=?@)", -"MetricName": "Memory_RD_BW_Chip", -"MetricGroup": "Memory_BW", -"ScaleUnit": "1.6e-2MB" + "MetricExpr": "(hv_24x7@PM_MCS01_128B_RD_DISP_PORT01\\,chip\\=?@ + hv_24x7@PM_MCS01_128B_RD_DISP_PORT23\\,chip\\=?@ + hv_24x7@PM_MCS23_128B_RD_DISP_PORT01\\,chip\\=?@ + hv_24x7@PM_MCS23_128B_RD_DISP_PORT23\\,chip\\=?@)", + "MetricName": "Memory_RD_BW_Chip", + "MetricGroup": "Memory_BW", + "ScaleUnit": "1.6e-2MB", + "AggregationMode": "PerChip" }, { "MetricExpr": "(hv_24x7@PM_MCS01_128B_WR_DISP_PORT01\\,chip\\=?@ + hv_24x7@PM_MCS01_128B_WR_DISP_PORT23\\,chip\\=?@ + hv_24x7@PM_MCS23_128B_WR_DISP_PORT01\\,chip\\=?@ + hv_24x7@PM_MCS23_128B_WR_DISP_PORT23\\,chip\\=?@ )", -"MetricName": "Memory_WR_BW_Chip", -"MetricGroup": "Memory_BW", -"ScaleUnit": "1.6e-2MB" + "MetricName": "Memory_WR_BW_Chip", + "MetricGroup": "Memory_BW", + "ScaleUnit": "1.6e-2MB", + "AggregationMode": "PerChip" }, { "MetricExpr": "(hv_24x7@PM_PB_CYC\\,chip\\=?@ )", -"MetricName": "PowerBUS_Frequency", -"ScaleUnit": "2.5e-7GHz" + "MetricName": "PowerBUS_Frequency", + "ScaleUnit": "2.5e-7GHz", + "AggregationMode": "PerChip" +}, +{ + "MetricExpr": "(hv_24x7@CPM_CS_32MHZ_CYC\\,domain\\=3\\,core\\=?@ )", + "MetricName": "CPM_CS_32MHZ_CYC", + "ScaleUnit": "1MHz", + "AggregationMode": "PerCore" }, { "MetricExpr" : "nest_mcs01_imc@PM_MCS01_128B_RD_DISP_PORT01@ + nest_mcs01_imc@PM_MCS01_128B_RD_DISP_PORT23@", -- 2.26.2
[PATCH v4 3/5] perf jevents: Add support for parsing perchip/percore events
Added the "PerChiip" field in enum "aggr_mode_classs" so that perf knows they are per chip events. Added the "PerCore" field in enum "aggr_mode_class" so that perf knows they are per core events. Similar to the way we had "PerPkg field to specify perpkg events. Signed-off-by: Kajol Jain Acked-by: Ian Rogers --- tools/perf/pmu-events/jevents.c| 4 tools/perf/pmu-events/pmu-events.h | 4 +++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/tools/perf/pmu-events/jevents.c b/tools/perf/pmu-events/jevents.c index 6601f1fd2e80..2f48b783a64d 100644 --- a/tools/perf/pmu-events/jevents.c +++ b/tools/perf/pmu-events/jevents.c @@ -58,6 +58,10 @@ enum aggr_mode_class convert(const char *aggr_mode) { if (!strcmp(aggr_mode, "PerPkg")) return PerPkg; + else if (!strcmp(aggr_mode, "PerCore")) + return PerCore; + else if (!strcmp(aggr_mode, "PerChip")) + return PerChip; return -1; } diff --git a/tools/perf/pmu-events/pmu-events.h b/tools/perf/pmu-events/pmu-events.h index 71b7aa6278d0..214ffc681b54 100644 --- a/tools/perf/pmu-events/pmu-events.h +++ b/tools/perf/pmu-events/pmu-events.h @@ -3,7 +3,9 @@ #define PMU_EVENTS_H enum aggr_mode_class { - PerPkg = 1 + PerPkg = 1, + PerChip, + PerCore }; /* -- 2.26.2
[PATCH v3 0/5] powerpc/perf: Add json file support for hv_24x7 core level events
Patchset enhance current runtime parameter support. It introduces new fields like "PerChip" and "PerCore" similar to the field "PerPkg" which is used to specify perpkg events. The "PerCore" and "PerChip" specifies whether its core or chip events. Based on which we can decide which runtime parameter user want to access. Now character '?' can refers different parameter based on user requirement. Initially, every time we want to add new terms like chip, core, thread etc, we need to create corrsponding fields in pmu_events and event struct. This patchset adds an enum called 'aggr_mode_class' which store all these aggregation like perpkg/percore. It also adds new field 'AggregationMode' to capture these terms. Now, if user wants to add any new term, they just need to add it in the enum defined. I try to test it with my current setup. I also need to replace PerPkg field to AggregationMode in all the x86 uncore json files. It will great if Andi and team can test it and let me know if they have any concerns. Changelog: v2 -> v3: - Did some nits changes suggested by Jiri include correction of indentation, and making PerCore/PerChip values forward after PerPkg as 1 in the enum. - Rebase the patchset on Arnaldo's tmp.perf/core branch. - Change RFC tag v1 -> v2: - Rather then adding new field as PerCore/PerChip, created a new enum to get these fields. And new field as "AggregationMode" which can be used to capture these fields from json file. - Suggested By Ian Rogers Kajol Jain (5): perf/pmu-events/jevents: Add enum to store aggregation like PerPkg pmu-events/x86/uncore: Replace PerPkg field to AggregationMode in x86 json files perf jevents: Add support for parsing perchip/percore events perf/tools: Pass pmu_event structure as a parameter for arch_get_runtimeparam perf/tools/pmu_events/powerpc: Add hv_24x7 core level metric events tools/perf/arch/powerpc/util/header.c | 7 +- .../arch/powerpc/power9/nest_metrics.json | 27 +- .../arch/x86/broadwellde/uncore-cache.json| 62 ++-- .../arch/x86/broadwellde/uncore-memory.json | 18 +- .../arch/x86/broadwellde/uncore-power.json| 18 +- .../arch/x86/broadwellx/uncore-cache.json | 62 ++-- .../x86/broadwellx/uncore-interconnect.json | 6 +- .../arch/x86/broadwellx/uncore-memory.json| 18 +- .../arch/x86/broadwellx/uncore-power.json | 18 +- .../arch/x86/cascadelakex/uncore-memory.json | 64 ++-- .../arch/x86/cascadelakex/uncore-other.json | 332 +- .../arch/x86/haswellx/uncore-cache.json | 62 ++-- .../x86/haswellx/uncore-interconnect.json | 6 +- .../arch/x86/haswellx/uncore-memory.json | 18 +- .../arch/x86/haswellx/uncore-power.json | 18 +- .../arch/x86/ivytown/uncore-cache.json| 62 ++-- .../arch/x86/ivytown/uncore-interconnect.json | 10 +- .../arch/x86/ivytown/uncore-memory.json | 16 +- .../arch/x86/ivytown/uncore-power.json| 52 +-- .../arch/x86/jaketown/uncore-cache.json | 40 +-- .../x86/jaketown/uncore-interconnect.json | 10 +- .../arch/x86/jaketown/uncore-memory.json | 18 +- .../arch/x86/jaketown/uncore-power.json | 52 +-- .../x86/knightslanding/uncore-memory.json | 8 +- .../arch/x86/skylakex/uncore-memory.json | 36 +- .../arch/x86/skylakex/uncore-other.json | 220 ++-- .../arch/x86/tremontx/uncore-memory.json | 14 +- .../arch/x86/tremontx/uncore-other.json | 70 ++-- .../arch/x86/tremontx/uncore-power.json | 2 +- tools/perf/pmu-events/jevents.c | 45 ++- tools/perf/pmu-events/jevents.h | 2 +- tools/perf/pmu-events/pmu-events.h| 8 +- tools/perf/tests/pmu-events.c | 8 +- tools/perf/util/metricgroup.c | 5 +- tools/perf/util/metricgroup.h | 3 +- tools/perf/util/pmu.c | 6 +- 36 files changed, 729 insertions(+), 694 deletions(-) -- 2.26.2
[PATCH v3 1/5] perf/pmu-events/jevents: Add enum to store aggregation like PerPkg
Initially, every time we want to add new terms like chip, core thread etc, we need to create corrsponding fields in pmu_events and event struct. This patch adds an enum called 'aggr_mode_class' which store all these aggregation like perpkg/percore. It also adds new field 'aggr_mode' to capture these terms. Now, if user wants to add any new term, they just need to add it in the enum defined. Signed-off-by: Kajol Jain --- tools/perf/pmu-events/jevents.c| 39 +++--- tools/perf/pmu-events/jevents.h| 2 +- tools/perf/pmu-events/pmu-events.h | 6 - tools/perf/tests/pmu-events.c | 8 +++--- tools/perf/util/pmu.c | 6 ++--- 5 files changed, 38 insertions(+), 23 deletions(-) diff --git a/tools/perf/pmu-events/jevents.c b/tools/perf/pmu-events/jevents.c index fa86c5f997cc..b2f59f0af63d 100644 --- a/tools/perf/pmu-events/jevents.c +++ b/tools/perf/pmu-events/jevents.c @@ -53,6 +53,17 @@ int verbose; char *prog; +enum aggr_mode_class { + PerPkg = 1 +}; + +enum aggr_mode_class convert(const char *aggr_mode) +{ + if (!strcmp(aggr_mode, "PerPkg")) + return PerPkg; + return -1; +} + int eprintf(int level, int var, const char *fmt, ...) { @@ -320,7 +331,7 @@ static void print_events_table_prefix(FILE *fp, const char *tblname) static int print_events_table_entry(void *data, char *name, char *event, char *desc, char *long_desc, - char *pmu, char *unit, char *perpkg, + char *pmu, char *unit, char *aggr_mode, char *metric_expr, char *metric_name, char *metric_group, char *deprecated, char *metric_constraint) @@ -345,10 +356,10 @@ static int print_events_table_entry(void *data, char *name, char *event, fprintf(outfp, "\t.long_desc = \"%s\",\n", long_desc); if (pmu) fprintf(outfp, "\t.pmu = \"%s\",\n", pmu); + if (aggr_mode) + fprintf(outfp, "\t.aggr_mode = \"%d\",\n", convert(aggr_mode)); if (unit) fprintf(outfp, "\t.unit = \"%s\",\n", unit); - if (perpkg) - fprintf(outfp, "\t.perpkg = \"%s\",\n", perpkg); if (metric_expr) fprintf(outfp, "\t.metric_expr = \"%s\",\n", metric_expr); if (metric_name) @@ -372,7 +383,7 @@ struct event_struct { char *long_desc; char *pmu; char *unit; - char *perpkg; + char *aggr_mode; char *metric_expr; char *metric_name; char *metric_group; @@ -401,7 +412,7 @@ struct event_struct { op(long_desc); \ op(pmu);\ op(unit); \ - op(perpkg); \ + op(aggr_mode); \ op(metric_expr);\ op(metric_name);\ op(metric_group); \ @@ -423,7 +434,7 @@ static void free_arch_std_events(void) static int save_arch_std_events(void *data, char *name, char *event, char *desc, char *long_desc, char *pmu, - char *unit, char *perpkg, char *metric_expr, + char *unit, char *aggr_mode, char *metric_expr, char *metric_name, char *metric_group, char *deprecated, char *metric_constraint) { @@ -487,7 +498,7 @@ static char *real_event(const char *name, char *event) static int try_fixup(const char *fn, char *arch_std, char **event, char **desc, char **name, char **long_desc, char **pmu, char **filter, - char **perpkg, char **unit, char **metric_expr, char **metric_name, + char **aggr_mode, char **unit, char **metric_expr, char **metric_name, char **metric_group, unsigned long long eventcode, char **deprecated, char **metric_constraint) { @@ -515,7 +526,7 @@ try_fixup(const char *fn, char *arch_std, char **event, char **desc, int json_events(const char *fn, int (*func)(void *data, char *name, char *event, char *desc, char *long_desc, - char *pmu, char *unit, char *perpkg, + char *pmu, char *unit, char *aggr_mode, char *metric_expr, char *metric_name, char *metric_group, char *deprecated, char *metric_constraint), @@ -542,7 +553,7 @@ int json_events(const char *f
[PATCH v3 3/5] perf jevents: Add support for parsing perchip/percore events
Added the "PerChip" field in enum so that perf knows they are per chip events. Added the "PerCore" field in enum so that perf knows they are per core events and add these fields to pmu_event structure. Similar to the way we had "PerPkg field to specify perpkg events. Signed-off-by: Kajol Jain --- tools/perf/pmu-events/jevents.c| 8 +++- tools/perf/pmu-events/pmu-events.h | 4 +++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/tools/perf/pmu-events/jevents.c b/tools/perf/pmu-events/jevents.c index b2f59f0af63d..e1c43f739083 100644 --- a/tools/perf/pmu-events/jevents.c +++ b/tools/perf/pmu-events/jevents.c @@ -54,13 +54,19 @@ int verbose; char *prog; enum aggr_mode_class { - PerPkg = 1 + PerPkg = 1, + PerChip, + PerCore }; enum aggr_mode_class convert(const char *aggr_mode) { if (!strcmp(aggr_mode, "PerPkg")) return PerPkg; + else if (!strcmp(aggr_mode, "PerCore")) + return PerCore; + else if (!strcmp(aggr_mode, "PerChip")) + return PerChip; return -1; } diff --git a/tools/perf/pmu-events/pmu-events.h b/tools/perf/pmu-events/pmu-events.h index 71b7aa6278d0..214ffc681b54 100644 --- a/tools/perf/pmu-events/pmu-events.h +++ b/tools/perf/pmu-events/pmu-events.h @@ -3,7 +3,9 @@ #define PMU_EVENTS_H enum aggr_mode_class { - PerPkg = 1 + PerPkg = 1, + PerChip, + PerCore }; /* -- 2.26.2
[PATCH v3 5/5] perf/tools/pmu_events/powerpc: Add hv_24x7 core level metric events
This patch adds hv_24x7 core level events in nest_metric.json file and also add PerChip/PerCore field in metric events. Result: power9 platform: command:# ./perf stat --metric-only -M PowerBUS_Frequency -C 0 -I 1000 1.706011.92.0 2.0002538812.01.9 3.0003648102.02.0 Signed-off-by: Kajol Jain --- .../arch/powerpc/power9/nest_metrics.json | 27 --- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/tools/perf/pmu-events/arch/powerpc/power9/nest_metrics.json b/tools/perf/pmu-events/arch/powerpc/power9/nest_metrics.json index 8383a37647ad..4672e6d7e7cb 100644 --- a/tools/perf/pmu-events/arch/powerpc/power9/nest_metrics.json +++ b/tools/perf/pmu-events/arch/powerpc/power9/nest_metrics.json @@ -1,20 +1,29 @@ [ { -"MetricExpr": "(hv_24x7@PM_MCS01_128B_RD_DISP_PORT01\\,chip\\=?@ + hv_24x7@PM_MCS01_128B_RD_DISP_PORT23\\,chip\\=?@ + hv_24x7@PM_MCS23_128B_RD_DISP_PORT01\\,chip\\=?@ + hv_24x7@PM_MCS23_128B_RD_DISP_PORT23\\,chip\\=?@)", -"MetricName": "Memory_RD_BW_Chip", -"MetricGroup": "Memory_BW", -"ScaleUnit": "1.6e-2MB" + "MetricExpr": "(hv_24x7@PM_MCS01_128B_RD_DISP_PORT01\\,chip\\=?@ + hv_24x7@PM_MCS01_128B_RD_DISP_PORT23\\,chip\\=?@ + hv_24x7@PM_MCS23_128B_RD_DISP_PORT01\\,chip\\=?@ + hv_24x7@PM_MCS23_128B_RD_DISP_PORT23\\,chip\\=?@)", + "MetricName": "Memory_RD_BW_Chip", + "MetricGroup": "Memory_BW", + "ScaleUnit": "1.6e-2MB", + "AggregationMode": "PerChip" }, { "MetricExpr": "(hv_24x7@PM_MCS01_128B_WR_DISP_PORT01\\,chip\\=?@ + hv_24x7@PM_MCS01_128B_WR_DISP_PORT23\\,chip\\=?@ + hv_24x7@PM_MCS23_128B_WR_DISP_PORT01\\,chip\\=?@ + hv_24x7@PM_MCS23_128B_WR_DISP_PORT23\\,chip\\=?@ )", -"MetricName": "Memory_WR_BW_Chip", -"MetricGroup": "Memory_BW", -"ScaleUnit": "1.6e-2MB" + "MetricName": "Memory_WR_BW_Chip", + "MetricGroup": "Memory_BW", + "ScaleUnit": "1.6e-2MB", + "AggregationMode": "PerChip" }, { "MetricExpr": "(hv_24x7@PM_PB_CYC\\,chip\\=?@ )", -"MetricName": "PowerBUS_Frequency", -"ScaleUnit": "2.5e-7GHz" + "MetricName": "PowerBUS_Frequency", + "ScaleUnit": "2.5e-7GHz", + "AggregationMode": "PerChip" +}, +{ + "MetricExpr": "(hv_24x7@CPM_CS_32MHZ_CYC\\,domain\\=3\\,core\\=?@ )", + "MetricName": "CPM_CS_32MHZ_CYC", + "ScaleUnit": "1MHz", + "AggregationMode": "PerCore" }, { "MetricExpr" : "nest_mcs01_imc@PM_MCS01_128B_RD_DISP_PORT01@ + nest_mcs01_imc@PM_MCS01_128B_RD_DISP_PORT23@", -- 2.26.2
[PATCH v3 4/5] perf/tools: Pass pmu_event structure as a parameter for arch_get_runtimeparam
This patch adds passing of pmu_event as a parameter in function 'arch_get_runtimeparam' which can be used to get details like if the event is percore/perchip. Signed-off-by: Kajol Jain --- tools/perf/arch/powerpc/util/header.c | 7 +-- tools/perf/util/metricgroup.c | 5 ++--- tools/perf/util/metricgroup.h | 3 ++- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/tools/perf/arch/powerpc/util/header.c b/tools/perf/arch/powerpc/util/header.c index d4870074f14c..c8a33120a7a3 100644 --- a/tools/perf/arch/powerpc/util/header.c +++ b/tools/perf/arch/powerpc/util/header.c @@ -47,8 +47,11 @@ get_cpuid_str(struct perf_pmu *pmu __maybe_unused) return bufp; } -int arch_get_runtimeparam(void) +int arch_get_runtimeparam(struct pmu_event *pe) { int count; - return sysfs__read_int("/devices/hv_24x7/interface/sockets", &count) < 0 ? 1 : count; + char path[PATH_MAX] = "/devices/hv_24x7/interface/"; + + atoi(pe->aggr_mode) == PerChip ? strcat(path, "sockets") : strcat(path, "coresperchip"); + return sysfs__read_int(path, &count) < 0 ? 1 : count; } diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c index 82fecb5a302d..58054588f599 100644 --- a/tools/perf/util/metricgroup.c +++ b/tools/perf/util/metricgroup.c @@ -15,7 +15,6 @@ #include "rblist.h" #include #include -#include "pmu-events/pmu-events.h" #include "strlist.h" #include #include @@ -566,7 +565,7 @@ static bool metricgroup__has_constraint(struct pmu_event *pe) return false; } -int __weak arch_get_runtimeparam(void) +int __weak arch_get_runtimeparam(struct pmu_event *pe __maybe_unused) { return 1; } @@ -650,7 +649,7 @@ static int metricgroup__add_metric(const char *metric, bool metric_no_group, } else { int j, count; - count = arch_get_runtimeparam(); + count = arch_get_runtimeparam(pe); /* This loop is added to create multiple * events depend on count value and add diff --git a/tools/perf/util/metricgroup.h b/tools/perf/util/metricgroup.h index 8315bd1a7da4..3917b5e43ebb 100644 --- a/tools/perf/util/metricgroup.h +++ b/tools/perf/util/metricgroup.h @@ -5,6 +5,7 @@ #include #include #include +#include "pmu-events/pmu-events.h" struct evsel; struct evlist; @@ -46,6 +47,6 @@ int metricgroup__parse_groups_test(struct evlist *evlist, void metricgroup__print(bool metrics, bool groups, char *filter, bool raw, bool details); bool metricgroup__has_metric(const char *metric); -int arch_get_runtimeparam(void); +int arch_get_runtimeparam(struct pmu_event *pe __maybe_unused); void metricgroup__rblist_exit(struct rblist *metric_events); #endif -- 2.26.2
[tip: perf/core] perf: Fix task_function_call() error handling
The following commit has been merged into the perf/core branch of tip: Commit-ID: 84ad70320241566e028ada955c694ab92f3351e3 Gitweb: https://git.kernel.org/tip/84ad70320241566e028ada955c694ab92f3351e3 Author:Kajol Jain AuthorDate:Thu, 27 Aug 2020 12:17:32 +05:30 Committer: Peter Zijlstra CommitterDate: Thu, 08 Oct 2020 15:16:29 +02:00 perf: Fix task_function_call() error handling The error handling introduced by commit: 2ed6edd33a21 ("perf: Add cond_resched() to task_function_call()") looses any return value from smp_call_function_single() that is not {0, -EINVAL}. This is a problem because it will return -EXNIO when the target CPU is offline. Worse, in that case it'll turn into an infinite loop. Fixes: 2ed6edd33a21 ("perf: Add cond_resched() to task_function_call()") Reported-by: Srikar Dronamraju Signed-off-by: Kajol Jain Signed-off-by: Peter Zijlstra (Intel) Reviewed-by: Barret Rhoden Tested-by: Srikar Dronamraju Link: https://lkml.kernel.org/r/20200827064732.20860-1-kj...@linux.ibm.com --- kernel/events/core.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/kernel/events/core.c b/kernel/events/core.c index 45edb85..85a6e7f 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -99,7 +99,7 @@ static void remote_function(void *data) * retry due to any failures in smp_call_function_single(), such as if the * task_cpu() goes offline concurrently. * - * returns @func return value or -ESRCH when the process isn't running + * returns @func return value or -ESRCH or -ENXIO when the process isn't running */ static int task_function_call(struct task_struct *p, remote_function_f func, void *info) @@ -115,7 +115,8 @@ task_function_call(struct task_struct *p, remote_function_f func, void *info) for (;;) { ret = smp_call_function_single(task_cpu(p), remote_function, &data, 1); - ret = !ret ? data.ret : -EAGAIN; + if (!ret) + ret = data.ret; if (ret != -EAGAIN) break;
[tip: perf/urgent] perf: Fix task_function_call() error handling
The following commit has been merged into the perf/urgent branch of tip: Commit-ID: 6d6b8b9f4fceab7266ca03d194f60ec72bd4b654 Gitweb: https://git.kernel.org/tip/6d6b8b9f4fceab7266ca03d194f60ec72bd4b654 Author:Kajol Jain AuthorDate:Thu, 27 Aug 2020 12:17:32 +05:30 Committer: Ingo Molnar CommitterDate: Fri, 09 Oct 2020 08:18:33 +02:00 perf: Fix task_function_call() error handling The error handling introduced by commit: 2ed6edd33a21 ("perf: Add cond_resched() to task_function_call()") looses any return value from smp_call_function_single() that is not {0, -EINVAL}. This is a problem because it will return -EXNIO when the target CPU is offline. Worse, in that case it'll turn into an infinite loop. Fixes: 2ed6edd33a21 ("perf: Add cond_resched() to task_function_call()") Reported-by: Srikar Dronamraju Signed-off-by: Kajol Jain Signed-off-by: Peter Zijlstra (Intel) Signed-off-by: Ingo Molnar Reviewed-by: Barret Rhoden Tested-by: Srikar Dronamraju Link: https://lkml.kernel.org/r/20200827064732.20860-1-kj...@linux.ibm.com --- kernel/events/core.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/kernel/events/core.c b/kernel/events/core.c index 7ed5248..e8bf922 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -99,7 +99,7 @@ static void remote_function(void *data) * retry due to any failures in smp_call_function_single(), such as if the * task_cpu() goes offline concurrently. * - * returns @func return value or -ESRCH when the process isn't running + * returns @func return value or -ESRCH or -ENXIO when the process isn't running */ static int task_function_call(struct task_struct *p, remote_function_f func, void *info) @@ -115,7 +115,8 @@ task_function_call(struct task_struct *p, remote_function_f func, void *info) for (;;) { ret = smp_call_function_single(task_cpu(p), remote_function, &data, 1); - ret = !ret ? data.ret : -EAGAIN; + if (!ret) + ret = data.ret; if (ret != -EAGAIN) break;
[tip: perf/core] perf metricgroups: Enhance JSON/metric infrastructure to handle "?"
The following commit has been merged into the perf/core branch of tip: Commit-ID: 1e1a873dc67fc748cc319a27603f33db91027730 Gitweb: https://git.kernel.org/tip/1e1a873dc67fc748cc319a27603f33db91027730 Author:Kajol Jain AuthorDate:Thu, 02 Apr 2020 02:03:37 +05:30 Committer: Arnaldo Carvalho de Melo CommitterDate: Thu, 30 Apr 2020 10:48:33 -03:00 perf metricgroups: Enhance JSON/metric infrastructure to handle "?" Patch enhances current metric infrastructure to handle "?" in the metric expression. The "?" can be use for parameters whose value not known while creating metric events and which can be replace later at runtime to the proper value. It also add flexibility to create multiple events out of single metric event added in JSON file. Patch adds function 'arch_get_runtimeparam' which is a arch specific function, returns the count of metric events need to be created. By default it return 1. This infrastructure needed for hv_24x7 socket/chip level events. "hv_24x7" chip level events needs specific chip-id to which the data is requested. Function 'arch_get_runtimeparam' implemented in header.c which extract number of sockets from sysfs file "sockets" under "/sys/devices/hv_24x7/interface/". With this patch basically we are trying to create as many metric events as define by runtime_param. For that one loop is added in function 'metricgroup__add_metric', which create multiple events at run time depend on return value of 'arch_get_runtimeparam' and merge that event in 'group_list'. To achieve that we are actually passing this parameter value as part of `expr__find_other` function and changing "?" present in metric expression with this value. As in our JSON file, there gonna be single metric event, and out of which we are creating multiple events. To understand which data count belongs to which parameter value, we also printing param value in generic_metric function. For example, command:# ./perf stat -M PowerBUS_Frequency -C 0 -I 1000 1.000101867 9,356,933 hv_24x7/pm_pb_cyc,chip=0/ # 2.3 GHz PowerBUS_Frequency_0 1.000101867 9,366,134 hv_24x7/pm_pb_cyc,chip=1/ # 2.3 GHz PowerBUS_Frequency_1 2.000314878 9,365,868 hv_24x7/pm_pb_cyc,chip=0/ # 2.3 GHz PowerBUS_Frequency_0 2.000314878 9,366,092 hv_24x7/pm_pb_cyc,chip=1/ # 2.3 GHz PowerBUS_Frequency_1 So, here _0 and _1 after PowerBUS_Frequency specify parameter value. Signed-off-by: Kajol Jain Acked-by: Jiri Olsa Cc: Alexander Shishkin Cc: Andi Kleen Cc: Anju T Sudhakar Cc: Benjamin Herrenschmidt Cc: Greg Kroah-Hartman Cc: Jin Yao Cc: Joe Mario Cc: Kan Liang Cc: Madhavan Srinivasan Cc: Mamatha Inamdar Cc: Mark Rutland Cc: Michael Ellerman Cc: Michael Petlan Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Ravi Bangoria Cc: Sukadev Bhattiprolu Cc: Thomas Gleixner Cc: linuxppc-...@lists.ozlabs.org Link: http://lore.kernel.org/lkml/20200401203340.31402-5-kj...@linux.ibm.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/powerpc/util/header.c | 8 +++- tools/perf/tests/expr.c | 8 +++ tools/perf/util/expr.c| 11 +- tools/perf/util/expr.h| 5 +++-- tools/perf/util/expr.l| 27 ++--- tools/perf/util/metricgroup.c | 28 +++--- tools/perf/util/metricgroup.h | 2 ++- tools/perf/util/stat-shadow.c | 17 ++-- 8 files changed, 79 insertions(+), 27 deletions(-) diff --git a/tools/perf/arch/powerpc/util/header.c b/tools/perf/arch/powerpc/util/header.c index 3b4cdfc..d487007 100644 --- a/tools/perf/arch/powerpc/util/header.c +++ b/tools/perf/arch/powerpc/util/header.c @@ -7,6 +7,8 @@ #include #include #include "header.h" +#include "metricgroup.h" +#include #define mfspr(rn) ({unsigned long rval; \ asm volatile("mfspr %0," __stringify(rn) \ @@ -44,3 +46,9 @@ get_cpuid_str(struct perf_pmu *pmu __maybe_unused) return bufp; } + +int arch_get_runtimeparam(void) +{ + int count; + return sysfs__read_int("/devices/hv_24x7/interface/sockets", &count) < 0 ? 1 : count; +} diff --git a/tools/perf/tests/expr.c b/tools/perf/tests/expr.c index ea10fc4..516504c 100644 --- a/tools/perf/tests/expr.c +++ b/tools/perf/tests/expr.c @@ -10,7 +10,7 @@ static int test(struct expr_parse_ctx *ctx, const char *e, double val2) { double val; - if (expr__parse(&val, ctx, e)) + if (expr__parse(&val, ctx, e, 1)) TEST_ASSERT_VAL("parse test failed", 0); TEST_ASSERT_VAL("unexpected value", val == val2); return 0; @@ -44,15 +44,15 @@ int test__expr(struct test *t __maybe_unused, int subtest __maybe_unused) r
[tip: perf/core] perf tests expr: Added test for runtime param in metric expression
The following commit has been merged into the perf/core branch of tip: Commit-ID: 9022608ec5babbb0fa631234098d52895e7e34d8 Gitweb: https://git.kernel.org/tip/9022608ec5babbb0fa631234098d52895e7e34d8 Author:Kajol Jain AuthorDate:Thu, 02 Apr 2020 02:03:38 +05:30 Committer: Arnaldo Carvalho de Melo CommitterDate: Thu, 30 Apr 2020 10:48:33 -03:00 perf tests expr: Added test for runtime param in metric expression Added test case for parsing "?" in metric expression. Signed-off-by: Kajol Jain Acked-by: Jiri Olsa Cc: Alexander Shishkin Cc: Andi Kleen Cc: Anju T Sudhakar Cc: Benjamin Herrenschmidt Cc: Greg Kroah-Hartman Cc: Jin Yao Cc: Joe Mario Cc: Kan Liang Cc: Madhavan Srinivasan Cc: Mamatha Inamdar Cc: Mark Rutland Cc: Michael Ellerman Cc: Michael Petlan Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Ravi Bangoria Cc: Sukadev Bhattiprolu Cc: Thomas Gleixner Cc: linuxppc-...@lists.ozlabs.org Link: http://lore.kernel.org/lkml/20200401203340.31402-6-kj...@linux.ibm.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/expr.c | 8 1 file changed, 8 insertions(+) diff --git a/tools/perf/tests/expr.c b/tools/perf/tests/expr.c index 516504c..f9e8e56 100644 --- a/tools/perf/tests/expr.c +++ b/tools/perf/tests/expr.c @@ -59,6 +59,14 @@ int test__expr(struct test *t __maybe_unused, int subtest __maybe_unused) TEST_ASSERT_VAL("find other", !strcmp(other[2], "BOZO")); TEST_ASSERT_VAL("find other", other[3] == NULL); + TEST_ASSERT_VAL("find other", + expr__find_other("EVENT1\\,param\\=?@ + EVENT2\\,param\\=?@", NULL, + &other, &num_other, 3) == 0); + TEST_ASSERT_VAL("find other", num_other == 2); + TEST_ASSERT_VAL("find other", !strcmp(other[0], "EVENT1,param=3/")); + TEST_ASSERT_VAL("find other", !strcmp(other[1], "EVENT2,param=3/")); + TEST_ASSERT_VAL("find other", other[2] == NULL); + for (i = 0; i < num_other; i++) zfree(&other[i]); free((void *)other);
[tip: perf/core] perf vendor events power9: Add hv_24x7 socket/chip level metric events
The following commit has been merged into the perf/core branch of tip: Commit-ID: 354575c00d61c174e0ff070f56cf3cdbe6d23f9e Gitweb: https://git.kernel.org/tip/354575c00d61c174e0ff070f56cf3cdbe6d23f9e Author:Kajol Jain AuthorDate:Thu, 02 Apr 2020 02:03:40 +05:30 Committer: Arnaldo Carvalho de Melo CommitterDate: Thu, 30 Apr 2020 10:48:33 -03:00 perf vendor events power9: Add hv_24x7 socket/chip level metric events The hv_24×7 feature in IBM® POWER9™ processor-based servers provide the facility to continuously collect large numbers of hardware performance metrics efficiently and accurately. This patch adds hv_24x7 metric file for different Socket/chip resources. Result: power9 platform: command:# ./perf stat --metric-only -M Memory_RD_BW_Chip -C 0 -I 1000 1.96188 0.9 0.3 2.000285720 0.5 0.1 3.000424990 0.4 0.1 command:# ./perf stat --metric-only -M PowerBUS_Frequency -C 0 -I 1000 1.97981 2.3 2.3 2.000291713 2.3 2.3 3.000421719 2.3 2.3 4.000550912 2.3 2.3 Signed-off-by: Kajol Jain Acked-by: Jiri Olsa Cc: Alexander Shishkin Cc: Andi Kleen Cc: Anju T Sudhakar Cc: Benjamin Herrenschmidt Cc: Greg Kroah-Hartman Cc: Jin Yao Cc: Joe Mario Cc: Kan Liang Cc: Madhavan Srinivasan Cc: Mamatha Inamdar Cc: Mark Rutland Cc: Michael Ellerman Cc: Michael Petlan Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Ravi Bangoria Cc: Sukadev Bhattiprolu Cc: Thomas Gleixner Cc: linuxppc-...@lists.ozlabs.org Link: http://lore.kernel.org/lkml/20200401203340.31402-8-kj...@linux.ibm.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/pmu-events/arch/powerpc/power9/nest_metrics.json | 19 +++- 1 file changed, 19 insertions(+) create mode 100644 tools/perf/pmu-events/arch/powerpc/power9/nest_metrics.json diff --git a/tools/perf/pmu-events/arch/powerpc/power9/nest_metrics.json b/tools/perf/pmu-events/arch/powerpc/power9/nest_metrics.json new file mode 100644 index 000..c121e52 --- /dev/null +++ b/tools/perf/pmu-events/arch/powerpc/power9/nest_metrics.json @@ -0,0 +1,19 @@ +[ +{ +"MetricExpr": "(hv_24x7@PM_MCS01_128B_RD_DISP_PORT01\\,chip\\=?@ + hv_24x7@PM_MCS01_128B_RD_DISP_PORT23\\,chip\\=?@ + hv_24x7@PM_MCS23_128B_RD_DISP_PORT01\\,chip\\=?@ + hv_24x7@PM_MCS23_128B_RD_DISP_PORT23\\,chip\\=?@)", +"MetricName": "Memory_RD_BW_Chip", +"MetricGroup": "Memory_BW", +"ScaleUnit": "1.6e-2MB" +}, +{ + "MetricExpr": "(hv_24x7@PM_MCS01_128B_WR_DISP_PORT01\\,chip\\=?@ + hv_24x7@PM_MCS01_128B_WR_DISP_PORT23\\,chip\\=?@ + hv_24x7@PM_MCS23_128B_WR_DISP_PORT01\\,chip\\=?@ + hv_24x7@PM_MCS23_128B_WR_DISP_PORT23\\,chip\\=?@ )", +"MetricName": "Memory_WR_BW_Chip", +"MetricGroup": "Memory_BW", +"ScaleUnit": "1.6e-2MB" +}, +{ + "MetricExpr": "(hv_24x7@PM_PB_CYC\\,chip\\=?@ )", +"MetricName": "PowerBUS_Frequency", +"ScaleUnit": "2.5e-7GHz" +} +]
[tip: perf/core] perf tools: Enable Hz/hz prinitg for --metric-only option
The following commit has been merged into the perf/core branch of tip: Commit-ID: 3351c6da896bf521b118bfbb699fbda8f2a816b3 Gitweb: https://git.kernel.org/tip/3351c6da896bf521b118bfbb699fbda8f2a816b3 Author:Kajol Jain AuthorDate:Thu, 02 Apr 2020 02:03:39 +05:30 Committer: Arnaldo Carvalho de Melo CommitterDate: Thu, 30 Apr 2020 10:48:33 -03:00 perf tools: Enable Hz/hz prinitg for --metric-only option Commit 54b5091606c18 ("perf stat: Implement --metric-only mode") added function 'valid_only_metric()' which drops "Hz" or "hz", if it is part of "ScaleUnit". This patch enable it since hv_24x7 supports couple of frequency events. Signed-off-by: Kajol Jain Acked-by: Jiri Olsa Cc: Alexander Shishkin Cc: Andi Kleen Cc: Anju T Sudhakar Cc: Benjamin Herrenschmidt Cc: Greg Kroah-Hartman Cc: Jin Yao Cc: Joe Mario Cc: Kan Liang Cc: Madhavan Srinivasan Cc: Mamatha Inamdar Cc: Mark Rutland Cc: Michael Ellerman Cc: Michael Petlan Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Ravi Bangoria Cc: Sukadev Bhattiprolu Cc: Thomas Gleixner Cc: linuxppc-...@lists.ozlabs.org Link: http://lore.kernel.org/lkml/20200401203340.31402-7-kj...@linux.ibm.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/stat-display.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c index 9e757d1..679aaa6 100644 --- a/tools/perf/util/stat-display.c +++ b/tools/perf/util/stat-display.c @@ -237,8 +237,6 @@ static bool valid_only_metric(const char *unit) if (!unit) return false; if (strstr(unit, "/sec") || - strstr(unit, "hz") || - strstr(unit, "Hz") || strstr(unit, "CPUs utilized")) return false; return true;