diff options
author | Vaibhav Jain <vaibhav@linux.ibm.com> | 2021-05-17 21:18:24 +0530 |
---|---|---|
committer | Vishal Verma <vishal.l.verma@intel.com> | 2021-05-20 16:20:23 -0600 |
commit | e086106b4d81a2079141c848db7695451c04e877 (patch) | |
tree | 344a51790830436533e53149cc69824ae779e6e1 | |
parent | 063af7c447d257397a925df81897da2c71e31653 (diff) |
libndctl/papr: Fix probe for papr-scm compatible nvdimms
With recent changes introduced for unification of PAPR and NFIT
families the probe for papr-scm nvdimms is broken since they don't
expose 'handle' or 'phys_id' sysfs attributes. These attributes are
only exposed by NFIT and 'nvdimm_test' nvdimms. Since 'unable to read'
these sysfs attributes is a non-recoverable error hence this prevents
probing of 'PAPR-SCM' nvdimms and ndctl reports following error:
$ sudo NDCTL_LOG=debug ndctl list -DH
libndctl: ndctl_new: ctx 0x10015342c70 created
libndctl: add_dimm: nmem1: probe failed: Operation not permitted
libndctl: __sysfs_device_parse: nmem1: add_dev() failed
libndctl: add_dimm: nmem0: probe failed: Operation not permitted
libndctl: __sysfs_device_parse: nmem0: add_dev() failed
Fixing this bug is complicated by the fact these attributes are needed
for by the 'nvdimm_test' nvdimms which also uses the
NVDIMM_FAMILY_PAPR. Adding a two way comparison for these two
attributes in populate_dimm_attributes() to distinguish between
'nvdimm_test' and papr-scm nvdimms will be clunky and make future
updates to populate_dimm_attributes() error prone.
So, this patch proposes to fix the issue by re-introducing
add_papr_dimm() to probe both papr-scm and 'nvdimm_test' nvdimms. The
'compatible' sysfs attribute associated with the PAPR device is used
to distinguish between the two nvdimm types and in case an
'nvdimm_test' device is detected then forward its probe to
populate_dimm_attributes().
families")
Link: https://lore.kernel.org/r/20210517154824.142237-1-vaibhav@linux.ibm.com
Fixes: daef3a386a9c("libndctl: Unify adding dimms for papr and nfit
Signed-off-by: Vaibhav Jain <vaibhav@linux.ibm.com>
Signed-off-by: Vishal Verma <vishal.l.verma@intel.com>
-rw-r--r-- | ndctl/lib/libndctl.c | 57 |
1 files changed, 55 insertions, 2 deletions
diff --git a/ndctl/lib/libndctl.c b/ndctl/lib/libndctl.c index 3a496ed0..aa36a3c8 100644 --- a/ndctl/lib/libndctl.c +++ b/ndctl/lib/libndctl.c @@ -1754,6 +1754,58 @@ static int populate_dimm_attributes(struct ndctl_dimm *dimm, return rc; } +static int add_papr_dimm(struct ndctl_dimm *dimm, const char *dimm_base) +{ + int rc = -ENODEV; + char buf[SYSFS_ATTR_SIZE]; + struct ndctl_ctx *ctx = dimm->bus->ctx; + char *path = calloc(1, strlen(dimm_base) + 100); + const char * const devname = ndctl_dimm_get_devname(dimm); + + dbg(ctx, "%s: Probing of_pmem dimm at %s\n", devname, dimm_base); + + if (!path) + return -ENOMEM; + + /* Check the compatibility of the probed nvdimm */ + sprintf(path, "%s/../of_node/compatible", dimm_base); + if (sysfs_read_attr(ctx, path, buf) < 0) { + dbg(ctx, "%s: Unable to read compatible field\n", devname); + rc = -ENODEV; + goto out; + } + + dbg(ctx, "%s:Compatible of_pmem = '%s'\n", devname, buf); + + /* Probe for papr-scm memory */ + if (strcmp(buf, "ibm,pmemory") == 0) { + /* Read the dimm flags file */ + sprintf(path, "%s/papr/flags", dimm_base); + if (sysfs_read_attr(ctx, path, buf) < 0) { + rc = -errno; + err(ctx, "%s: Unable to read dimm-flags\n", devname); + goto out; + } + + dbg(ctx, "%s: Adding papr-scm dimm flags:\"%s\"\n", devname, buf); + dimm->cmd_family = NVDIMM_FAMILY_PAPR; + + /* Parse dimm flags */ + parse_papr_flags(dimm, buf); + + /* Allocate monitor mode fd */ + dimm->health_eventfd = open(path, O_RDONLY|O_CLOEXEC); + rc = 0; + + } else if (strcmp(buf, "nvdimm_test") == 0) { + /* probe via common populate_dimm_attributes() */ + rc = populate_dimm_attributes(dimm, dimm_base, "papr"); + } +out: + free(path); + return rc; +} + static void *add_dimm(void *parent, int id, const char *dimm_base) { int formats, i, rc = -ENODEV; @@ -1845,8 +1897,9 @@ static void *add_dimm(void *parent, int id, const char *dimm_base) /* Check if the given dimm supports nfit */ if (ndctl_bus_has_nfit(bus)) { rc = populate_dimm_attributes(dimm, dimm_base, "nfit"); - } else if (ndctl_bus_has_of_node(bus)) - rc = populate_dimm_attributes(dimm, dimm_base, "papr"); + } else if (ndctl_bus_has_of_node(bus)) { + rc = add_papr_dimm(dimm, dimm_base); + } if (rc == -ENODEV) { /* Unprobed dimm with no family */ |