When we're gathering statistics, we are traversing the freelist,
which may change under our feet in multithreaded scenario. This
is verified by occasional segfaults when running malloc autotest
on a machine with big amount of cores.

This patch protects malloc heap stats call with a lock. It changes
its definition in the process due to locking invalidating the
const-ness, but this isn't a public API, so that's OK.

Cc: sta...@dpdk.org
Signed-off-by: Anatoly Burakov <anatoly.bura...@intel.com>
---
 lib/librte_eal/common/malloc_heap.c | 6 +++++-
 lib/librte_eal/common/malloc_heap.h | 2 +-
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/lib/librte_eal/common/malloc_heap.c 
b/lib/librte_eal/common/malloc_heap.c
index 267a4c6..c731f1c 100644
--- a/lib/librte_eal/common/malloc_heap.c
+++ b/lib/librte_eal/common/malloc_heap.c
@@ -178,12 +178,14 @@ malloc_heap_alloc(struct malloc_heap *heap,
  * Function to retrieve data for heap on given socket
  */
 int
-malloc_heap_get_stats(const struct malloc_heap *heap,
+malloc_heap_get_stats(struct malloc_heap *heap,
                struct rte_malloc_socket_stats *socket_stats)
 {
        size_t idx;
        struct malloc_elem *elem;
 
+       rte_spinlock_lock(&heap->lock);
+
        /* Initialise variables for heap */
        socket_stats->free_count = 0;
        socket_stats->heap_freesz_bytes = 0;
@@ -205,6 +207,8 @@ malloc_heap_get_stats(const struct malloc_heap *heap,
        socket_stats->heap_allocsz_bytes = (socket_stats->heap_totalsz_bytes -
                        socket_stats->heap_freesz_bytes);
        socket_stats->alloc_count = heap->alloc_count;
+
+       rte_spinlock_unlock(&heap->lock);
        return 0;
 }
 
diff --git a/lib/librte_eal/common/malloc_heap.h 
b/lib/librte_eal/common/malloc_heap.h
index 3ccbef0..3b1166f 100644
--- a/lib/librte_eal/common/malloc_heap.h
+++ b/lib/librte_eal/common/malloc_heap.h
@@ -57,7 +57,7 @@ malloc_heap_alloc(struct malloc_heap *heap,   const char 
*type, size_t size,
                unsigned flags, size_t align, size_t bound);
 
 int
-malloc_heap_get_stats(const struct malloc_heap *heap,
+malloc_heap_get_stats(struct malloc_heap *heap,
                struct rte_malloc_socket_stats *socket_stats);
 
 int
-- 
2.7.4

Reply via email to