malloc: allow attaching to external memory chunks

In order to use external memory in multiple processes, we need to
attach to primary process's memseg lists, so add a new API to do
that. It is the responsibility of the user to ensure that memory
is accessible and that it has been previously added to the malloc
heap by another process.

Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
This commit is contained in:
Anatoly Burakov 2018-10-02 14:34:53 +01:00 committed by Thomas Monjalon
parent 75185aa5fe
commit ff3619d624
3 changed files with 112 additions and 0 deletions

View File

@ -268,6 +268,10 @@ rte_malloc_get_socket_stats(int socket,
*
* @note Multiple memory chunks can be added to the same heap
*
* @note Before accessing this memory in other processes, it needs to be
* attached in each of those processes by calling
* ``rte_malloc_heap_memory_attach`` in each other process.
*
* @note Memory must be previously allocated for DPDK to be able to use it as a
* malloc heap. Failing to do so will result in undefined behavior, up to and
* including segmentation faults.
@ -329,6 +333,30 @@ rte_malloc_heap_memory_add(const char *heap_name, void *va_addr, size_t len,
int __rte_experimental
rte_malloc_heap_memory_remove(const char *heap_name, void *va_addr, size_t len);
/**
* Attach to an already existing chunk of external memory in another process.
*
* @note This function must be called before any attempt is made to use an
* already existing external memory chunk. This function does *not* need to
* be called if a call to ``rte_malloc_heap_memory_add`` was made in the
* current process.
*
* @param heap_name
* Heap name to which this chunk of memory belongs
* @param va_addr
* Start address of memory chunk to attach to
* @param len
* Length of memory chunk to attach to
* @return
* 0 on successful attach
* -1 on unsuccessful attach, with rte_errno set to indicate cause for error:
* EINVAL - one of the parameters was invalid
* EPERM - attempted to attach memory to a reserved heap
* ENOENT - heap or memory chunk was not found
*/
int __rte_experimental
rte_malloc_heap_memory_attach(const char *heap_name, void *va_addr, size_t len);
/**
* Creates a new empty malloc heap with a specified name.
*

View File

@ -417,6 +417,89 @@ rte_malloc_heap_memory_remove(const char *heap_name, void *va_addr, size_t len)
return ret;
}
struct sync_mem_walk_arg {
void *va_addr;
size_t len;
int result;
};
static int
attach_mem_walk(const struct rte_memseg_list *msl, void *arg)
{
struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;
struct sync_mem_walk_arg *wa = arg;
size_t len = msl->page_sz * msl->memseg_arr.len;
if (msl->base_va == wa->va_addr &&
len == wa->len) {
struct rte_memseg_list *found_msl;
int msl_idx, ret;
/* msl is const */
msl_idx = msl - mcfg->memsegs;
found_msl = &mcfg->memsegs[msl_idx];
ret = rte_fbarray_attach(&found_msl->memseg_arr);
if (ret < 0)
wa->result = -rte_errno;
else
wa->result = 0;
return 1;
}
return 0;
}
int
rte_malloc_heap_memory_attach(const char *heap_name, void *va_addr, size_t len)
{
struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;
struct malloc_heap *heap = NULL;
struct sync_mem_walk_arg wa;
int ret;
if (heap_name == NULL || va_addr == NULL || len == 0 ||
strnlen(heap_name, RTE_HEAP_NAME_MAX_LEN) == 0 ||
strnlen(heap_name, RTE_HEAP_NAME_MAX_LEN) ==
RTE_HEAP_NAME_MAX_LEN) {
rte_errno = EINVAL;
return -1;
}
rte_rwlock_read_lock(&mcfg->memory_hotplug_lock);
/* find our heap */
heap = find_named_heap(heap_name);
if (heap == NULL) {
rte_errno = ENOENT;
ret = -1;
goto unlock;
}
/* we shouldn't be able to attach to internal heaps */
if (heap->socket_id < RTE_MAX_NUMA_NODES) {
rte_errno = EPERM;
ret = -1;
goto unlock;
}
/* find corresponding memseg list to attach to */
wa.va_addr = va_addr;
wa.len = len;
wa.result = -ENOENT; /* fail unless explicitly told to succeed */
/* we're already holding a read lock */
rte_memseg_list_walk_thread_unsafe(attach_mem_walk, &wa);
if (wa.result < 0) {
rte_errno = -wa.result;
ret = -1;
} else {
ret = 0;
}
unlock:
rte_rwlock_read_unlock(&mcfg->memory_hotplug_lock);
return ret;
}
int
rte_malloc_heap_create(const char *heap_name)
{

View File

@ -322,6 +322,7 @@ EXPERIMENTAL {
rte_malloc_heap_destroy;
rte_malloc_heap_get_socket;
rte_malloc_heap_memory_add;
rte_malloc_heap_memory_attach;
rte_malloc_heap_memory_remove;
rte_malloc_heap_socket_is_external;
rte_mem_alloc_validator_register;