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