Add the following APIs to be able to iterate over a dynamic device-dax mapping list, as well as fetching each of the mapping attributes.
Signed-off-by: Joao Martins <[email protected]> --- daxctl/lib/libdaxctl-private.h | 8 ++++ daxctl/lib/libdaxctl.c | 91 +++++++++++++++++++++++++++++++++++++++++- daxctl/lib/libdaxctl.sym | 6 +++ daxctl/libdaxctl.h | 12 ++++++ 4 files changed, 116 insertions(+), 1 deletion(-) diff --git a/daxctl/lib/libdaxctl-private.h b/daxctl/lib/libdaxctl-private.h index b307a8bc9438..6d05aefbeda0 100644 --- a/daxctl/lib/libdaxctl-private.h +++ b/daxctl/lib/libdaxctl-private.h @@ -91,6 +91,12 @@ struct daxctl_region { struct list_head devices; }; +struct daxctl_mapping { + struct daxctl_dev *dev; + unsigned long long pgoff, start, end; + struct list_node list; +}; + struct daxctl_dev { int id, major, minor; void *dev_buf; @@ -104,6 +110,8 @@ struct daxctl_dev { struct daxctl_region *region; struct daxctl_memory *mem; int target_node; + int num_mappings; + struct list_head mappings; }; struct daxctl_memory { diff --git a/daxctl/lib/libdaxctl.c b/daxctl/lib/libdaxctl.c index c62e04bcdfd1..506cf4b93236 100644 --- a/daxctl/lib/libdaxctl.c +++ b/daxctl/lib/libdaxctl.c @@ -524,7 +524,8 @@ static void *add_dax_dev(void *parent, int id, const char *daxdev_base) free(path); return dev_dup; } - + dev->num_mappings = -1; + list_head_init(&dev->mappings); list_add(®ion->devices, &dev->list); free(path); return dev; @@ -1148,6 +1149,94 @@ DAXCTL_EXPORT unsigned long daxctl_memory_get_block_size(struct daxctl_memory *m return mem->block_size; } +static void mappings_init(struct daxctl_dev *dev) +{ + struct daxctl_ctx *ctx = daxctl_dev_get_ctx(dev); + char buf[SYSFS_ATTR_SIZE]; + char *path = dev->dev_buf; + int i; + + if (dev->num_mappings != -1) + return; + + dev->num_mappings = 0; + for (;;) { + struct daxctl_mapping *mapping; + unsigned long long pgoff, start, end; + + i = dev->num_mappings; + mapping = calloc(1, sizeof(*mapping)); + if (!mapping) { + err(ctx, "%s: mapping%u allocation failure\n", + daxctl_dev_get_devname(dev), i); + continue; + } + + sprintf(path, "%s/mapping%d/start", dev->dev_path, i); + if (sysfs_read_attr(ctx, path, buf) < 0) { + free(mapping); + break; + } + start = strtoull(buf, NULL, 0); + + sprintf(path, "%s/mapping%d/end", dev->dev_path, i); + if (sysfs_read_attr(ctx, path, buf) < 0) { + free(mapping); + break; + } + end = strtoull(buf, NULL, 0); + + sprintf(path, "%s/mapping%d/page_offset", dev->dev_path, i); + if (sysfs_read_attr(ctx, path, buf) < 0) { + free(mapping); + break; + } + pgoff = strtoull(buf, NULL, 0); + + mapping->dev = dev; + mapping->start = start; + mapping->end = end; + mapping->pgoff = pgoff; + + dev->num_mappings++; + list_add(&dev->mappings, &mapping->list); + } +} + +DAXCTL_EXPORT struct daxctl_mapping *daxctl_mapping_get_first(struct daxctl_dev *dev) +{ + mappings_init(dev); + + return list_top(&dev->mappings, struct daxctl_mapping, list); +} + +DAXCTL_EXPORT struct daxctl_mapping *daxctl_mapping_get_next(struct daxctl_mapping *mapping) +{ + struct daxctl_dev *dev = mapping->dev; + + return list_next(&dev->mappings, mapping, list); +} + +DAXCTL_EXPORT unsigned long long daxctl_mapping_get_start(struct daxctl_mapping *mapping) +{ + return mapping->start; +} + +DAXCTL_EXPORT unsigned long long daxctl_mapping_get_end(struct daxctl_mapping *mapping) +{ + return mapping->end; +} + +DAXCTL_EXPORT unsigned long long daxctl_mapping_get_offset(struct daxctl_mapping *mapping) +{ + return mapping->pgoff; +} + +DAXCTL_EXPORT unsigned long long daxctl_mapping_get_size(struct daxctl_mapping *mapping) +{ + return mapping->end - mapping->start + 1; +} + static int memblock_is_online(struct daxctl_memory *mem, char *memblock) { struct daxctl_dev *dev = daxctl_memory_get_dev(mem); diff --git a/daxctl/lib/libdaxctl.sym b/daxctl/lib/libdaxctl.sym index c3d08179c9fd..08362b683678 100644 --- a/daxctl/lib/libdaxctl.sym +++ b/daxctl/lib/libdaxctl.sym @@ -83,4 +83,10 @@ global: daxctl_region_destroy_dev; daxctl_dev_get_align; daxctl_dev_set_align; + daxctl_mapping_get_first; + daxctl_mapping_get_next; + daxctl_mapping_get_start; + daxctl_mapping_get_end; + daxctl_mapping_get_offset; + daxctl_mapping_get_size; } LIBDAXCTL_7; diff --git a/daxctl/libdaxctl.h b/daxctl/libdaxctl.h index b0bb5d78d357..f94a72fed85b 100644 --- a/daxctl/libdaxctl.h +++ b/daxctl/libdaxctl.h @@ -103,6 +103,18 @@ int daxctl_memory_online_no_movable(struct daxctl_memory *mem); region != NULL; \ region = daxctl_region_get_next(region)) +struct daxctl_mapping; +struct daxctl_mapping *daxctl_mapping_get_first(struct daxctl_dev *dev); +struct daxctl_mapping *daxctl_mapping_get_next(struct daxctl_mapping *mapping); +#define daxctl_mapping_foreach(dev, mapping) \ + for (mapping = daxctl_mapping_get_first(dev); \ + mapping != NULL; \ + mapping = daxctl_mapping_get_next(mapping)) +unsigned long long daxctl_mapping_get_start(struct daxctl_mapping *mapping); +unsigned long long daxctl_mapping_get_end(struct daxctl_mapping *mapping); +unsigned long long daxctl_mapping_get_offset(struct daxctl_mapping *mapping); +unsigned long long daxctl_mapping_get_size(struct daxctl_mapping *mapping); + #ifdef __cplusplus } /* extern "C" */ #endif -- 1.8.3.1 _______________________________________________ Linux-nvdimm mailing list -- [email protected] To unsubscribe send an email to [email protected]
