malloc: make heap a doubly-linked list
[dpdk.git] / lib / librte_eal / common / malloc_heap.c
index d170d03..9c95166 100644 (file)
@@ -1,34 +1,5 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2010-2014 Intel Corporation
  */
 #include <stdint.h>
 #include <stddef.h>
@@ -87,7 +58,7 @@ check_hugepage_sz(unsigned flags, uint64_t hugepage_sz)
                check_flag = RTE_MEMZONE_16GB;
        }
 
-       return (check_flag & flags);
+       return check_flag & flags;
 }
 
 /*
@@ -99,15 +70,11 @@ check_hugepage_sz(unsigned flags, uint64_t hugepage_sz)
 static void
 malloc_heap_add_memseg(struct malloc_heap *heap, struct rte_memseg *ms)
 {
-       /* allocate the memory block headers, one at end, one at start */
        struct malloc_elem *start_elem = (struct malloc_elem *)ms->addr;
-       struct malloc_elem *end_elem = RTE_PTR_ADD(ms->addr,
-                       ms->len - MALLOC_ELEM_OVERHEAD);
-       end_elem = RTE_PTR_ALIGN_FLOOR(end_elem, RTE_CACHE_LINE_SIZE);
-       const size_t elem_size = (uintptr_t)end_elem - (uintptr_t)start_elem;
+       const size_t elem_size = ms->len - MALLOC_ELEM_OVERHEAD;
 
        malloc_elem_init(start_elem, heap, ms, elem_size);
-       malloc_elem_mkend(end_elem, start_elem);
+       malloc_elem_insert(start_elem);
        malloc_elem_free_list_insert(start_elem);
 
        heap->total_size += elem_size;
@@ -174,16 +141,56 @@ malloc_heap_alloc(struct malloc_heap *heap,
        return elem == NULL ? NULL : (void *)(&elem[1]);
 }
 
+int
+malloc_heap_free(struct malloc_elem *elem)
+{
+       struct malloc_heap *heap;
+       int ret;
+
+       if (!malloc_elem_cookies_ok(elem) || elem->state != ELEM_BUSY)
+               return -1;
+
+       /* elem may be merged with previous element, so keep heap address */
+       heap = elem->heap;
+
+       rte_spinlock_lock(&(heap->lock));
+
+       ret = malloc_elem_free(elem);
+
+       rte_spinlock_unlock(&(heap->lock));
+
+       return ret;
+}
+
+int
+malloc_heap_resize(struct malloc_elem *elem, size_t size)
+{
+       int ret;
+
+       if (!malloc_elem_cookies_ok(elem) || elem->state != ELEM_BUSY)
+               return -1;
+
+       rte_spinlock_lock(&(elem->heap->lock));
+
+       ret = malloc_elem_resize(elem, size);
+
+       rte_spinlock_unlock(&(elem->heap->lock));
+
+       return ret;
+}
+
 /*
  * 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 +212,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;
 }
 
@@ -221,14 +230,6 @@ rte_eal_malloc_heap_init(void)
        for (ms = &mcfg->memseg[0], ms_cnt = 0;
                        (ms_cnt < RTE_MAX_MEMSEG) && (ms->len > 0);
                        ms_cnt++, ms++) {
-#ifdef RTE_LIBRTE_IVSHMEM
-               /*
-                * if segment has ioremap address set, it's an IVSHMEM segment and
-                * it is not memory to allocate from.
-                */
-               if (ms->ioremap_addr != 0)
-                       continue;
-#endif
                malloc_heap_add_memseg(&mcfg->malloc_heaps[ms->socket_id], ms);
        }