[dpdk-dev,1/2] malloc: add biggest free IOVA-contiguous element to stats
Checks
Commit Message
User might be interested to find out what is the biggest chunk of
IOVA-contiguous free space that can be allocated from malloc. Add
relevant malloc-internal functions and expose this through malloc
stats calculation call.
Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
---
lib/librte_eal/common/include/rte_malloc.h | 1 +
lib/librte_eal/common/malloc_elem.c | 55 ++++++++++++++++++++++++++++++
lib/librte_eal/common/malloc_elem.h | 3 ++
lib/librte_eal/common/malloc_heap.c | 8 +++++
lib/librte_eal/common/rte_malloc.c | 2 ++
5 files changed, 69 insertions(+)
Comments
On 25-Apr-18 3:10 PM, Anatoly Burakov wrote:
> User might be interested to find out what is the biggest chunk of
> IOVA-contiguous free space that can be allocated from malloc. Add
> relevant malloc-internal functions and expose this through malloc
> stats calculation call.
>
> Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
> ---
Note: this breaks the ABI, but ABI is already broken for this release,
so it's OK.
@@ -27,6 +27,7 @@ struct rte_malloc_socket_stats {
size_t heap_totalsz_bytes; /**< Total bytes on heap */
size_t heap_freesz_bytes; /**< Total free bytes on heap */
size_t greatest_free_size; /**< Size in bytes of largest free block */
+ size_t greatest_free_iova_contig_size; /**< Size in bytes of largest IOVA-contiguous block */
unsigned free_count; /**< Number of free elements on heap */
unsigned alloc_count; /**< Number of allocated elements on heap */
size_t heap_allocsz_bytes; /**< Total allocated bytes on heap */
@@ -18,12 +18,67 @@
#include <rte_common.h>
#include <rte_spinlock.h>
+#include "eal_internal_cfg.h"
#include "eal_memalloc.h"
#include "malloc_elem.h"
#include "malloc_heap.h"
#define MIN_DATA_SIZE (RTE_CACHE_LINE_SIZE)
+size_t
+malloc_elem_find_max_iova_contig(struct malloc_elem *elem)
+{
+ void *cur_page, *contig_seg_start, *page_end, *elem_end, *cur_seg_end;
+ rte_iova_t expected_iova;
+ struct rte_memseg *ms;
+ size_t page_sz, cur, max;
+
+ /* if we're in IOVA as VA mode, or if we're in legacy mode with
+ * hugepages, all elements are IOVA-contiguous.
+ */
+ if (rte_eal_iova_mode() == RTE_IOVA_VA ||
+ (internal_config.legacy_mem && rte_eal_has_hugepages()))
+ return elem->size;
+
+ page_sz = (size_t)elem->msl->page_sz;
+ elem_end = RTE_PTR_ADD(elem, elem->size);
+ cur_page = RTE_PTR_ALIGN_FLOOR(elem, page_sz);
+ ms = rte_mem_virt2memseg(cur_page, elem->msl);
+ contig_seg_start = elem;
+
+ /* do first iteration outside the loop */
+ page_end = RTE_PTR_ADD(cur_page, page_sz);
+ cur_seg_end = RTE_MIN(page_end, elem_end);
+ cur = RTE_PTR_DIFF(cur_seg_end, contig_seg_start);
+ max = cur;
+ expected_iova = ms->iova + page_sz;
+ /* memsegs are contiguous in memory */
+ ms++;
+
+ cur_page = RTE_PTR_ADD(cur_page, page_sz);
+
+ while (cur_page < elem_end) {
+ page_end = RTE_PTR_ADD(cur_page, page_sz);
+ cur_seg_end = RTE_MIN(page_end, elem_end);
+
+ /* reset start of contiguous segment if unexpected iova */
+ if (ms->iova != expected_iova)
+ contig_seg_start = cur_page;
+ cur = RTE_PTR_DIFF(cur_seg_end, contig_seg_start);
+ /* update max if cur value is bigger */
+ if (cur > max)
+ max = cur;
+
+ /* move to next page */
+ cur_page = page_end;
+ expected_iova = ms->iova + page_sz;
+ /* memsegs are contiguous in memory */
+ ms++;
+ }
+
+ return max;
+}
+
/*
* Initialize a general malloc_elem header structure
*/
@@ -177,4 +177,7 @@ malloc_elem_free_list_index(size_t size);
void
malloc_elem_free_list_insert(struct malloc_elem *elem);
+size_t
+malloc_elem_find_max_iova_contig(struct malloc_elem *elem);
+
#endif /* MALLOC_ELEM_H_ */
@@ -764,16 +764,24 @@ malloc_heap_get_stats(struct malloc_heap *heap,
socket_stats->free_count = 0;
socket_stats->heap_freesz_bytes = 0;
socket_stats->greatest_free_size = 0;
+ socket_stats->greatest_free_iova_contig_size = 0;
/* Iterate through free list */
for (idx = 0; idx < RTE_HEAP_NUM_FREELISTS; idx++) {
for (elem = LIST_FIRST(&heap->free_head[idx]);
!!elem; elem = LIST_NEXT(elem, free_list))
{
+ size_t iova_contig_sz;
socket_stats->free_count++;
socket_stats->heap_freesz_bytes += elem->size;
if (elem->size > socket_stats->greatest_free_size)
socket_stats->greatest_free_size = elem->size;
+ iova_contig_sz =
+ malloc_elem_find_max_iova_contig(elem);
+ if (iova_contig_sz >
+ socket_stats->greatest_free_iova_contig_size)
+ socket_stats->greatest_free_iova_contig_size =
+ iova_contig_sz;
}
}
/* Get stats on overall heap and allocated memory on this heap */
@@ -195,6 +195,8 @@ rte_malloc_dump_stats(FILE *f, __rte_unused const char *type)
fprintf(f, "\tAlloc_size:%zu,\n", sock_stats.heap_allocsz_bytes);
fprintf(f, "\tGreatest_free_size:%zu,\n",
sock_stats.greatest_free_size);
+ fprintf(f, "\tGreatest_free_iova_contig_size:%zu,\n",
+ sock_stats.greatest_free_iova_contig_size);
fprintf(f, "\tAlloc_count:%u,\n",sock_stats.alloc_count);
fprintf(f, "\tFree_count:%u,\n", sock_stats.free_count);
}