All of lore.kernel.org
 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>
Subject: [ndctl PATCH 3/3] libndctl: check for active system-ram before disabling daxctl devices
Date: Tue, 30 Mar 2021 21:12:29 -0600	[thread overview]
Message-ID: <20210331031229.384068-4-vishal.l.verma@intel.com> (raw)
In-Reply-To: <20210331031229.384068-1-vishal.l.verma@intel.com>

Teach ndctl_namespace_disable_safe() to look at the state of a
daxctl_dev with respect to whether it is active in 'system-ram' mode
before disabling it. This is similar to checking whether a filesystem is
actively mounted on a namespace before disabling it.

Without this, libndctl would happily disable a devdax namespace while the
device was active in system-ram mode. If the namespace was subsequently
also destroyed, this would leave the memory without any sort of a
'handle' to perform any subsequent operation on it, and the system would
have to be rebooted to get out of this situation.

Reported-by: Chunye Xu <chunye.xu@intel.com>
Cc: Dan Williams <dan.j.williams@intel.com>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Signed-off-by: Vishal Verma <vishal.l.verma@intel.com>
---
 ndctl/lib/libndctl.c   | 25 ++++++++++++++++++++++++-
 test/daxctl-devices.sh | 16 ++++++++++++++++
 2 files changed, 40 insertions(+), 1 deletion(-)

diff --git a/ndctl/lib/libndctl.c b/ndctl/lib/libndctl.c
index 2f6d806..2eda56c 100644
--- a/ndctl/lib/libndctl.c
+++ b/ndctl/lib/libndctl.c
@@ -4593,21 +4593,40 @@ NDCTL_EXPORT int ndctl_namespace_disable_invalidate(struct ndctl_namespace *ndns
 	return ndctl_namespace_disable(ndns);
 }
 
+static int ndctl_dax_has_active_memory(struct ndctl_dax *dax)
+{
+	struct daxctl_region *dax_region;
+	struct daxctl_dev *dax_dev;
+
+	dax_region = ndctl_dax_get_daxctl_region(dax);
+	if (!dax_region)
+		return 0;
+
+	daxctl_dev_foreach(dax_region, dax_dev)
+		if (daxctl_dev_has_online_memory(dax_dev))
+			return 1;
+
+	return 0;
+}
+
 NDCTL_EXPORT int ndctl_namespace_disable_safe(struct ndctl_namespace *ndns)
 {
 	const char *devname = ndctl_namespace_get_devname(ndns);
 	struct ndctl_ctx *ctx = ndctl_namespace_get_ctx(ndns);
 	struct ndctl_pfn *pfn = ndctl_namespace_get_pfn(ndns);
 	struct ndctl_btt *btt = ndctl_namespace_get_btt(ndns);
+	struct ndctl_dax *dax = ndctl_namespace_get_dax(ndns);
 	const char *bdev = NULL;
+	int fd, active = 0;
 	char path[50];
-	int fd;
 	unsigned long long size = ndctl_namespace_get_size(ndns);
 
 	if (pfn && ndctl_pfn_is_enabled(pfn))
 		bdev = ndctl_pfn_get_block_device(pfn);
 	else if (btt && ndctl_btt_is_enabled(btt))
 		bdev = ndctl_btt_get_block_device(btt);
+	else if (dax && ndctl_dax_is_enabled(dax))
+		active = ndctl_dax_has_active_memory(dax);
 	else if (ndctl_namespace_is_enabled(ndns))
 		bdev = ndctl_namespace_get_block_device(ndns);
 
@@ -4632,6 +4651,10 @@ NDCTL_EXPORT int ndctl_namespace_disable_safe(struct ndctl_namespace *ndns)
 					devname, bdev, strerror(errno));
 			return -errno;
 		}
+	} else if (active) {
+		dbg(ctx, "%s: active as system-ram, refusing to disable\n",
+				devname);
+		return -EBUSY;
 	} else {
 		if (size == 0)
 			/* No disable necessary due to no capacity allocated */
diff --git a/test/daxctl-devices.sh b/test/daxctl-devices.sh
index eed5906..56c9691 100755
--- a/test/daxctl-devices.sh
+++ b/test/daxctl-devices.sh
@@ -105,6 +105,22 @@ daxctl_test()
 	"$DAXCTL" reconfigure-device -f -m devdax "$daxdev"
 	[[ $(daxctl_get_mode "$daxdev") == "devdax" ]]
 
+	# fail 'ndctl-disable-namespace' while the devdax namespace is active
+	# as system-ram. If this test fails, a reboot will be required to
+	# recover from the resulting state.
+	test -n "$testdev"
+	"$DAXCTL" reconfigure-device -m system-ram "$daxdev"
+	[[ $(daxctl_get_mode "$daxdev") == "system-ram" ]]
+	if ! "$NDCTL" disable-namespace "$testdev"; then
+		echo "disable-namespace failed as expected"
+	else
+		echo "disable-namespace succeded, expected failure"
+		echo "reboot required to recover from this state"
+		return 1
+	fi
+	"$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:"
-- 
2.30.2
_______________________________________________
Linux-nvdimm mailing list -- linux-nvdimm@lists.01.org
To unsubscribe send an email to linux-nvdimm-leave@lists.01.org

      parent 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 ` [ndctl PATCH 1/3] daxctl: fail reconfigure-device based on kernel onlining policy Vishal Verma
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 ` Vishal Verma [this message]

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-4-vishal.l.verma@intel.com \
    --to=vishal.l.verma@intel.com \
    --cc=chunye.xu@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.