From patchwork Fri Jul 6 13:17:28 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Burakov, Anatoly" X-Patchwork-Id: 42504 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 685201BF0E; Fri, 6 Jul 2018 15:17:49 +0200 (CEST) Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by dpdk.org (Postfix) with ESMTP id 2AA5A1BE4E for ; Fri, 6 Jul 2018 15:17:38 +0200 (CEST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga005.fm.intel.com ([10.253.24.32]) by orsmga101.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 06 Jul 2018 06:17:35 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.51,316,1526367600"; d="scan'208";a="243136088" Received: from irvmail001.ir.intel.com ([163.33.26.43]) by fmsmga005.fm.intel.com with ESMTP; 06 Jul 2018 06:17:34 -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 w66DHY8f027488; Fri, 6 Jul 2018 14:17:34 +0100 Received: from sivswdev01.ir.intel.com (localhost [127.0.0.1]) by sivswdev01.ir.intel.com with ESMTP id w66DHY5w003797; Fri, 6 Jul 2018 14:17:34 +0100 Received: (from aburakov@localhost) by sivswdev01.ir.intel.com with LOCAL id w66DHXaI003793; Fri, 6 Jul 2018 14:17:33 +0100 From: Anatoly Burakov To: dev@dpdk.org Cc: srinath.mannam@broadcom.com, scott.branden@broadcom.com, ajit.khaparde@broadcom.com Date: Fri, 6 Jul 2018 14:17:28 +0100 Message-Id: <19df594b15fcecefc3d9790e7f7b426a4f609a10.1530881548.git.anatoly.burakov@intel.com> X-Mailer: git-send-email 1.7.0.7 In-Reply-To: References: In-Reply-To: References: Subject: [dpdk-dev] [RFC 07/11] malloc: enable creating new malloc heaps 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: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Add API to allow creating new malloc heaps. They will be created with indexes higher than heaps reserved for NUMA sockets, and up to RTE_MAX_HEAPS. Signed-off-by: Anatoly Burakov --- lib/librte_eal/common/include/rte_malloc.h | 21 ++++++++++ lib/librte_eal/common/malloc_heap.c | 16 ++++++++ lib/librte_eal/common/malloc_heap.h | 3 ++ lib/librte_eal/common/rte_malloc.c | 46 ++++++++++++++++++++++ lib/librte_eal/rte_eal_version.map | 1 + 5 files changed, 87 insertions(+) diff --git a/lib/librte_eal/common/include/rte_malloc.h b/lib/librte_eal/common/include/rte_malloc.h index f1bcd9b65..fa6de073a 100644 --- a/lib/librte_eal/common/include/rte_malloc.h +++ b/lib/librte_eal/common/include/rte_malloc.h @@ -253,6 +253,27 @@ rte_malloc_from_heap(const char *heap_name, const char *type, size_t size, void rte_free(void *ptr); +/** + * Creates a new empty malloc heap with a specified name. + * + * @note Concurrently creating or destroying heaps is not safe. + * + * @note This function does not need to be called in multiple processes, as + * multiprocess synchronization will happen automatically as far as heap data + * is concerned. However, before accessing pointers to memory in this heap, it + * is responsibility of the user to ensure that the heap memory is accessible + * in all processes. + * + * @param heap_name + * Name of the heap to create. + * + * @return + * - 0 on successful creation. + * - -1 on error. + */ +int __rte_experimental +rte_malloc_heap_create(const char *heap_name); + /** * If malloc debug is enabled, check a memory block for header * and trailer markers to indicate that all is well with the block. diff --git a/lib/librte_eal/common/malloc_heap.c b/lib/librte_eal/common/malloc_heap.c index a33acc252..f5d103626 100644 --- a/lib/librte_eal/common/malloc_heap.c +++ b/lib/librte_eal/common/malloc_heap.c @@ -892,6 +892,22 @@ malloc_heap_dump(struct malloc_heap *heap, FILE *f) rte_spinlock_unlock(&heap->lock); } +int +malloc_heap_create(struct malloc_heap *heap, const char *heap_name) +{ + /* initialize empty heap */ + heap->alloc_count = 0; + heap->first = NULL; + heap->last = NULL; + LIST_INIT(heap->free_head); + rte_spinlock_init(&heap->lock); + heap->total_size = 0; + + /* set up name */ + strlcpy(heap->name, heap_name, RTE_HEAP_NAME_MAX_LEN); + return 0; +} + int rte_eal_malloc_heap_init(void) { diff --git a/lib/librte_eal/common/malloc_heap.h b/lib/librte_eal/common/malloc_heap.h index a7e408c99..aa819ef65 100644 --- a/lib/librte_eal/common/malloc_heap.h +++ b/lib/librte_eal/common/malloc_heap.h @@ -35,6 +35,9 @@ malloc_heap_alloc_on_heap_id(const char *type, size_t size, unsigned int heap_id, unsigned int flags, size_t align, size_t bound, bool contig); +int +malloc_heap_create(struct malloc_heap *heap, const char *heap_name); + int malloc_heap_find_named_heap_idx(const char *name); diff --git a/lib/librte_eal/common/rte_malloc.c b/lib/librte_eal/common/rte_malloc.c index 215876a59..e000dc5b7 100644 --- a/lib/librte_eal/common/rte_malloc.c +++ b/lib/librte_eal/common/rte_malloc.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -272,3 +273,48 @@ rte_malloc_virt2iova(const void *addr) return ms->iova + RTE_PTR_DIFF(addr, ms->addr); } + +int +rte_malloc_heap_create(const char *heap_name) +{ + struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config; + struct malloc_heap *heap = NULL; + int i; + + /* iova_addrs is allowed to be NULL */ + if (heap_name == NULL || + strnlen(heap_name, RTE_HEAP_NAME_MAX_LEN) == 0 || + strnlen(heap_name, RTE_HEAP_NAME_MAX_LEN) == + RTE_HEAP_NAME_MAX_LEN) { + rte_errno = EINVAL; + return -1; + } + /* check if there is space in the heap list, or if heap with this name + * already exists. start from non-socket heaps. + */ + for (i = rte_socket_count(); i < RTE_MAX_HEAPS; i++) { + struct malloc_heap *tmp = &mcfg->malloc_heaps[i]; + /* existing heap */ + if (strncmp(heap_name, tmp->name, + RTE_HEAP_NAME_MAX_LEN) == 0) { + RTE_LOG(ERR, EAL, "Heap %s already exists\n", + heap_name); + rte_errno = EEXIST; + return -1; + } + /* empty heap */ + if (strnlen(tmp->name, RTE_HEAP_NAME_MAX_LEN) == 0) { + heap = tmp; + break; + } + } + if (heap == NULL) { + RTE_LOG(ERR, EAL, "Cannot create new heap: no space\n"); + rte_errno = ENOSPC; + return -1; + } + + /* we're sure that we can create a new heap, so do it */ + return malloc_heap_create(heap, heap_name); +} + diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map index 716a7585d..f3c375156 100644 --- a/lib/librte_eal/rte_eal_version.map +++ b/lib/librte_eal/rte_eal_version.map @@ -280,6 +280,7 @@ EXPERIMENTAL { rte_malloc_dump_heaps; rte_malloc_from_heap; rte_malloc_get_stats_from_heap; + rte_malloc_heap_create; rte_mem_alloc_validator_register; rte_mem_alloc_validator_unregister; rte_mem_event_callback_register;