Previous commit [1] introduced 'struct nd_papr_scm_dimm_health_stat' for
communicating health status of an nvdimm to libndctl. This struct
however can also be used to cache the nvdimm health information in
'struct papr_scm_priv' instead of two '__be64' values. Benefit of this
re-factoring will be apparent when support for libndctl being able to
request nvdimm health stats is implemented where we can simply memcpy
this struct over to the user-space provided payload envelope.

Hence this patch introduces a new member 'struct papr_scm_priv.health'
that caches the health information of a dimm. This member is populated
inside drc_pmem_query_health() which checks for the various bit flags
returned from H_SCM_HEALTH and sets them in this struct. We also
re-factor 'papr_flags' sysfs attribute show function papr_flags_show()
to use the flags in 'struct papr_scm_priv.health' to return
appropriate status strings pertaining to dimm health.

This patch shouldn't introduce any behavioral change.

Signed-off-by: Vaibhav Jain <vaib...@linux.ibm.com>
---
 arch/powerpc/platforms/pseries/papr_scm.c | 61 ++++++++++++++++-------
 1 file changed, 44 insertions(+), 17 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/papr_scm.c 
b/arch/powerpc/platforms/pseries/papr_scm.c
index d5eea2f38fa6..29f38246c59f 100644
--- a/arch/powerpc/platforms/pseries/papr_scm.c
+++ b/arch/powerpc/platforms/pseries/papr_scm.c
@@ -47,8 +47,7 @@ struct papr_scm_priv {
        struct mutex dimm_mutex;
 
        /* Health information for the dimm */
-       __be64 health_bitmap;
-       __be64 health_bitmap_valid;
+       struct nd_papr_scm_dimm_health_stat health;
 
        /* length of the stat buffer as expected by phyp */
        size_t len_stat_buffer;
@@ -205,6 +204,7 @@ static int drc_pmem_query_health(struct papr_scm_priv *p)
 {
        unsigned long ret[PLPAR_HCALL_BUFSIZE];
        int64_t rc;
+       __be64 health;
 
        rc = plpar_hcall(H_SCM_HEALTH, ret, p->drc_index);
        if (rc != H_SUCCESS) {
@@ -219,13 +219,41 @@ static int drc_pmem_query_health(struct papr_scm_priv *p)
                return rc;
 
        /* Store the retrieved health information in dimm platform data */
-       p->health_bitmap = ret[0];
-       p->health_bitmap_valid = ret[1];
+       health = ret[0] & ret[1];
 
        dev_dbg(&p->pdev->dev,
                "Queried dimm health info. Bitmap:0x%016llx Mask:0x%016llx\n",
-               be64_to_cpu(p->health_bitmap),
-               be64_to_cpu(p->health_bitmap_valid));
+               be64_to_cpu(ret[0]),
+               be64_to_cpu(ret[1]));
+
+       memset(&p->health, 0, sizeof(p->health));
+
+       /* Check for various masks in bitmap and set the buffer */
+       if (health & PAPR_SCM_DIMM_UNARMED_MASK)
+               p->health.dimm_unarmed = true;
+
+       if (health & PAPR_SCM_DIMM_BAD_SHUTDOWN_MASK)
+               p->health.dimm_bad_shutdown = true;
+
+       if (health & PAPR_SCM_DIMM_BAD_RESTORE_MASK)
+               p->health.dimm_bad_restore = true;
+
+       if (health & PAPR_SCM_DIMM_ENCRYPTED)
+               p->health.dimm_encrypted = true;
+
+       if (health & PAPR_SCM_DIMM_SCRUBBED_AND_LOCKED) {
+               p->health.dimm_locked = true;
+               p->health.dimm_scrubbed = true;
+       }
+
+       if (health & PAPR_SCM_DIMM_HEALTH_UNHEALTHY)
+               p->health.dimm_health = DSM_PAPR_SCM_DIMM_UNHEALTHY;
+
+       if (health & PAPR_SCM_DIMM_HEALTH_CRITICAL)
+               p->health.dimm_health = DSM_PAPR_SCM_DIMM_CRITICAL;
+
+       if (health & PAPR_SCM_DIMM_HEALTH_FATAL)
+               p->health.dimm_health = DSM_PAPR_SCM_DIMM_FATAL;
 
        mutex_unlock(&p->dimm_mutex);
        return 0;
@@ -513,7 +541,6 @@ static ssize_t papr_flags_show(struct device *dev,
 {
        struct nvdimm *dimm = to_nvdimm(dev);
        struct papr_scm_priv *p = nvdimm_provider_data(dimm);
-       __be64 health;
        int rc;
 
        rc = drc_pmem_query_health(p);
@@ -525,26 +552,26 @@ static ssize_t papr_flags_show(struct device *dev,
        if (rc)
                return rc;
 
-       health = p->health_bitmap & p->health_bitmap_valid;
-
-       /* Check for various masks in bitmap and set the buffer */
-       if (health & PAPR_SCM_DIMM_UNARMED_MASK)
+       if (p->health.dimm_unarmed)
                rc += sprintf(buf, "not_armed ");
 
-       if (health & PAPR_SCM_DIMM_BAD_SHUTDOWN_MASK)
+       if (p->health.dimm_bad_shutdown)
                rc += sprintf(buf + rc, "save_fail ");
 
-       if (health & PAPR_SCM_DIMM_BAD_RESTORE_MASK)
+       if (p->health.dimm_bad_restore)
                rc += sprintf(buf + rc, "restore_fail ");
 
-       if (health & PAPR_SCM_DIMM_ENCRYPTED)
+       if (p->health.dimm_encrypted)
                rc += sprintf(buf + rc, "encrypted ");
 
-       if (health & PAPR_SCM_DIMM_SMART_EVENT_MASK)
+       if (p->health.dimm_health)
                rc += sprintf(buf + rc, "smart_notify ");
 
-       if (health & PAPR_SCM_DIMM_SCRUBBED_AND_LOCKED)
-               rc += sprintf(buf + rc, "scrubbed locked ");
+       if (p->health.dimm_scrubbed)
+               rc += sprintf(buf + rc, "scrubbed ");
+
+       if (p->health.dimm_locked)
+               rc += sprintf(buf + rc, "locked ");
 
        if (rc > 0)
                rc += sprintf(buf + rc, "\n");
-- 
2.24.1

Reply via email to