anitazha / rpms / ndctl

Forked from rpms/ndctl 2 years ago
Clone

Blame 0014-daxctl-fail-reconfigure-device-based-on-kernel-onlin.patch

Jeff Moyer 2c91dc
From 99415dfc7c5167c49a5732f577836f68872645b2 Mon Sep 17 00:00:00 2001
Jeff Moyer 2c91dc
From: Vishal Verma <vishal.l.verma@intel.com>
Jeff Moyer 2c91dc
Date: Wed, 24 Mar 2021 12:09:29 -0700
Jeff Moyer 2c91dc
Subject: [PATCH 014/217] daxctl: fail reconfigure-device based on kernel
Jeff Moyer 2c91dc
 onlining policy
Jeff Moyer 2c91dc
Jeff Moyer 2c91dc
If the kernel has a policy set to auto-online any new memory blocks, we
Jeff Moyer 2c91dc
know that an attempt to reconfigure a device either in ZONE_MOVABLE, or
Jeff Moyer 2c91dc
with the --no-online is going to fail. While we detect this race after
Jeff Moyer 2c91dc
the fact, and print a warning, that is often insufficient as the user
Jeff Moyer 2c91dc
may be forced to reboot to get out of the situation, resulting in an
Jeff Moyer 2c91dc
unpleasant experience.
Jeff Moyer 2c91dc
Jeff Moyer 2c91dc
Detect whether the kernel policy is set to auto-online. If so, fail
Jeff Moyer 2c91dc
device reconfigure operations that we know can't be satisfied. Allow
Jeff Moyer 2c91dc
for overriding this safety check via the -f (--force) option. Update the
Jeff Moyer 2c91dc
man page to talk about this, and the unit test to test for an expected
Jeff Moyer 2c91dc
failure by enabling auto-onlining.
Jeff Moyer 2c91dc
Jeff Moyer 2c91dc
Cc: Dave Hansen <dave.hansen@intel.com>
Jeff Moyer 2c91dc
Reported-by: Chunye Xu <chunye.xu@intel.com>
Jeff Moyer 2c91dc
Reported-by: Dan Williams <dan.j.williams@intel.com>
Jeff Moyer 2c91dc
Signed-off-by: Vishal Verma <vishal.l.verma@intel.com>
Jeff Moyer 2c91dc
---
Jeff Moyer 2c91dc
 .../daxctl/daxctl-reconfigure-device.txt      | 12 ++++++-
Jeff Moyer 2c91dc
 daxctl/device.c                               | 10 ++++++
Jeff Moyer 2c91dc
 daxctl/lib/libdaxctl-private.h                |  1 +
Jeff Moyer 2c91dc
 daxctl/lib/libdaxctl.c                        | 21 +++++++++++
Jeff Moyer 2c91dc
 daxctl/lib/libdaxctl.sym                      |  5 +++
Jeff Moyer 2c91dc
 daxctl/libdaxctl.h                            |  1 +
Jeff Moyer 2c91dc
 test/daxctl-devices.sh                        | 36 +++++++++++++++++++
Jeff Moyer 2c91dc
 7 files changed, 85 insertions(+), 1 deletion(-)
Jeff Moyer 2c91dc
Jeff Moyer 2c91dc
diff --git a/Documentation/daxctl/daxctl-reconfigure-device.txt b/Documentation/daxctl/daxctl-reconfigure-device.txt
Jeff Moyer 2c91dc
index ad33eda..f112b3c 100644
Jeff Moyer 2c91dc
--- a/Documentation/daxctl/daxctl-reconfigure-device.txt
Jeff Moyer 2c91dc
+++ b/Documentation/daxctl/daxctl-reconfigure-device.txt
Jeff Moyer 2c91dc
@@ -119,6 +119,10 @@ recommended to use the --no-online option described below. This will abridge
Jeff Moyer 2c91dc
 the device reconfiguration operation to just hotplugging the memory, and
Jeff Moyer 2c91dc
 refrain from then onlining it.
Jeff Moyer 2c91dc
 
Jeff Moyer 2c91dc
+In case daxctl detects that there is a kernel policy to auto-online blocks
Jeff Moyer 2c91dc
+(via /sys/devices/system/memory/auto_online_blocks), then reconfiguring to
Jeff Moyer 2c91dc
+system-ram will result in a failure. This can be overridden with '--force'.
Jeff Moyer 2c91dc
+
Jeff Moyer 2c91dc
 OPTIONS
Jeff Moyer 2c91dc
 -------
Jeff Moyer 2c91dc
 include::region-option.txt[]
Jeff Moyer 2c91dc
@@ -162,12 +166,18 @@ include::movable-options.txt[]
Jeff Moyer 2c91dc
 
Jeff Moyer 2c91dc
 -f::
Jeff Moyer 2c91dc
 --force::
Jeff Moyer 2c91dc
-	When converting from "system-ram" mode to "devdax", it is expected
Jeff Moyer 2c91dc
+	- When converting from "system-ram" mode to "devdax", it is expected
Jeff Moyer 2c91dc
 	that all the memory sections are first made offline. By default,
Jeff Moyer 2c91dc
 	daxctl won't touch online memory. However with this option, attempt
Jeff Moyer 2c91dc
 	to offline the memory on the NUMA node associated with the dax device
Jeff Moyer 2c91dc
 	before converting it back to "devdax" mode.
Jeff Moyer 2c91dc
 
Jeff Moyer 2c91dc
+	- Additionally, if a kernel policy to auto-online blocks is detected,
Jeff Moyer 2c91dc
+	reconfiguration to system-ram fails. With this option, the failure can
Jeff Moyer 2c91dc
+	be overridden to allow reconfiguration regardless of kernel policy.
Jeff Moyer 2c91dc
+	Doing this may result in a successful reconfiguration, but it may
Jeff Moyer 2c91dc
+	not be possible to subsequently offline the memory without a reboot.
Jeff Moyer 2c91dc
+
Jeff Moyer 2c91dc
 
Jeff Moyer 2c91dc
 include::human-option.txt[]
Jeff Moyer 2c91dc
 
Jeff Moyer 2c91dc
diff --git a/daxctl/device.c b/daxctl/device.c
Jeff Moyer 2c91dc
index 0721a57..a427b7d 100644
Jeff Moyer 2c91dc
--- a/daxctl/device.c
Jeff Moyer 2c91dc
+++ b/daxctl/device.c
Jeff Moyer 2c91dc
@@ -541,8 +541,18 @@ static int disable_devdax_device(struct daxctl_dev *dev)
Jeff Moyer 2c91dc
 
Jeff Moyer 2c91dc
 static int reconfig_mode_system_ram(struct daxctl_dev *dev)
Jeff Moyer 2c91dc
 {
Jeff Moyer 2c91dc
+	const char *devname = daxctl_dev_get_devname(dev);
Jeff Moyer 2c91dc
 	int rc, skip_enable = 0;
Jeff Moyer 2c91dc
 
Jeff Moyer 2c91dc
+	if (param.no_online || !param.no_movable) {
Jeff Moyer 2c91dc
+		if (!param.force && daxctl_dev_will_auto_online_memory(dev)) {
Jeff Moyer 2c91dc
+			fprintf(stderr,
Jeff Moyer 2c91dc
+				"%s: error: kernel policy will auto-online memory, aborting\n",
Jeff Moyer 2c91dc
+				devname);
Jeff Moyer 2c91dc
+			return -EBUSY;
Jeff Moyer 2c91dc
+		}
Jeff Moyer 2c91dc
+	}
Jeff Moyer 2c91dc
+
Jeff Moyer 2c91dc
 	if (daxctl_dev_is_enabled(dev)) {
Jeff Moyer 2c91dc
 		rc = disable_devdax_device(dev);
Jeff Moyer 2c91dc
 		if (rc < 0)
Jeff Moyer 2c91dc
diff --git a/daxctl/lib/libdaxctl-private.h b/daxctl/lib/libdaxctl-private.h
Jeff Moyer 2c91dc
index af257fd..ae45311 100644
Jeff Moyer 2c91dc
--- a/daxctl/lib/libdaxctl-private.h
Jeff Moyer 2c91dc
+++ b/daxctl/lib/libdaxctl-private.h
Jeff Moyer 2c91dc
@@ -111,6 +111,7 @@ struct daxctl_memory {
Jeff Moyer 2c91dc
 	char *node_path;
Jeff Moyer 2c91dc
 	unsigned long block_size;
Jeff Moyer 2c91dc
 	enum memory_zones zone;
Jeff Moyer 2c91dc
+	bool auto_online;
Jeff Moyer 2c91dc
 };
Jeff Moyer 2c91dc
 
Jeff Moyer 2c91dc
 
Jeff Moyer 2c91dc
diff --git a/daxctl/lib/libdaxctl.c b/daxctl/lib/libdaxctl.c
Jeff Moyer 2c91dc
index 479e8f6..879f7e6 100644
Jeff Moyer 2c91dc
--- a/daxctl/lib/libdaxctl.c
Jeff Moyer 2c91dc
+++ b/daxctl/lib/libdaxctl.c
Jeff Moyer 2c91dc
@@ -1644,3 +1644,24 @@ DAXCTL_EXPORT int daxctl_memory_is_movable(struct daxctl_memory *mem)
Jeff Moyer 2c91dc
 		return rc;
Jeff Moyer 2c91dc
 	return (mem->zone == MEM_ZONE_MOVABLE) ? 1 : 0;
Jeff Moyer 2c91dc
 }
Jeff Moyer 2c91dc
+
Jeff Moyer 2c91dc
+DAXCTL_EXPORT int daxctl_dev_will_auto_online_memory(struct daxctl_dev *dev)
Jeff Moyer 2c91dc
+{
Jeff Moyer 2c91dc
+	const char *auto_path = "/sys/devices/system/memory/auto_online_blocks";
Jeff Moyer 2c91dc
+	const char *devname = daxctl_dev_get_devname(dev);
Jeff Moyer 2c91dc
+	struct daxctl_ctx *ctx = daxctl_dev_get_ctx(dev);
Jeff Moyer 2c91dc
+	char buf[SYSFS_ATTR_SIZE];
Jeff Moyer 2c91dc
+
Jeff Moyer 2c91dc
+	/*
Jeff Moyer 2c91dc
+	 * If we can't read the policy for some reason, don't fail yet. Assume
Jeff Moyer 2c91dc
+	 * the auto-onlining policy is absent, and carry on. If onlining blocks
Jeff Moyer 2c91dc
+	 * does result in the memory being in an inconsistent state, we have a
Jeff Moyer 2c91dc
+	 * check and warning for it after the fact
Jeff Moyer 2c91dc
+	 */
Jeff Moyer 2c91dc
+	if (sysfs_read_attr(ctx, auto_path, buf) != 0)
Jeff Moyer 2c91dc
+		err(ctx, "%s: Unable to determine auto-online policy: %s\n",
Jeff Moyer 2c91dc
+				devname, strerror(errno));
Jeff Moyer 2c91dc
+
Jeff Moyer 2c91dc
+	/* match both "online" and "online_movable" */
Jeff Moyer 2c91dc
+	return !strncmp(buf, "online", 6);
Jeff Moyer 2c91dc
+}
Jeff Moyer 2c91dc
diff --git a/daxctl/lib/libdaxctl.sym b/daxctl/lib/libdaxctl.sym
Jeff Moyer 2c91dc
index a4e1684..892e393 100644
Jeff Moyer 2c91dc
--- a/daxctl/lib/libdaxctl.sym
Jeff Moyer 2c91dc
+++ b/daxctl/lib/libdaxctl.sym
Jeff Moyer 2c91dc
@@ -91,3 +91,8 @@ global:
Jeff Moyer 2c91dc
 	daxctl_mapping_get_size;
Jeff Moyer 2c91dc
 	daxctl_dev_set_mapping;
Jeff Moyer 2c91dc
 } LIBDAXCTL_7;
Jeff Moyer 2c91dc
+
Jeff Moyer 2c91dc
+LIBDAXCTL_9 {
Jeff Moyer 2c91dc
+global:
Jeff Moyer 2c91dc
+	daxctl_dev_will_auto_online_memory;
Jeff Moyer 2c91dc
+} LIBDAXCTL_8;
Jeff Moyer 2c91dc
diff --git a/daxctl/libdaxctl.h b/daxctl/libdaxctl.h
Jeff Moyer 2c91dc
index e82b274..30ab51a 100644
Jeff Moyer 2c91dc
--- a/daxctl/libdaxctl.h
Jeff Moyer 2c91dc
+++ b/daxctl/libdaxctl.h
Jeff Moyer 2c91dc
@@ -71,6 +71,7 @@ int daxctl_dev_disable(struct daxctl_dev *dev);
Jeff Moyer 2c91dc
 int daxctl_dev_enable_devdax(struct daxctl_dev *dev);
Jeff Moyer 2c91dc
 int daxctl_dev_enable_ram(struct daxctl_dev *dev);
Jeff Moyer 2c91dc
 int daxctl_dev_get_target_node(struct daxctl_dev *dev);
Jeff Moyer 2c91dc
+int daxctl_dev_will_auto_online_memory(struct daxctl_dev *dev);
Jeff Moyer 2c91dc
 
Jeff Moyer 2c91dc
 struct daxctl_memory;
Jeff Moyer 2c91dc
 struct daxctl_memory *daxctl_dev_get_memory(struct daxctl_dev *dev);
Jeff Moyer 2c91dc
diff --git a/test/daxctl-devices.sh b/test/daxctl-devices.sh
Jeff Moyer 2c91dc
index 496e4f2..eed5906 100755
Jeff Moyer 2c91dc
--- a/test/daxctl-devices.sh
Jeff Moyer 2c91dc
+++ b/test/daxctl-devices.sh
Jeff Moyer 2c91dc
@@ -64,6 +64,26 @@ daxctl_get_mode()
Jeff Moyer 2c91dc
 	"$DAXCTL" list -d "$1" | jq -er '.[].mode'
Jeff Moyer 2c91dc
 }
Jeff Moyer 2c91dc
 
Jeff Moyer 2c91dc
+set_online_policy()
Jeff Moyer 2c91dc
+{
Jeff Moyer 2c91dc
+	echo "online" > /sys/devices/system/memory/auto_online_blocks
Jeff Moyer 2c91dc
+}
Jeff Moyer 2c91dc
+
Jeff Moyer 2c91dc
+unset_online_policy()
Jeff Moyer 2c91dc
+{
Jeff Moyer 2c91dc
+	echo "offline" > /sys/devices/system/memory/auto_online_blocks
Jeff Moyer 2c91dc
+}
Jeff Moyer 2c91dc
+
Jeff Moyer 2c91dc
+save_online_policy()
Jeff Moyer 2c91dc
+{
Jeff Moyer 2c91dc
+	saved_policy="$(cat /sys/devices/system/memory/auto_online_blocks)"
Jeff Moyer 2c91dc
+}
Jeff Moyer 2c91dc
+
Jeff Moyer 2c91dc
+restore_online_policy()
Jeff Moyer 2c91dc
+{
Jeff Moyer 2c91dc
+	echo "$saved_policy" > /sys/devices/system/memory/auto_online_blocks
Jeff Moyer 2c91dc
+}
Jeff Moyer 2c91dc
+
Jeff Moyer 2c91dc
 daxctl_test()
Jeff Moyer 2c91dc
 {
Jeff Moyer 2c91dc
 	local daxdev
Jeff Moyer 2c91dc
@@ -71,6 +91,9 @@ daxctl_test()
Jeff Moyer 2c91dc
 	daxdev=$(daxctl_get_dev "$testdev")
Jeff Moyer 2c91dc
 	test -n "$daxdev"
Jeff Moyer 2c91dc
 
Jeff Moyer 2c91dc
+	# these tests need to run with kernel onlining policy turned off
Jeff Moyer 2c91dc
+	save_online_policy
Jeff Moyer 2c91dc
+	unset_online_policy
Jeff Moyer 2c91dc
 	"$DAXCTL" reconfigure-device -N -m system-ram "$daxdev"
Jeff Moyer 2c91dc
 	[[ $(daxctl_get_mode "$daxdev") == "system-ram" ]]
Jeff Moyer 2c91dc
 	"$DAXCTL" online-memory "$daxdev"
Jeff Moyer 2c91dc
@@ -81,6 +104,19 @@ daxctl_test()
Jeff Moyer 2c91dc
 	[[ $(daxctl_get_mode "$daxdev") == "system-ram" ]]
Jeff Moyer 2c91dc
 	"$DAXCTL" reconfigure-device -f -m devdax "$daxdev"
Jeff Moyer 2c91dc
 	[[ $(daxctl_get_mode "$daxdev") == "devdax" ]]
Jeff Moyer 2c91dc
+
Jeff Moyer 2c91dc
+	# this tests for reconfiguration failure if an online-policy is set
Jeff Moyer 2c91dc
+	set_online_policy
Jeff Moyer 2c91dc
+	: "This command is expected to fail:"
Jeff Moyer 2c91dc
+	if ! "$DAXCTL" reconfigure-device -N -m system-ram "$daxdev"; then
Jeff Moyer 2c91dc
+		echo "reconfigure failed as expected"
Jeff Moyer 2c91dc
+	else
Jeff Moyer 2c91dc
+		echo "reconfigure succeded, expected failure"
Jeff Moyer 2c91dc
+		restore_online_policy
Jeff Moyer 2c91dc
+		return 1
Jeff Moyer 2c91dc
+	fi
Jeff Moyer 2c91dc
+
Jeff Moyer 2c91dc
+	restore_online_policy
Jeff Moyer 2c91dc
 }
Jeff Moyer 2c91dc
 
Jeff Moyer 2c91dc
 find_testdev
Jeff Moyer 2c91dc
-- 
Jeff Moyer 2c91dc
2.27.0
Jeff Moyer 2c91dc