]> git.droids-corp.org - dpdk.git/commitdiff
malloc: add function to check if socket is external
authorAnatoly Burakov <anatoly.burakov@intel.com>
Tue, 2 Oct 2018 13:34:48 +0000 (14:34 +0100)
committerThomas Monjalon <thomas@monjalon.net>
Thu, 11 Oct 2018 09:11:25 +0000 (11:11 +0200)
An API is needed to check whether a particular socket ID belongs
to an internal or external heap. Prime user of this would be
mempool allocator, because normal assumptions of IOVA
contiguousness in IOVA as VA mode do not hold in case of
externally allocated memory.

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
lib/librte_mempool/rte_mempool.c

index 8870732a6bf086a74dc7ee8d946577a8a9bd033a..403271ddc9c44545afd571bcc7babc71ffa4eb2f 100644 (file)
@@ -277,6 +277,21 @@ rte_malloc_get_socket_stats(int socket,
 int __rte_experimental
 rte_malloc_heap_get_socket(const char *name);
 
+/**
+ * Check if a given socket ID refers to externally allocated memory.
+ *
+ * @note Passing SOCKET_ID_ANY will return 0.
+ *
+ * @param socket_id
+ *   Socket ID to check
+ * @return
+ *   1 if socket ID refers to externally allocated memory
+ *   0 if socket ID refers to internal DPDK memory
+ *   -1 if socket ID is invalid
+ */
+int __rte_experimental
+rte_malloc_heap_socket_is_external(int socket_id);
+
 /**
  * Dump statistics.
  *
index b807dfe0964deb7cc01aa15190e08fac3c1682b2..fa81d786267bad2498c7aea2ed60a5b910398f7f 100644 (file)
@@ -220,6 +220,31 @@ rte_malloc_heap_get_socket(const char *name)
        return ret;
 }
 
+int
+rte_malloc_heap_socket_is_external(int socket_id)
+{
+       struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;
+       unsigned int idx;
+       int ret = -1;
+
+       if (socket_id == SOCKET_ID_ANY)
+               return 0;
+
+       rte_rwlock_read_lock(&mcfg->memory_hotplug_lock);
+       for (idx = 0; idx < RTE_MAX_HEAPS; idx++) {
+               struct malloc_heap *tmp = &mcfg->malloc_heaps[idx];
+
+               if ((int)tmp->socket_id == socket_id) {
+                       /* external memory always has large socket ID's */
+                       ret = tmp->socket_id >= RTE_MAX_NUMA_NODES;
+                       break;
+               }
+       }
+       rte_rwlock_read_unlock(&mcfg->memory_hotplug_lock);
+
+       return ret;
+}
+
 /*
  * Print stats on memory type. If type is NULL, info on all types is printed
  */
index d8f9665b8ffa45ab2515a9903fd798e587e8eb15..bd60506af9b0bdbabbaa893b299d89b5137b90e5 100644 (file)
@@ -319,6 +319,7 @@ EXPERIMENTAL {
        rte_log_register_type_and_pick_level;
        rte_malloc_dump_heaps;
        rte_malloc_heap_get_socket;
+       rte_malloc_heap_socket_is_external;
        rte_mem_alloc_validator_register;
        rte_mem_alloc_validator_unregister;
        rte_mem_event_callback_register;
index 2ed539f019d6f93a6f06f912d7725156ec91d162..683b216f92d8636fdaff5466dd9b1a5d25b5a507 100644 (file)
@@ -428,12 +428,18 @@ rte_mempool_populate_default(struct rte_mempool *mp)
        rte_iova_t iova;
        unsigned mz_id, n;
        int ret;
-       bool no_contig, try_contig, no_pageshift;
+       bool no_contig, try_contig, no_pageshift, external;
 
        ret = mempool_ops_alloc_once(mp);
        if (ret != 0)
                return ret;
 
+       /* check if we can retrieve a valid socket ID */
+       ret = rte_malloc_heap_socket_is_external(mp->socket_id);
+       if (ret < 0)
+               return -EINVAL;
+       external = ret;
+
        /* mempool must not be populated */
        if (mp->nb_mem_chunks != 0)
                return -EEXIST;
@@ -481,9 +487,19 @@ rte_mempool_populate_default(struct rte_mempool *mp)
         * in one contiguous chunk as well (otherwise we might end up wasting a
         * 1G page on a 10MB memzone). If we fail to get enough contiguous
         * memory, then we'll go and reserve space page-by-page.
+        *
+        * We also have to take into account the fact that memory that we're
+        * going to allocate from can belong to an externally allocated memory
+        * area, in which case the assumption of IOVA as VA mode being
+        * synonymous with IOVA contiguousness will not hold. We should also try
+        * to go for contiguous memory even if we're in no-huge mode, because
+        * external memory may in fact be IOVA-contiguous.
         */
-       no_pageshift = no_contig || rte_eal_iova_mode() == RTE_IOVA_VA;
-       try_contig = !no_contig && !no_pageshift && rte_eal_has_hugepages();
+       external = rte_malloc_heap_socket_is_external(mp->socket_id) == 1;
+       no_pageshift = no_contig ||
+                       (!external && rte_eal_iova_mode() == RTE_IOVA_VA);
+       try_contig = !no_contig && !no_pageshift &&
+                       (rte_eal_has_hugepages() || external);
 
        if (no_pageshift) {
                pg_sz = 0;