Skip to content

Commit af0870c

Browse files
vaibhav92mpe
authored andcommitted
powerpc/papr_scm: Add support for fetching nvdimm 'fuel-gauge' metric
We add support for reporting 'fuel-gauge' NVDIMM metric via PAPR_PDSM_HEALTH pdsm payload. 'fuel-gauge' metric indicates the usage life remaining of a papr-scm compatible NVDIMM. PHYP exposes this metric via the H_SCM_PERFORMANCE_STATS. The metric value is returned from the pdsm by extending the return payload 'struct nd_papr_pdsm_health' without breaking the ABI. A new field 'dimm_fuel_gauge' to hold the metric value is introduced at the end of the payload struct and its presence is indicated by by extension flag PDSM_DIMM_HEALTH_RUN_GAUGE_VALID. The patch introduces a new function papr_pdsm_fuel_gauge() that is called from papr_pdsm_health(). If fetching NVDIMM performance stats is supported then 'papr_pdsm_fuel_gauge()' allocated an output buffer large enough to hold the performance stat and passes it to drc_pmem_query_stats() that issues the HCALL to PHYP. The return value of the stat is then populated in the 'struct nd_papr_pdsm_health.dimm_fuel_gauge' field with extension flag 'PDSM_DIMM_HEALTH_RUN_GAUGE_VALID' set in 'struct nd_papr_pdsm_health.extension_flags' Signed-off-by: Vaibhav Jain <[email protected]> Reviewed-by: Aneesh Kumar K.V <[email protected]> Signed-off-by: Michael Ellerman <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 2d02bf8 commit af0870c

File tree

2 files changed

+58
-0
lines changed

2 files changed

+58
-0
lines changed

arch/powerpc/include/uapi/asm/papr_pdsm.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,11 @@
7272
#define PAPR_PDSM_DIMM_CRITICAL 2
7373
#define PAPR_PDSM_DIMM_FATAL 3
7474

75+
/* struct nd_papr_pdsm_health.extension_flags field flags */
76+
77+
/* Indicate that the 'dimm_fuel_gauge' field is valid */
78+
#define PDSM_DIMM_HEALTH_RUN_GAUGE_VALID 1
79+
7580
/*
7681
* Struct exchanged between kernel & ndctl in for PAPR_PDSM_HEALTH
7782
* Various flags indicate the health status of the dimm.
@@ -84,6 +89,7 @@
8489
* dimm_locked : Contents of the dimm cant be modified until CEC reboot
8590
* dimm_encrypted : Contents of dimm are encrypted.
8691
* dimm_health : Dimm health indicator. One of PAPR_PDSM_DIMM_XXXX
92+
* dimm_fuel_gauge : Life remaining of DIMM as a percentage from 0-100
8793
*/
8894
struct nd_papr_pdsm_health {
8995
union {
@@ -96,6 +102,9 @@ struct nd_papr_pdsm_health {
96102
__u8 dimm_locked;
97103
__u8 dimm_encrypted;
98104
__u16 dimm_health;
105+
106+
/* Extension flag PDSM_DIMM_HEALTH_RUN_GAUGE_VALID */
107+
__u16 dimm_fuel_gauge;
99108
};
100109
__u8 buf[ND_PDSM_PAYLOAD_MAX_SIZE];
101110
};

arch/powerpc/platforms/pseries/papr_scm.c

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -518,6 +518,51 @@ static int is_cmd_valid(struct nvdimm *nvdimm, unsigned int cmd, void *buf,
518518
return 0;
519519
}
520520

521+
static int papr_pdsm_fuel_gauge(struct papr_scm_priv *p,
522+
union nd_pdsm_payload *payload)
523+
{
524+
int rc, size;
525+
u64 statval;
526+
struct papr_scm_perf_stat *stat;
527+
struct papr_scm_perf_stats *stats;
528+
529+
/* Silently fail if fetching performance metrics isn't supported */
530+
if (!p->stat_buffer_len)
531+
return 0;
532+
533+
/* Allocate request buffer enough to hold single performance stat */
534+
size = sizeof(struct papr_scm_perf_stats) +
535+
sizeof(struct papr_scm_perf_stat);
536+
537+
stats = kzalloc(size, GFP_KERNEL);
538+
if (!stats)
539+
return -ENOMEM;
540+
541+
stat = &stats->scm_statistic[0];
542+
memcpy(&stat->stat_id, "MemLife ", sizeof(stat->stat_id));
543+
stat->stat_val = 0;
544+
545+
/* Fetch the fuel gauge and populate it in payload */
546+
rc = drc_pmem_query_stats(p, stats, 1);
547+
if (rc < 0) {
548+
dev_dbg(&p->pdev->dev, "Err(%d) fetching fuel gauge\n", rc);
549+
goto free_stats;
550+
}
551+
552+
statval = be64_to_cpu(stat->stat_val);
553+
dev_dbg(&p->pdev->dev,
554+
"Fetched fuel-gauge %llu", statval);
555+
payload->health.extension_flags |=
556+
PDSM_DIMM_HEALTH_RUN_GAUGE_VALID;
557+
payload->health.dimm_fuel_gauge = statval;
558+
559+
rc = sizeof(struct nd_papr_pdsm_health);
560+
561+
free_stats:
562+
kfree(stats);
563+
return rc;
564+
}
565+
521566
/* Fetch the DIMM health info and populate it in provided package. */
522567
static int papr_pdsm_health(struct papr_scm_priv *p,
523568
union nd_pdsm_payload *payload)
@@ -558,6 +603,10 @@ static int papr_pdsm_health(struct papr_scm_priv *p,
558603

559604
/* struct populated hence can release the mutex now */
560605
mutex_unlock(&p->health_mutex);
606+
607+
/* Populate the fuel gauge meter in the payload */
608+
papr_pdsm_fuel_gauge(p, payload);
609+
561610
rc = sizeof(struct nd_papr_pdsm_health);
562611

563612
out:

0 commit comments

Comments
 (0)