[v8,01/21] mem: add length to memseg list
Checks
Commit Message
Previously, to calculate length of memory area covered by a memseg
list, we would've needed to multiply page size by length of fbarray
backing that memseg list. This is not obvious and unnecessarily
low level, so store length in the memseg list itself.
This breaks ABI, so bump the EAL ABI version and document the
change.
Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
Acked-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
doc/guides/rel_notes/release_18_11.rst | 8 +++++++-
drivers/bus/pci/linux/pci.c | 2 +-
lib/librte_eal/bsdapp/eal/Makefile | 2 +-
lib/librte_eal/bsdapp/eal/eal_memory.c | 2 ++
lib/librte_eal/common/eal_common_memory.c | 5 ++---
lib/librte_eal/common/include/rte_eal_memconfig.h | 1 +
lib/librte_eal/linuxapp/eal/Makefile | 2 +-
lib/librte_eal/linuxapp/eal/eal_memalloc.c | 3 ++-
lib/librte_eal/linuxapp/eal/eal_memory.c | 4 +++-
lib/librte_eal/meson.build | 2 +-
10 files changed, 21 insertions(+), 10 deletions(-)
Comments
On Mon, 1 Oct 2018 13:56:09 +0100
Anatoly Burakov <anatoly.burakov@intel.com> wrote:
> diff --git a/lib/librte_eal/common/include/rte_eal_memconfig.h b/lib/librte_eal/common/include/rte_eal_memconfig.h
> index aff0688dd..1d8b0a6fe 100644
> --- a/lib/librte_eal/common/include/rte_eal_memconfig.h
> +++ b/lib/librte_eal/common/include/rte_eal_memconfig.h
> @@ -30,6 +30,7 @@ struct rte_memseg_list {
> uint64_t addr_64;
> /**< Makes sure addr is always 64-bits */
> };
> + size_t len; /**< Length of memory area covered by this memseg list. */
> int socket_id; /**< Socket ID for all memsegs in this list. */
> uint64_t page_sz; /**< Page size for all memsegs in this list. */
> volatile uint32_t version; /**< version number for multiprocess sync. */
If you are going to break ABI, why not try and rearrange to eliminate holes:
Output of pahole (on x86 64 bit):
struct rte_memseg_list {
union {
void * base_va; /* 0 8 */
uint64_t addr_64; /* 0 8 */
}; /* 0 8 */
size_t len; /* 8 8 */
int socket_id; /* 16 4 */
/* XXX 4 bytes hole, try to pack */
uint64_t page_sz; /* 24 8 */
volatile uint32_t version; /* 32 4 */
/* XXX 4 bytes hole, try to pack */
struct rte_fbarray memseg_arr; /* 40 96 */
/* XXX last struct has 4 bytes of padding */
/* size: 136, cachelines: 3, members: 6 */
/* sum members: 128, holes: 2, sum holes: 8 */
/* paddings: 1, sum paddings: 4 */
/* last cacheline: 8 bytes */
};
On 01-Oct-18 6:01 PM, Stephen Hemminger wrote:
> On Mon, 1 Oct 2018 13:56:09 +0100
> Anatoly Burakov <anatoly.burakov@intel.com> wrote:
>
>> diff --git a/lib/librte_eal/common/include/rte_eal_memconfig.h b/lib/librte_eal/common/include/rte_eal_memconfig.h
>> index aff0688dd..1d8b0a6fe 100644
>> --- a/lib/librte_eal/common/include/rte_eal_memconfig.h
>> +++ b/lib/librte_eal/common/include/rte_eal_memconfig.h
>> @@ -30,6 +30,7 @@ struct rte_memseg_list {
>> uint64_t addr_64;
>> /**< Makes sure addr is always 64-bits */
>> };
>> + size_t len; /**< Length of memory area covered by this memseg list. */
>> int socket_id; /**< Socket ID for all memsegs in this list. */
>> uint64_t page_sz; /**< Page size for all memsegs in this list. */
>> volatile uint32_t version; /**< version number for multiprocess sync. */
>
> If you are going to break ABI, why not try and rearrange to eliminate holes:
>
> Output of pahole (on x86 64 bit):
>
> struct rte_memseg_list {
> union {
> void * base_va; /* 0 8 */
> uint64_t addr_64; /* 0 8 */
> }; /* 0 8 */
> size_t len; /* 8 8 */
> int socket_id; /* 16 4 */
>
> /* XXX 4 bytes hole, try to pack */
>
> uint64_t page_sz; /* 24 8 */
> volatile uint32_t version; /* 32 4 */
>
> /* XXX 4 bytes hole, try to pack */
>
> struct rte_fbarray memseg_arr; /* 40 96 */
>
> /* XXX last struct has 4 bytes of padding */
>
> /* size: 136, cachelines: 3, members: 6 */
> /* sum members: 128, holes: 2, sum holes: 8 */
> /* paddings: 1, sum paddings: 4 */
> /* last cacheline: 8 bytes */
> };
>
Hi Stephen,
This data structure isn't performance-critical in any remote sense, but
sure, I can do that.
@@ -134,6 +134,12 @@ ABI Changes
=========================================================
+* eal: EAL library ABI version was changed due to previously announced work on
+ supporting external memory in DPDK:
+ - structure ``rte_memseg_list`` now has a new field indicating length
+ of memory addressed by the segment list
+
+
Removed Items
-------------
@@ -179,7 +185,7 @@ The libraries prepended with a plus sign were incremented in this version.
librte_compressdev.so.1
librte_cryptodev.so.5
librte_distributor.so.1
- librte_eal.so.8
+ + librte_eal.so.9
librte_ethdev.so.10
librte_eventdev.so.4
librte_flow_classify.so.1
@@ -119,7 +119,7 @@ rte_pci_unmap_device(struct rte_pci_device *dev)
static int
find_max_end_va(const struct rte_memseg_list *msl, void *arg)
{
- size_t sz = msl->memseg_arr.len * msl->page_sz;
+ size_t sz = msl->len;
void *end_va = RTE_PTR_ADD(msl->base_va, sz);
void **max_va = arg;
@@ -22,7 +22,7 @@ LDLIBS += -lrte_kvargs
EXPORT_MAP := ../../rte_eal_version.map
-LIBABIVER := 8
+LIBABIVER := 9
# specific to bsdapp exec-env
SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) := eal.c
@@ -79,6 +79,7 @@ rte_eal_hugepage_init(void)
}
msl->base_va = addr;
msl->page_sz = page_sz;
+ msl->len = internal_config.memory;
msl->socket_id = 0;
/* populate memsegs. each memseg is 1 page long */
@@ -370,6 +371,7 @@ alloc_va_space(struct rte_memseg_list *msl)
return -1;
}
msl->base_va = addr;
+ msl->len = mem_sz;
return 0;
}
@@ -171,7 +171,7 @@ virt2memseg(const void *addr, const struct rte_memseg_list *msl)
/* a memseg list was specified, check if it's the right one */
start = msl->base_va;
- end = RTE_PTR_ADD(start, (size_t)msl->page_sz * msl->memseg_arr.len);
+ end = RTE_PTR_ADD(start, msl->len);
if (addr < start || addr >= end)
return NULL;
@@ -194,8 +194,7 @@ virt2memseg_list(const void *addr)
msl = &mcfg->memsegs[msl_idx];
start = msl->base_va;
- end = RTE_PTR_ADD(start,
- (size_t)msl->page_sz * msl->memseg_arr.len);
+ end = RTE_PTR_ADD(start, msl->len);
if (addr >= start && addr < end)
break;
}
@@ -30,6 +30,7 @@ struct rte_memseg_list {
uint64_t addr_64;
/**< Makes sure addr is always 64-bits */
};
+ size_t len; /**< Length of memory area covered by this memseg list. */
int socket_id; /**< Socket ID for all memsegs in this list. */
uint64_t page_sz; /**< Page size for all memsegs in this list. */
volatile uint32_t version; /**< version number for multiprocess sync. */
@@ -10,7 +10,7 @@ ARCH_DIR ?= $(RTE_ARCH)
EXPORT_MAP := ../../rte_eal_version.map
VPATH += $(RTE_SDK)/lib/librte_eal/common/arch/$(ARCH_DIR)
-LIBABIVER := 8
+LIBABIVER := 9
VPATH += $(RTE_SDK)/lib/librte_eal/common
@@ -986,7 +986,7 @@ free_seg_walk(const struct rte_memseg_list *msl, void *arg)
int msl_idx, seg_idx, ret, dir_fd = -1;
start_addr = (uintptr_t) msl->base_va;
- end_addr = start_addr + msl->memseg_arr.len * (size_t)msl->page_sz;
+ end_addr = start_addr + msl->len;
if ((uintptr_t)wa->ms->addr < start_addr ||
(uintptr_t)wa->ms->addr >= end_addr)
@@ -1472,6 +1472,7 @@ secondary_msl_create_walk(const struct rte_memseg_list *msl,
return -1;
}
local_msl->base_va = primary_msl->base_va;
+ local_msl->len = primary_msl->len;
return 0;
}
@@ -861,6 +861,7 @@ alloc_va_space(struct rte_memseg_list *msl)
return -1;
}
msl->base_va = addr;
+ msl->len = mem_sz;
return 0;
}
@@ -1369,6 +1370,7 @@ eal_legacy_hugepage_init(void)
msl->base_va = addr;
msl->page_sz = page_sz;
msl->socket_id = 0;
+ msl->len = internal_config.memory;
/* populate memsegs. each memseg is one page long */
for (cur_seg = 0; cur_seg < n_segs; cur_seg++) {
@@ -1615,7 +1617,7 @@ eal_legacy_hugepage_init(void)
if (msl->memseg_arr.count > 0)
continue;
/* this is an unused list, deallocate it */
- mem_sz = (size_t)msl->page_sz * msl->memseg_arr.len;
+ mem_sz = msl->len;
munmap(msl->base_va, mem_sz);
msl->base_va = NULL;
@@ -21,7 +21,7 @@ else
error('unsupported system type "@0@"'.format(host_machine.system()))
endif
-version = 8 # the version of the EAL API
+version = 9 # the version of the EAL API
allow_experimental_apis = true
deps += 'compat'
deps += 'kvargs'