[ndctl,11/36] ndctl/namespace: Validate resource alignment for dax-mode namespaces
diff mbox series

Message ID 158300766271.2141307.12541085220843554138.stgit@dwillia2-desk3.amr.corp.intel.com
State New
Headers show
Series
  • Multiple topics / backlog for v68
Related show

Commit Message

Williams, Dan J Feb. 29, 2020, 8:21 p.m. UTC
The kernel sets the default region alignment to 16M to promote
cross-arch compatible namespace creation. While ndctl never touches the
region alignment the end user might have changed it from its default.
Enforce 16MiB alignment for the namespace resource base by default for
dax-mode namespaces.

It is still possible to use a 2MiB region-align for dax-mode namespaces
on x86, but that requires --force to bypass this default alignment
check.

I chose a hard coded default value in ndctl with a --force to bypass the
check rather than having a new sysfs attribute to probe for this detail.
I.e. the kernel could export the minimum alignment for dax namespaces,
but since the minimum compat value is already known, no need for a trip
to the kernel.

Cc: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
Cc: Jeff Moyer <jmoyer@redhat.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
 Documentation/ndctl/ndctl-create-namespace.txt |    8 ++++++++
 ndctl/namespace.c                              |   24 ++++++++++++++++++++++++
 2 files changed, 32 insertions(+)

Patch
diff mbox series

diff --git a/Documentation/ndctl/ndctl-create-namespace.txt b/Documentation/ndctl/ndctl-create-namespace.txt
index 8cd80fa789c1..7637e2403132 100644
--- a/Documentation/ndctl/ndctl-create-namespace.txt
+++ b/Documentation/ndctl/ndctl-create-namespace.txt
@@ -88,6 +88,14 @@  OPTIONS
 	    fault scenarios are supported. I.e. if a device is
 	    configured with a 2M alignment an attempt to fault a 4K
 	    aligned offset will result in SIGBUS.
+::
+	Note both 'fsdax' and 'devdax' mode require 16MiB physical
+	alignment to be cross-arch compatible. By default ndctl will
+	block attempts to create namespaces in these modes when the
+	physical starting address of the namespace is not 16MiB aligned.
+	The --force option tries to override this constraint if the
+	platform supports a smaller alignment, but this is not
+	recommended.
 
 -s::
 --size=::
diff --git a/ndctl/namespace.c b/ndctl/namespace.c
index c4aab94abcd4..96d318166300 100644
--- a/ndctl/namespace.c
+++ b/ndctl/namespace.c
@@ -356,6 +356,24 @@  static bool do_setup_pfn(struct ndctl_namespace *ndns,
 	return false;
 }
 
+static int check_dax_align(struct ndctl_namespace *ndns)
+{
+	unsigned long long resource = ndctl_namespace_get_resource(ndns);
+	const char *devname = ndctl_namespace_get_devname(ndns);
+
+	if (resource == ULLONG_MAX) {
+		warning("%s unable to validate alignment\n", devname);
+		return 0;
+	}
+
+	if (IS_ALIGNED(resource, SZ_16M) || force)
+		return 0;
+
+	error("%s misaligned to 16M, adjust region alignment and retry\n",
+			devname);
+	return -EINVAL;
+}
+
 static int setup_namespace(struct ndctl_region *region,
 		struct ndctl_namespace *ndns, struct parsed_parameters *p)
 {
@@ -406,6 +424,9 @@  static int setup_namespace(struct ndctl_region *region,
 	if (do_setup_pfn(ndns, p)) {
 		struct ndctl_pfn *pfn = ndctl_region_get_pfn_seed(region);
 
+		rc = check_dax_align(ndns);
+		if (rc)
+			return rc;
 		try(ndctl_pfn, set_uuid, pfn, uuid);
 		try(ndctl_pfn, set_location, pfn, p->loc);
 		if (ndctl_pfn_has_align(pfn))
@@ -417,6 +438,9 @@  static int setup_namespace(struct ndctl_region *region,
 	} else if (p->mode == NDCTL_NS_MODE_DAX) {
 		struct ndctl_dax *dax = ndctl_region_get_dax_seed(region);
 
+		rc = check_dax_align(ndns);
+		if (rc)
+			return rc;
 		try(ndctl_dax, set_uuid, dax, uuid);
 		try(ndctl_dax, set_location, dax, p->loc);
 		/* device-dax assumes 'align' attribute present */