From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by dpdk.org (Postfix) with ESMTP id 156D26CC2 for ; Thu, 26 Apr 2018 10:06:50 +0200 (CEST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga007.jf.intel.com ([10.7.209.58]) by orsmga101.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 26 Apr 2018 01:06:49 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.49,330,1520924400"; d="scan'208";a="36295155" Received: from irvmail001.ir.intel.com ([163.33.26.43]) by orsmga007.jf.intel.com with ESMTP; 26 Apr 2018 01:06:48 -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 w3Q86m62029476; Thu, 26 Apr 2018 09:06:48 +0100 Received: from sivswdev01.ir.intel.com (localhost [127.0.0.1]) by sivswdev01.ir.intel.com with ESMTP id w3Q86m4A029066; Thu, 26 Apr 2018 09:06:48 +0100 Received: (from aburakov@localhost) by sivswdev01.ir.intel.com with LOCAL id w3Q86lN2029062; Thu, 26 Apr 2018 09:06:47 +0100 From: Anatoly Burakov To: dev@dpdk.org Cc: shreyansh.jain@nxp.com Date: Thu, 26 Apr 2018 09:06:46 +0100 Message-Id: <777ae6b10a7524e188c07ba14e576fc7b0e21018.1524729978.git.anatoly.burakov@intel.com> X-Mailer: git-send-email 1.7.0.7 In-Reply-To: <90b66ba14bac0b9dc8b8a2258931463f6319e3f3.1524665242.git.anatoly.burakov@intel.com> References: <90b66ba14bac0b9dc8b8a2258931463f6319e3f3.1524665242.git.anatoly.burakov@intel.com> Subject: [dpdk-dev] [PATCH v2 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: Thu, 26 Apr 2018 08:06:51 -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 --- Notes: v2: - Add header to newly recalculated element start lib/librte_eal/common/include/rte_malloc.h | 1 + lib/librte_eal/common/malloc_elem.c | 59 ++++++++++++++++++++++++++++++ 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, 73 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..d28ede6 100644 --- a/lib/librte_eal/common/malloc_elem.c +++ b/lib/librte_eal/common/malloc_elem.c @@ -18,12 +18,71 @@ #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. this is + * a contiguous segment, and elem->size includes header len, so + * move element start point to where header would've started + */ + if (ms->iova != expected_iova) + contig_seg_start = RTE_PTR_SUB(cur_page, + MALLOC_ELEM_HEADER_LEN); + 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