diff options
Diffstat (limited to 'platform/linux-dpdk/odp_shared_memory.c')
-rw-r--r-- | platform/linux-dpdk/odp_shared_memory.c | 134 |
1 files changed, 119 insertions, 15 deletions
diff --git a/platform/linux-dpdk/odp_shared_memory.c b/platform/linux-dpdk/odp_shared_memory.c index dba91eede..470b78eb5 100644 --- a/platform/linux-dpdk/odp_shared_memory.c +++ b/platform/linux-dpdk/odp_shared_memory.c @@ -68,13 +68,15 @@ typedef struct { * Memory block descriptor */ typedef struct { + /* DPDK memzone. If != NULL, the shm block is interpreted as reserved. */ + const struct rte_memzone *mz; + /* User requested SHM size */ + uint64_t size; /* Memory block type */ shm_type_t type; /* Memory block name */ char name[ODP_SHM_NAME_LEN]; - /* DPDK memzone. If this pointer != NULL, the shm block is interpreted - * as reserved. */ - const struct rte_memzone *mz; + } shm_block_t; /** @@ -121,19 +123,20 @@ static void name_to_mz_name(const char *name, char *mz_name) } /** - * Convert DPDK memzone length into ODP shm block size + * Return a pointer to shm zone descriptor stored at the end of DPDK memzone */ -static uint64_t shm_size(const struct rte_memzone *mz) +static shm_zone_t *shm_zone(const struct rte_memzone *mz) { - return mz->len - sizeof(shm_zone_t); + return (shm_zone_t *)(uintptr_t)((uint8_t *)mz->addr + mz->len - sizeof(shm_zone_t)); } -/** - * Return a pointer to shm zone descriptor stored at the end of DPDK memzone - */ -static shm_zone_t *shm_zone(const struct rte_memzone *mz) +static shm_block_t *mz_to_shm_block(const struct rte_memzone *mz) { - return (shm_zone_t *)(uintptr_t)((uint8_t *)mz->addr + shm_size(mz)); + for (int i = 0; i < SHM_MAX_NB_BLOCKS; i++) { + if (shm_tbl->block[i].mz == mz) + return &shm_tbl->block[i]; + } + return NULL; } static int find_free_block(void) @@ -294,6 +297,8 @@ odp_shm_t odp_shm_reserve(const char *name, uint64_t size, uint64_t align, snprintf(block->name, ODP_SHM_NAME_LEN, "%s", name); block->name[ODP_SHM_NAME_LEN - 1] = 0; block->type = SHM_TYPE_LOCAL; + block->size = size; + /* Note: ODP_SHM_SW_ONLY/ODP_SHM_PROC/ODP_SHM_SINGLE_VA flags are * currently ignored. */ shm_zone(mz)->flags = flags; @@ -427,15 +432,114 @@ int odp_shm_info(odp_shm_t shm, odp_shm_info_t *info) info->name = block->name; info->addr = block->mz->addr; - info->size = shm_size(block->mz); + info->size = block->size; info->page_size = block->mz->hugepage_sz; info->flags = shm_zone(block->mz)->flags; + info->num_seg = 1; odp_spinlock_unlock(&shm_tbl->lock); return 0; } +int odp_shm_segment_info(odp_shm_t shm, uint32_t index, uint32_t num, + odp_shm_segment_info_t seg_info[]) +{ + shm_block_t *block; + int idx = handle_to_idx(shm); + phys_addr_t pa; + + if (index != 0 || num != 1) { + _ODP_ERR("Only single segment supported (%u, %u)\n", index, num); + return -1; + } + + odp_spinlock_lock(&shm_tbl->lock); + + if (!handle_is_valid(shm)) { + odp_spinlock_unlock(&shm_tbl->lock); + return -1; + } + + block = &shm_tbl->block[idx]; + pa = rte_mem_virt2phy(block->mz->addr); + + seg_info[0].addr = (uintptr_t)block->mz->addr; + seg_info[0].iova = block->mz->iova != RTE_BAD_IOVA ? block->mz->iova : ODP_SHM_IOVA_INVALID; + seg_info[0].pa = pa != RTE_BAD_IOVA ? pa : ODP_SHM_PA_INVALID; + seg_info[0].len = block->size; + + odp_spinlock_unlock(&shm_tbl->lock); + + return 0; +} + +typedef struct { + odp_system_meminfo_t *info; + odp_system_memblock_t *memblock; + int32_t blocks; + int32_t max_num; + +} memzone_walker_data_t; + +static void walk_memzone(const struct rte_memzone *mz, void *arg) +{ + memzone_walker_data_t *data = arg; + shm_block_t *block = mz_to_shm_block(mz); + odp_system_memblock_t *memblock; + int32_t cur = data->blocks; + const char *name; + int name_len; + + data->info->total_mapped += mz->len; + data->blocks++; + + if (block != NULL) { + name = block->name; + data->info->total_used += block->size; + data->info->total_overhead += mz->len - block->size; + } else { /* DPDK internal reservations */ + name = mz->name; + data->info->total_used += mz->len; + } + + if (cur >= data->max_num) + return; + memblock = &data->memblock[cur]; + + name_len = strlen(name); + if (name_len >= ODP_SYSTEM_MEMBLOCK_NAME_LEN) + name_len = ODP_SYSTEM_MEMBLOCK_NAME_LEN - 1; + + memcpy(memblock->name, name, name_len); + memblock->name[name_len] = 0; + + memblock->addr = (uintptr_t)mz->addr; + memblock->used = mz->len; + memblock->overhead = block != NULL ? mz->len - block->size : 0; + memblock->page_size = mz->hugepage_sz; +} + +int32_t odp_system_meminfo(odp_system_meminfo_t *info, odp_system_memblock_t memblock[], + int32_t max_num) +{ + memzone_walker_data_t walker_data; + + memset(info, 0, sizeof(odp_system_meminfo_t)); + memset(&walker_data, 0, sizeof(memzone_walker_data_t)); + walker_data.max_num = max_num; + walker_data.info = info; + walker_data.memblock = memblock; + + odp_spinlock_lock(&shm_tbl->lock); + + rte_memzone_walk(walk_memzone, (void *)&walker_data); + + odp_spinlock_unlock(&shm_tbl->lock); + + return walker_data.blocks; +} + void odp_shm_print_all(void) { shm_block_t *block; @@ -451,7 +555,7 @@ void odp_shm_print_all(void) continue; _ODP_PRINT(" %s: addr: %p, len: %" PRIu64 " page size: %" PRIu64 "\n", block->name, block->mz->addr, - shm_size(block->mz), block->mz->hugepage_sz); + block->size, block->mz->hugepage_sz); } odp_spinlock_unlock(&shm_tbl->lock); @@ -476,9 +580,9 @@ void odp_shm_print(odp_shm_t shm) _ODP_PRINT(" type: %s\n", block->type == SHM_TYPE_LOCAL ? "local" : "remote"); _ODP_PRINT(" flags: 0x%x\n", shm_zone(block->mz)->flags); _ODP_PRINT(" start: %p\n", block->mz->addr); - _ODP_PRINT(" len: %" PRIu64 "\n", shm_size(block->mz)); + _ODP_PRINT(" len: %" PRIu64 "\n", block->size); _ODP_PRINT(" page size: %" PRIu64 "\n", block->mz->hugepage_sz); - _ODP_PRINT(" NUMA ID: %" PRIi32 "\n", block->mz->socket_id); + _ODP_PRINT(" NUMA ID: %" PRIi32 "\n", block->mz->socket_id); _ODP_PRINT("\n"); odp_spinlock_unlock(&shm_tbl->lock); |