nvdimm.lists.linux.dev archive mirror
 help / color / mirror / Atom feed
* [ndctl PATCH v4 00/10] daxctl: add a new reconfigure-device command
@ 2019-05-28 22:24 Vishal Verma
  2019-05-28 22:24 ` [ndctl PATCH v4 01/10] libdaxctl: add interfaces in support of device modes Vishal Verma
                   ` (9 more replies)
  0 siblings, 10 replies; 20+ messages in thread
From: Vishal Verma @ 2019-05-28 22:24 UTC (permalink / raw)
  To: linux-nvdimm; +Cc: Dave Hansen, Pavel Tatashin

Changes in v4:
 - Don't fail add_dax_dev for kmod failures. Instead fail only when the kmod
   list is actually used, i.e. during daxctl-reconfigure-device

Changes in v3:
 - In daxctl_dev_get_mode(), remove the subsystem warning, detect dax-class
   and simply make it return devdax

Changes in v2:
 - Add examples to the documentation page (Dave Hansen)
 - Clarify documentation regarding the conversion from system-ram to devdax
 - Remove any references to a persistent config from the documentation -
   those can be added when the feature is added.
 - device.c: validate option compatibility
 - daxctl-list: display numa_node for device listings
 - daxctl-list: display mode for device listings
 - make the options more consistent by adding a '-O' short option
   for --attempt-offline

Add a new daxctl-reconfigure-device command that lets us reconfigure DAX
devices back and forth between 'system-ram' and 'device-dax' modes. It
also includes facilities to online any newly hot-plugged memory
(default), and attempt to offline memory before converting away from the
system-ram mode (not default, requires a --attempt-offline option).

Currently missing from this series is a way to persistently store which
devices have been 'marked' for use as system-ram. This depends on a
config system overhaul in ndctl, and patches for those will follow
separately and are independent of this work.

Example invocations:

1. Reconfigure dax0.0 to system-ram mode, don’t online the memory
    # daxctl reconfigure-device --mode=system-ram --no-online dax0.0
    [
      {
        "chardev":"dax0.0",
        "size":16777216000,
        "numa_node":2,
        "mode":"system-ram"
      }
    ]

2. Reconfigure dax0.0 to devdax mode, attempt to offline the memory
    # daxctl reconfigure-device --human --mode=devdax --attempt-offline dax0.0
    {
      "chardev":"dax0.0",
      "size":"15.63 GiB (16.78 GB)",
      "numa_node":2,
      "mode":"devdax"
    }

3. Reconfigure all dax devices on region0 to system-ram mode
    # daxctl reconfigure-device --mode=system-ram --region=0 all
    [
      {
        "chardev":"dax0.0",
        "size":16777216000,
        "numa_node":2,
        "mode":"system-ram"
      },
      {
        "chardev":"dax0.1",
        "size":16777216000,
        "numa_node":3,
        "mode":"system-ram"
      }
    ]

These patches can also be found in the 'kmem-pending' branch on github:
https://github.com/pmem/ndctl/tree/kmem-pending

Cc: Dan Williams <dan.j.williams@intel.com>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: Pavel Tatashin <pasha.tatashin@soleen.com>

Vishal Verma (10):
  libdaxctl: add interfaces in support of device modes
  libdaxctl: cache 'subsystem' in daxctl_ctx
  libdaxctl: add interfaces to enable/disable devices
  libdaxctl: add interfaces to get/set the online state for a node
  daxctl/list: add numa_node for device listings
  libdaxctl: add an interface to get the mode for a dax device
  daxctl: add a new reconfigure-device command
  Documentation/daxctl: add a man page for daxctl-reconfigure-device
  contrib/ndctl: fix region-id completions for daxctl
  contrib/ndctl: add bash-completion for daxctl-reconfigure-device

 Documentation/daxctl/Makefile.am              |   3 +-
 .../daxctl/daxctl-reconfigure-device.txt      | 118 ++++
 contrib/ndctl                                 |  34 +-
 daxctl/Makefile.am                            |   2 +
 daxctl/builtin.h                              |   1 +
 daxctl/daxctl.c                               |   1 +
 daxctl/device.c                               | 237 ++++++++
 daxctl/lib/Makefile.am                        |   3 +-
 daxctl/lib/libdaxctl-private.h                |  21 +
 daxctl/lib/libdaxctl.c                        | 548 +++++++++++++++++-
 daxctl/lib/libdaxctl.sym                      |  14 +
 daxctl/libdaxctl.h                            |  16 +
 util/json.c                                   |  22 +
 13 files changed, 1009 insertions(+), 11 deletions(-)
 create mode 100644 Documentation/daxctl/daxctl-reconfigure-device.txt
 create mode 100644 daxctl/device.c

-- 
2.20.1

_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [ndctl PATCH v4 01/10] libdaxctl: add interfaces in support of device modes
  2019-05-28 22:24 [ndctl PATCH v4 00/10] daxctl: add a new reconfigure-device command Vishal Verma
@ 2019-05-28 22:24 ` Vishal Verma
  2019-05-28 22:24 ` [ndctl PATCH v4 02/10] libdaxctl: cache 'subsystem' in daxctl_ctx Vishal Verma
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 20+ messages in thread
From: Vishal Verma @ 2019-05-28 22:24 UTC (permalink / raw)
  To: linux-nvdimm; +Cc: Dave Hansen, Pavel Tatashin

In preparation for libdaxctl and daxctl to grow operational modes for
DAX devices, add the following supporting APIs:

  daxctl_dev_get_ctx
  daxctl_dev_is_enabled

Cc: Dan Williams <dan.j.williams@intel.com>
Signed-off-by: Vishal Verma <vishal.l.verma@intel.com>
---
 daxctl/lib/libdaxctl.c   | 30 ++++++++++++++++++++++++++++++
 daxctl/lib/libdaxctl.sym |  6 ++++++
 daxctl/libdaxctl.h       |  2 ++
 3 files changed, 38 insertions(+)

diff --git a/daxctl/lib/libdaxctl.c b/daxctl/lib/libdaxctl.c
index c2e3a52..70f896b 100644
--- a/daxctl/lib/libdaxctl.c
+++ b/daxctl/lib/libdaxctl.c
@@ -559,6 +559,36 @@ static void dax_regions_init(struct daxctl_ctx *ctx)
 	}
 }
 
+static int is_enabled(const char *drvpath)
+{
+	struct stat st;
+
+	if (lstat(drvpath, &st) < 0 || !S_ISLNK(st.st_mode))
+		return 0;
+	else
+		return 1;
+}
+
+DAXCTL_EXPORT int daxctl_dev_is_enabled(struct daxctl_dev *dev)
+{
+	struct daxctl_ctx *ctx = daxctl_dev_get_ctx(dev);
+	char *path = dev->dev_buf;
+	int len = dev->buf_len;
+
+	if (snprintf(path, len, "%s/driver", dev->dev_path) >= len) {
+		err(ctx, "%s: buffer too small!\n",
+				daxctl_dev_get_devname(dev));
+		return 0;
+	}
+
+	return is_enabled(path);
+}
+
+DAXCTL_EXPORT struct daxctl_ctx *daxctl_dev_get_ctx(struct daxctl_dev *dev)
+{
+	return dev->region->ctx;
+}
+
 DAXCTL_EXPORT struct daxctl_dev *daxctl_dev_get_first(struct daxctl_region *region)
 {
 	dax_devices_init(region);
diff --git a/daxctl/lib/libdaxctl.sym b/daxctl/lib/libdaxctl.sym
index 84d3a69..c4af9a7 100644
--- a/daxctl/lib/libdaxctl.sym
+++ b/daxctl/lib/libdaxctl.sym
@@ -50,3 +50,9 @@ LIBDAXCTL_5 {
 global:
 	daxctl_region_get_path;
 } LIBDAXCTL_4;
+
+LIBDAXCTL_6 {
+global:
+	daxctl_dev_get_ctx;
+	daxctl_dev_is_enabled;
+} LIBDAXCTL_5;
diff --git a/daxctl/libdaxctl.h b/daxctl/libdaxctl.h
index 1d13ea2..e20ccb4 100644
--- a/daxctl/libdaxctl.h
+++ b/daxctl/libdaxctl.h
@@ -67,6 +67,8 @@ const char *daxctl_dev_get_devname(struct daxctl_dev *dev);
 int daxctl_dev_get_major(struct daxctl_dev *dev);
 int daxctl_dev_get_minor(struct daxctl_dev *dev);
 unsigned long long daxctl_dev_get_size(struct daxctl_dev *dev);
+struct daxctl_ctx *daxctl_dev_get_ctx(struct daxctl_dev *dev);
+int daxctl_dev_is_enabled(struct daxctl_dev *dev);
 
 #define daxctl_dev_foreach(region, dev) \
         for (dev = daxctl_dev_get_first(region); \
-- 
2.20.1

_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [ndctl PATCH v4 02/10] libdaxctl: cache 'subsystem' in daxctl_ctx
  2019-05-28 22:24 [ndctl PATCH v4 00/10] daxctl: add a new reconfigure-device command Vishal Verma
  2019-05-28 22:24 ` [ndctl PATCH v4 01/10] libdaxctl: add interfaces in support of device modes Vishal Verma
@ 2019-05-28 22:24 ` Vishal Verma
  2019-05-29  0:27   ` Dan Williams
  2019-05-28 22:24 ` [ndctl PATCH v4 03/10] libdaxctl: add interfaces to enable/disable devices Vishal Verma
                   ` (7 subsequent siblings)
  9 siblings, 1 reply; 20+ messages in thread
From: Vishal Verma @ 2019-05-28 22:24 UTC (permalink / raw)
  To: linux-nvdimm; +Cc: Dave Hansen, Pavel Tatashin

The 'DAX subsystem' in effect is determined at region or device init
time, and dictates the sysfs base paths for all device/region
operations. In preparation for adding bind/unbind functionality, cache
the subsystem as determined at init time in the library context.

Cc: Dan Williams <dan.j.williams@intel.com>
Signed-off-by: Vishal Verma <vishal.l.verma@intel.com>
---
 daxctl/lib/libdaxctl.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/daxctl/lib/libdaxctl.c b/daxctl/lib/libdaxctl.c
index 70f896b..f8f5b8c 100644
--- a/daxctl/lib/libdaxctl.c
+++ b/daxctl/lib/libdaxctl.c
@@ -46,6 +46,7 @@ struct daxctl_ctx {
 	void *userdata;
 	int regions_init;
 	struct list_head regions;
+	enum dax_subsystem subsys;
 };
 
 /**
@@ -96,6 +97,7 @@ DAXCTL_EXPORT int daxctl_new(struct daxctl_ctx **ctx)
 	dbg(c, "log_priority=%d\n", c->ctx.log_priority);
 	*ctx = c;
 	list_head_init(&c->regions);
+	c->subsys = DAX_UNKNOWN;
 
 	return 0;
 }
@@ -454,14 +456,18 @@ static void dax_devices_init(struct daxctl_region *region)
 	for (i = 0; i < ARRAY_SIZE(dax_subsystems); i++) {
 		char *region_path;
 
-		if (i == DAX_BUS)
+		if (i == DAX_BUS) {
 			region_path = region->region_path;
-		else if (i == DAX_CLASS) {
+			if (ctx->subsys == DAX_UNKNOWN)
+				ctx->subsys = DAX_BUS;
+		} else if (i == DAX_CLASS) {
 			if (asprintf(&region_path, "%s/dax",
 						region->region_path) < 0) {
 				dbg(ctx, "region path alloc fail\n");
 				continue;
 			}
+			if (ctx->subsys == DAX_UNKNOWN)
+				ctx->subsys = DAX_CLASS;
 		} else
 			continue;
 		sysfs_device_parse(ctx, region_path, daxdev_fmt, region,
@@ -539,6 +545,8 @@ static void __dax_regions_init(struct daxctl_ctx *ctx, enum dax_subsystem subsys
 		free(dev_path);
 		if (!region)
 			err(ctx, "add_dax_region() for %s failed\n", de->d_name);
+		if (ctx->subsys == DAX_UNKNOWN)
+			ctx->subsys = subsys;
 	}
 	closedir(dir);
 }
-- 
2.20.1

_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [ndctl PATCH v4 03/10] libdaxctl: add interfaces to enable/disable devices
  2019-05-28 22:24 [ndctl PATCH v4 00/10] daxctl: add a new reconfigure-device command Vishal Verma
  2019-05-28 22:24 ` [ndctl PATCH v4 01/10] libdaxctl: add interfaces in support of device modes Vishal Verma
  2019-05-28 22:24 ` [ndctl PATCH v4 02/10] libdaxctl: cache 'subsystem' in daxctl_ctx Vishal Verma
@ 2019-05-28 22:24 ` Vishal Verma
  2019-05-29  2:13   ` Dan Williams
  2019-05-28 22:24 ` [ndctl PATCH v4 04/10] libdaxctl: add interfaces to get/set the online state for a node Vishal Verma
                   ` (6 subsequent siblings)
  9 siblings, 1 reply; 20+ messages in thread
From: Vishal Verma @ 2019-05-28 22:24 UTC (permalink / raw)
  To: linux-nvdimm; +Cc: Dave Hansen, Pavel Tatashin

Add new libdaxctl interfaces to disable a device_dax based devices, and
to enable it into a given mode. The modes available are 'device_dax',
and 'system-ram', where device_dax is the normal device DAX mode used
via a character device, and 'system-ram' uses the kernel's 'kmem'
facility to hotplug the device into the system's memory space, and can
be used as normal system memory.

This adds the following new interfaces:

  daxctl_dev_disable;
  daxctl_dev_enable_devdax;
  daxctl_dev_enable_ram;

Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: Dan Williams <dan.j.williams@intel.com>
Signed-off-by: Vishal Verma <vishal.l.verma@intel.com>
---
 daxctl/lib/Makefile.am         |   3 +-
 daxctl/lib/libdaxctl-private.h |  15 +++
 daxctl/lib/libdaxctl.c         | 237 +++++++++++++++++++++++++++++++++
 daxctl/lib/libdaxctl.sym       |   3 +
 daxctl/libdaxctl.h             |   9 ++
 5 files changed, 266 insertions(+), 1 deletion(-)

diff --git a/daxctl/lib/Makefile.am b/daxctl/lib/Makefile.am
index d3d4852..9f0e444 100644
--- a/daxctl/lib/Makefile.am
+++ b/daxctl/lib/Makefile.am
@@ -16,7 +16,8 @@ libdaxctl_la_SOURCES =\
 	libdaxctl.c
 
 libdaxctl_la_LIBADD =\
-	$(UUID_LIBS)
+	$(UUID_LIBS) \
+	$(KMOD_LIBS)
 
 daxctl_modprobe_data_DATA = daxctl.conf
 
diff --git a/daxctl/lib/libdaxctl-private.h b/daxctl/lib/libdaxctl-private.h
index 4a462e7..e64d0a7 100644
--- a/daxctl/lib/libdaxctl-private.h
+++ b/daxctl/lib/libdaxctl-private.h
@@ -13,6 +13,8 @@
 #ifndef _LIBDAXCTL_PRIVATE_H_
 #define _LIBDAXCTL_PRIVATE_H_
 
+#include <libkmod.h>
+
 #define DAXCTL_EXPORT __attribute__ ((visibility("default")))
 
 enum dax_subsystem {
@@ -26,6 +28,11 @@ static const char *dax_subsystems[] = {
 	[DAX_BUS] = "/sys/bus/dax/devices",
 };
 
+static const char *dax_modules[] = {
+	[DAXCTL_DEV_MODE_DEVDAX] = "device_dax",
+	[DAXCTL_DEV_MODE_RAM] = "kmem",
+};
+
 /**
  * struct daxctl_region - container for dax_devices
  */
@@ -53,6 +60,14 @@ struct daxctl_dev {
 	char *dev_path;
 	struct list_node list;
 	unsigned long long size;
+	struct kmod_module *module;
+	struct kmod_list *kmod_list;
 	struct daxctl_region *region;
 };
+
+static inline int check_kmod(struct kmod_ctx *kmod_ctx)
+{
+	return kmod_ctx ? 0 : -ENXIO;
+}
+
 #endif /* _LIBDAXCTL_PRIVATE_H_ */
diff --git a/daxctl/lib/libdaxctl.c b/daxctl/lib/libdaxctl.c
index f8f5b8c..2890f69 100644
--- a/daxctl/lib/libdaxctl.c
+++ b/daxctl/lib/libdaxctl.c
@@ -47,6 +47,7 @@ struct daxctl_ctx {
 	int regions_init;
 	struct list_head regions;
 	enum dax_subsystem subsys;
+	struct kmod_ctx *kmod_ctx;
 };
 
 /**
@@ -85,12 +86,20 @@ DAXCTL_EXPORT void daxctl_set_userdata(struct daxctl_ctx *ctx, void *userdata)
  */
 DAXCTL_EXPORT int daxctl_new(struct daxctl_ctx **ctx)
 {
+	struct kmod_ctx *kmod_ctx;
 	struct daxctl_ctx *c;
+	int rc = 0;
 
 	c = calloc(1, sizeof(struct daxctl_ctx));
 	if (!c)
 		return -ENOMEM;
 
+	kmod_ctx = kmod_new(NULL, NULL);
+	if (check_kmod(kmod_ctx) != 0) {
+		rc = -ENXIO;
+		goto out;
+	}
+
 	c->refcount = 1;
 	log_init(&c->ctx, "libdaxctl", "DAXCTL_LOG");
 	info(c, "ctx %p created\n", c);
@@ -98,8 +107,12 @@ DAXCTL_EXPORT int daxctl_new(struct daxctl_ctx **ctx)
 	*ctx = c;
 	list_head_init(&c->regions);
 	c->subsys = DAX_UNKNOWN;
+	c->kmod_ctx = kmod_ctx;
 
 	return 0;
+out:
+	free(c);
+	return rc;
 }
 
 /**
@@ -134,6 +147,7 @@ DAXCTL_EXPORT void daxctl_unref(struct daxctl_ctx *ctx)
 	list_for_each_safe(&ctx->regions, region, _r, list)
 		free_region(region, &ctx->regions);
 
+	kmod_unref(ctx->kmod_ctx);
 	info(ctx, "context %p released\n", ctx);
 	free(ctx);
 }
@@ -191,6 +205,7 @@ static void free_dev(struct daxctl_dev *dev, struct list_head *head)
 {
 	if (head)
 		list_del_from(head, &dev->list);
+	kmod_module_unref_list(dev->kmod_list);
 	free(dev->dev_buf);
 	free(dev->dev_path);
 	free(dev);
@@ -308,6 +323,27 @@ DAXCTL_EXPORT struct daxctl_region *daxctl_new_region(struct daxctl_ctx *ctx,
 	return region;
 }
 
+static struct kmod_list *to_module_list(struct daxctl_ctx *ctx,
+		const char *alias)
+{
+	struct kmod_list *list = NULL;
+	int rc;
+
+	if (!ctx->kmod_ctx || !alias)
+		return NULL;
+	if (alias[0] == 0)
+		return NULL;
+
+	rc = kmod_module_new_from_lookup(ctx->kmod_ctx, alias, &list);
+	if (rc < 0 || !list) {
+		dbg(ctx, "failed to find modules for alias: %s %d list: %s\n",
+				alias, rc, list ? "populated" : "empty");
+		return NULL;
+	}
+
+	return list;
+}
+
 static void *add_dax_dev(void *parent, int id, const char *daxdev_base)
 {
 	const char *devname = devpath_to_devname(daxdev_base);
@@ -317,6 +353,7 @@ static void *add_dax_dev(void *parent, int id, const char *daxdev_base)
 	struct daxctl_dev *dev, *dev_dup;
 	char buf[SYSFS_ATTR_SIZE];
 	struct stat st;
+	int rc;
 
 	if (!path)
 		return NULL;
@@ -348,6 +385,14 @@ static void *add_dax_dev(void *parent, int id, const char *daxdev_base)
 		goto err_read;
 	dev->buf_len = strlen(daxdev_base) + 50;
 
+	sprintf(path, "%s/modalias", daxdev_base);
+	rc = sysfs_read_attr(ctx, path, buf);
+	/* older kernels may be lack the modalias attribute */
+	if (rc < 0 && rc != -ENOENT)
+		goto err_read;
+	if (rc == 0)
+		dev->kmod_list = to_module_list(ctx, buf);
+
 	daxctl_dev_foreach(region, dev_dup)
 		if (dev_dup->id == dev->id) {
 			free_dev(dev, NULL);
@@ -577,6 +622,83 @@ static int is_enabled(const char *drvpath)
 		return 1;
 }
 
+static int daxctl_bind(struct daxctl_ctx *ctx, const char *devname,
+		const char *mod_name)
+{
+	DIR *dir;
+	int rc = 0;
+	char path[200];
+	struct dirent *de;
+	const int len = sizeof(path);
+
+	if (!devname) {
+		err(ctx, "missing devname\n");
+		return -EINVAL;
+	}
+
+	/* this is only called by daxctl_dev_enable which gates on dax-bus */
+	if (snprintf(path, len, "/sys/bus/dax/drivers") >= len) {
+		err(ctx, "%s: buffer too small!\n", devname);
+		return -ENXIO;
+	}
+
+	dir = opendir(path);
+	if (!dir) {
+		err(ctx, "%s: opendir(\"%s\") failed\n", devname, path);
+		return -ENXIO;
+	}
+
+	while ((de = readdir(dir)) != NULL) {
+		char *drv_path;
+
+		if (de->d_ino == 0)
+			continue;
+		if (de->d_name[0] == '.')
+			continue;
+		if (strcmp(de->d_name, mod_name) != 0)
+			continue;
+
+		if (asprintf(&drv_path, "%s/%s/new_id", path, de->d_name) < 0) {
+			err(ctx, "%s: path allocation failure\n", devname);
+			rc = -ENOMEM;
+			break;
+		}
+		rc = sysfs_write_attr_quiet(ctx, drv_path, devname);
+		free(drv_path);
+
+		if (asprintf(&drv_path, "%s/%s/bind", path, de->d_name) < 0) {
+			err(ctx, "%s: path allocation failure\n", devname);
+			rc = -ENOMEM;
+			break;
+		}
+		rc = sysfs_write_attr_quiet(ctx, drv_path, devname);
+		free(drv_path);
+		break;
+	}
+	closedir(dir);
+
+	if (rc) {
+		dbg(ctx, "%s: bind failed\n", devname);
+		return rc;
+	}
+	return 0;
+}
+
+static int daxctl_unbind(struct daxctl_ctx *ctx, const char *devpath)
+{
+	const char *devname = devpath_to_devname(devpath);
+	char path[200];
+	const int len = sizeof(path);
+
+	/* this is only called by daxctl_dev_disable which gates on dax-bus */
+	if (snprintf(path, len, "%s/driver/unbind", devpath) >= len) {
+		err(ctx, "%s: buffer too small!\n", devname);
+		return -ENXIO;
+	}
+
+	return sysfs_write_attr(ctx, path, devname);
+}
+
 DAXCTL_EXPORT int daxctl_dev_is_enabled(struct daxctl_dev *dev)
 {
 	struct daxctl_ctx *ctx = daxctl_dev_get_ctx(dev);
@@ -592,6 +714,121 @@ DAXCTL_EXPORT int daxctl_dev_is_enabled(struct daxctl_dev *dev)
 	return is_enabled(path);
 }
 
+static int daxctl_insert_kmod_for_mode(struct daxctl_dev *dev,
+		const char *mod_name)
+{
+	const char *devname = daxctl_dev_get_devname(dev);
+	struct daxctl_ctx *ctx = daxctl_dev_get_ctx(dev);
+	struct kmod_list *iter;
+	int rc = -ENXIO;
+
+	if (dev->kmod_list == NULL) {
+		err(ctx, "%s: a modalias lookup list was not created\n",
+				devname);
+		return rc;
+	}
+
+	kmod_list_foreach(iter, dev->kmod_list) {
+		struct kmod_module *mod = kmod_module_get_module(iter);
+		const char *name = kmod_module_get_name(mod);
+
+		if (strcmp(name, mod_name) != 0) {
+			kmod_module_unref(mod);
+			continue;
+		}
+		dbg(ctx, "%s inserting module: %s\n", devname, name);
+		rc = kmod_module_probe_insert_module(mod,
+				KMOD_PROBE_APPLY_BLACKLIST, NULL, NULL, NULL,
+				NULL);
+		if (rc < 0) {
+			err(ctx, "%s: insert failure: %d\n", devname, rc);
+			return rc;
+		}
+		dev->module = mod;
+	}
+
+	if (rc == -ENXIO)
+		err(ctx, "%s: Unable to find module: %s in alias list\n",
+				devname, mod_name);
+	return rc;
+}
+
+static int daxctl_dev_enable(struct daxctl_dev *dev, enum daxctl_dev_mode mode)
+{
+	struct daxctl_region *region = daxctl_dev_get_region(dev);
+	const char *devname = daxctl_dev_get_devname(dev);
+	struct daxctl_ctx *ctx = daxctl_dev_get_ctx(dev);
+	const char *mod_name = dax_modules[mode];
+	int rc;
+
+	if (daxctl_dev_is_enabled(dev))
+		return 0;
+
+	if (ctx->subsys != DAX_BUS) {
+		err(ctx, "%s: invalid operation for dax subsystem\n", devname);
+		err(ctx, "%s:  see daxctl-migrate-device-model(1)\n", devname);
+		return -ENXIO;
+	}
+
+	if (mode == DAXCTL_DEV_MODE_UNKNOWN || mod_name == NULL) {
+		err(ctx, "%s: Invalid mode: %d\n", devname, mode);
+		return -EINVAL;
+	}
+
+	rc = daxctl_insert_kmod_for_mode(dev, mod_name);
+	if (rc)
+		return rc;
+
+	rc = daxctl_bind(ctx, devname, mod_name);
+	if (!daxctl_dev_is_enabled(dev)) {
+		err(ctx, "%s: failed to enable\n", devname);
+		return rc ? rc : -ENXIO;
+	}
+
+	region->devices_init = 0;
+	dax_devices_init(region);
+	rc = 0;
+	dbg(ctx, "%s: enabled\n", devname);
+	return rc;
+}
+
+DAXCTL_EXPORT int daxctl_dev_enable_devdax(struct daxctl_dev *dev)
+{
+	return daxctl_dev_enable(dev, DAXCTL_DEV_MODE_DEVDAX);
+}
+
+DAXCTL_EXPORT int daxctl_dev_enable_ram(struct daxctl_dev *dev)
+{
+	return daxctl_dev_enable(dev, DAXCTL_DEV_MODE_RAM);
+}
+
+DAXCTL_EXPORT int daxctl_dev_disable(struct daxctl_dev *dev)
+{
+	const char *devname = daxctl_dev_get_devname(dev);
+	struct daxctl_ctx *ctx = daxctl_dev_get_ctx(dev);
+
+	if (!daxctl_dev_is_enabled(dev))
+		return 0;
+
+	if (ctx->subsys != DAX_BUS) {
+		err(ctx, "%s: invalid operation for dax subsystem\n", devname);
+		err(ctx, "%s:  see daxctl-migrate-device-model(1)\n", devname);
+		return -ENXIO;
+	}
+
+	daxctl_unbind(ctx, dev->dev_path);
+
+	if (daxctl_dev_is_enabled(dev)) {
+		err(ctx, "%s: failed to disable\n", devname);
+		return -EBUSY;
+	}
+
+	kmod_module_unref(dev->module);
+	dbg(ctx, "%s: disabled\n", devname);
+
+	return 0;
+}
+
 DAXCTL_EXPORT struct daxctl_ctx *daxctl_dev_get_ctx(struct daxctl_dev *dev)
 {
 	return dev->region->ctx;
diff --git a/daxctl/lib/libdaxctl.sym b/daxctl/lib/libdaxctl.sym
index c4af9a7..19904a2 100644
--- a/daxctl/lib/libdaxctl.sym
+++ b/daxctl/lib/libdaxctl.sym
@@ -55,4 +55,7 @@ LIBDAXCTL_6 {
 global:
 	daxctl_dev_get_ctx;
 	daxctl_dev_is_enabled;
+	daxctl_dev_disable;
+	daxctl_dev_enable_devdax;
+	daxctl_dev_enable_ram;
 } LIBDAXCTL_5;
diff --git a/daxctl/libdaxctl.h b/daxctl/libdaxctl.h
index e20ccb4..b80488e 100644
--- a/daxctl/libdaxctl.h
+++ b/daxctl/libdaxctl.h
@@ -69,6 +69,9 @@ int daxctl_dev_get_minor(struct daxctl_dev *dev);
 unsigned long long daxctl_dev_get_size(struct daxctl_dev *dev);
 struct daxctl_ctx *daxctl_dev_get_ctx(struct daxctl_dev *dev);
 int daxctl_dev_is_enabled(struct daxctl_dev *dev);
+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);
 
 #define daxctl_dev_foreach(region, dev) \
         for (dev = daxctl_dev_get_first(region); \
@@ -81,6 +84,12 @@ int daxctl_dev_is_enabled(struct daxctl_dev *dev);
              region != NULL; \
              region = daxctl_region_get_next(region))
 
+enum daxctl_dev_mode {
+	DAXCTL_DEV_MODE_UNKNOWN,
+	DAXCTL_DEV_MODE_RAM,
+	DAXCTL_DEV_MODE_DEVDAX,
+};
+
 #ifdef __cplusplus
 } /* extern "C" */
 #endif
-- 
2.20.1

_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [ndctl PATCH v4 04/10] libdaxctl: add interfaces to get/set the online state for a node
  2019-05-28 22:24 [ndctl PATCH v4 00/10] daxctl: add a new reconfigure-device command Vishal Verma
                   ` (2 preceding siblings ...)
  2019-05-28 22:24 ` [ndctl PATCH v4 03/10] libdaxctl: add interfaces to enable/disable devices Vishal Verma
@ 2019-05-28 22:24 ` Vishal Verma
  2019-05-29  3:18   ` Dan Williams
  2019-05-28 22:24 ` [ndctl PATCH v4 05/10] daxctl/list: add numa_node for device listings Vishal Verma
                   ` (5 subsequent siblings)
  9 siblings, 1 reply; 20+ messages in thread
From: Vishal Verma @ 2019-05-28 22:24 UTC (permalink / raw)
  To: linux-nvdimm; +Cc: Dave Hansen, Pavel Tatashin

In preparation for converting DAX devices for use as system-ram via the
kernel's 'kmem' facility, add libndctl helpers to manipulate the sysfs
interfaces to get the target_node of a DAX device, and to online,
offline, and query the state of hotplugged memory sections associated
with a given node.

This adds the following new interfaces:

  daxctl_dev_get_target_node
  daxctl_dev_online_node
  daxctl_dev_offline_node
  daxctl_dev_node_is_online

Cc: Pavel Tatashin <pasha.tatashin@soleen.com>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: Dan Williams <dan.j.williams@intel.com>
Signed-off-by: Vishal Verma <vishal.l.verma@intel.com>
---
 daxctl/lib/libdaxctl-private.h |   6 +
 daxctl/lib/libdaxctl.c         | 228 +++++++++++++++++++++++++++++++++
 daxctl/lib/libdaxctl.sym       |   4 +
 daxctl/libdaxctl.h             |   4 +
 4 files changed, 242 insertions(+)

diff --git a/daxctl/lib/libdaxctl-private.h b/daxctl/lib/libdaxctl-private.h
index e64d0a7..ef443aa 100644
--- a/daxctl/lib/libdaxctl-private.h
+++ b/daxctl/lib/libdaxctl-private.h
@@ -33,6 +33,11 @@ static const char *dax_modules[] = {
 	[DAXCTL_DEV_MODE_RAM] = "kmem",
 };
 
+enum node_state {
+	NODE_OFFLINE,
+	NODE_ONLINE,
+};
+
 /**
  * struct daxctl_region - container for dax_devices
  */
@@ -63,6 +68,7 @@ struct daxctl_dev {
 	struct kmod_module *module;
 	struct kmod_list *kmod_list;
 	struct daxctl_region *region;
+	int target_node;
 };
 
 static inline int check_kmod(struct kmod_ctx *kmod_ctx)
diff --git a/daxctl/lib/libdaxctl.c b/daxctl/lib/libdaxctl.c
index 2890f69..46dbd63 100644
--- a/daxctl/lib/libdaxctl.c
+++ b/daxctl/lib/libdaxctl.c
@@ -28,6 +28,7 @@
 #include "libdaxctl-private.h"
 
 static const char *attrs = "dax_region";
+static const char *node_base = "/sys/devices/system/node";
 
 static void free_region(struct daxctl_region *region, struct list_head *head);
 
@@ -393,6 +394,12 @@ static void *add_dax_dev(void *parent, int id, const char *daxdev_base)
 	if (rc == 0)
 		dev->kmod_list = to_module_list(ctx, buf);
 
+	sprintf(path, "%s/target_node", daxdev_base);
+	if (sysfs_read_attr(ctx, path, buf) == 0)
+		dev->target_node = strtol(buf, NULL, 0);
+	else
+		dev->target_node = -1;
+
 	daxctl_dev_foreach(region, dev_dup)
 		if (dev_dup->id == dev->id) {
 			free_dev(dev, NULL);
@@ -893,3 +900,224 @@ DAXCTL_EXPORT unsigned long long daxctl_dev_get_size(struct daxctl_dev *dev)
 {
 	return dev->size;
 }
+
+DAXCTL_EXPORT int daxctl_dev_get_target_node(struct daxctl_dev *dev)
+{
+	return dev->target_node;
+}
+
+static int online_one_memblock(struct daxctl_dev *dev, char *path)
+{
+	const char *devname = daxctl_dev_get_devname(dev);
+	struct daxctl_ctx *ctx = daxctl_dev_get_ctx(dev);
+	const char *mode = "online_movable";
+	char buf[SYSFS_ATTR_SIZE];
+	int rc;
+
+	rc = sysfs_read_attr(ctx, path, buf);
+	if (rc) {
+		err(ctx, "%s: Failed to read %s: %s\n",
+			devname, path, strerror(-rc));
+		return rc;
+	}
+
+	/*
+	 * if already online, possibly due to kernel config or a udev rule,
+	 * there is nothing to do and we can skip over the memblock
+	 */
+	if (strncmp(buf, "online", 6) == 0)
+		return 0;
+
+	rc = sysfs_write_attr_quiet(ctx, path, mode);
+	if (rc)
+		err(ctx, "%s: Failed to online %s: %s\n",
+			devname, path, strerror(-rc));
+	return rc;
+}
+
+static int offline_one_memblock(struct daxctl_dev *dev, char *path)
+{
+	const char *devname = daxctl_dev_get_devname(dev);
+	struct daxctl_ctx *ctx = daxctl_dev_get_ctx(dev);
+	const char *mode = "offline";
+	char buf[SYSFS_ATTR_SIZE];
+	int rc;
+
+	rc = sysfs_read_attr(ctx, path, buf);
+	if (rc) {
+		err(ctx, "%s: Failed to read %s: %s\n",
+			devname, path, strerror(-rc));
+		return rc;
+	}
+
+	/* if already offline, there is nothing to do */
+	if (strncmp(buf, "offline", 6) == 0)
+		return 0;
+
+	rc = sysfs_write_attr_quiet(ctx, path, mode);
+	if (rc)
+		err(ctx, "%s: Failed to offline %s: %s\n",
+			devname, path, strerror(-rc));
+	return rc;
+}
+
+static int daxctl_dev_node_set_state(struct daxctl_dev *dev,
+		enum node_state state)
+{
+	struct daxctl_ctx *ctx = daxctl_dev_get_ctx(dev);
+	int target_node, rc, changed = 0;
+	struct dirent *de;
+	char *node_path;
+	DIR *node_dir;
+
+	target_node = daxctl_dev_get_target_node(dev);
+	if (target_node < 0) {
+		err(ctx, "%s: Unable to get target node\n",
+			daxctl_dev_get_devname(dev));
+		return -ENXIO;
+	}
+
+	rc = asprintf(&node_path, "%s/node%d", node_base, target_node);
+	if (rc < 0)
+		return -ENOMEM;
+
+	node_dir = opendir(node_path);
+	if (!node_dir) {
+		rc = -errno;
+		goto out_path;
+	}
+
+	errno = 0;
+	while ((de = readdir(node_dir)) != NULL) {
+		char *mem_path;
+
+		if (strcmp(de->d_name, ".") == 0 ||
+				strcmp(de->d_name, "..") == 0)
+			continue;
+		if (strncmp(de->d_name, "memory", 6) == 0) {
+			rc = asprintf(&mem_path, "%s/%s/state",
+				node_path, de->d_name);
+			if (rc < 0) {
+				rc = -ENOMEM;
+				goto out_dir;
+			}
+			if (state == NODE_ONLINE)
+				rc = online_one_memblock(dev, mem_path);
+			else if (state == NODE_OFFLINE)
+				rc = offline_one_memblock(dev, mem_path);
+			else
+				rc = -EINVAL;
+			free(mem_path);
+			if (rc)
+				goto out_dir;
+			changed++;
+		}
+		errno = 0;
+	}
+	if (errno) {
+		rc = -errno;
+		goto out_dir;
+	}
+	rc = changed;
+
+out_dir:
+	closedir(node_dir);
+out_path:
+	free(node_path);
+	return rc;
+}
+
+DAXCTL_EXPORT int daxctl_dev_online_node(struct daxctl_dev *dev)
+{
+	return daxctl_dev_node_set_state(dev, NODE_ONLINE);
+}
+
+DAXCTL_EXPORT int daxctl_dev_offline_node(struct daxctl_dev *dev)
+{
+	return daxctl_dev_node_set_state(dev, NODE_OFFLINE);
+}
+
+static int memblock_is_online(struct daxctl_dev *dev, char *path)
+{
+	const char *devname = daxctl_dev_get_devname(dev);
+	struct daxctl_ctx *ctx = daxctl_dev_get_ctx(dev);
+	char buf[SYSFS_ATTR_SIZE];
+	int rc;
+
+	rc = sysfs_read_attr(ctx, path, buf);
+	if (rc) {
+		err(ctx, "%s: Failed to read %s: %s\n",
+			devname, path, strerror(-rc));
+		return rc;
+	}
+
+	if (strncmp(buf, "online", 6) == 0)
+		return 1;
+
+	return 0;
+}
+
+DAXCTL_EXPORT int daxctl_dev_node_is_online(struct daxctl_dev *dev)
+{
+	const char *devname = daxctl_dev_get_devname(dev);
+	struct daxctl_ctx *ctx = daxctl_dev_get_ctx(dev);
+	int target_node, rc, num_online = 0;
+	struct dirent *de;
+	char *node_path;
+	DIR *node_dir;
+
+	target_node = daxctl_dev_get_target_node(dev);
+	if (target_node < 0) {
+		err(ctx, "%s: Unable to get target node\n", devname);
+		return -ENXIO;
+	}
+
+	rc = asprintf(&node_path, "%s/node%d", node_base, target_node);
+	if (rc < 0)
+		return -ENOMEM;
+
+	node_dir = opendir(node_path);
+	if (!node_dir) {
+		rc = -errno;
+		goto out_path;
+	}
+
+	errno = 0;
+	while ((de = readdir(node_dir)) != NULL) {
+		char *mem_path;
+
+		if (strcmp(de->d_name, ".") == 0 ||
+				strcmp(de->d_name, "..") == 0)
+			continue;
+		if (strncmp(de->d_name, "memory", 6) == 0) {
+			rc = asprintf(&mem_path, "%s/%s/state",
+				node_path, de->d_name);
+			if (rc < 0) {
+				rc = -ENOMEM;
+				goto out_dir;
+			}
+			rc = memblock_is_online(dev, mem_path);
+			if (rc < 0) {
+				err(ctx, "%s: Unable to determine state: %s\n",
+					devname, mem_path);
+				goto out_dir;
+			}
+			if (rc > 0)
+				num_online++;
+			free(mem_path);
+		}
+		errno = 0;
+	}
+	if (errno) {
+		rc = -errno;
+		goto out_dir;
+	}
+	rc = num_online;
+
+out_dir:
+	closedir(node_dir);
+out_path:
+	free(node_path);
+	return rc;
+
+}
diff --git a/daxctl/lib/libdaxctl.sym b/daxctl/lib/libdaxctl.sym
index 19904a2..cc47ed6 100644
--- a/daxctl/lib/libdaxctl.sym
+++ b/daxctl/lib/libdaxctl.sym
@@ -54,8 +54,12 @@ global:
 LIBDAXCTL_6 {
 global:
 	daxctl_dev_get_ctx;
+	daxctl_dev_get_target_node;
 	daxctl_dev_is_enabled;
 	daxctl_dev_disable;
 	daxctl_dev_enable_devdax;
 	daxctl_dev_enable_ram;
+	daxctl_dev_online_node;
+	daxctl_dev_offline_node;
+	daxctl_dev_node_is_online;
 } LIBDAXCTL_5;
diff --git a/daxctl/libdaxctl.h b/daxctl/libdaxctl.h
index b80488e..db0d4ea 100644
--- a/daxctl/libdaxctl.h
+++ b/daxctl/libdaxctl.h
@@ -68,10 +68,14 @@ int daxctl_dev_get_major(struct daxctl_dev *dev);
 int daxctl_dev_get_minor(struct daxctl_dev *dev);
 unsigned long long daxctl_dev_get_size(struct daxctl_dev *dev);
 struct daxctl_ctx *daxctl_dev_get_ctx(struct daxctl_dev *dev);
+int daxctl_dev_get_target_node(struct daxctl_dev *dev);
 int daxctl_dev_is_enabled(struct daxctl_dev *dev);
 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_online_node(struct daxctl_dev *dev);
+int daxctl_dev_offline_node(struct daxctl_dev *dev);
+int daxctl_dev_node_is_online(struct daxctl_dev *dev);
 
 #define daxctl_dev_foreach(region, dev) \
         for (dev = daxctl_dev_get_first(region); \
-- 
2.20.1

_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [ndctl PATCH v4 05/10] daxctl/list: add numa_node for device listings
  2019-05-28 22:24 [ndctl PATCH v4 00/10] daxctl: add a new reconfigure-device command Vishal Verma
                   ` (3 preceding siblings ...)
  2019-05-28 22:24 ` [ndctl PATCH v4 04/10] libdaxctl: add interfaces to get/set the online state for a node Vishal Verma
@ 2019-05-28 22:24 ` Vishal Verma
  2019-05-29  3:22   ` Dan Williams
  2019-05-28 22:24 ` [ndctl PATCH v4 06/10] libdaxctl: add an interface to get the mode for a dax device Vishal Verma
                   ` (4 subsequent siblings)
  9 siblings, 1 reply; 20+ messages in thread
From: Vishal Verma @ 2019-05-28 22:24 UTC (permalink / raw)
  To: linux-nvdimm; +Cc: Dave Hansen, Pavel Tatashin

The kernel provides a 'target_node' attribute for dax devices. When
converting a dax device to the system-ram mode, the memory is hotplugged
into this numa node. It would be helpful to print this in device
listings so that it is easy for applications to detect the numa node to
which the new memory belongs.

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>
---
 util/json.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/util/json.c b/util/json.c
index babdc8c..b7ce719 100644
--- a/util/json.c
+++ b/util/json.c
@@ -271,6 +271,7 @@ struct json_object *util_daxctl_dev_to_json(struct daxctl_dev *dev,
 {
 	const char *devname = daxctl_dev_get_devname(dev);
 	struct json_object *jdev, *jobj;
+	int node;
 
 	jdev = json_object_new_object();
 	if (!devname || !jdev)
@@ -284,6 +285,13 @@ struct json_object *util_daxctl_dev_to_json(struct daxctl_dev *dev,
 	if (jobj)
 		json_object_object_add(jdev, "size", jobj);
 
+	node = daxctl_dev_get_target_node(dev);
+	if (node >= 0) {
+		jobj = json_object_new_int(node);
+		if (jobj)
+			json_object_object_add(jdev, "numa_node", jobj);
+	}
+
 	return jdev;
 }
 
-- 
2.20.1

_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [ndctl PATCH v4 06/10] libdaxctl: add an interface to get the mode for a dax device
  2019-05-28 22:24 [ndctl PATCH v4 00/10] daxctl: add a new reconfigure-device command Vishal Verma
                   ` (4 preceding siblings ...)
  2019-05-28 22:24 ` [ndctl PATCH v4 05/10] daxctl/list: add numa_node for device listings Vishal Verma
@ 2019-05-28 22:24 ` Vishal Verma
  2019-05-29 17:43   ` Dan Williams
  2019-05-28 22:24 ` [ndctl PATCH v4 07/10] daxctl: add a new reconfigure-device command Vishal Verma
                   ` (3 subsequent siblings)
  9 siblings, 1 reply; 20+ messages in thread
From: Vishal Verma @ 2019-05-28 22:24 UTC (permalink / raw)
  To: linux-nvdimm; +Cc: Dave Hansen, Pavel Tatashin

In preparation for a reconfigure-device command, add an interface to
retrieve the 'mode' of a dax device. This will allow the
reconfigure-device command (and via daxctl_dev_to_json()), also
daxctl-list) to print the mode on device listings via a list command or
immediately after a mode change.

Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: Dan Williams <dan.j.williams@intel.com>
Signed-off-by: Vishal Verma <vishal.l.verma@intel.com>
---
 daxctl/lib/libdaxctl.c   | 41 ++++++++++++++++++++++++++++++++++++++++
 daxctl/lib/libdaxctl.sym |  1 +
 daxctl/libdaxctl.h       |  1 +
 util/json.c              | 14 ++++++++++++++
 4 files changed, 57 insertions(+)

diff --git a/daxctl/lib/libdaxctl.c b/daxctl/lib/libdaxctl.c
index 46dbd63..9d23d12 100644
--- a/daxctl/lib/libdaxctl.c
+++ b/daxctl/lib/libdaxctl.c
@@ -12,6 +12,8 @@
  */
 #include <stdio.h>
 #include <errno.h>
+#include <limits.h>
+#include <libgen.h>
 #include <stdlib.h>
 #include <dirent.h>
 #include <unistd.h>
@@ -836,6 +838,45 @@ DAXCTL_EXPORT int daxctl_dev_disable(struct daxctl_dev *dev)
 	return 0;
 }
 
+DAXCTL_EXPORT enum daxctl_dev_mode daxctl_dev_get_mode(struct daxctl_dev *dev)
+{
+	const char *devname = daxctl_dev_get_devname(dev);
+	struct daxctl_ctx *ctx = daxctl_dev_get_ctx(dev);
+	int rc = DAXCTL_DEV_MODE_UNKNOWN;
+	char path[200];
+	const int len = sizeof(path);
+	char *mod_path, *mod_base;
+
+	if (!daxctl_dev_is_enabled(dev))
+		return rc;
+
+	/* dax-class model only has conventional devdax devices */
+	if (ctx->subsys != DAX_BUS)
+		return DAXCTL_DEV_MODE_DEVDAX;
+
+	if (snprintf(path, len, "%s/driver/module", dev->dev_path) >= len) {
+		err(ctx, "%s: buffer too small!\n", devname);
+		return -ENXIO;
+	}
+
+	mod_path = realpath(path, NULL);
+	if (!mod_path) {
+		rc = -errno;
+		err(ctx, "%s:  unable to determine module: %s\n", devname,
+			strerror(errno));
+		return rc;
+	}
+
+	mod_base = basename(mod_path);
+	if (strcmp(mod_base, dax_modules[DAXCTL_DEV_MODE_RAM]) == 0)
+		rc = DAXCTL_DEV_MODE_RAM;
+	else if (strcmp(mod_base, dax_modules[DAXCTL_DEV_MODE_DEVDAX]) == 0)
+		rc = DAXCTL_DEV_MODE_DEVDAX;
+
+	free(mod_path);
+	return rc;
+}
+
 DAXCTL_EXPORT struct daxctl_ctx *daxctl_dev_get_ctx(struct daxctl_dev *dev)
 {
 	return dev->region->ctx;
diff --git a/daxctl/lib/libdaxctl.sym b/daxctl/lib/libdaxctl.sym
index cc47ed6..d53976d 100644
--- a/daxctl/lib/libdaxctl.sym
+++ b/daxctl/lib/libdaxctl.sym
@@ -62,4 +62,5 @@ global:
 	daxctl_dev_online_node;
 	daxctl_dev_offline_node;
 	daxctl_dev_node_is_online;
+	daxctl_dev_get_mode;
 } LIBDAXCTL_5;
diff --git a/daxctl/libdaxctl.h b/daxctl/libdaxctl.h
index db0d4ea..4f9088f 100644
--- a/daxctl/libdaxctl.h
+++ b/daxctl/libdaxctl.h
@@ -76,6 +76,7 @@ int daxctl_dev_enable_ram(struct daxctl_dev *dev);
 int daxctl_dev_online_node(struct daxctl_dev *dev);
 int daxctl_dev_offline_node(struct daxctl_dev *dev);
 int daxctl_dev_node_is_online(struct daxctl_dev *dev);
+enum daxctl_dev_mode daxctl_dev_get_mode(struct daxctl_dev *dev);
 
 #define daxctl_dev_foreach(region, dev) \
         for (dev = daxctl_dev_get_first(region); \
diff --git a/util/json.c b/util/json.c
index b7ce719..4f13222 100644
--- a/util/json.c
+++ b/util/json.c
@@ -271,6 +271,7 @@ struct json_object *util_daxctl_dev_to_json(struct daxctl_dev *dev,
 {
 	const char *devname = daxctl_dev_get_devname(dev);
 	struct json_object *jdev, *jobj;
+	enum daxctl_dev_mode mode;
 	int node;
 
 	jdev = json_object_new_object();
@@ -292,6 +293,19 @@ struct json_object *util_daxctl_dev_to_json(struct daxctl_dev *dev,
 			json_object_object_add(jdev, "numa_node", jobj);
 	}
 
+	mode = daxctl_dev_get_mode(dev);
+	if (mode > 0) {
+		jobj = NULL;
+		if (mode == DAXCTL_DEV_MODE_RAM)
+			jobj = json_object_new_string("system-ram");
+		else if (mode == DAXCTL_DEV_MODE_DEVDAX)
+			jobj = json_object_new_string("devdax");
+		else
+			jobj = json_object_new_string("unknown");
+		if (jobj)
+			json_object_object_add(jdev, "mode", jobj);
+	}
+
 	return jdev;
 }
 
-- 
2.20.1

_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [ndctl PATCH v4 07/10] daxctl: add a new reconfigure-device command
  2019-05-28 22:24 [ndctl PATCH v4 00/10] daxctl: add a new reconfigure-device command Vishal Verma
                   ` (5 preceding siblings ...)
  2019-05-28 22:24 ` [ndctl PATCH v4 06/10] libdaxctl: add an interface to get the mode for a dax device Vishal Verma
@ 2019-05-28 22:24 ` Vishal Verma
  2019-05-28 22:24 ` [ndctl PATCH v4 08/10] Documentation/daxctl: add a man page for daxctl-reconfigure-device Vishal Verma
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 20+ messages in thread
From: Vishal Verma @ 2019-05-28 22:24 UTC (permalink / raw)
  To: linux-nvdimm; +Cc: Dave Hansen, Pavel Tatashin

Add a new command 'daxctl-reconfigure-device'. This is used to switch
the mode of a dax device between regular 'device_dax' and
'system-memory'. The command also uses the memory hotplug sysfs
interfaces to online the newly available memory when converting to
'system-ram', and to attempt to offline the memory when converting back
to a DAX device.

Cc: Pavel Tatashin <pasha.tatashin@soleen.com>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: Dan Williams <dan.j.williams@intel.com>
Signed-off-by: Vishal Verma <vishal.l.verma@intel.com>
---
 daxctl/Makefile.am |   2 +
 daxctl/builtin.h   |   1 +
 daxctl/daxctl.c    |   1 +
 daxctl/device.c    | 237 +++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 241 insertions(+)
 create mode 100644 daxctl/device.c

diff --git a/daxctl/Makefile.am b/daxctl/Makefile.am
index 94f73f9..66dcc7f 100644
--- a/daxctl/Makefile.am
+++ b/daxctl/Makefile.am
@@ -15,10 +15,12 @@ daxctl_SOURCES =\
 		daxctl.c \
 		list.c \
 		migrate.c \
+		device.c \
 		../util/json.c
 
 daxctl_LDADD =\
 	lib/libdaxctl.la \
 	../libutil.a \
 	$(UUID_LIBS) \
+	$(KMOD_LIBS) \
 	$(JSON_LIBS)
diff --git a/daxctl/builtin.h b/daxctl/builtin.h
index 00ef5e9..756ba2a 100644
--- a/daxctl/builtin.h
+++ b/daxctl/builtin.h
@@ -6,4 +6,5 @@
 struct daxctl_ctx;
 int cmd_list(int argc, const char **argv, struct daxctl_ctx *ctx);
 int cmd_migrate(int argc, const char **argv, struct daxctl_ctx *ctx);
+int cmd_reconfig_device(int argc, const char **argv, struct daxctl_ctx *ctx);
 #endif /* _DAXCTL_BUILTIN_H_ */
diff --git a/daxctl/daxctl.c b/daxctl/daxctl.c
index 2e41747..e1ba7b8 100644
--- a/daxctl/daxctl.c
+++ b/daxctl/daxctl.c
@@ -71,6 +71,7 @@ static struct cmd_struct commands[] = {
 	{ "list", .d_fn = cmd_list },
 	{ "help", .d_fn = cmd_help },
 	{ "migrate-device-model", .d_fn = cmd_migrate },
+	{ "reconfigure-device", .d_fn = cmd_reconfig_device },
 };
 
 int main(int argc, const char **argv)
diff --git a/daxctl/device.c b/daxctl/device.c
new file mode 100644
index 0000000..12644c5
--- /dev/null
+++ b/daxctl/device.c
@@ -0,0 +1,237 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2019 Intel Corporation. All rights reserved. */
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <limits.h>
+#include <util/json.h>
+#include <util/filter.h>
+#include <json-c/json.h>
+#include <daxctl/libdaxctl.h>
+#include <util/parse-options.h>
+#include <ccan/array_size/array_size.h>
+
+static struct {
+	const char *dev;
+	const char *mode;
+	int region_id;
+	bool no_online;
+	bool do_offline;
+	bool human;
+	bool verbose;
+} param = {
+	.region_id = -1,
+};
+
+static int dev_disable(struct daxctl_dev *dev)
+{
+	int rc;
+
+	if (!daxctl_dev_is_enabled(dev))
+		return 0;
+
+	rc = daxctl_dev_disable(dev);
+	if (rc)
+		fprintf(stderr, "%s: disable failed: %s\n",
+			daxctl_dev_get_devname(dev), strerror(-rc));
+
+	return rc;
+}
+
+static int reconfig_mode_ram(struct daxctl_dev *dev)
+{
+	const char *devname = daxctl_dev_get_devname(dev);
+	int rc;
+
+	rc = dev_disable(dev);
+	if (rc)
+		return rc;
+	rc = daxctl_dev_enable_ram(dev);
+	if (rc)
+		return rc;
+
+	if (param.no_online)
+		return 0;
+
+	rc = daxctl_dev_online_node(dev);
+	if (rc < 0) {
+		fprintf(stderr, "%s: unable to online memory: %s\n",
+			devname, strerror(-rc));
+		return rc;
+	}
+	if (param.verbose)
+		fprintf(stderr, "%s: onlined %d memory sections\n",
+			devname, rc);
+
+	return 0;
+}
+
+static int reconfig_mode_devdax(struct daxctl_dev *dev)
+{
+	const char *devname = daxctl_dev_get_devname(dev);
+	int rc;
+
+	if (param.do_offline) {
+		rc = daxctl_dev_offline_node(dev);
+		if (rc < 0) {
+			fprintf(stderr, "%s: unable to offline memory: %s\n",
+				devname, strerror(-rc));
+			return rc;
+		}
+		if (param.verbose)
+			fprintf(stderr, "%s: offlined %d memory sections\n",
+				devname, rc);
+	}
+
+	rc = daxctl_dev_node_is_online(dev);
+	if (rc < 0) {
+		fprintf(stderr, "%s: unable to determine node state: %s\n",
+			devname, strerror(-rc));
+		return rc;
+	}
+	if (rc > 0) {
+		if (param.verbose) {
+			fprintf(stderr, "%s: found %d memory sections online\n",
+				devname, rc);
+			fprintf(stderr, "%s: refusing to change modes\n",
+				devname);
+		}
+		return -EBUSY;
+	}
+
+	rc = dev_disable(dev);
+	if (rc)
+		return rc;
+
+	rc = daxctl_dev_enable_devdax(dev);
+	if (rc)
+		return rc;
+
+	return 0;
+}
+
+static int do_reconfig(struct daxctl_dev *dev, enum daxctl_dev_mode mode)
+{
+	int rc = 0;
+
+	switch (mode) {
+	case DAXCTL_DEV_MODE_RAM:
+		rc = reconfig_mode_ram(dev);
+		break;
+	case DAXCTL_DEV_MODE_DEVDAX:
+		rc = reconfig_mode_devdax(dev);
+		break;
+	default:
+		fprintf(stderr, "%s: unknown mode: %d\n",
+			daxctl_dev_get_devname(dev), mode);
+		rc = -EINVAL;
+	}
+
+	return rc;
+}
+
+int cmd_reconfig_device(int argc, const char **argv, struct daxctl_ctx *ctx)
+{
+	const struct option options[] = {
+		OPT_INTEGER('r', "region", &param.region_id,
+				"restrict to the given region"),
+		OPT_STRING('m', "mode", &param.mode, "mode",
+				"mode to switch the device to"),
+		OPT_BOOLEAN('N', "no-online", &param.no_online,
+				"don't auto-online memory sections"),
+		OPT_BOOLEAN('O', "attempt-offline", &param.do_offline,
+				"attempt to offline memory sections"),
+		OPT_BOOLEAN('u', "human", &param.human,
+				"use human friendly number formats"),
+		OPT_BOOLEAN('v', "verbose", &param.verbose,
+				"emit more debug messages"),
+		OPT_END(),
+	};
+	const char * const u[] = {
+		"daxctl reconfigure-device [<options>] <device> ...",
+		NULL
+	};
+	enum daxctl_dev_mode mode = DAXCTL_DEV_MODE_UNKNOWN;
+	struct json_object *jdevs = json_object_new_array();
+	struct daxctl_region *region;
+	struct json_object *jdev;
+	int i, rc = 0, done = 0;
+	unsigned long flags = 0;
+	struct daxctl_dev *dev;
+
+        argc = parse_options(argc, argv, options, u, 0);
+	if (argc == 0)
+		usage_with_options(u, options);
+	for (i = 0; i < argc; i++) {
+		if (strcmp(argv[i], "all") == 0) {
+			argv[0] = "all";
+			argc = 1;
+			break;
+		}
+	}
+
+	if (param.human)
+		flags |= UTIL_JSON_HUMAN;
+
+	if (!param.mode) {
+		fprintf(stderr, "error: a 'mode' option is required\n");
+		usage_with_options(u, options);
+	}
+	if (strcmp(param.mode, "system-ram") == 0) {
+		mode = DAXCTL_DEV_MODE_RAM;
+		if (param.do_offline) {
+			fprintf(stderr,
+				"can't --attempt-offline for system-ram mode\n");
+			return -EINVAL;
+		}
+	} else if (strcmp(param.mode, "devdax") == 0) {
+		mode = DAXCTL_DEV_MODE_DEVDAX;
+		if (param.no_online) {
+			fprintf(stderr,
+				"can't --no-online for devdax mode\n");
+			return -EINVAL;
+		}
+	}
+
+	daxctl_region_foreach(ctx, region) {
+		if (param.region_id >= 0 && param.region_id
+				!= daxctl_region_get_id(region))
+			continue;
+
+		daxctl_dev_foreach(region, dev) {
+			bool dev_requested = false;
+
+			for (i = 0; i < argc; i++) {
+				if ((strcmp(daxctl_dev_get_devname(dev),
+						argv[i]) == 0) ||
+						(strcmp(argv[i], "all") == 0)) {
+					dev_requested = true;
+					break;
+				}
+			}
+			if (dev_requested) {
+				rc = do_reconfig(dev, mode);
+				if (rc < 0)
+					goto out_err;
+				done++;
+				if (!jdevs)
+					continue;
+				jdev = util_daxctl_dev_to_json(dev, flags);
+				if (jdev)
+					json_object_array_add(jdevs, jdev);
+			}
+		}
+	}
+	if (jdevs)
+		util_display_json_array(stdout, jdevs, flags);
+
+	fprintf(stderr, "reconfigured %d device%s\n", done,
+		done == 1 ? "" : "s");
+	return 0;
+
+out_err:
+	fprintf(stderr, "error reconfiguring %s: %s\n",
+		daxctl_dev_get_devname(dev), strerror(-rc));
+	return rc;
+}
-- 
2.20.1

_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [ndctl PATCH v4 08/10] Documentation/daxctl: add a man page for daxctl-reconfigure-device
  2019-05-28 22:24 [ndctl PATCH v4 00/10] daxctl: add a new reconfigure-device command Vishal Verma
                   ` (6 preceding siblings ...)
  2019-05-28 22:24 ` [ndctl PATCH v4 07/10] daxctl: add a new reconfigure-device command Vishal Verma
@ 2019-05-28 22:24 ` Vishal Verma
  2019-05-29 17:49   ` Dan Williams
  2019-05-28 22:24 ` [ndctl PATCH v4 09/10] contrib/ndctl: fix region-id completions for daxctl Vishal Verma
  2019-05-28 22:24 ` [ndctl PATCH v4 10/10] contrib/ndctl: add bash-completion for daxctl-reconfigure-device Vishal Verma
  9 siblings, 1 reply; 20+ messages in thread
From: Vishal Verma @ 2019-05-28 22:24 UTC (permalink / raw)
  To: linux-nvdimm; +Cc: Dave Hansen, Pavel Tatashin

Add a man page describing the new daxctl-reconfigure-device command.

Cc: Pavel Tatashin <pasha.tatashin@soleen.com>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: Dan Williams <dan.j.williams@intel.com>
Signed-off-by: Vishal Verma <vishal.l.verma@intel.com>
---
 Documentation/daxctl/Makefile.am              |   3 +-
 .../daxctl/daxctl-reconfigure-device.txt      | 118 ++++++++++++++++++
 2 files changed, 120 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/daxctl/daxctl-reconfigure-device.txt

diff --git a/Documentation/daxctl/Makefile.am b/Documentation/daxctl/Makefile.am
index 6aba035..715fbad 100644
--- a/Documentation/daxctl/Makefile.am
+++ b/Documentation/daxctl/Makefile.am
@@ -28,7 +28,8 @@ endif
 man1_MANS = \
 	daxctl.1 \
 	daxctl-list.1 \
-	daxctl-migrate-device-model.1
+	daxctl-migrate-device-model.1 \
+	daxctl-reconfigure-device.1
 
 CLEANFILES = $(man1_MANS)
 
diff --git a/Documentation/daxctl/daxctl-reconfigure-device.txt b/Documentation/daxctl/daxctl-reconfigure-device.txt
new file mode 100644
index 0000000..b575091
--- /dev/null
+++ b/Documentation/daxctl/daxctl-reconfigure-device.txt
@@ -0,0 +1,118 @@
+// SPDX-License-Identifier: GPL-2.0
+
+daxctl-reconfigure-device(1)
+============================
+
+NAME
+----
+daxctl-reconfigure-device - Reconfigure a dax device into a different mode
+
+SYNOPSIS
+--------
+[verse]
+'daxctl reconfigure-device' <dax0.0> [<dax1.0>...<daxY.Z>] [<options>]
+
+EXAMPLES
+--------
+
+* Reconfigure dax0.0 to system-ram mode, don't online the memory
+----
+# daxctl reconfigure-device --mode=system-ram --no-online dax0.0
+[
+  {
+    "chardev":"dax0.0",
+    "size":16777216000,
+    "numa_node":2,
+    "mode":"system-ram"
+  }
+]
+----
+
+* Reconfigure dax0.0 to devdax mode, attempt to offline the memory
+----
+# daxctl reconfigure-device --human --mode=devdax --attempt-offline dax0.0
+{
+  "chardev":"dax0.0",
+  "size":"15.63 GiB (16.78 GB)",
+  "numa_node":2,
+  "mode":"devdax"
+}
+----
+
+* Reconfigure all dax devices on region0 to system-ram mode
+----
+# daxctl reconfigure-device --mode=system-ram --region=0 all
+[
+  {
+    "chardev":"dax0.0",
+    "size":16777216000,
+    "numa_node":2,
+    "mode":"system-ram"
+  },
+  {
+    "chardev":"dax0.1",
+    "size":16777216000,
+    "numa_node":3,
+    "mode":"system-ram"
+  }
+]
+----
+
+DESCRIPTION
+-----------
+
+Reconfigure the operational mode of a dax device. This can be used to convert
+a regular 'devdax' mode device to the 'system-ram' mode which allows for the dax
+range to be hot-plugged into the system as regular memory.
+
+NOTE: This is a destructive operation. Any data on the dax device *will* be
+lost.
+
+OPTIONS
+-------
+-r::
+--region=::
+	Restrict the reconfigure operation to devices belonging to the
+	specified region(s). A device-dax region is a contiguous range of
+	memory that hosts one or more /dev/daxX.Y devices, where X is the
+	region id and Y is the device instance id.
+
+-m::
+--mode=::
+	Specify the mode to which the dax device(s) should be reconfigured.
+	- "system-ram": hotplug the device into system memory.
+
+	- "devdax": switch to the normal "device dax" mode. This may not work
+	  on kernels prior to v5.2. In such a case, a reboot is the only way to
+	  switch back to 'devdax' mode.
+
+-N::
+--no-online::
+	By default, memory sections provided by system-ram devices will be
+	brought online automatically and immediately. Use this option to
+	disable the automatic onlining behavior.
+
+-O::
+--attempt-offline::
+	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.
+
+-u::
+--human::
+	By default the command will output machine-friendly raw-integer
+	data. Instead, with this flag, numbers representing storage size
+	will be formatted as human readable strings with units, other
+	fields are converted to hexadecimal strings.
+
+-v::
+--verbose::
+	Emit more debug messages for the reconfiguration process
+
+include::../copyright.txt[]
+
+SEE ALSO
+--------
+linkdaxctl:daxctl-list[1]
-- 
2.20.1

_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [ndctl PATCH v4 09/10] contrib/ndctl: fix region-id completions for daxctl
  2019-05-28 22:24 [ndctl PATCH v4 00/10] daxctl: add a new reconfigure-device command Vishal Verma
                   ` (7 preceding siblings ...)
  2019-05-28 22:24 ` [ndctl PATCH v4 08/10] Documentation/daxctl: add a man page for daxctl-reconfigure-device Vishal Verma
@ 2019-05-28 22:24 ` Vishal Verma
  2019-05-28 22:24 ` [ndctl PATCH v4 10/10] contrib/ndctl: add bash-completion for daxctl-reconfigure-device Vishal Verma
  9 siblings, 0 replies; 20+ messages in thread
From: Vishal Verma @ 2019-05-28 22:24 UTC (permalink / raw)
  To: linux-nvdimm; +Cc: Dave Hansen, Pavel Tatashin

The completion helpers for daxctl assumed the region arguments for
specifying daxctl regions were the same as ndctl regions, i.e.
"regionX". This is not true - daxctl region arguments are a simple
numeric 'id'.

Add a new helper __daxctl_get_regions() to complete daxctl region IDs
properly.

While at it, fix a useless use of 'echo' in __daxctl_get_devs() and
quoting in __daxctl_comp_options()

Fixes: d6790a32f32c ("daxctl: Add bash-completion")
Signed-off-by: Vishal Verma <vishal.l.verma@intel.com>
---
 contrib/ndctl | 14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/contrib/ndctl b/contrib/ndctl
index 396a344..cacee2d 100755
--- a/contrib/ndctl
+++ b/contrib/ndctl
@@ -531,8 +531,14 @@ _ndctl()
 
 __daxctl_get_devs()
 {
-	local opts="--devices $*"
-	echo "$(daxctl list $opts | grep -E "^\s*\"chardev\":" | cut -d\" -f4)"
+	local opts=("--devices" "$*")
+	daxctl list "${opts[@]}" | grep -E "^\s*\"chardev\":" | cut -d'"' -f4
+}
+
+__daxctl_get_regions()
+{
+	local opts=("--regions" "$*")
+	daxctl list "${opts[@]}" | grep -E "^\s*\"id\":" | grep -Eo "[0-9]+"
 }
 
 __daxctlcomp()
@@ -561,10 +567,10 @@ __daxctl_comp_options()
 		local cur_arg=${cur##*=}
 		case $cur_subopt in
 		--region)
-			opts=$(__ndctl_get_regions -i)
+			opts="$(__daxctl_get_regions -i)"
 			;;
 		--dev)
-			opts=$(__daxctl_get_devs -i)
+			opts="$(__daxctl_get_devs -i)"
 			;;
 		*)
 			return
-- 
2.20.1

_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [ndctl PATCH v4 10/10] contrib/ndctl: add bash-completion for daxctl-reconfigure-device
  2019-05-28 22:24 [ndctl PATCH v4 00/10] daxctl: add a new reconfigure-device command Vishal Verma
                   ` (8 preceding siblings ...)
  2019-05-28 22:24 ` [ndctl PATCH v4 09/10] contrib/ndctl: fix region-id completions for daxctl Vishal Verma
@ 2019-05-28 22:24 ` Vishal Verma
  9 siblings, 0 replies; 20+ messages in thread
From: Vishal Verma @ 2019-05-28 22:24 UTC (permalink / raw)
  To: linux-nvdimm; +Cc: Dave Hansen, Pavel Tatashin

Add bash completion helpers for the new daxctl-reconfigure-device
command.

Cc: Dan Williams <dan.j.williams@intel.com>
Signed-off-by: Vishal Verma <vishal.l.verma@intel.com>
---
 contrib/ndctl | 20 +++++++++++++++++---
 1 file changed, 17 insertions(+), 3 deletions(-)

diff --git a/contrib/ndctl b/contrib/ndctl
index cacee2d..1850343 100755
--- a/contrib/ndctl
+++ b/contrib/ndctl
@@ -547,7 +547,7 @@ __daxctlcomp()
 
 	COMPREPLY=( $( compgen -W "$1" -- "$2" ) )
 	for cword in "${COMPREPLY[@]}"; do
-		if [[ "$cword" == @(--region|--dev) ]]; then
+		if [[ "$cword" == @(--region|--dev|--mode) ]]; then
 			COMPREPLY[$i]="${cword}="
 		else
 			COMPREPLY[$i]="${cword} "
@@ -572,6 +572,9 @@ __daxctl_comp_options()
 		--dev)
 			opts="$(__daxctl_get_devs -i)"
 			;;
+		--mode)
+			opts="system-ram devdax"
+			;;
 		*)
 			return
 			;;
@@ -582,8 +585,19 @@ __daxctl_comp_options()
 
 __daxctl_comp_non_option_args()
 {
-	# there aren't any commands that accept non option arguments yet
-	return
+	local subcmd=$1
+	local cur=$2
+	local opts
+
+	case $subcmd in
+	reconfigure-device)
+		opts="$(__daxctl_get_devs -i) all"
+		;;
+	*)
+		return
+		;;
+	esac
+	__daxctlcomp "$opts" "$cur"
 }
 
 __daxctl_main()
-- 
2.20.1

_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* Re: [ndctl PATCH v4 02/10] libdaxctl: cache 'subsystem' in daxctl_ctx
  2019-05-28 22:24 ` [ndctl PATCH v4 02/10] libdaxctl: cache 'subsystem' in daxctl_ctx Vishal Verma
@ 2019-05-29  0:27   ` Dan Williams
  2019-05-29 17:25     ` Verma, Vishal L
  0 siblings, 1 reply; 20+ messages in thread
From: Dan Williams @ 2019-05-29  0:27 UTC (permalink / raw)
  To: Vishal Verma; +Cc: Dave Hansen, Pavel Tatashin, linux-nvdimm

On Tue, May 28, 2019 at 3:24 PM Vishal Verma <vishal.l.verma@intel.com> wrote:
>
> The 'DAX subsystem' in effect is determined at region or device init
> time, and dictates the sysfs base paths for all device/region
> operations. In preparation for adding bind/unbind functionality, cache
> the subsystem as determined at init time in the library context.

I'm missing how this patch determines the subsystem at init time? ...more below.

>
> Cc: Dan Williams <dan.j.williams@intel.com>
> Signed-off-by: Vishal Verma <vishal.l.verma@intel.com>
> ---
>  daxctl/lib/libdaxctl.c | 12 ++++++++++--
>  1 file changed, 10 insertions(+), 2 deletions(-)
>
> diff --git a/daxctl/lib/libdaxctl.c b/daxctl/lib/libdaxctl.c
> index 70f896b..f8f5b8c 100644
> --- a/daxctl/lib/libdaxctl.c
> +++ b/daxctl/lib/libdaxctl.c
> @@ -46,6 +46,7 @@ struct daxctl_ctx {
>         void *userdata;
>         int regions_init;
>         struct list_head regions;
> +       enum dax_subsystem subsys;
>  };
>
>  /**
> @@ -96,6 +97,7 @@ DAXCTL_EXPORT int daxctl_new(struct daxctl_ctx **ctx)
>         dbg(c, "log_priority=%d\n", c->ctx.log_priority);
>         *ctx = c;
>         list_head_init(&c->regions);
> +       c->subsys = DAX_UNKNOWN;
>
>         return 0;
>  }
> @@ -454,14 +456,18 @@ static void dax_devices_init(struct daxctl_region *region)
>         for (i = 0; i < ARRAY_SIZE(dax_subsystems); i++) {
>                 char *region_path;
>
> -               if (i == DAX_BUS)
> +               if (i == DAX_BUS) {
>                         region_path = region->region_path;
> -               else if (i == DAX_CLASS) {
> +                       if (ctx->subsys == DAX_UNKNOWN)
> +                               ctx->subsys = DAX_BUS;
> +               } else if (i == DAX_CLASS) {
>                         if (asprintf(&region_path, "%s/dax",
>                                                 region->region_path) < 0) {
>                                 dbg(ctx, "region path alloc fail\n");
>                                 continue;
>                         }
> +                       if (ctx->subsys == DAX_UNKNOWN)
> +                               ctx->subsys = DAX_CLASS;
>                 } else
>                         continue;
>                 sysfs_device_parse(ctx, region_path, daxdev_fmt, region,

dax_devices_init() is just blindly looping through both device models
attempting to add devices. If this patch was detecting device-models I
would expect it would be looking for the first successful
sysfs_device_parse() to judge which of those blind shots actually
worked.
_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [ndctl PATCH v4 03/10] libdaxctl: add interfaces to enable/disable devices
  2019-05-28 22:24 ` [ndctl PATCH v4 03/10] libdaxctl: add interfaces to enable/disable devices Vishal Verma
@ 2019-05-29  2:13   ` Dan Williams
  2019-05-29 16:55     ` Verma, Vishal L
  0 siblings, 1 reply; 20+ messages in thread
From: Dan Williams @ 2019-05-29  2:13 UTC (permalink / raw)
  To: Vishal Verma; +Cc: Dave Hansen, Pavel Tatashin, linux-nvdimm

On Tue, May 28, 2019 at 3:24 PM Vishal Verma <vishal.l.verma@intel.com> wrote:
>
> Add new libdaxctl interfaces to disable a device_dax based devices, and
> to enable it into a given mode. The modes available are 'device_dax',

Does this mode name get exposed to the command line interface? If
"yes", I think this should be 'devdax' to match the ndctl namespace
mode, or just 'device', but otherwise no "_" in any command-line
interfaces. Otherwise I think the module names are an internal
implementation detail of the kernel ABI and need not leak further than
the libdaxctl to kernel interface.

> and 'system-ram', where device_dax is the normal device DAX mode used
> via a character device, and 'system-ram' uses the kernel's 'kmem'
> facility to hotplug the device into the system's memory space, and can
> be used as normal system memory.
>
> This adds the following new interfaces:
>
>   daxctl_dev_disable;
>   daxctl_dev_enable_devdax;
>   daxctl_dev_enable_ram;
>
> Cc: Dave Hansen <dave.hansen@linux.intel.com>
> Cc: Dan Williams <dan.j.williams@intel.com>
> Signed-off-by: Vishal Verma <vishal.l.verma@intel.com>
_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [ndctl PATCH v4 04/10] libdaxctl: add interfaces to get/set the online state for a node
  2019-05-28 22:24 ` [ndctl PATCH v4 04/10] libdaxctl: add interfaces to get/set the online state for a node Vishal Verma
@ 2019-05-29  3:18   ` Dan Williams
  0 siblings, 0 replies; 20+ messages in thread
From: Dan Williams @ 2019-05-29  3:18 UTC (permalink / raw)
  To: Vishal Verma; +Cc: Dave Hansen, Pavel Tatashin, linux-nvdimm

On Tue, May 28, 2019 at 3:24 PM Vishal Verma <vishal.l.verma@intel.com> wrote:
>
> In preparation for converting DAX devices for use as system-ram via the
> kernel's 'kmem' facility, add libndctl helpers to manipulate the sysfs
> interfaces to get the target_node of a DAX device, and to online,
> offline, and query the state of hotplugged memory sections associated
> with a given node.
>
> This adds the following new interfaces:
>
>   daxctl_dev_get_target_node
>   daxctl_dev_online_node
>   daxctl_dev_offline_node
>   daxctl_dev_node_is_online

I'm wondering if these should s/node/memory/, or even create a
sub-object called 'memory' to start a new object-verb relationship.
I.e. daxctl_dev_get_memory() +
daxctl_memory_{online,offline,is_online}.

Otherwise functionality looks good to me, just one note about asprintf below:

>
> Cc: Pavel Tatashin <pasha.tatashin@soleen.com>
> Cc: Dave Hansen <dave.hansen@linux.intel.com>
> Cc: Dan Williams <dan.j.williams@intel.com>
> Signed-off-by: Vishal Verma <vishal.l.verma@intel.com>
> ---
>  daxctl/lib/libdaxctl-private.h |   6 +
>  daxctl/lib/libdaxctl.c         | 228 +++++++++++++++++++++++++++++++++
>  daxctl/lib/libdaxctl.sym       |   4 +
>  daxctl/libdaxctl.h             |   4 +
>  4 files changed, 242 insertions(+)
>
> diff --git a/daxctl/lib/libdaxctl-private.h b/daxctl/lib/libdaxctl-private.h
> index e64d0a7..ef443aa 100644
> --- a/daxctl/lib/libdaxctl-private.h
> +++ b/daxctl/lib/libdaxctl-private.h
> @@ -33,6 +33,11 @@ static const char *dax_modules[] = {
>         [DAXCTL_DEV_MODE_RAM] = "kmem",
>  };
>
> +enum node_state {
> +       NODE_OFFLINE,
> +       NODE_ONLINE,
> +};
> +
>  /**
>   * struct daxctl_region - container for dax_devices
>   */
> @@ -63,6 +68,7 @@ struct daxctl_dev {
>         struct kmod_module *module;
>         struct kmod_list *kmod_list;
>         struct daxctl_region *region;
> +       int target_node;
>  };
>
>  static inline int check_kmod(struct kmod_ctx *kmod_ctx)
> diff --git a/daxctl/lib/libdaxctl.c b/daxctl/lib/libdaxctl.c
> index 2890f69..46dbd63 100644
> --- a/daxctl/lib/libdaxctl.c
> +++ b/daxctl/lib/libdaxctl.c
> @@ -28,6 +28,7 @@
>  #include "libdaxctl-private.h"
>
>  static const char *attrs = "dax_region";
> +static const char *node_base = "/sys/devices/system/node";
>
>  static void free_region(struct daxctl_region *region, struct list_head *head);
>
> @@ -393,6 +394,12 @@ static void *add_dax_dev(void *parent, int id, const char *daxdev_base)
>         if (rc == 0)
>                 dev->kmod_list = to_module_list(ctx, buf);
>
> +       sprintf(path, "%s/target_node", daxdev_base);
> +       if (sysfs_read_attr(ctx, path, buf) == 0)
> +               dev->target_node = strtol(buf, NULL, 0);
> +       else
> +               dev->target_node = -1;
> +
>         daxctl_dev_foreach(region, dev_dup)
>                 if (dev_dup->id == dev->id) {
>                         free_dev(dev, NULL);
> @@ -893,3 +900,224 @@ DAXCTL_EXPORT unsigned long long daxctl_dev_get_size(struct daxctl_dev *dev)
>  {
>         return dev->size;
>  }
> +
> +DAXCTL_EXPORT int daxctl_dev_get_target_node(struct daxctl_dev *dev)
> +{
> +       return dev->target_node;
> +}
> +
> +static int online_one_memblock(struct daxctl_dev *dev, char *path)
> +{
> +       const char *devname = daxctl_dev_get_devname(dev);
> +       struct daxctl_ctx *ctx = daxctl_dev_get_ctx(dev);
> +       const char *mode = "online_movable";
> +       char buf[SYSFS_ATTR_SIZE];
> +       int rc;
> +
> +       rc = sysfs_read_attr(ctx, path, buf);
> +       if (rc) {
> +               err(ctx, "%s: Failed to read %s: %s\n",
> +                       devname, path, strerror(-rc));
> +               return rc;
> +       }
> +
> +       /*
> +        * if already online, possibly due to kernel config or a udev rule,
> +        * there is nothing to do and we can skip over the memblock
> +        */
> +       if (strncmp(buf, "online", 6) == 0)
> +               return 0;
> +
> +       rc = sysfs_write_attr_quiet(ctx, path, mode);
> +       if (rc)
> +               err(ctx, "%s: Failed to online %s: %s\n",
> +                       devname, path, strerror(-rc));
> +       return rc;
> +}
> +
> +static int offline_one_memblock(struct daxctl_dev *dev, char *path)
> +{
> +       const char *devname = daxctl_dev_get_devname(dev);
> +       struct daxctl_ctx *ctx = daxctl_dev_get_ctx(dev);
> +       const char *mode = "offline";
> +       char buf[SYSFS_ATTR_SIZE];
> +       int rc;
> +
> +       rc = sysfs_read_attr(ctx, path, buf);
> +       if (rc) {
> +               err(ctx, "%s: Failed to read %s: %s\n",
> +                       devname, path, strerror(-rc));
> +               return rc;
> +       }
> +
> +       /* if already offline, there is nothing to do */
> +       if (strncmp(buf, "offline", 6) == 0)
> +               return 0;
> +
> +       rc = sysfs_write_attr_quiet(ctx, path, mode);
> +       if (rc)
> +               err(ctx, "%s: Failed to offline %s: %s\n",
> +                       devname, path, strerror(-rc));
> +       return rc;
> +}
> +
> +static int daxctl_dev_node_set_state(struct daxctl_dev *dev,
> +               enum node_state state)
> +{
> +       struct daxctl_ctx *ctx = daxctl_dev_get_ctx(dev);
> +       int target_node, rc, changed = 0;
> +       struct dirent *de;
> +       char *node_path;
> +       DIR *node_dir;
> +
> +       target_node = daxctl_dev_get_target_node(dev);
> +       if (target_node < 0) {
> +               err(ctx, "%s: Unable to get target node\n",
> +                       daxctl_dev_get_devname(dev));
> +               return -ENXIO;
> +       }
> +
> +       rc = asprintf(&node_path, "%s/node%d", node_base, target_node);
> +       if (rc < 0)
> +               return -ENOMEM;

To date the only usage of asprintf for path names has been in object
constructor / init paths. This tries to guarantee that all userspace
-ENOMEM errors are bypassed once you have the object established. The
thinking here is to simplify any future audit where we need to
guarantee APIs that don't allocate memory, but also to make all
allocate/free management symmetrical with object create/destroy.
_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [ndctl PATCH v4 05/10] daxctl/list: add numa_node for device listings
  2019-05-28 22:24 ` [ndctl PATCH v4 05/10] daxctl/list: add numa_node for device listings Vishal Verma
@ 2019-05-29  3:22   ` Dan Williams
  0 siblings, 0 replies; 20+ messages in thread
From: Dan Williams @ 2019-05-29  3:22 UTC (permalink / raw)
  To: Vishal Verma; +Cc: Dave Hansen, Pavel Tatashin, linux-nvdimm

On Tue, May 28, 2019 at 3:24 PM Vishal Verma <vishal.l.verma@intel.com> wrote:
>
> The kernel provides a 'target_node' attribute for dax devices. When
> converting a dax device to the system-ram mode, the memory is hotplugged
> into this numa node. It would be helpful to print this in device
> listings so that it is easy for applications to detect the numa node to
> which the new memory belongs.
>
> 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>
> ---
>  util/json.c | 8 ++++++++
>  1 file changed, 8 insertions(+)
>
> diff --git a/util/json.c b/util/json.c
> index babdc8c..b7ce719 100644
> --- a/util/json.c
> +++ b/util/json.c
> @@ -271,6 +271,7 @@ struct json_object *util_daxctl_dev_to_json(struct daxctl_dev *dev,
>  {
>         const char *devname = daxctl_dev_get_devname(dev);
>         struct json_object *jdev, *jobj;
> +       int node;
>
>         jdev = json_object_new_object();
>         if (!devname || !jdev)
> @@ -284,6 +285,13 @@ struct json_object *util_daxctl_dev_to_json(struct daxctl_dev *dev,
>         if (jobj)
>                 json_object_object_add(jdev, "size", jobj);
>
> +       node = daxctl_dev_get_target_node(dev);
> +       if (node >= 0) {
> +               jobj = json_object_new_int(node);
> +               if (jobj)
> +                       json_object_object_add(jdev, "numa_node", jobj);

I think this should be named 'target_node' to not be confused with the
typical 'numa_node' attribute of a device that indicates closest cpu
node. This also collides with the 'numa_node' attribute that is
already emitted at the namespace level.

  {
    "dev":"namespace1.0",
    "mode":"devdax",
    "map":"dev",
    "size":134232408064,
    "uuid":"e6613922-80e9-49f9-ace8-961def867d32",
    "raw_uuid":"b79ce059-e33d-4a90-90ec-06d6786b3644",
    "daxregion":{
      "id":1,
      "size":134232408064,
      "align":2097152,
      "devices":[
        {
          "chardev":"dax1.0",
          "size":134232408064
        }
      ]
    },
    "align":2097152,
    "numa_node":0
_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [ndctl PATCH v4 03/10] libdaxctl: add interfaces to enable/disable devices
  2019-05-29  2:13   ` Dan Williams
@ 2019-05-29 16:55     ` Verma, Vishal L
  0 siblings, 0 replies; 20+ messages in thread
From: Verma, Vishal L @ 2019-05-29 16:55 UTC (permalink / raw)
  To: Williams, Dan J; +Cc: dave.hansen, pasha.tatashin, linux-nvdimm


On Tue, 2019-05-28 at 19:13 -0700, Dan Williams wrote:
> On Tue, May 28, 2019 at 3:24 PM Vishal Verma <vishal.l.verma@intel.com> wrote:
> > Add new libdaxctl interfaces to disable a device_dax based devices, and
> > to enable it into a given mode. The modes available are 'device_dax',
> 
> Does this mode name get exposed to the command line interface? If
> "yes", I think this should be 'devdax' to match the ndctl namespace
> mode, or just 'device', but otherwise no "_" in any command-line
> interfaces. Otherwise I think the module names are an internal
> implementation detail of the kernel ABI and need not leak further than
> the libdaxctl to kernel interface.

The command line option is just 'devdax', but good catch in that I will
fix up this commit message.

> 
> > and 'system-ram', where device_dax is the normal device DAX mode used
> > via a character device, and 'system-ram' uses the kernel's 'kmem'
> > facility to hotplug the device into the system's memory space, and can
> > be used as normal system memory.
> > 
> > This adds the following new interfaces:
> > 
> >   daxctl_dev_disable;
> >   daxctl_dev_enable_devdax;
> >   daxctl_dev_enable_ram;
> > 
> > Cc: Dave Hansen <dave.hansen@linux.intel.com>
> > Cc: Dan Williams <dan.j.williams@intel.com>
> > Signed-off-by: Vishal Verma <vishal.l.verma@intel.com>

_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [ndctl PATCH v4 02/10] libdaxctl: cache 'subsystem' in daxctl_ctx
  2019-05-29  0:27   ` Dan Williams
@ 2019-05-29 17:25     ` Verma, Vishal L
  0 siblings, 0 replies; 20+ messages in thread
From: Verma, Vishal L @ 2019-05-29 17:25 UTC (permalink / raw)
  To: Williams, Dan J; +Cc: dave.hansen, pasha.tatashin, linux-nvdimm

On Tue, 2019-05-28 at 17:27 -0700, Dan Williams wrote:
> On Tue, May 28, 2019 at 3:24 PM Vishal Verma <vishal.l.verma@intel.com> wrote:
> > The 'DAX subsystem' in effect is determined at region or device init
> > time, and dictates the sysfs base paths for all device/region
> > operations. In preparation for adding bind/unbind functionality, cache
> > the subsystem as determined at init time in the library context.
> 
> I'm missing how this patch determines the subsystem at init time? ...more below.
> 
[..]

> >  }
> > @@ -454,14 +456,18 @@ static void dax_devices_init(struct daxctl_region *region)
> >         for (i = 0; i < ARRAY_SIZE(dax_subsystems); i++) {
> >                 char *region_path;
> > 
> > -               if (i == DAX_BUS)
> > +               if (i == DAX_BUS) {
> >                         region_path = region->region_path;
> > -               else if (i == DAX_CLASS) {
> > +                       if (ctx->subsys == DAX_UNKNOWN)
> > +                               ctx->subsys = DAX_BUS;
> > +               } else if (i == DAX_CLASS) {
> >                         if (asprintf(&region_path, "%s/dax",
> >                                                 region->region_path) < 0) {
> >                                 dbg(ctx, "region path alloc fail\n");
> >                                 continue;
> >                         }
> > +                       if (ctx->subsys == DAX_UNKNOWN)
> > +                               ctx->subsys = DAX_CLASS;
> >                 } else
> >                         continue;
> >                 sysfs_device_parse(ctx, region_path, daxdev_fmt, region,
> 
> dax_devices_init() is just blindly looping through both device models
> attempting to add devices. If this patch was detecting device-models I
> would expect it would be looking for the first successful
> sysfs_device_parse() to judge which of those blind shots actually
> worked.

I see - I was definitely misunderstanding how this worked. I'll fix up
for v5, essentially something like:

-               sysfs_device_parse(ctx, region_path, daxdev_fmt, region,
-                               add_dax_dev);
+               if (sysfs_device_parse(ctx, region_path, daxdev_fmt, region,
+                               add_dax_dev) == 0)
+                       ctx->subsys = i;



_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [ndctl PATCH v4 06/10] libdaxctl: add an interface to get the mode for a dax device
  2019-05-28 22:24 ` [ndctl PATCH v4 06/10] libdaxctl: add an interface to get the mode for a dax device Vishal Verma
@ 2019-05-29 17:43   ` Dan Williams
  0 siblings, 0 replies; 20+ messages in thread
From: Dan Williams @ 2019-05-29 17:43 UTC (permalink / raw)
  To: Vishal Verma; +Cc: Dave Hansen, Pavel Tatashin, linux-nvdimm

On Tue, May 28, 2019 at 3:24 PM Vishal Verma <vishal.l.verma@intel.com> wrote:
>
> In preparation for a reconfigure-device command, add an interface to
> retrieve the 'mode' of a dax device. This will allow the
> reconfigure-device command (and via daxctl_dev_to_json()), also
> daxctl-list) to print the mode on device listings via a list command or
> immediately after a mode change.
>
> Cc: Dave Hansen <dave.hansen@linux.intel.com>
> Cc: Dan Williams <dan.j.williams@intel.com>
> Signed-off-by: Vishal Verma <vishal.l.verma@intel.com>

Hmm, if we add a daxctl_dev_get_memory() helper to retrieve a context
for doing kmem-related operations could that be a stand-in for
daxctl_dev_get_mode()? I.e. "if (!daxctl_dev_get_memory())
is_devdax..."

I also think it's ok to treat disabled device instances as devdax mode
as "unknown" will just increase user anxiety.
_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [ndctl PATCH v4 08/10] Documentation/daxctl: add a man page for daxctl-reconfigure-device
  2019-05-28 22:24 ` [ndctl PATCH v4 08/10] Documentation/daxctl: add a man page for daxctl-reconfigure-device Vishal Verma
@ 2019-05-29 17:49   ` Dan Williams
  2019-05-29 18:04     ` Verma, Vishal L
  0 siblings, 1 reply; 20+ messages in thread
From: Dan Williams @ 2019-05-29 17:49 UTC (permalink / raw)
  To: Vishal Verma; +Cc: Dave Hansen, Pavel Tatashin, linux-nvdimm

On Tue, May 28, 2019 at 3:24 PM Vishal Verma <vishal.l.verma@intel.com> wrote:
>
> Add a man page describing the new daxctl-reconfigure-device command.
>
> Cc: Pavel Tatashin <pasha.tatashin@soleen.com>
> Cc: Dave Hansen <dave.hansen@linux.intel.com>
> Cc: Dan Williams <dan.j.williams@intel.com>
> Signed-off-by: Vishal Verma <vishal.l.verma@intel.com>
> ---
>  Documentation/daxctl/Makefile.am              |   3 +-
>  .../daxctl/daxctl-reconfigure-device.txt      | 118 ++++++++++++++++++
>  2 files changed, 120 insertions(+), 1 deletion(-)
>  create mode 100644 Documentation/daxctl/daxctl-reconfigure-device.txt
[..]
> +-N::
> +--no-online::
> +       By default, memory sections provided by system-ram devices will be
> +       brought online automatically and immediately. Use this option to
> +       disable the automatic onlining behavior.

With a --no-online option it feels like we also need a "daxctl
online-memory" command to hot-add the memory range associated with the
given dax device. Otherwise, this looks good to me.
_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [ndctl PATCH v4 08/10] Documentation/daxctl: add a man page for daxctl-reconfigure-device
  2019-05-29 17:49   ` Dan Williams
@ 2019-05-29 18:04     ` Verma, Vishal L
  0 siblings, 0 replies; 20+ messages in thread
From: Verma, Vishal L @ 2019-05-29 18:04 UTC (permalink / raw)
  To: Williams, Dan J; +Cc: dave.hansen, pasha.tatashin, linux-nvdimm


On Wed, 2019-05-29 at 10:49 -0700, Dan Williams wrote:
> On Tue, May 28, 2019 at 3:24 PM Vishal Verma <vishal.l.verma@intel.com
> > wrote:
> > Add a man page describing the new daxctl-reconfigure-device command.
> > 
> > Cc: Pavel Tatashin <pasha.tatashin@soleen.com>
> > Cc: Dave Hansen <dave.hansen@linux.intel.com>
> > Cc: Dan Williams <dan.j.williams@intel.com>
> > Signed-off-by: Vishal Verma <vishal.l.verma@intel.com>
> > ---
> >  Documentation/daxctl/Makefile.am              |   3 +-
> >  .../daxctl/daxctl-reconfigure-device.txt      | 118
> > ++++++++++++++++++
> >  2 files changed, 120 insertions(+), 1 deletion(-)
> >  create mode 100644 Documentation/daxctl/daxctl-reconfigure-
> > device.txt
> [..]
> > +-N::
> > +--no-online::
> > +       By default, memory sections provided by system-ram devices
> > will be
> > +       brought online automatically and immediately. Use this
> > option to
> > +       disable the automatic onlining behavior.
> 
> With a --no-online option it feels like we also need a "daxctl
> online-memory" command to hot-add the memory range associated with the
> given dax device. Otherwise, this looks good to me.

Yes good idea, I'll add a command for that. Would we also then need a
complementary offline-memory command? For someone that might want to
split the offlining step from the mode change? I can't imagine a use
case for it..
_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm

^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2019-05-29 18:04 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-05-28 22:24 [ndctl PATCH v4 00/10] daxctl: add a new reconfigure-device command Vishal Verma
2019-05-28 22:24 ` [ndctl PATCH v4 01/10] libdaxctl: add interfaces in support of device modes Vishal Verma
2019-05-28 22:24 ` [ndctl PATCH v4 02/10] libdaxctl: cache 'subsystem' in daxctl_ctx Vishal Verma
2019-05-29  0:27   ` Dan Williams
2019-05-29 17:25     ` Verma, Vishal L
2019-05-28 22:24 ` [ndctl PATCH v4 03/10] libdaxctl: add interfaces to enable/disable devices Vishal Verma
2019-05-29  2:13   ` Dan Williams
2019-05-29 16:55     ` Verma, Vishal L
2019-05-28 22:24 ` [ndctl PATCH v4 04/10] libdaxctl: add interfaces to get/set the online state for a node Vishal Verma
2019-05-29  3:18   ` Dan Williams
2019-05-28 22:24 ` [ndctl PATCH v4 05/10] daxctl/list: add numa_node for device listings Vishal Verma
2019-05-29  3:22   ` Dan Williams
2019-05-28 22:24 ` [ndctl PATCH v4 06/10] libdaxctl: add an interface to get the mode for a dax device Vishal Verma
2019-05-29 17:43   ` Dan Williams
2019-05-28 22:24 ` [ndctl PATCH v4 07/10] daxctl: add a new reconfigure-device command Vishal Verma
2019-05-28 22:24 ` [ndctl PATCH v4 08/10] Documentation/daxctl: add a man page for daxctl-reconfigure-device Vishal Verma
2019-05-29 17:49   ` Dan Williams
2019-05-29 18:04     ` Verma, Vishal L
2019-05-28 22:24 ` [ndctl PATCH v4 09/10] contrib/ndctl: fix region-id completions for daxctl Vishal Verma
2019-05-28 22:24 ` [ndctl PATCH v4 10/10] contrib/ndctl: add bash-completion for daxctl-reconfigure-device Vishal Verma

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).