* [PATCH v2] powerpc/papr_scm: Fix nvdimm event mappings
@ 2022-07-11 3:46 Kajol Jain
2022-07-12 5:15 ` Vaibhav Jain
0 siblings, 1 reply; 3+ messages in thread
From: Kajol Jain @ 2022-07-11 3:46 UTC (permalink / raw)
To: mpe, linuxppc-dev, vaibhav
Cc: nvdimm, atrajeev, rnsastry, kjain, maddy, Aneesh Kumar K . V,
dan.j.williams, disgoel
Commit 4c08d4bbc089 ("powerpc/papr_scm: Add perf interface support")
added performance monitoring support for papr-scm nvdimm devices via
perf interface. Commit also added an array in papr_scm_priv
structure called "nvdimm_events_map", which got filled based on the
result of H_SCM_PERFORMANCE_STATS hcall.
Currently there is an assumption that the order of events in the
stats buffer, returned by the hypervisor is same. And that order also
matches with the events specified in nvdimm driver code.
But this assumption is not documented anywhere in Power Architecture
Platform Requirements (PAPR) document. Although the order
of events happens to be same on current systems, but it might
not be true in future generation systems. Fix the issue, by
adding a static mapping for nvdimm events to corresponding stat-id,
and removing the dynamic map from papr_scm_priv structure.
Fixes: 4c08d4bbc089 ("powerpc/papr_scm: Add perf interface support")
Reported-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
Signed-off-by: Kajol Jain <kjain@linux.ibm.com>
---
arch/powerpc/platforms/pseries/papr_scm.c | 62 ++++++++++-------------
1 file changed, 28 insertions(+), 34 deletions(-)
---
Changelog:
v1 -> v2
- To avoid accidental reordering, explicitly defined index for all
the events. Also added valid config check in papr_scm_pmu_event_init
function as suggested by Michael Ellerman.
- Did minor commit message changes and remove initialization of
rc variable as suggested by Michael Ellerman
- Link to the patch v1: https://patchwork.kernel.org/project/linux-nvdimm/patch/20220610133431.410514-1-kjain@linux.ibm.com/
---
diff --git a/arch/powerpc/platforms/pseries/papr_scm.c b/arch/powerpc/platforms/pseries/papr_scm.c
index 82cae08976bc..139e243c3f49 100644
--- a/arch/powerpc/platforms/pseries/papr_scm.c
+++ b/arch/powerpc/platforms/pseries/papr_scm.c
@@ -124,9 +124,6 @@ struct papr_scm_priv {
/* The bits which needs to be overridden */
u64 health_bitmap_inject_mask;
-
- /* array to have event_code and stat_id mappings */
- u8 *nvdimm_events_map;
};
static int papr_scm_pmem_flush(struct nd_region *nd_region,
@@ -350,6 +347,25 @@ static ssize_t drc_pmem_query_stats(struct papr_scm_priv *p,
#ifdef CONFIG_PERF_EVENTS
#define to_nvdimm_pmu(_pmu) container_of(_pmu, struct nvdimm_pmu, pmu)
+static const char * const nvdimm_events_map[] = {
+ [1] = "CtlResCt",
+ [2] = "CtlResTm",
+ [3] = "PonSecs ",
+ [4] = "MemLife ",
+ [5] = "CritRscU",
+ [6] = "HostLCnt",
+ [7] = "HostSCnt",
+ [8] = "HostSDur",
+ [9] = "HostLDur",
+ [10] = "MedRCnt ",
+ [11] = "MedWCnt ",
+ [12] = "MedRDur ",
+ [13] = "MedWDur ",
+ [14] = "CchRHCnt",
+ [15] = "CchWHCnt",
+ [16] = "FastWCnt",
+};
+
static int papr_scm_pmu_get_value(struct perf_event *event, struct device *dev, u64 *count)
{
struct papr_scm_perf_stat *stat;
@@ -357,11 +373,15 @@ static int papr_scm_pmu_get_value(struct perf_event *event, struct device *dev,
struct papr_scm_priv *p = (struct papr_scm_priv *)dev->driver_data;
int rc, size;
+ /* Invalid eventcode */
+ if (event->attr.config == 0 || event->attr.config >= ARRAY_SIZE(nvdimm_events_map))
+ return -EINVAL;
+
/* 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)
+ if (!p)
return -EINVAL;
stats = kzalloc(size, GFP_KERNEL);
@@ -370,7 +390,7 @@ static int papr_scm_pmu_get_value(struct perf_event *event, struct device *dev,
stat = &stats->scm_statistic[0];
memcpy(&stat->stat_id,
- &p->nvdimm_events_map[event->attr.config * sizeof(stat->stat_id)],
+ nvdimm_events_map[event->attr.config],
sizeof(stat->stat_id));
stat->stat_val = 0;
@@ -460,10 +480,9 @@ static void papr_scm_pmu_del(struct perf_event *event, int flags)
static int papr_scm_pmu_check_events(struct papr_scm_priv *p, struct nvdimm_pmu *nd_pmu)
{
- struct papr_scm_perf_stat *stat;
struct papr_scm_perf_stats *stats;
u32 available_events;
- int index, rc = 0;
+ int rc;
if (!p->stat_buffer_len)
return -ENOENT;
@@ -476,34 +495,12 @@ static int papr_scm_pmu_check_events(struct papr_scm_priv *p, struct nvdimm_pmu
/* Allocate the buffer for phyp where stats are written */
stats = kzalloc(p->stat_buffer_len, GFP_KERNEL);
if (!stats) {
- rc = -ENOMEM;
- return rc;
+ return -ENOMEM;
}
/* Called to get list of events supported */
rc = drc_pmem_query_stats(p, stats, 0);
- if (rc)
- goto out;
-
- /*
- * Allocate memory and populate nvdimm_event_map.
- * Allocate an extra element for NULL entry
- */
- p->nvdimm_events_map = kcalloc(available_events + 1,
- sizeof(stat->stat_id),
- GFP_KERNEL);
- if (!p->nvdimm_events_map) {
- rc = -ENOMEM;
- goto out;
- }
- /* Copy all stat_ids to event map */
- for (index = 0, stat = stats->scm_statistic;
- index < available_events; index++, ++stat) {
- memcpy(&p->nvdimm_events_map[index * sizeof(stat->stat_id)],
- &stat->stat_id, sizeof(stat->stat_id));
- }
-out:
kfree(stats);
return rc;
}
@@ -539,7 +536,7 @@ static void papr_scm_pmu_register(struct papr_scm_priv *p)
rc = register_nvdimm_pmu(nd_pmu, p->pdev);
if (rc)
- goto pmu_register_err;
+ goto pmu_check_events_err;
/*
* Set archdata.priv value to nvdimm_pmu structure, to handle the
@@ -548,8 +545,6 @@ static void papr_scm_pmu_register(struct papr_scm_priv *p)
p->pdev->archdata.priv = nd_pmu;
return;
-pmu_register_err:
- kfree(p->nvdimm_events_map);
pmu_check_events_err:
kfree(nd_pmu);
pmu_err_print:
@@ -1560,7 +1555,6 @@ static int papr_scm_remove(struct platform_device *pdev)
unregister_nvdimm_pmu(pdev->archdata.priv);
pdev->archdata.priv = NULL;
- kfree(p->nvdimm_events_map);
kfree(p->bus_desc.provider_name);
kfree(p);
--
2.31.1
^ permalink raw reply related [flat|nested] 3+ messages in thread* Re: [PATCH v2] powerpc/papr_scm: Fix nvdimm event mappings
2022-07-11 3:46 [PATCH v2] powerpc/papr_scm: Fix nvdimm event mappings Kajol Jain
@ 2022-07-12 5:15 ` Vaibhav Jain
2022-07-13 6:02 ` kajoljain
0 siblings, 1 reply; 3+ messages in thread
From: Vaibhav Jain @ 2022-07-12 5:15 UTC (permalink / raw)
To: Kajol Jain, mpe, linuxppc-dev
Cc: nvdimm, atrajeev, rnsastry, kjain, maddy, Aneesh Kumar K . V,
dan.j.williams, disgoel
Hi Kajol,
Thanks for the patch. Minor review comment below:
Kajol Jain <kjain@linux.ibm.com> writes:
> Commit 4c08d4bbc089 ("powerpc/papr_scm: Add perf interface support")
> added performance monitoring support for papr-scm nvdimm devices via
> perf interface. Commit also added an array in papr_scm_priv
> structure called "nvdimm_events_map", which got filled based on the
> result of H_SCM_PERFORMANCE_STATS hcall.
>
> Currently there is an assumption that the order of events in the
> stats buffer, returned by the hypervisor is same. And that order also
> matches with the events specified in nvdimm driver code.
> But this assumption is not documented anywhere in Power Architecture
> Platform Requirements (PAPR) document. Although the order
> of events happens to be same on current systems, but it might
> not be true in future generation systems. Fix the issue, by
> adding a static mapping for nvdimm events to corresponding stat-id,
> and removing the dynamic map from papr_scm_priv structure.
>
> Fixes: 4c08d4bbc089 ("powerpc/papr_scm: Add perf interface support")
> Reported-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
> Signed-off-by: Kajol Jain <kjain@linux.ibm.com>
<snip>
> @@ -460,10 +480,9 @@ static void papr_scm_pmu_del(struct perf_event *event, int flags)
>
> static int papr_scm_pmu_check_events(struct papr_scm_priv *p, struct nvdimm_pmu *nd_pmu)
> {
> - struct papr_scm_perf_stat *stat;
> struct papr_scm_perf_stats *stats;
> u32 available_events;
> - int index, rc = 0;
> + int rc;
>
> if (!p->stat_buffer_len)
> return -ENOENT;
> @@ -476,34 +495,12 @@ static int papr_scm_pmu_check_events(struct papr_scm_priv *p, struct nvdimm_pmu
> /* Allocate the buffer for phyp where stats are written */
> stats = kzalloc(p->stat_buffer_len, GFP_KERNEL);
> if (!stats) {
> - rc = -ENOMEM;
> - return rc;
> + return -ENOMEM;
> }
>
> /* Called to get list of events supported */
> rc = drc_pmem_query_stats(p, stats, 0);
> - if (rc)
> - goto out;
> -
> - /*
> - * Allocate memory and populate nvdimm_event_map.
> - * Allocate an extra element for NULL entry
> - */
> - p->nvdimm_events_map = kcalloc(available_events + 1,
> - sizeof(stat->stat_id),
> - GFP_KERNEL);
> - if (!p->nvdimm_events_map) {
> - rc = -ENOMEM;
> - goto out;
> - }
>
> - /* Copy all stat_ids to event map */
> - for (index = 0, stat = stats->scm_statistic;
> - index < available_events; index++, ++stat) {
> - memcpy(&p->nvdimm_events_map[index * sizeof(stat->stat_id)],
> - &stat->stat_id, sizeof(stat->stat_id));
> - }
> -out:
> kfree(stats);
> return rc;
> }
Earlier implementation of papr_scm_pmu_check_events() would copy the
contents of returned stat-ids to struct papr_scm_priv->nvdimm_events_map,
hence it was needed.
With static events map you dont really need to call
drc_pmem_query_stats() as that would have been already being done once
in papr_scm_probe() before papr_scm_pmu_register() is called:
papr_scm_probe()
{
...
/* Try retrieving the stat buffer and see if its supported */
stat_size = drc_pmem_query_stats(p, NULL, 0);
...
papr_scm_pmu_register(p);
...
}
I would suggest replacing single callsite of papr_scm_pmu_check_events()
with the check
if (!p->stat_buffer_len)
goto pmu_check_events_err;
<snip>
--
Cheers
~ Vaibhav
^ permalink raw reply [flat|nested] 3+ messages in thread* Re: [PATCH v2] powerpc/papr_scm: Fix nvdimm event mappings
2022-07-12 5:15 ` Vaibhav Jain
@ 2022-07-13 6:02 ` kajoljain
0 siblings, 0 replies; 3+ messages in thread
From: kajoljain @ 2022-07-13 6:02 UTC (permalink / raw)
To: Vaibhav Jain, mpe, linuxppc-dev
Cc: nvdimm, atrajeev, rnsastry, Aneesh Kumar K . V, maddy,
dan.j.williams, disgoel
On 7/12/22 10:45, Vaibhav Jain wrote:
> Hi Kajol,
>
> Thanks for the patch. Minor review comment below:
>
> Kajol Jain <kjain@linux.ibm.com> writes:
>
>> Commit 4c08d4bbc089 ("powerpc/papr_scm: Add perf interface support")
>> added performance monitoring support for papr-scm nvdimm devices via
>> perf interface. Commit also added an array in papr_scm_priv
>> structure called "nvdimm_events_map", which got filled based on the
>> result of H_SCM_PERFORMANCE_STATS hcall.
>>
>> Currently there is an assumption that the order of events in the
>> stats buffer, returned by the hypervisor is same. And that order also
>> matches with the events specified in nvdimm driver code.
>> But this assumption is not documented anywhere in Power Architecture
>> Platform Requirements (PAPR) document. Although the order
>> of events happens to be same on current systems, but it might
>> not be true in future generation systems. Fix the issue, by
>> adding a static mapping for nvdimm events to corresponding stat-id,
>> and removing the dynamic map from papr_scm_priv structure.
>>
>> Fixes: 4c08d4bbc089 ("powerpc/papr_scm: Add perf interface support")
>> Reported-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
>> Signed-off-by: Kajol Jain <kjain@linux.ibm.com>
>
> <snip>
>> @@ -460,10 +480,9 @@ static void papr_scm_pmu_del(struct perf_event *event, int flags)
>>
>> static int papr_scm_pmu_check_events(struct papr_scm_priv *p, struct nvdimm_pmu *nd_pmu)
>> {
>> - struct papr_scm_perf_stat *stat;
>> struct papr_scm_perf_stats *stats;
>> u32 available_events;
>> - int index, rc = 0;
>> + int rc;
>>
>> if (!p->stat_buffer_len)
>> return -ENOENT;
>> @@ -476,34 +495,12 @@ static int papr_scm_pmu_check_events(struct papr_scm_priv *p, struct nvdimm_pmu
>> /* Allocate the buffer for phyp where stats are written */
>> stats = kzalloc(p->stat_buffer_len, GFP_KERNEL);
>> if (!stats) {
>> - rc = -ENOMEM;
>> - return rc;
>> + return -ENOMEM;
>> }
>>
>> /* Called to get list of events supported */
>> rc = drc_pmem_query_stats(p, stats, 0);
>> - if (rc)
>> - goto out;
>> -
>> - /*
>> - * Allocate memory and populate nvdimm_event_map.
>> - * Allocate an extra element for NULL entry
>> - */
>> - p->nvdimm_events_map = kcalloc(available_events + 1,
>> - sizeof(stat->stat_id),
>> - GFP_KERNEL);
>> - if (!p->nvdimm_events_map) {
>> - rc = -ENOMEM;
>> - goto out;
>> - }
>>
>> - /* Copy all stat_ids to event map */
>> - for (index = 0, stat = stats->scm_statistic;
>> - index < available_events; index++, ++stat) {
>> - memcpy(&p->nvdimm_events_map[index * sizeof(stat->stat_id)],
>> - &stat->stat_id, sizeof(stat->stat_id));
>> - }
>> -out:
>> kfree(stats);
>> return rc;
>> }
>
> Earlier implementation of papr_scm_pmu_check_events() would copy the
> contents of returned stat-ids to struct papr_scm_priv->nvdimm_events_map,
> hence it was needed.
>
> With static events map you dont really need to call
> drc_pmem_query_stats() as that would have been already being done once
> in papr_scm_probe() before papr_scm_pmu_register() is called:
>
>
Hi Vaibhav,
Thanks for reviewing the patch. Yes it make sense, as mainly we want
to make sure, in case stat buffer is empty we will not register the
nvdimm pmu. I will do the change and send next version of the patch.
Thanks,
Kajol Jain
> papr_scm_probe()
> {
> ...
> /* Try retrieving the stat buffer and see if its supported */
> stat_size = drc_pmem_query_stats(p, NULL, 0);
> ...
> papr_scm_pmu_register(p);
> ...
> }
>
> I would suggest replacing single callsite of papr_scm_pmu_check_events()
> with the check
>
> if (!p->stat_buffer_len)
> goto pmu_check_events_err;
>
> <snip>
>
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2022-07-13 6:04 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-07-11 3:46 [PATCH v2] powerpc/papr_scm: Fix nvdimm event mappings Kajol Jain
2022-07-12 5:15 ` Vaibhav Jain
2022-07-13 6:02 ` kajoljain
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).