Some users may want additional control over the state in which memory gets onlined - specifically, controlling the 'movable' aspect of the resulting memory blocks.
Until now, libdaxctl only brought up memory in the 'movable' state. Add a new interface to online memory in the non-movable state. Link: https://github.com/pmem/ndctl/issues/110 Cc: Ben Olson <[email protected]> Cc: Dave Hansen <[email protected]> Cc: Dan Williams <[email protected]> Signed-off-by: Vishal Verma <[email protected]> --- daxctl/lib/libdaxctl-private.h | 6 +++++ daxctl/lib/libdaxctl.c | 45 ++++++++++++++++++++++++++++------ daxctl/lib/libdaxctl.sym | 1 + daxctl/libdaxctl.h | 1 + 4 files changed, 46 insertions(+), 7 deletions(-) diff --git a/daxctl/lib/libdaxctl-private.h b/daxctl/lib/libdaxctl-private.h index 82939bb..3e0457f 100644 --- a/daxctl/lib/libdaxctl-private.h +++ b/daxctl/lib/libdaxctl-private.h @@ -42,6 +42,7 @@ static const char *dax_modules[] = { enum memory_op { MEM_SET_OFFLINE, MEM_SET_ONLINE, + MEM_SET_ONLINE_NO_MOVABLE, MEM_IS_ONLINE, MEM_COUNT, MEM_FIND_ZONE, @@ -65,6 +66,11 @@ static const char *zone_strings[] = { [MEM_ZONE_MOVABLE] = "Movable", }; +static const char *state_strings[] = { + [MEM_ZONE_NORMAL] = "online", + [MEM_ZONE_MOVABLE] = "online_movable", +}; + /** * struct daxctl_region - container for dax_devices */ diff --git a/daxctl/lib/libdaxctl.c b/daxctl/lib/libdaxctl.c index 5a7e37c..d913807 100644 --- a/daxctl/lib/libdaxctl.c +++ b/daxctl/lib/libdaxctl.c @@ -1080,11 +1080,10 @@ static int memblock_is_online(struct daxctl_memory *mem, char *memblock) } static int online_one_memblock(struct daxctl_memory *mem, char *memblock, - int *status) + enum memory_zones zone, int *status) { struct daxctl_dev *dev = daxctl_memory_get_dev(mem); struct daxctl_ctx *ctx = daxctl_dev_get_ctx(dev); - const char *mode = "online_movable"; int len = mem->buf_len, rc; char *path = mem->mem_buf; const char *node_path; @@ -1101,7 +1100,14 @@ static int online_one_memblock(struct daxctl_memory *mem, char *memblock, if (rc) return rc; - rc = sysfs_write_attr_quiet(ctx, path, mode); + switch (zone) { + case MEM_ZONE_MOVABLE: + case MEM_ZONE_NORMAL: + rc = sysfs_write_attr_quiet(ctx, path, state_strings[zone]); + break; + default: + rc = -EINVAL; + } if (rc) { /* * If the block got onlined, potentially by some other agent, @@ -1266,7 +1272,11 @@ static int op_for_one_memblock(struct daxctl_memory *mem, char *memblock, switch (op) { case MEM_SET_ONLINE: - return online_one_memblock(mem, memblock, status); + return online_one_memblock(mem, memblock, MEM_ZONE_MOVABLE, + status); + case MEM_SET_ONLINE_NO_MOVABLE: + return online_one_memblock(mem, memblock, MEM_ZONE_NORMAL, + status); case MEM_SET_OFFLINE: return offline_one_memblock(mem, memblock); case MEM_IS_ONLINE: @@ -1344,14 +1354,25 @@ out_dir: /* * daxctl_memory_online() will online to ZONE_MOVABLE by default */ -DAXCTL_EXPORT int daxctl_memory_online(struct daxctl_memory *mem) +static int daxctl_memory_online_with_zone(struct daxctl_memory *mem, + enum memory_zones zone) { struct daxctl_dev *dev = daxctl_memory_get_dev(mem); const char *devname = daxctl_dev_get_devname(dev); struct daxctl_ctx *ctx = daxctl_dev_get_ctx(dev); int rc; - rc = daxctl_memory_op(mem, MEM_SET_ONLINE); + switch (zone) { + case MEM_ZONE_MOVABLE: + rc = daxctl_memory_op(mem, MEM_SET_ONLINE); + break; + case MEM_ZONE_NORMAL: + rc = daxctl_memory_op(mem, MEM_SET_ONLINE_NO_MOVABLE); + break; + default: + err(ctx, "%s: BUG: invalid zone for onlining\n", devname); + rc = -EINVAL; + } if (rc) return rc; @@ -1364,7 +1385,7 @@ DAXCTL_EXPORT int daxctl_memory_online(struct daxctl_memory *mem) rc = daxctl_memory_op(mem, MEM_FIND_ZONE); if (rc) return rc; - if (mem->zone != MEM_ZONE_MOVABLE) { + if (mem->zone != zone) { err(ctx, "%s:\n WARNING: detected a race while onlining memory\n" " Some memory may not be in the expected zone. It is\n" @@ -1378,6 +1399,16 @@ DAXCTL_EXPORT int daxctl_memory_online(struct daxctl_memory *mem) return rc; } +DAXCTL_EXPORT int daxctl_memory_online(struct daxctl_memory *mem) +{ + return daxctl_memory_online_with_zone(mem, MEM_ZONE_MOVABLE); +} + +DAXCTL_EXPORT int daxctl_memory_online_no_movable(struct daxctl_memory *mem) +{ + return daxctl_memory_online_with_zone(mem, MEM_ZONE_NORMAL); +} + DAXCTL_EXPORT int daxctl_memory_offline(struct daxctl_memory *mem) { return daxctl_memory_op(mem, MEM_SET_OFFLINE); diff --git a/daxctl/lib/libdaxctl.sym b/daxctl/lib/libdaxctl.sym index 041d9a5..87d0236 100644 --- a/daxctl/lib/libdaxctl.sym +++ b/daxctl/lib/libdaxctl.sym @@ -73,4 +73,5 @@ global: LIBDAXCTL_7 { global: daxctl_memory_is_movable; + daxctl_memory_online_no_movable; } LIBDAXCTL_6; diff --git a/daxctl/libdaxctl.h b/daxctl/libdaxctl.h index 8d5f8b7..6c545e1 100644 --- a/daxctl/libdaxctl.h +++ b/daxctl/libdaxctl.h @@ -85,6 +85,7 @@ int daxctl_memory_offline(struct daxctl_memory *mem); int daxctl_memory_is_online(struct daxctl_memory *mem); int daxctl_memory_num_sections(struct daxctl_memory *mem); int daxctl_memory_is_movable(struct daxctl_memory *mem); +int daxctl_memory_online_no_movable(struct daxctl_memory *mem); #define daxctl_dev_foreach(region, dev) \ for (dev = daxctl_dev_get_first(region); \ -- 2.20.1 _______________________________________________ Linux-nvdimm mailing list -- [email protected] To unsubscribe send an email to [email protected]
