malloc: protect stats with lock
authorAnatoly Burakov <anatoly.burakov@intel.com>
Thu, 21 Dec 2017 17:32:04 +0000 (17:32 +0000)
committerThomas Monjalon <thomas@monjalon.net>
Fri, 12 Jan 2018 14:46:19 +0000 (15:46 +0100)
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.

Fixes: 2a5c356e177d ("memory: stats for malloc")
Cc: stable@dpdk.org
Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
lib/librte_eal/common/malloc_heap.c
lib/librte_eal/common/malloc_heap.h

index b98b3af..7aafc88 100644 (file)
@@ -149,12 +149,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;
@@ -176,6 +178,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;
 }
 
index be5e6e6..e0defa7 100644 (file)
@@ -28,7 +28,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