[RFC][PATCH 2/2] powerpc/papr_scm: Implement support for reporting generic nvdimm stats

Christophe Leroy christophe.leroy at csgroup.eu
Wed Mar 30 17:01:47 AEDT 2022


Hi,

Le 08/11/2020 à 22:15, Vaibhav Jain a écrit :
> Add support for reporting papr-scm supported generic nvdimm stats by
> implementing support for handling ND_CMD_GET_STAT in
> 'papr_scm_ndctl().
> 
> The mapping between libnvdimm generic nvdimm-stats and papr-scm
> specific performance-stats is embedded inside 'dimm_stats_map[]'. This
> array is queried by newly introduced 'papr_scm_get_stat()' that
> verifies if the requested nvdimm-stat is supported and if yes does an
> hcall via 'drc_pmem_query_stat()' to request the performance-stat and
> return it back to libnvdimm.
> 
> Signed-off-by: Vaibhav Jain <vaibhav at linux.ibm.com>

I see this series is still flagged as 'new' in patchwork.

I saw some patches providing stats to nvdimm are in a pull request for 5.18.

I imagine this is the same subject, so I'm going to change the status of 
this series. Let me know if I'm wrong.

Thanks
Christophe

> ---
>   arch/powerpc/platforms/pseries/papr_scm.c | 66 ++++++++++++++++++++++-
>   1 file changed, 65 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/powerpc/platforms/pseries/papr_scm.c b/arch/powerpc/platforms/pseries/papr_scm.c
> index 835163f54244..51eeab3376fd 100644
> --- a/arch/powerpc/platforms/pseries/papr_scm.c
> +++ b/arch/powerpc/platforms/pseries/papr_scm.c
> @@ -25,7 +25,8 @@
>   	((1ul << ND_CMD_GET_CONFIG_SIZE) | \
>   	 (1ul << ND_CMD_GET_CONFIG_DATA) | \
>   	 (1ul << ND_CMD_SET_CONFIG_DATA) | \
> -	 (1ul << ND_CMD_CALL))
> +	 (1ul << ND_CMD_CALL) |		   \
> +	 (1ul << ND_CMD_GET_STAT))
>   
>   /* DIMM health bitmap bitmap indicators */
>   /* SCM device is unable to persist memory contents */
> @@ -120,6 +121,16 @@ struct papr_scm_priv {
>   static LIST_HEAD(papr_nd_regions);
>   static DEFINE_MUTEX(papr_ndr_lock);
>   
> +/* Map generic nvdimm stats to papr-scm stats */
> +static const char * const dimm_stat_map[] = {
> +	[ND_DIMM_STAT_INVALID] = NULL,
> +	[ND_DIMM_STAT_MEDIA_READS] = "MedRCnt ",
> +	[ND_DIMM_STAT_MEDIA_WRITES] = "MedWCnt ",
> +	[ND_DIMM_STAT_READ_REQUESTS] = "HostLCnt",
> +	[ND_DIMM_STAT_WRITE_REQUESTS] = "HostSCnt",
> +	[ND_DIMM_STAT_MAX] = NULL,
> +};
> +
>   static int drc_pmem_bind(struct papr_scm_priv *p)
>   {
>   	unsigned long ret[PLPAR_HCALL_BUFSIZE];
> @@ -728,6 +739,54 @@ static int papr_scm_service_pdsm(struct papr_scm_priv *p,
>   	return pdsm_pkg->cmd_status;
>   }
>   
> +/*
> + * For a given pdsm request call an appropriate service function.
> + * Returns errors if any while handling the pdsm command package.
> + */
> +static int papr_scm_get_stat(struct papr_scm_priv *p,
> +			     struct nd_cmd_get_dimm_stat *dimm_stat)
> +
> +{
> +	int rc;
> +	ssize_t size;
> +	struct papr_scm_perf_stat *stat;
> +	struct papr_scm_perf_stats *stats;
> +
> +	/* Check if the requested stat-id is supported */
> +	if (dimm_stat->stat_id >= ARRAY_SIZE(dimm_stat_map) ||
> +	    !dimm_stat_map[dimm_stat->stat_id]) {
> +		dev_dbg(&p->pdev->dev, "Invalid stat-id %lld\n", dimm_stat->stat_id);
> +		return -ENOSPC;
> +	}
> +
> +	/* Allocate request buffer enough to hold single performance stat */
> +	size = sizeof(struct papr_scm_perf_stats) +
> +		sizeof(struct papr_scm_perf_stat);
> +
> +	stats = kzalloc(size, GFP_KERNEL);
> +	if (!stats)
> +		return -ENOMEM;
> +
> +	stat = &stats->scm_statistic[0];
> +	memcpy(&stat->stat_id, dimm_stat_map[dimm_stat->stat_id],
> +	       sizeof(stat->stat_id));
> +	stat->stat_val = 0;
> +
> +	/* Fetch the statistic from PHYP and copy it to provided payload */
> +	rc = drc_pmem_query_stats(p, stats, 1);
> +	if (rc < 0) {
> +		dev_dbg(&p->pdev->dev, "Err(%d) fetching stat '%.8s'\n",
> +			rc, stat->stat_id);
> +		kfree(stats);
> +		return rc;
> +	}
> +
> +	dimm_stat->int_val = be64_to_cpu(stat->stat_val);
> +
> +	kfree(stats);
> +	return 0;
> +}
> +
>   static int papr_scm_ndctl(struct nvdimm_bus_descriptor *nd_desc,
>   			  struct nvdimm *nvdimm, unsigned int cmd, void *buf,
>   			  unsigned int buf_len, int *cmd_rc)
> @@ -772,6 +831,11 @@ static int papr_scm_ndctl(struct nvdimm_bus_descriptor *nd_desc,
>   		*cmd_rc = papr_scm_service_pdsm(p, call_pkg);
>   		break;
>   
> +	case ND_CMD_GET_STAT:
> +		*cmd_rc = papr_scm_get_stat(p,
> +					    (struct nd_cmd_get_dimm_stat *)buf);
> +		break;
> +
>   	default:
>   		dev_dbg(&p->pdev->dev, "Unknown command = %d\n", cmd);
>   		return -EINVAL;


More information about the Linuxppc-dev mailing list