diff options
Diffstat (limited to 'drivers/nvdimm')
-rw-r--r-- | drivers/nvdimm/btt.c | 17 | ||||
-rw-r--r-- | drivers/nvdimm/btt_devs.c | 6 | ||||
-rw-r--r-- | drivers/nvdimm/bus.c | 4 | ||||
-rw-r--r-- | drivers/nvdimm/dax_devs.c | 4 | ||||
-rw-r--r-- | drivers/nvdimm/dimm_devs.c | 17 | ||||
-rw-r--r-- | drivers/nvdimm/namespace_devs.c | 19 | ||||
-rw-r--r-- | drivers/nvdimm/pfn_devs.c | 4 | ||||
-rw-r--r-- | drivers/nvdimm/virtio_pmem.c | 36 |
8 files changed, 74 insertions, 33 deletions
diff --git a/drivers/nvdimm/btt.c b/drivers/nvdimm/btt.c index d5593b0dc7..bb3726b622 100644 --- a/drivers/nvdimm/btt.c +++ b/drivers/nvdimm/btt.c @@ -16,6 +16,7 @@ #include <linux/fs.h> #include <linux/nd.h> #include <linux/backing-dev.h> +#include <linux/cleanup.h> #include "btt.h" #include "nd.h" @@ -847,23 +848,20 @@ static int discover_arenas(struct btt *btt) { int ret = 0; struct arena_info *arena; - struct btt_sb *super; size_t remaining = btt->rawsize; u64 cur_nlba = 0; size_t cur_off = 0; int num_arenas = 0; - super = kzalloc(sizeof(*super), GFP_KERNEL); + struct btt_sb *super __free(kfree) = kzalloc(sizeof(*super), GFP_KERNEL); if (!super) return -ENOMEM; while (remaining) { /* Alloc memory for arena */ arena = alloc_arena(btt, 0, 0, 0); - if (!arena) { - ret = -ENOMEM; - goto out_super; - } + if (!arena) + return -ENOMEM; arena->infooff = cur_off; ret = btt_info_read(arena, super); @@ -919,14 +917,11 @@ static int discover_arenas(struct btt *btt) btt->nlba = cur_nlba; btt->init_state = INIT_READY; - kfree(super); return ret; out: kfree(arena); free_arenas(btt); - out_super: - kfree(super); return ret; } @@ -986,7 +981,7 @@ static int btt_arena_write_layout(struct arena_info *arena) if (!super) return -ENOMEM; - strncpy(super->signature, BTT_SIG, BTT_SIG_LEN); + strscpy(super->signature, BTT_SIG, sizeof(super->signature)); export_uuid(super->uuid, nd_btt->uuid); export_uuid(super->parent_uuid, parent_uuid); super->flags = cpu_to_le32(arena->flags); @@ -1550,7 +1545,7 @@ static void btt_blk_cleanup(struct btt *btt) * @rawsize: raw size in bytes of the backing device * @lbasize: lba size of the backing device * @uuid: A uuid for the backing device - this is stored on media - * @maxlane: maximum number of parallel requests the device can handle + * @nd_region: &struct nd_region for the REGION device * * Initialize a Block Translation Table on a backing device to provide * single sector power fail atomicity. diff --git a/drivers/nvdimm/btt_devs.c b/drivers/nvdimm/btt_devs.c index fabbb31f2c..497fd434a6 100644 --- a/drivers/nvdimm/btt_devs.c +++ b/drivers/nvdimm/btt_devs.c @@ -19,7 +19,7 @@ static void nd_btt_release(struct device *dev) dev_dbg(dev, "trace\n"); nd_detach_ndns(&nd_btt->dev, &nd_btt->ndns); - ida_simple_remove(&nd_region->btt_ida, nd_btt->id); + ida_free(&nd_region->btt_ida, nd_btt->id); kfree(nd_btt->uuid); kfree(nd_btt); } @@ -191,7 +191,7 @@ static struct device *__nd_btt_create(struct nd_region *nd_region, if (!nd_btt) return NULL; - nd_btt->id = ida_simple_get(&nd_region->btt_ida, 0, 0, GFP_KERNEL); + nd_btt->id = ida_alloc(&nd_region->btt_ida, GFP_KERNEL); if (nd_btt->id < 0) goto out_nd_btt; @@ -217,7 +217,7 @@ static struct device *__nd_btt_create(struct nd_region *nd_region, return dev; out_put_id: - ida_simple_remove(&nd_region->btt_ida, nd_btt->id); + ida_free(&nd_region->btt_ida, nd_btt->id); out_nd_btt: kfree(nd_btt); diff --git a/drivers/nvdimm/bus.c b/drivers/nvdimm/bus.c index 5852fe2905..ef3d0f8331 100644 --- a/drivers/nvdimm/bus.c +++ b/drivers/nvdimm/bus.c @@ -285,7 +285,7 @@ static void nvdimm_bus_release(struct device *dev) struct nvdimm_bus *nvdimm_bus; nvdimm_bus = container_of(dev, struct nvdimm_bus, dev); - ida_simple_remove(&nd_ida, nvdimm_bus->id); + ida_free(&nd_ida, nvdimm_bus->id); kfree(nvdimm_bus); } @@ -342,7 +342,7 @@ struct nvdimm_bus *nvdimm_bus_register(struct device *parent, INIT_LIST_HEAD(&nvdimm_bus->list); INIT_LIST_HEAD(&nvdimm_bus->mapping_list); init_waitqueue_head(&nvdimm_bus->wait); - nvdimm_bus->id = ida_simple_get(&nd_ida, 0, 0, GFP_KERNEL); + nvdimm_bus->id = ida_alloc(&nd_ida, GFP_KERNEL); if (nvdimm_bus->id < 0) { kfree(nvdimm_bus); return NULL; diff --git a/drivers/nvdimm/dax_devs.c b/drivers/nvdimm/dax_devs.c index 3bd61f2457..6b4922de30 100644 --- a/drivers/nvdimm/dax_devs.c +++ b/drivers/nvdimm/dax_devs.c @@ -18,7 +18,7 @@ static void nd_dax_release(struct device *dev) dev_dbg(dev, "trace\n"); nd_detach_ndns(dev, &nd_pfn->ndns); - ida_simple_remove(&nd_region->dax_ida, nd_pfn->id); + ida_free(&nd_region->dax_ida, nd_pfn->id); kfree(nd_pfn->uuid); kfree(nd_dax); } @@ -55,7 +55,7 @@ static struct nd_dax *nd_dax_alloc(struct nd_region *nd_region) return NULL; nd_pfn = &nd_dax->nd_pfn; - nd_pfn->id = ida_simple_get(&nd_region->dax_ida, 0, 0, GFP_KERNEL); + nd_pfn->id = ida_alloc(&nd_region->dax_ida, GFP_KERNEL); if (nd_pfn->id < 0) { kfree(nd_dax); return NULL; diff --git a/drivers/nvdimm/dimm_devs.c b/drivers/nvdimm/dimm_devs.c index 1273873582..21498d461f 100644 --- a/drivers/nvdimm/dimm_devs.c +++ b/drivers/nvdimm/dimm_devs.c @@ -53,7 +53,9 @@ static int validate_dimm(struct nvdimm_drvdata *ndd) /** * nvdimm_init_nsarea - determine the geometry of a dimm's namespace area - * @nvdimm: dimm to initialize + * @ndd: dimm to initialize + * + * Returns: %0 if the area is already valid, -errno on error */ int nvdimm_init_nsarea(struct nvdimm_drvdata *ndd) { @@ -194,7 +196,7 @@ static void nvdimm_release(struct device *dev) { struct nvdimm *nvdimm = to_nvdimm(dev); - ida_simple_remove(&dimm_ida, nvdimm->id); + ida_free(&dimm_ida, nvdimm->id); kfree(nvdimm); } @@ -592,7 +594,7 @@ struct nvdimm *__nvdimm_create(struct nvdimm_bus *nvdimm_bus, if (!nvdimm) return NULL; - nvdimm->id = ida_simple_get(&dimm_ida, 0, 0, GFP_KERNEL); + nvdimm->id = ida_alloc(&dimm_ida, GFP_KERNEL); if (nvdimm->id < 0) { kfree(nvdimm); return NULL; @@ -722,6 +724,9 @@ static unsigned long dpa_align(struct nd_region *nd_region) * contiguous unallocated dpa range. * @nd_region: constrain available space check to this reference region * @nd_mapping: container of dpa-resource-root + labels + * + * Returns: %0 if there is an alignment error, otherwise the max + * unallocated dpa range */ resource_size_t nd_pmem_max_contiguous_dpa(struct nd_region *nd_region, struct nd_mapping *nd_mapping) @@ -767,6 +772,8 @@ resource_size_t nd_pmem_max_contiguous_dpa(struct nd_region *nd_region, * * Validate that a PMEM label, if present, aligns with the start of an * interleave set. + * + * Returns: %0 if there is an alignment error, otherwise the unallocated dpa */ resource_size_t nd_pmem_available_dpa(struct nd_region *nd_region, struct nd_mapping *nd_mapping) @@ -836,8 +843,10 @@ struct resource *nvdimm_allocate_dpa(struct nvdimm_drvdata *ndd, /** * nvdimm_allocated_dpa - sum up the dpa currently allocated to this label_id - * @nvdimm: container of dpa-resource-root + labels + * @ndd: container of dpa-resource-root + labels * @label_id: dpa resource name of the form pmem-<human readable uuid> + * + * Returns: sum of the dpa allocated to the label_id */ resource_size_t nvdimm_allocated_dpa(struct nvdimm_drvdata *ndd, struct nd_label_id *label_id) diff --git a/drivers/nvdimm/namespace_devs.c b/drivers/nvdimm/namespace_devs.c index 07177eadc5..d6d558f94d 100644 --- a/drivers/nvdimm/namespace_devs.c +++ b/drivers/nvdimm/namespace_devs.c @@ -27,7 +27,7 @@ static void namespace_pmem_release(struct device *dev) struct nd_region *nd_region = to_nd_region(dev->parent); if (nspm->id >= 0) - ida_simple_remove(&nd_region->ns_ida, nspm->id); + ida_free(&nd_region->ns_ida, nspm->id); kfree(nspm->alt_name); kfree(nspm->uuid); kfree(nspm); @@ -71,6 +71,8 @@ static int is_namespace_uuid_busy(struct device *dev, void *data) * nd_is_uuid_unique - verify that no other namespace has @uuid * @dev: any device on a nvdimm_bus * @uuid: uuid to check + * + * Returns: %true if the uuid is unique, %false if not */ bool nd_is_uuid_unique(struct device *dev, uuid_t *uuid) { @@ -337,6 +339,8 @@ static int scan_free(struct nd_region *nd_region, * adjust_resource() the allocation to @n, but if @n is larger than the * allocation delete it and find the 'new' last allocation in the label * set. + * + * Returns: %0 on success on -errno on error */ static int shrink_dpa_allocation(struct nd_region *nd_region, struct nd_label_id *label_id, resource_size_t n) @@ -662,6 +666,8 @@ void release_free_pmem(struct nvdimm_bus *nvdimm_bus, * allocations from the start of an interleave set and end at the first * BLK allocation or the end of the interleave set, whichever comes * first. + * + * Returns: %0 on success on -errno on error */ static int grow_dpa_allocation(struct nd_region *nd_region, struct nd_label_id *label_id, resource_size_t n) @@ -951,6 +957,8 @@ static ssize_t uuid_show(struct device *dev, struct device_attribute *attr, * @dev: namespace type for generating label_id * @new_uuid: incoming uuid * @old_uuid: reference to the uuid storage location in the namespace object + * + * Returns: %0 on success on -errno on error */ static int namespace_update_uuid(struct nd_region *nd_region, struct device *dev, uuid_t *new_uuid, @@ -1656,8 +1664,10 @@ static int select_pmem_id(struct nd_region *nd_region, const uuid_t *pmem_id) /** * create_namespace_pmem - validate interleave set labelling, retrieve label0 * @nd_region: region with mappings to validate - * @nspm: target namespace to create + * @nd_mapping: container of dpa-resource-root + labels * @nd_label: target pmem namespace label to evaluate + * + * Returns: the created &struct device on success or ERR_PTR(-errno) on error */ static struct device *create_namespace_pmem(struct nd_region *nd_region, struct nd_mapping *nd_mapping, @@ -1810,7 +1820,7 @@ static struct device *nd_namespace_pmem_create(struct nd_region *nd_region) res->name = dev_name(&nd_region->dev); res->flags = IORESOURCE_MEM; - nspm->id = ida_simple_get(&nd_region->ns_ida, 0, 0, GFP_KERNEL); + nspm->id = ida_alloc(&nd_region->ns_ida, GFP_KERNEL); if (nspm->id < 0) { kfree(nspm); return NULL; @@ -2188,8 +2198,7 @@ int nd_region_register_namespaces(struct nd_region *nd_region, int *err) struct nd_namespace_pmem *nspm; nspm = to_nd_namespace_pmem(dev); - id = ida_simple_get(&nd_region->ns_ida, 0, 0, - GFP_KERNEL); + id = ida_alloc(&nd_region->ns_ida, GFP_KERNEL); nspm->id = id; } else id = i; diff --git a/drivers/nvdimm/pfn_devs.c b/drivers/nvdimm/pfn_devs.c index 0d08e21a1c..586348125b 100644 --- a/drivers/nvdimm/pfn_devs.c +++ b/drivers/nvdimm/pfn_devs.c @@ -22,7 +22,7 @@ static void nd_pfn_release(struct device *dev) dev_dbg(dev, "trace\n"); nd_detach_ndns(&nd_pfn->dev, &nd_pfn->ndns); - ida_simple_remove(&nd_region->pfn_ida, nd_pfn->id); + ida_free(&nd_region->pfn_ida, nd_pfn->id); kfree(nd_pfn->uuid); kfree(nd_pfn); } @@ -326,7 +326,7 @@ static struct nd_pfn *nd_pfn_alloc(struct nd_region *nd_region) if (!nd_pfn) return NULL; - nd_pfn->id = ida_simple_get(&nd_region->pfn_ida, 0, 0, GFP_KERNEL); + nd_pfn->id = ida_alloc(&nd_region->pfn_ida, GFP_KERNEL); if (nd_pfn->id < 0) { kfree(nd_pfn); return NULL; diff --git a/drivers/nvdimm/virtio_pmem.c b/drivers/nvdimm/virtio_pmem.c index a92eb172f0..4ceced5cef 100644 --- a/drivers/nvdimm/virtio_pmem.c +++ b/drivers/nvdimm/virtio_pmem.c @@ -29,12 +29,27 @@ static int init_vq(struct virtio_pmem *vpmem) return 0; }; +static int virtio_pmem_validate(struct virtio_device *vdev) +{ + struct virtio_shm_region shm_reg; + + if (virtio_has_feature(vdev, VIRTIO_PMEM_F_SHMEM_REGION) && + !virtio_get_shm_region(vdev, &shm_reg, (u8)VIRTIO_PMEM_SHMEM_REGION_ID) + ) { + dev_notice(&vdev->dev, "failed to get shared memory region %d\n", + VIRTIO_PMEM_SHMEM_REGION_ID); + __virtio_clear_bit(vdev, VIRTIO_PMEM_F_SHMEM_REGION); + } + return 0; +} + static int virtio_pmem_probe(struct virtio_device *vdev) { struct nd_region_desc ndr_desc = {}; struct nd_region *nd_region; struct virtio_pmem *vpmem; struct resource res; + struct virtio_shm_region shm_reg; int err = 0; if (!vdev->config->get) { @@ -57,10 +72,16 @@ static int virtio_pmem_probe(struct virtio_device *vdev) goto out_err; } - virtio_cread_le(vpmem->vdev, struct virtio_pmem_config, - start, &vpmem->start); - virtio_cread_le(vpmem->vdev, struct virtio_pmem_config, - size, &vpmem->size); + if (virtio_has_feature(vdev, VIRTIO_PMEM_F_SHMEM_REGION)) { + virtio_get_shm_region(vdev, &shm_reg, (u8)VIRTIO_PMEM_SHMEM_REGION_ID); + vpmem->start = shm_reg.addr; + vpmem->size = shm_reg.len; + } else { + virtio_cread_le(vpmem->vdev, struct virtio_pmem_config, + start, &vpmem->start); + virtio_cread_le(vpmem->vdev, struct virtio_pmem_config, + size, &vpmem->size); + } res.start = vpmem->start; res.end = vpmem->start + vpmem->size - 1; @@ -122,10 +143,17 @@ static void virtio_pmem_remove(struct virtio_device *vdev) virtio_reset_device(vdev); } +static unsigned int features[] = { + VIRTIO_PMEM_F_SHMEM_REGION, +}; + static struct virtio_driver virtio_pmem_driver = { + .feature_table = features, + .feature_table_size = ARRAY_SIZE(features), .driver.name = KBUILD_MODNAME, .driver.owner = THIS_MODULE, .id_table = id_table, + .validate = virtio_pmem_validate, .probe = virtio_pmem_probe, .remove = virtio_pmem_remove, }; |