Commit 40c9acf6 authored by Jim Harris's avatar Jim Harris
Browse files

env: add spdk_mem_get_numa_id



This returns the NUMA node ID associated with the specified memory
buffer. It will be used in future patches for returning buffers to
their respective per-NUMA node memory pools.

Signed-off-by: default avatarJim Harris <jim.harris@samsung.com>
Change-Id: Ia7f542b75d0e6d21ac414e45c4130780c060555c
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/24201


Reviewed-by: default avatarBen Walker <ben@nvidia.com>
Reviewed-by: default avatarKonrad Sztyber <konrad.sztyber@intel.com>
Community-CI: Broadcom CI <spdk-ci.pdl@broadcom.com>
Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Community-CI: Community CI Samsung <spdk.community.ci.samsung@gmail.com>
parent 0f99ab2f
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -1482,6 +1482,20 @@ int spdk_mem_unregister(void *vaddr, size_t len);
 */
int spdk_mem_reserve(void *vaddr, size_t len);

/**
 * Get the NUMA node ID for the specified memory buffer.
 *
 * Note: this only works for memory allocated via the environment layer.
 *
 * \param buf A pointer to a buffer.
 * \param size Contains the size of the memory region pointed to by vaddr.
 * If vaddr is successfully translated, then this is updated with the size of
 * the memory region for which the translation is valid.
 *
 * \return NUMA ID of the buffer if known, SPDK_ENV_NUMA_ID_ANY otherwise
 */
int32_t spdk_mem_get_numa_id(const void *buf, uint64_t *size);

/**
 * Get the address's file descriptor and offset, it works with spdk memory allocation APIs
 *
+1 −1
Original line number Diff line number Diff line
@@ -7,7 +7,7 @@ SPDK_ROOT_DIR := $(abspath $(CURDIR)/../..)
include $(SPDK_ROOT_DIR)/mk/spdk.common.mk

SO_VER := 15
SO_MINOR := 0
SO_MINOR := 1

CFLAGS += $(ENV_CFLAGS)
C_SRCS = env.c memory.c pci.c init.c threads.c
+54 −0
Original line number Diff line number Diff line
@@ -766,6 +766,7 @@ static TAILQ_HEAD(, spdk_vtophys_pci_device) g_vtophys_pci_devices =

static struct spdk_mem_map *g_vtophys_map;
static struct spdk_mem_map *g_phys_ref_map;
static struct spdk_mem_map *g_numa_map;

#if VFIO_ENABLED
static int
@@ -1275,6 +1276,40 @@ vtophys_notify(void *cb_ctx, struct spdk_mem_map *map,
	return rc;
}

static int
numa_notify(void *cb_ctx, struct spdk_mem_map *map,
	    enum spdk_mem_map_notify_action action,
	    void *vaddr, size_t len)
{
	struct rte_memseg *seg;

	/* We always return 0 from here, even if we aren't able to get a
	 * memseg for the address. This can happen in non-DPDK memory
	 * registration paths, for example vhost or vfio-user. That is OK,
	 * spdk_mem_get_numa_id() just returns SPDK_ENV_NUMA_ID_ANY for
	 * that kind of memory. If we return an error here, the
	 * spdk_mem_register() from vhost or vfio-user would fail which is
	 * not what we want.
	 */
	seg = rte_mem_virt2memseg(vaddr, NULL);
	if (seg == NULL) {
		return 0;
	}

	switch (action) {
	case SPDK_MEM_MAP_NOTIFY_REGISTER:
		spdk_mem_map_set_translation(map, (uint64_t)vaddr, len, seg->socket_id);
		break;
	case SPDK_MEM_MAP_NOTIFY_UNREGISTER:
		spdk_mem_map_clear_translation(map, (uint64_t)vaddr, len);
		break;
	default:
		break;
	}

	return 0;
}

static int
vtophys_check_contiguous_entries(uint64_t paddr1, uint64_t paddr2)
{
@@ -1487,6 +1522,11 @@ vtophys_init(void)
		.are_contiguous = NULL,
	};

	const struct spdk_mem_map_ops numa_map_ops = {
		.notify_cb = numa_notify,
		.are_contiguous = NULL,
	};

#if VFIO_ENABLED
	vtophys_iommu_init();
#endif
@@ -1497,10 +1537,18 @@ vtophys_init(void)
		return -ENOMEM;
	}

	g_numa_map = spdk_mem_map_alloc(SPDK_ENV_NUMA_ID_ANY, &numa_map_ops, NULL);
	if (g_numa_map == NULL) {
		DEBUG_PRINT("numa map allocation failed.\n");
		spdk_mem_map_free(&g_phys_ref_map);
		return -ENOMEM;
	}

	if (g_huge_pages) {
		g_vtophys_map = spdk_mem_map_alloc(SPDK_VTOPHYS_ERROR, &vtophys_map_ops, NULL);
		if (g_vtophys_map == NULL) {
			DEBUG_PRINT("vtophys map allocation failed\n");
			spdk_mem_map_free(&g_numa_map);
			spdk_mem_map_free(&g_phys_ref_map);
			return -ENOMEM;
		}
@@ -1534,6 +1582,12 @@ spdk_vtophys(const void *buf, uint64_t *size)
	}
}

int32_t
spdk_mem_get_numa_id(const void *buf, uint64_t *size)
{
	return spdk_mem_map_translate(g_numa_map, (uint64_t)buf, size);
}

int
spdk_mem_get_fd_and_offset(void *vaddr, uint64_t *offset)
{
+1 −0
Original line number Diff line number Diff line
@@ -117,6 +117,7 @@
	spdk_mem_register;
	spdk_mem_unregister;
	spdk_mem_get_fd_and_offset;
	spdk_mem_get_numa_id;
	spdk_pci_event_listen;
	spdk_pci_get_event;
	spdk_pci_register_error_handler;