malloc: allow detaching from external memory
authorAnatoly Burakov <anatoly.burakov@intel.com>
Tue, 2 Oct 2018 13:34:54 +0000 (14:34 +0100)
committerThomas Monjalon <thomas@monjalon.net>
Thu, 11 Oct 2018 09:56:55 +0000 (11:56 +0200)
Add API to detach from existing chunk of external memory in a
process.

Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
lib/librte_eal/common/include/rte_malloc.h
lib/librte_eal/common/rte_malloc.c
lib/librte_eal/rte_eal_version.map

index 793f947..7249e6a 100644 (file)
@@ -315,6 +315,9 @@ rte_malloc_heap_memory_add(const char *heap_name, void *va_addr, size_t len,
  * @note Memory area must not contain any allocated elements to allow its
  *   removal from the heap
  *
+ * @note All other processes must detach from the memory chunk prior to it being
+ *   removed from the heap.
+ *
  * @param heap_name
  *   Name of the heap to remove memory from
  * @param va_addr
@@ -357,6 +360,30 @@ rte_malloc_heap_memory_remove(const char *heap_name, void *va_addr, size_t len);
 int __rte_experimental
 rte_malloc_heap_memory_attach(const char *heap_name, void *va_addr, size_t len);
 
+/**
+ * Detach from a chunk of external memory in secondary process.
+ *
+ * @note This function must be called in before any attempt is made to remove
+ *   external memory from the heap in another process. This function does *not*
+ *   need to be called if a call to ``rte_malloc_heap_memory_remove`` will be
+ *   called in 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 detach
+ *   -1 on unsuccessful detach, with rte_errno set to indicate cause for error:
+ *     EINVAL - one of the parameters was invalid
+ *     EPERM  - attempted to detach memory from a reserved heap
+ *     ENOENT - heap or memory chunk was not found
+ */
+int __rte_experimental
+rte_malloc_heap_memory_detach(const char *heap_name, void *va_addr, size_t len);
+
 /**
  * Creates a new empty malloc heap with a specified name.
  *
index 1b95c04..dd00254 100644 (file)
@@ -421,10 +421,11 @@ struct sync_mem_walk_arg {
        void *va_addr;
        size_t len;
        int result;
+       bool attach;
 };
 
 static int
-attach_mem_walk(const struct rte_memseg_list *msl, void *arg)
+sync_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;
@@ -439,7 +440,10 @@ attach_mem_walk(const struct rte_memseg_list *msl, void *arg)
                msl_idx = msl - mcfg->memsegs;
                found_msl = &mcfg->memsegs[msl_idx];
 
-               ret = rte_fbarray_attach(&found_msl->memseg_arr);
+               if (wa->attach)
+                       ret = rte_fbarray_attach(&found_msl->memseg_arr);
+               else
+                       ret = rte_fbarray_detach(&found_msl->memseg_arr);
 
                if (ret < 0)
                        wa->result = -rte_errno;
@@ -450,8 +454,8 @@ attach_mem_walk(const struct rte_memseg_list *msl, void *arg)
        return 0;
 }
 
-int
-rte_malloc_heap_memory_attach(const char *heap_name, void *va_addr, size_t len)
+static int
+sync_memory(const char *heap_name, void *va_addr, size_t len, bool attach)
 {
        struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;
        struct malloc_heap *heap = NULL;
@@ -474,20 +478,21 @@ rte_malloc_heap_memory_attach(const char *heap_name, void *va_addr, size_t len)
                ret = -1;
                goto unlock;
        }
-       /* we shouldn't be able to attach to internal heaps */
+       /* we shouldn't be able to sync 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 */
+       /* find corresponding memseg list to sync to */
        wa.va_addr = va_addr;
        wa.len = len;
        wa.result = -ENOENT; /* fail unless explicitly told to succeed */
+       wa.attach = attach;
 
        /* we're already holding a read lock */
-       rte_memseg_list_walk_thread_unsafe(attach_mem_walk, &wa);
+       rte_memseg_list_walk_thread_unsafe(sync_mem_walk, &wa);
 
        if (wa.result < 0) {
                rte_errno = -wa.result;
@@ -500,6 +505,18 @@ unlock:
        return ret;
 }
 
+int
+rte_malloc_heap_memory_attach(const char *heap_name, void *va_addr, size_t len)
+{
+       return sync_memory(heap_name, va_addr, len, true);
+}
+
+int
+rte_malloc_heap_memory_detach(const char *heap_name, void *va_addr, size_t len)
+{
+       return sync_memory(heap_name, va_addr, len, false);
+}
+
 int
 rte_malloc_heap_create(const char *heap_name)
 {
index 9208520..30583ee 100644 (file)
@@ -323,6 +323,7 @@ EXPERIMENTAL {
        rte_malloc_heap_get_socket;
        rte_malloc_heap_memory_add;
        rte_malloc_heap_memory_attach;
+       rte_malloc_heap_memory_detach;
        rte_malloc_heap_memory_remove;
        rte_malloc_heap_socket_is_external;
        rte_mem_alloc_validator_register;