From: Anatoly Burakov <anatoly.burakov@intel.com>
To: dev@dpdk.org
Cc: remy.horton@intel.com
Subject: [dpdk-dev] [PATCH v5 1/3] malloc: add biggest free IOVA-contiguous element to stats
Date: Mon, 14 May 2018 14:47:28 +0100 [thread overview]
Message-ID: <064458eb7fc48457ed4e7fed521e11e68cb32c62.1526305599.git.anatoly.burakov@intel.com> (raw)
In-Reply-To: <cover.1526305599.git.anatoly.burakov@intel.com>
In-Reply-To: <cover.1526305599.git.anatoly.burakov@intel.com>
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>
Acked-by: Remy Horton <remy.horton@intel.com>
---
Notes:
v4:
- Fix comments to be more up to date with v4 code
- Add comments explaining trailer handling
v2:
- Add header to newly recalculated element start
v2:
- Add header to newly recalculated element start
lib/librte_eal/common/include/rte_malloc.h | 1 +
lib/librte_eal/common/malloc_elem.c | 79 ++++++++++++++++++++++++++++++
lib/librte_eal/common/malloc_elem.h | 6 +++
lib/librte_eal/common/malloc_heap.c | 11 +++++
lib/librte_eal/common/rte_malloc.c | 2 +
5 files changed, 99 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 9bfe9b9..f1bb4fe 100644
--- a/lib/librte_eal/common/malloc_elem.c
+++ b/lib/librte_eal/common/malloc_elem.c
@@ -18,10 +18,89 @@
#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"
+size_t
+malloc_elem_find_max_iova_contig(struct malloc_elem *elem, size_t align)
+{
+ void *cur_page, *contig_seg_start, *page_end, *cur_seg_end;
+ void *data_start, *data_end;
+ rte_iova_t expected_iova;
+ struct rte_memseg *ms;
+ size_t page_sz, cur, max;
+
+ page_sz = (size_t)elem->msl->page_sz;
+ data_start = RTE_PTR_ADD(elem, MALLOC_ELEM_HEADER_LEN);
+ data_end = RTE_PTR_ADD(elem, elem->size - MALLOC_ELEM_TRAILER_LEN);
+ /* segment must start after header and with specified alignment */
+ contig_seg_start = RTE_PTR_ALIGN_CEIL(data_start, align);
+
+ /* 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 RTE_PTR_DIFF(data_end, contig_seg_start);
+
+ cur_page = RTE_PTR_ALIGN_FLOOR(contig_seg_start, page_sz);
+ ms = rte_mem_virt2memseg(cur_page, elem->msl);
+
+ /* do first iteration outside the loop */
+ page_end = RTE_PTR_ADD(cur_page, page_sz);
+ cur_seg_end = RTE_MIN(page_end, data_end);
+ cur = RTE_PTR_DIFF(cur_seg_end, contig_seg_start) -
+ MALLOC_ELEM_TRAILER_LEN;
+ 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 < data_end) {
+ page_end = RTE_PTR_ADD(cur_page, page_sz);
+ cur_seg_end = RTE_MIN(page_end, data_end);
+
+ /* reset start of contiguous segment if unexpected iova */
+ if (ms->iova != expected_iova) {
+ /* next contiguous segment must start at specified
+ * alignment.
+ */
+ contig_seg_start = RTE_PTR_ALIGN(cur_page, align);
+ /* new segment start may be on a different page, so find
+ * the page and skip to next iteration to make sure
+ * we're not blowing past data end.
+ */
+ ms = rte_mem_virt2memseg(contig_seg_start, elem->msl);
+ cur_page = ms->addr;
+ /* don't trigger another recalculation */
+ expected_iova = ms->iova;
+ continue;
+ }
+ /* cur_seg_end ends on a page boundary or on data end. if we're
+ * looking at data end, then malloc trailer is already included
+ * in the calculations. if we're looking at page end, then we
+ * know there's more data past this page and thus there's space
+ * for malloc element trailer, so don't count it here.
+ */
+ 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 7331af9..e2bda4c 100644
--- a/lib/librte_eal/common/malloc_elem.h
+++ b/lib/librte_eal/common/malloc_elem.h
@@ -179,4 +179,10 @@ malloc_elem_free_list_index(size_t size);
void
malloc_elem_free_list_insert(struct malloc_elem *elem);
+/*
+ * Find biggest IOVA-contiguous zone within an element with specified alignment.
+ */
+size_t
+malloc_elem_find_max_iova_contig(struct malloc_elem *elem, size_t align);
+
#endif /* MALLOC_ELEM_H_ */
diff --git a/lib/librte_eal/common/malloc_heap.c b/lib/librte_eal/common/malloc_heap.c
index d6cf3af..9305b38 100644
--- a/lib/librte_eal/common/malloc_heap.c
+++ b/lib/librte_eal/common/malloc_heap.c
@@ -803,16 +803,27 @@ 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,
+ RTE_CACHE_LINE_SIZE);
+ /* find_max_iova_contig doesn't include overhead */
+ iova_contig_sz += MALLOC_ELEM_OVERHEAD;
+ 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
next prev parent reply other threads:[~2018-05-14 13:47 UTC|newest]
Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-04-25 14:10 [dpdk-dev] [PATCH 1/2] " Anatoly Burakov
2018-04-25 14:10 ` [dpdk-dev] [PATCH 2/2] memzone: allow IOVA-contiguous memzones with zero size Anatoly Burakov
2018-04-25 14:40 ` [dpdk-dev] [PATCH 1/2] malloc: add biggest free IOVA-contiguous element to stats Burakov, Anatoly
2018-04-26 8:06 ` [dpdk-dev] [PATCH v2 " Anatoly Burakov
2018-05-03 17:17 ` [dpdk-dev] [PATCH v3 0/3] Improve zero-length memzone allocation Anatoly Burakov
2018-05-14 11:19 ` [dpdk-dev] [PATCH v4 " Anatoly Burakov
2018-05-14 13:47 ` [dpdk-dev] [PATCH v5 " Anatoly Burakov
2018-05-31 9:50 ` [dpdk-dev] [PATCH v6 " Anatoly Burakov
2018-07-13 9:24 ` Thomas Monjalon
2018-05-31 9:50 ` [dpdk-dev] [PATCH v6 1/3] malloc: add finding biggest free IOVA-contiguous element Anatoly Burakov
2018-05-31 9:51 ` [dpdk-dev] [PATCH v6 2/3] malloc: allow reserving biggest element Anatoly Burakov
2018-05-31 9:51 ` [dpdk-dev] [PATCH v6 3/3] memzone: improve zero-length memzone reserve Anatoly Burakov
2018-05-14 13:47 ` Anatoly Burakov [this message]
2018-05-14 13:58 ` [dpdk-dev] [PATCH v5 1/3] malloc: add biggest free IOVA-contiguous element to stats Shreyansh Jain
2018-05-14 13:47 ` [dpdk-dev] [PATCH v5 2/3] malloc: allow reserving biggest element Anatoly Burakov
2018-05-14 13:47 ` [dpdk-dev] [PATCH v5 3/3] memzone: improve zero-length memzone reserve Anatoly Burakov
2018-05-14 11:19 ` [dpdk-dev] [PATCH v4 1/3] malloc: add biggest free IOVA-contiguous element to stats Anatoly Burakov
2018-05-14 11:19 ` [dpdk-dev] [PATCH v4 2/3] malloc: allow reserving biggest element Anatoly Burakov
2018-05-14 11:19 ` [dpdk-dev] [PATCH v4 3/3] memzone: improve zero-length memzone reserve Anatoly Burakov
2018-05-03 17:17 ` [dpdk-dev] [PATCH v3 1/3] malloc: add biggest free IOVA-contiguous element to stats Anatoly Burakov
2018-05-10 13:39 ` Remy Horton
2018-05-03 17:18 ` [dpdk-dev] [PATCH v3 2/3] malloc: allow reserving biggest element Anatoly Burakov
2018-05-10 13:57 ` Remy Horton
2018-05-14 8:22 ` Burakov, Anatoly
2018-05-03 17:18 ` [dpdk-dev] [PATCH v3 3/3] memzone: improve zero-length memzone reserve Anatoly Burakov
2018-05-11 10:25 ` Remy Horton
2018-05-14 8:21 ` Burakov, Anatoly
2018-05-14 11:29 ` Burakov, Anatoly
2018-05-14 12:23 ` Burakov, Anatoly
2018-05-15 6:24 ` Remy Horton
2018-05-15 8:37 ` Burakov, Anatoly
2018-04-26 8:06 ` [dpdk-dev] [PATCH v2 2/2] memzone: allow IOVA-contiguous memzones with zero size Anatoly Burakov
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=064458eb7fc48457ed4e7fed521e11e68cb32c62.1526305599.git.anatoly.burakov@intel.com \
--to=anatoly.burakov@intel.com \
--cc=dev@dpdk.org \
--cc=remy.horton@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).