diff --git a/include/spdk/env.h b/include/spdk/env.h index 3d47aed7bb..c3bab39485 100644 --- a/include/spdk/env.h +++ b/include/spdk/env.h @@ -404,9 +404,9 @@ enum spdk_mem_map_notify_action { SPDK_MEM_MAP_NOTIFY_UNREGISTER, }; -typedef void (*spdk_mem_map_notify_cb)(void *cb_ctx, struct spdk_mem_map *map, - enum spdk_mem_map_notify_action action, - void *vaddr, size_t size); +typedef int (*spdk_mem_map_notify_cb)(void *cb_ctx, struct spdk_mem_map *map, + enum spdk_mem_map_notify_action action, + void *vaddr, size_t size); /** * Allocate a virtual memory address translation map @@ -429,15 +429,15 @@ void spdk_mem_map_free(struct spdk_mem_map **pmap); * * \sa spdk_mem_map_clear_translation() */ -void spdk_mem_map_set_translation(struct spdk_mem_map *map, uint64_t vaddr, uint64_t size, - uint64_t translation); +int spdk_mem_map_set_translation(struct spdk_mem_map *map, uint64_t vaddr, uint64_t size, + uint64_t translation); /** * Unregister an address translation. * * \sa spdk_mem_map_set_translation() */ -void spdk_mem_map_clear_translation(struct spdk_mem_map *map, uint64_t vaddr, uint64_t size); +int spdk_mem_map_clear_translation(struct spdk_mem_map *map, uint64_t vaddr, uint64_t size); /** * Look up the translation of a virtual address in a memory map. @@ -448,14 +448,14 @@ uint64_t spdk_mem_map_translate(const struct spdk_mem_map *map, uint64_t vaddr); * Register the specified memory region for address translation. * The memory region must map to pinned huge pages (2MB or greater). */ -void spdk_mem_register(void *vaddr, size_t len); +int spdk_mem_register(void *vaddr, size_t len); /** * Unregister the specified memory region from vtophys address translation. * The caller must ensure all in-flight DMA operations to this memory region * are completed or cancelled before calling this function. */ -void spdk_mem_unregister(void *vaddr, size_t len); +int spdk_mem_unregister(void *vaddr, size_t len); #ifdef __cplusplus } diff --git a/lib/env_dpdk/vtophys.c b/lib/env_dpdk/vtophys.c index b5ea99ca49..f2da1a30e6 100644 --- a/lib/env_dpdk/vtophys.c +++ b/lib/env_dpdk/vtophys.c @@ -38,6 +38,8 @@ #include #include +#include "spdk_internal/assert.h" + #include "spdk/assert.h" #include "spdk/likely.h" #include "spdk/queue.h" @@ -221,28 +223,40 @@ spdk_mem_map_free(struct spdk_mem_map **pmap) *pmap = NULL; } -void +int spdk_mem_register(void *vaddr, size_t len) { struct spdk_mem_map *map; + int rc; pthread_mutex_lock(&g_spdk_mem_map_mutex); TAILQ_FOREACH(map, &g_spdk_mem_maps, tailq) { - map->notify_cb(map->cb_ctx, map, SPDK_MEM_MAP_NOTIFY_REGISTER, vaddr, len); + rc = map->notify_cb(map->cb_ctx, map, SPDK_MEM_MAP_NOTIFY_REGISTER, vaddr, len); + if (rc != 0) { + pthread_mutex_unlock(&g_spdk_mem_map_mutex); + return rc; + } } pthread_mutex_unlock(&g_spdk_mem_map_mutex); + return 0; } -void +int spdk_mem_unregister(void *vaddr, size_t len) { struct spdk_mem_map *map; + int rc; pthread_mutex_lock(&g_spdk_mem_map_mutex); TAILQ_FOREACH(map, &g_spdk_mem_maps, tailq) { - map->notify_cb(map->cb_ctx, map, SPDK_MEM_MAP_NOTIFY_UNREGISTER, vaddr, len); + rc = map->notify_cb(map->cb_ctx, map, SPDK_MEM_MAP_NOTIFY_UNREGISTER, vaddr, len); + if (rc != 0) { + pthread_mutex_unlock(&g_spdk_mem_map_mutex); + return rc; + } } pthread_mutex_unlock(&g_spdk_mem_map_mutex); + return 0; } static struct map_1gb * @@ -284,7 +298,7 @@ spdk_mem_map_get_map_1gb(struct spdk_mem_map *map, uint64_t vfn_2mb) return map_1gb; } -void +int spdk_mem_map_set_translation(struct spdk_mem_map *map, uint64_t vaddr, uint64_t size, uint64_t translation) { @@ -306,7 +320,7 @@ spdk_mem_map_set_translation(struct spdk_mem_map *map, uint64_t vaddr, uint64_t #ifdef DEBUG fprintf(stderr, "could not get %p map\n", (void *)vaddr); #endif - return; + return -ENOMEM; } idx_1gb = MAP_1GB_IDX(vfn_2mb); @@ -318,7 +332,7 @@ spdk_mem_map_set_translation(struct spdk_mem_map *map, uint64_t vaddr, uint64_t fprintf(stderr, "ref count for %p already at %d\n", (void *)vaddr, VTOPHYS_MAX_REF_COUNT); #endif - return; + return -EBUSY; } map_2mb->translation_2mb = translation; @@ -328,9 +342,11 @@ spdk_mem_map_set_translation(struct spdk_mem_map *map, uint64_t vaddr, uint64_t size -= 2 * 1024 * 1024; vfn_2mb++; } + + return 0; } -void +int spdk_mem_map_clear_translation(struct spdk_mem_map *map, uint64_t vaddr, uint64_t size) { uint64_t vfn_2mb; @@ -351,7 +367,7 @@ spdk_mem_map_clear_translation(struct spdk_mem_map *map, uint64_t vaddr, uint64_ #ifdef DEBUG fprintf(stderr, "could not get %p map\n", (void *)vaddr); #endif - return; + return -ENOMEM; } idx_1gb = MAP_1GB_IDX(vfn_2mb); @@ -362,7 +378,7 @@ spdk_mem_map_clear_translation(struct spdk_mem_map *map, uint64_t vaddr, uint64_ #ifdef DEBUG fprintf(stderr, "vaddr %p not registered\n", (void *)vaddr); #endif - return; + return -EINVAL; } (*ref_count)--; @@ -373,6 +389,8 @@ spdk_mem_map_clear_translation(struct spdk_mem_map *map, uint64_t vaddr, uint64_ size -= 2 * 1024 * 1024; vfn_2mb++; } + + return 0; } uint64_t @@ -459,35 +477,36 @@ vtophys_get_paddr(uint64_t vaddr) return SPDK_VTOPHYS_ERROR; } -static void +static int _spdk_vtophys_register_one(uint64_t vfn_2mb, uint64_t paddr) { if (paddr & MASK_2MB) { #ifdef DEBUG fprintf(stderr, "invalid paddr 0x%" PRIx64 " - must be 2MB aligned\n", paddr); #endif - return; + return -EINVAL; } - spdk_mem_map_set_translation(g_vtophys_map, vfn_2mb << SHIFT_2MB, 2 * 1024 * 1024, paddr); + return spdk_mem_map_set_translation(g_vtophys_map, vfn_2mb << SHIFT_2MB, 2 * 1024 * 1024, paddr); } -static void +static int _spdk_vtophys_unregister_one(uint64_t vfn_2mb) { - spdk_mem_map_clear_translation(g_vtophys_map, vfn_2mb << SHIFT_2MB, 2 * 1024 * 1024); + return spdk_mem_map_clear_translation(g_vtophys_map, vfn_2mb << SHIFT_2MB, 2 * 1024 * 1024); } -static void +static int spdk_vtophys_register(void *vaddr, uint64_t len) { uint64_t vfn_2mb; + int rc; if ((uintptr_t)vaddr & ~MASK_128TB) { #ifdef DEBUG printf("invalid usermode virtual address %p\n", vaddr); #endif - return; + return -EINVAL; } if (((uintptr_t)vaddr & MASK_2MB) || (len & MASK_2MB)) { @@ -495,7 +514,7 @@ spdk_vtophys_register(void *vaddr, uint64_t len) fprintf(stderr, "invalid %s parameters, vaddr=%p len=%ju\n", __func__, vaddr, len); #endif - return; + return -EINVAL; } vfn_2mb = (uintptr_t)vaddr >> SHIFT_2MB; @@ -509,25 +528,31 @@ spdk_vtophys_register(void *vaddr, uint64_t len) #ifdef DEBUG fprintf(stderr, "could not get phys addr for 0x%" PRIx64 "\n", vaddr); #endif - return; + return -EFAULT; } - _spdk_vtophys_register_one(vfn_2mb, paddr); + rc = _spdk_vtophys_register_one(vfn_2mb, paddr); + if (rc != 0) { + return rc; + } vfn_2mb++; len--; } + + return 0; } -static void +static int spdk_vtophys_unregister(void *vaddr, uint64_t len) { uint64_t vfn_2mb; + int rc; if ((uintptr_t)vaddr & ~MASK_128TB) { #ifdef DEBUG printf("invalid usermode virtual address %p\n", vaddr); #endif - return; + return -EINVAL; } if (((uintptr_t)vaddr & MASK_2MB) || (len & MASK_2MB)) { @@ -535,32 +560,43 @@ spdk_vtophys_unregister(void *vaddr, uint64_t len) fprintf(stderr, "invalid %s parameters, vaddr=%p len=%ju\n", __func__, vaddr, len); #endif - return; + return -EINVAL; } vfn_2mb = (uintptr_t)vaddr >> SHIFT_2MB; len = len >> SHIFT_2MB; while (len > 0) { - _spdk_vtophys_unregister_one(vfn_2mb); + rc = _spdk_vtophys_unregister_one(vfn_2mb); + if (rc != 0) { + return rc; + } vfn_2mb++; len--; } + + return 0; } -static void +static int spdk_vtophys_notify(void *cb_ctx, struct spdk_mem_map *map, enum spdk_mem_map_notify_action action, void *vaddr, size_t len) { + int rc; + switch (action) { case SPDK_MEM_MAP_NOTIFY_REGISTER: - spdk_vtophys_register(vaddr, len); + rc = spdk_vtophys_register(vaddr, len); break; case SPDK_MEM_MAP_NOTIFY_UNREGISTER: - spdk_vtophys_unregister(vaddr, len); + rc = spdk_vtophys_unregister(vaddr, len); break; + default: + SPDK_UNREACHABLE(); } + + return rc; } void diff --git a/lib/nvme/nvme_rdma.c b/lib/nvme/nvme_rdma.c index edd1c0e611..19aeef4bb6 100644 --- a/lib/nvme/nvme_rdma.c +++ b/lib/nvme/nvme_rdma.c @@ -630,13 +630,14 @@ ret: return rc; } -static void +static int nvme_rdma_mr_map_notify(void *cb_ctx, struct spdk_mem_map *map, enum spdk_mem_map_notify_action action, void *vaddr, size_t size) { struct ibv_pd *pd = cb_ctx; struct ibv_mr *mr; + int rc; switch (action) { case SPDK_MEM_MAP_NOTIFY_REGISTER: @@ -646,18 +647,23 @@ nvme_rdma_mr_map_notify(void *cb_ctx, struct spdk_mem_map *map, IBV_ACCESS_REMOTE_WRITE); if (mr == NULL) { SPDK_ERRLOG("ibv_reg_mr() failed\n"); + return -EFAULT; } else { - spdk_mem_map_set_translation(map, (uint64_t)vaddr, size, (uint64_t)mr); + rc = spdk_mem_map_set_translation(map, (uint64_t)vaddr, size, (uint64_t)mr); } break; case SPDK_MEM_MAP_NOTIFY_UNREGISTER: mr = (struct ibv_mr *)spdk_mem_map_translate(map, (uint64_t)vaddr); - spdk_mem_map_clear_translation(map, (uint64_t)vaddr, size); + rc = spdk_mem_map_clear_translation(map, (uint64_t)vaddr, size); if (mr) { ibv_dereg_mr(mr); } break; + default: + SPDK_UNREACHABLE(); } + + return rc; } diff --git a/test/lib/env/vtophys/vtophys.c b/test/lib/env/vtophys/vtophys.c index 425f2cef34..023ae9d37f 100644 --- a/test/lib/env/vtophys/vtophys.c +++ b/test/lib/env/vtophys/vtophys.c @@ -106,7 +106,7 @@ vtophys_positive_test(void) return rc; } -static void +static int test_map_notify(void *cb_ctx, struct spdk_mem_map *map, enum spdk_mem_map_notify_action action, void *vaddr, size_t size) @@ -123,6 +123,7 @@ test_map_notify(void *cb_ctx, struct spdk_mem_map *map, } printf("%s: %s %p-%p (%zu bytes)\n", __func__, action_str, vaddr, vaddr + size - 1, size); + return 0; } static int diff --git a/test/unit/lib/vhost/vhost.c/vhost_ut.c b/test/unit/lib/vhost/vhost.c/vhost_ut.c index 0fb56b6634..8b4e19030d 100644 --- a/test/unit/lib/vhost/vhost.c/vhost_ut.c +++ b/test/unit/lib/vhost/vhost.c/vhost_ut.c @@ -42,8 +42,8 @@ DEFINE_STUB(rte_vhost_driver_unregister, int, (const char *path), 0); DEFINE_STUB(spdk_event_allocate, struct spdk_event *, (uint32_t lcore, spdk_event_fn fn, void *arg1, void *arg2), NULL); -DEFINE_STUB_V(spdk_mem_register, (void *vaddr, size_t len)); -DEFINE_STUB_V(spdk_mem_unregister, (void *vaddr, size_t len)); +DEFINE_STUB(spdk_mem_register, int, (void *vaddr, size_t len), 0); +DEFINE_STUB(spdk_mem_unregister, int, (void *vaddr, size_t len), 0); DEFINE_STUB(spdk_iommu_mem_register, int, (uint64_t addr, uint64_t len), 0); DEFINE_STUB(spdk_app_get_core_mask, uint64_t, (void), 0); DEFINE_STUB_V(spdk_app_stop, (int rc));