anitazha / rpms / ndctl

Forked from rpms/ndctl 2 years ago
Clone

Blame SOURCES/e086106-libndctl-papr-Fix-probe-for-papr-scm-compatible-nvdimms.patch

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