From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga18.intel.com (mga18.intel.com [134.134.136.126]) by dpdk.org (Postfix) with ESMTP id DEC106CC8 for ; Wed, 25 Apr 2018 16:10:47 +0200 (CEST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga004.jf.intel.com ([10.7.209.38]) by orsmga106.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 25 Apr 2018 07:10:46 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.49,326,1520924400"; d="scan'208";a="194300030" Received: from irvmail001.ir.intel.com ([163.33.26.43]) by orsmga004.jf.intel.com with ESMTP; 25 Apr 2018 07:10:45 -0700 Received: from sivswdev01.ir.intel.com (sivswdev01.ir.intel.com [10.237.217.45]) by irvmail001.ir.intel.com (8.14.3/8.13.6/MailSET/Hub) with ESMTP id w3PEAjlJ028314; Wed, 25 Apr 2018 15:10:45 +0100 Received: from sivswdev01.ir.intel.com (localhost [127.0.0.1]) by sivswdev01.ir.intel.com with ESMTP id w3PEAjqi030763; Wed, 25 Apr 2018 15:10:45 +0100 Received: (from aburakov@localhost) by sivswdev01.ir.intel.com with LOCAL id w3PEAjon030759; Wed, 25 Apr 2018 15:10:45 +0100 From: Anatoly Burakov To: dev@dpdk.org Cc: shreyansh.jain@nxp.com Date: Wed, 25 Apr 2018 15:10:43 +0100 Message-Id: <90b66ba14bac0b9dc8b8a2258931463f6319e3f3.1524665242.git.anatoly.burakov@intel.com> X-Mailer: git-send-email 1.7.0.7 Subject: [dpdk-dev] [PATCH 1/2] malloc: add biggest free IOVA-contiguous element to stats X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 25 Apr 2018 14:10:48 -0000 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 --- 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(+) diff --git a/lib/librte_eal/common/include/rte_malloc.h b/lib/librte_eal/common/include/rte_malloc.h index a9fb7e4..2553201 100644 --- a/lib/librte_eal/common/include/rte_malloc.h +++ b/lib/librte_eal/common/include/rte_malloc.h @@ -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 */ diff --git a/lib/librte_eal/common/malloc_elem.c b/lib/librte_eal/common/malloc_elem.c index ee79dcd..415ce64 100644 --- a/lib/librte_eal/common/malloc_elem.c +++ b/lib/librte_eal/common/malloc_elem.c @@ -18,12 +18,67 @@ #include #include +#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 */ diff --git a/lib/librte_eal/common/malloc_elem.h b/lib/librte_eal/common/malloc_elem.h index 8f4aef8..19e8db5 100644 --- a/lib/librte_eal/common/malloc_elem.h +++ b/lib/librte_eal/common/malloc_elem.h @@ -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_ */ diff --git a/lib/librte_eal/common/malloc_heap.c b/lib/librte_eal/common/malloc_heap.c index 590e9e3..d8ad164 100644 --- a/lib/librte_eal/common/malloc_heap.c +++ b/lib/librte_eal/common/malloc_heap.c @@ -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 */ diff --git a/lib/librte_eal/common/rte_malloc.c b/lib/librte_eal/common/rte_malloc.c index b51a6d1..b4e87a3 100644 --- a/lib/librte_eal/common/rte_malloc.c +++ b/lib/librte_eal/common/rte_malloc.c @@ -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); } -- 2.7.4