nvdimm.lists.linux.dev archive mirror
 help / color / mirror / Atom feed
From: Vishal Verma <vishal.l.verma@intel.com>
To: <linux-nvdimm@lists.01.org>
Cc: Dave Hansen <dave.hansen@linux.intel.com>,
	Chunye Xu <chunye.xu@intel.com>,
	Dave Hansen <dave.hansen@intel.com>
Subject: [ndctl PATCH 1/3] daxctl: fail reconfigure-device based on kernel onlining policy
Date: Tue, 30 Mar 2021 21:12:27 -0600	[thread overview]
Message-ID: <20210331031229.384068-2-vishal.l.verma@intel.com> (raw)
In-Reply-To: <20210331031229.384068-1-vishal.l.verma@intel.com>

If the kernel has a policy set to auto-online any new memory blocks, we
know that an attempt to reconfigure a device either in ZONE_MOVABLE, or
with the --no-online is going to fail. While we detect this race after
the fact, and print a warning, that is often insufficient as the user
may be forced to reboot to get out of the situation, resulting in an
unpleasant experience.

Detect whether the kernel policy is set to auto-online. If so, fail
device reconfigure operations that we know can't be satisfied. Allow
for overriding this safety check via the -f (--force) option. Update the
man page to talk about this, and the unit test to test for an expected
failure by enabling auto-onlining.

Cc: Dave Hansen <dave.hansen@intel.com>
Reported-by: Chunye Xu <chunye.xu@intel.com>
Reported-by: Dan Williams <dan.j.williams@intel.com>
Signed-off-by: Vishal Verma <vishal.l.verma@intel.com>
---
 .../daxctl/daxctl-reconfigure-device.txt      | 12 ++++++-
 daxctl/lib/libdaxctl-private.h                |  1 +
 daxctl/lib/libdaxctl.c                        | 21 +++++++++++
 daxctl/libdaxctl.h                            |  1 +
 daxctl/device.c                               | 10 ++++++
 daxctl/lib/libdaxctl.sym                      |  5 +++
 test/daxctl-devices.sh                        | 36 +++++++++++++++++++
 7 files changed, 85 insertions(+), 1 deletion(-)

diff --git a/Documentation/daxctl/daxctl-reconfigure-device.txt b/Documentation/daxctl/daxctl-reconfigure-device.txt
index ad33eda..f112b3c 100644
--- a/Documentation/daxctl/daxctl-reconfigure-device.txt
+++ b/Documentation/daxctl/daxctl-reconfigure-device.txt
@@ -119,6 +119,10 @@ recommended to use the --no-online option described below. This will abridge
 the device reconfiguration operation to just hotplugging the memory, and
 refrain from then onlining it.
 
+In case daxctl detects that there is a kernel policy to auto-online blocks
+(via /sys/devices/system/memory/auto_online_blocks), then reconfiguring to
+system-ram will result in a failure. This can be overridden with '--force'.
+
 OPTIONS
 -------
 include::region-option.txt[]
@@ -162,12 +166,18 @@ include::movable-options.txt[]
 
 -f::
 --force::
-	When converting from "system-ram" mode to "devdax", it is expected
+	- When converting from "system-ram" mode to "devdax", it is expected
 	that all the memory sections are first made offline. By default,
 	daxctl won't touch online memory. However with this option, attempt
 	to offline the memory on the NUMA node associated with the dax device
 	before converting it back to "devdax" mode.
 
+	- Additionally, if a kernel policy to auto-online blocks is detected,
+	reconfiguration to system-ram fails. With this option, the failure can
+	be overridden to allow reconfiguration regardless of kernel policy.
+	Doing this may result in a successful reconfiguration, but it may
+	not be possible to subsequently offline the memory without a reboot.
+
 
 include::human-option.txt[]
 
diff --git a/daxctl/lib/libdaxctl-private.h b/daxctl/lib/libdaxctl-private.h
index af257fd..ae45311 100644
--- a/daxctl/lib/libdaxctl-private.h
+++ b/daxctl/lib/libdaxctl-private.h
@@ -111,6 +111,7 @@ struct daxctl_memory {
 	char *node_path;
 	unsigned long block_size;
 	enum memory_zones zone;
+	bool auto_online;
 };
 
 
diff --git a/daxctl/lib/libdaxctl.c b/daxctl/lib/libdaxctl.c
index 479e8f6..879f7e6 100644
--- a/daxctl/lib/libdaxctl.c
+++ b/daxctl/lib/libdaxctl.c
@@ -1644,3 +1644,24 @@ DAXCTL_EXPORT int daxctl_memory_is_movable(struct daxctl_memory *mem)
 		return rc;
 	return (mem->zone == MEM_ZONE_MOVABLE) ? 1 : 0;
 }
+
+DAXCTL_EXPORT int daxctl_dev_will_auto_online_memory(struct daxctl_dev *dev)
+{
+	const char *auto_path = "/sys/devices/system/memory/auto_online_blocks";
+	const char *devname = daxctl_dev_get_devname(dev);
+	struct daxctl_ctx *ctx = daxctl_dev_get_ctx(dev);
+	char buf[SYSFS_ATTR_SIZE];
+
+	/*
+	 * If we can't read the policy for some reason, don't fail yet. Assume
+	 * the auto-onlining policy is absent, and carry on. If onlining blocks
+	 * does result in the memory being in an inconsistent state, we have a
+	 * check and warning for it after the fact
+	 */
+	if (sysfs_read_attr(ctx, auto_path, buf) != 0)
+		err(ctx, "%s: Unable to determine auto-online policy: %s\n",
+				devname, strerror(errno));
+
+	/* match both "online" and "online_movable" */
+	return !strncmp(buf, "online", 6);
+}
diff --git a/daxctl/libdaxctl.h b/daxctl/libdaxctl.h
index e82b274..30ab51a 100644
--- a/daxctl/libdaxctl.h
+++ b/daxctl/libdaxctl.h
@@ -71,6 +71,7 @@ int daxctl_dev_disable(struct daxctl_dev *dev);
 int daxctl_dev_enable_devdax(struct daxctl_dev *dev);
 int daxctl_dev_enable_ram(struct daxctl_dev *dev);
 int daxctl_dev_get_target_node(struct daxctl_dev *dev);
+int daxctl_dev_will_auto_online_memory(struct daxctl_dev *dev);
 
 struct daxctl_memory;
 struct daxctl_memory *daxctl_dev_get_memory(struct daxctl_dev *dev);
diff --git a/daxctl/device.c b/daxctl/device.c
index 0721a57..a427b7d 100644
--- a/daxctl/device.c
+++ b/daxctl/device.c
@@ -541,8 +541,18 @@ static int disable_devdax_device(struct daxctl_dev *dev)
 
 static int reconfig_mode_system_ram(struct daxctl_dev *dev)
 {
+	const char *devname = daxctl_dev_get_devname(dev);
 	int rc, skip_enable = 0;
 
+	if (param.no_online || !param.no_movable) {
+		if (!param.force && daxctl_dev_will_auto_online_memory(dev)) {
+			fprintf(stderr,
+				"%s: error: kernel policy will auto-online memory, aborting\n",
+				devname);
+			return -EBUSY;
+		}
+	}
+
 	if (daxctl_dev_is_enabled(dev)) {
 		rc = disable_devdax_device(dev);
 		if (rc < 0)
diff --git a/daxctl/lib/libdaxctl.sym b/daxctl/lib/libdaxctl.sym
index a4e1684..892e393 100644
--- a/daxctl/lib/libdaxctl.sym
+++ b/daxctl/lib/libdaxctl.sym
@@ -91,3 +91,8 @@ global:
 	daxctl_mapping_get_size;
 	daxctl_dev_set_mapping;
 } LIBDAXCTL_7;
+
+LIBDAXCTL_9 {
+global:
+	daxctl_dev_will_auto_online_memory;
+} LIBDAXCTL_8;
diff --git a/test/daxctl-devices.sh b/test/daxctl-devices.sh
index 496e4f2..eed5906 100755
--- a/test/daxctl-devices.sh
+++ b/test/daxctl-devices.sh
@@ -64,6 +64,26 @@ daxctl_get_mode()
 	"$DAXCTL" list -d "$1" | jq -er '.[].mode'
 }
 
+set_online_policy()
+{
+	echo "online" > /sys/devices/system/memory/auto_online_blocks
+}
+
+unset_online_policy()
+{
+	echo "offline" > /sys/devices/system/memory/auto_online_blocks
+}
+
+save_online_policy()
+{
+	saved_policy="$(cat /sys/devices/system/memory/auto_online_blocks)"
+}
+
+restore_online_policy()
+{
+	echo "$saved_policy" > /sys/devices/system/memory/auto_online_blocks
+}
+
 daxctl_test()
 {
 	local daxdev
@@ -71,6 +91,9 @@ daxctl_test()
 	daxdev=$(daxctl_get_dev "$testdev")
 	test -n "$daxdev"
 
+	# these tests need to run with kernel onlining policy turned off
+	save_online_policy
+	unset_online_policy
 	"$DAXCTL" reconfigure-device -N -m system-ram "$daxdev"
 	[[ $(daxctl_get_mode "$daxdev") == "system-ram" ]]
 	"$DAXCTL" online-memory "$daxdev"
@@ -81,6 +104,19 @@ daxctl_test()
 	[[ $(daxctl_get_mode "$daxdev") == "system-ram" ]]
 	"$DAXCTL" reconfigure-device -f -m devdax "$daxdev"
 	[[ $(daxctl_get_mode "$daxdev") == "devdax" ]]
+
+	# this tests for reconfiguration failure if an online-policy is set
+	set_online_policy
+	: "This command is expected to fail:"
+	if ! "$DAXCTL" reconfigure-device -N -m system-ram "$daxdev"; then
+		echo "reconfigure failed as expected"
+	else
+		echo "reconfigure succeded, expected failure"
+		restore_online_policy
+		return 1
+	fi
+
+	restore_online_policy
 }
 
 find_testdev
-- 
2.30.2
_______________________________________________
Linux-nvdimm mailing list -- linux-nvdimm@lists.01.org
To unsubscribe send an email to linux-nvdimm-leave@lists.01.org

  reply	other threads:[~2021-03-31  3:12 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-03-31  3:12 [ndctl PATCH 0/3] daxctl-device fixes Vishal Verma
2021-03-31  3:12 ` Vishal Verma [this message]
2021-03-31  3:12 ` [ndctl PATCH 2/3] libdaxctl: add an API to check if a device is active Vishal Verma
2021-03-31  3:12 ` [ndctl PATCH 3/3] libndctl: check for active system-ram before disabling daxctl devices Vishal Verma

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210331031229.384068-2-vishal.l.verma@intel.com \
    --to=vishal.l.verma@intel.com \
    --cc=chunye.xu@intel.com \
    --cc=dave.hansen@intel.com \
    --cc=dave.hansen@linux.intel.com \
    --cc=linux-nvdimm@lists.01.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).