From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-we0-f176.google.com (mail-we0-f176.google.com [74.125.82.176]) by dpdk.org (Postfix) with ESMTP id 290DD5948 for ; Fri, 26 Jul 2013 16:40:11 +0200 (CEST) Received: by mail-we0-f176.google.com with SMTP id q56so1927422wes.21 for ; Fri, 26 Jul 2013 07:40:34 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references :in-reply-to:references:x-gm-message-state; bh=bt9WmMxl/Gj7tSeNEYEDdtve9cB2UrSrv12o5QJBwCs=; b=njH4n8aHGAR74U9DlbZQYdnKGkLSx/tvXhVjAoXYVPtDqYFaRgLRlH7HuN8MyJzTbG bjI5Ex6kBZ5x7EcuzdCE0blBdXreNsM2ez7TaBAMa+yy1uDTmK5f1RmYXqJ1VQrcKu2G nujl8gNRF/JOMChB1JSNUq8R8QpAHI7q7VhnLYb8vBK/Cu/WZgA3DOKij1NVRlFlnd+C cKaaPsZx+kZ35MvkeQGCR/MIoeb7SlxQbk8GCxPUX56m4RTigv2lwnIFowPiQKDQ7ngL 3f93UgEeXqv5kFTZ6snvpDwy/t6JMCgRsui9LtXDbhD7CKK60thOOaZQde610L9sLEKc J1HA== X-Received: by 10.194.22.41 with SMTP id a9mr34708519wjf.16.1374849634029; Fri, 26 Jul 2013 07:40:34 -0700 (PDT) Received: from 6wind.com (6wind.net2.nerim.net. [213.41.180.237]) by mx.google.com with ESMTPSA id l2sm5171933wif.8.2013.07.26.07.40.31 for (version=TLSv1.1 cipher=RC4-SHA bits=128/128); Fri, 26 Jul 2013 07:40:33 -0700 (PDT) From: Damien Millescamps To: dev@dpdk.org Date: Fri, 26 Jul 2013 16:39:13 +0200 Message-Id: X-Mailer: git-send-email 1.7.2.5 In-Reply-To: References: In-Reply-To: References: X-Gm-Message-State: ALoCoQlA8nqWB1Ms3bbCudUScRbr5QkCnZkUuzNCYiexKUt3sUD8iZt0L5X5F9IfEoDOWgQe67eT Subject: [dpdk-dev] [PATCH 2/2] mem: fix mempool for --no-huge X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 26 Jul 2013 14:40:11 -0000 In --no-huge mode, mempool provides objects with their associated header/trailer fitting in a standard page (usually 4KB). This means all non-UIO driver should work correctly in this mode, since UIO drivers allocate ring sizes that cannot fit in a page. Extend rte_mempool_virt2phy to obtain the correct physical address when elements of the pool are not on the same physically contiguous memory region. This is a first step for enhancement PR #29696. Reason for this patch is to be able to run on a kernel < 2.6.37 without the need to patch it, since all kernel below are either bugged or don't have huge page support at all (< 2.6.28). Signed-off-by: Damien Millescamps --- lib/librte_eal/linuxapp/eal/eal_memory.c | 2 +- lib/librte_mempool/rte_mempool.c | 54 +++++++++++++++++++++++++++++- lib/librte_mempool/rte_mempool.h | 20 +++++++---- 3 files changed, 67 insertions(+), 9 deletions(-) diff --git a/lib/librte_eal/linuxapp/eal/eal_memory.c b/lib/librte_eal/linuxapp/eal/eal_memory.c index ce0c2d8..00b5952 100644 --- a/lib/librte_eal/linuxapp/eal/eal_memory.c +++ b/lib/librte_eal/linuxapp/eal/eal_memory.c @@ -780,7 +780,7 @@ rte_eal_hugepage_init(void) /* get pointer to global configuration */ mcfg = rte_eal_get_configuration()->mem_config; - /* for debug purposes, hugetlbfs can be disabled */ + /* hugetlbfs can be disabled */ if (internal_config.no_hugetlbfs) { addr = malloc(internal_config.memory); mcfg->memseg[0].phys_addr = (phys_addr_t)(uintptr_t)addr; diff --git a/lib/librte_mempool/rte_mempool.c b/lib/librte_mempool/rte_mempool.c index aa8e76a..87183df 100644 --- a/lib/librte_mempool/rte_mempool.c +++ b/lib/librte_mempool/rte_mempool.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -139,6 +140,8 @@ rte_mempool_create(const char *name, unsigned n, unsigned elt_size, uint32_t header_size, trailer_size; unsigned i; void *obj; + void *startaddr; + int page_size = getpagesize(); /* compilation-time checks */ RTE_BUILD_BUG_ON((sizeof(struct rte_mempool) & @@ -227,6 +230,20 @@ rte_mempool_create(const char *name, unsigned n, unsigned elt_size, trailer_size); trailer_size = new_size - header_size - elt_size; } + if (! rte_eal_has_hugepages()) { + /* + * compute trailer size so that pool elements fit exactly in + * a standard page + */ + int new_size = page_size - header_size - elt_size; + if (new_size < 0 || (unsigned int)new_size < trailer_size) { + printf("When hugepages are disabled, pool objects " + "can't exceed PAGE_SIZE: %d + %d + %d > %d\n", + header_size, elt_size, trailer_size, page_size); + return NULL; + } + trailer_size = new_size; + } /* this is the size of an object, including header and trailer */ total_elt_size = header_size + elt_size + trailer_size; @@ -235,8 +252,31 @@ rte_mempool_create(const char *name, unsigned n, unsigned elt_size, * cache-aligned */ private_data_size = (private_data_size + CACHE_LINE_MASK) & (~CACHE_LINE_MASK); + + if (! rte_eal_has_hugepages()) { + /* + * expand private data size to a whole page, so that the + * first pool element will start on a new standard page + */ + int head = sizeof(struct rte_mempool); + int new_size = (private_data_size + head) % page_size; + if (new_size) { + private_data_size += page_size - new_size; + } + } + mempool_size = total_elt_size * n + sizeof(struct rte_mempool) + private_data_size; + + if (! rte_eal_has_hugepages()) { + /* + * we want the memory pool to start on a page boundary, + * because pool elements crossing page boundaries would + * result in discontiguous physical addresses + */ + mempool_size += page_size; + } + rte_snprintf(mz_name, sizeof(mz_name), "MP_%s", name); mz = rte_memzone_reserve(mz_name, mempool_size, socket_id, mz_flags); @@ -248,8 +288,20 @@ rte_mempool_create(const char *name, unsigned n, unsigned elt_size, if (mz == NULL) goto exit; + if (rte_eal_has_hugepages()) { + startaddr = (void*)mz->addr; + } else { + /* align memory pool start address on a page boundary */ + unsigned long addr = (unsigned long)mz->addr; + if (addr & (page_size - 1)) { + addr += page_size; + addr &= ~(page_size - 1); + } + startaddr = (void*)addr; + } + /* init the mempool structure */ - mp = mz->addr; + mp = startaddr; memset(mp, 0, sizeof(*mp)); rte_snprintf(mp->name, sizeof(mp->name), "%s", name); mp->phys_addr = mz->phys_addr; diff --git a/lib/librte_mempool/rte_mempool.h b/lib/librte_mempool/rte_mempool.h index 67d7f09..33ce35c 100644 --- a/lib/librte_mempool/rte_mempool.h +++ b/lib/librte_mempool/rte_mempool.h @@ -950,16 +950,22 @@ rte_mempool_empty(const struct rte_mempool *mp) * @return * The physical address of the elt element. */ -static inline phys_addr_t rte_mempool_virt2phy(const struct rte_mempool *mp, - const void *elt) +static inline phys_addr_t +rte_mempool_virt2phy(const struct rte_mempool *mp, const void *elt) { - uintptr_t off; - - off = (const char *)elt - (const char *)mp; - return mp->phys_addr + off; + if (rte_eal_has_hugepages()) { + uintptr_t offset = (const char *)elt - (const char *)mp; + return mp->phys_addr + offset; + } else { + /* + * If huge pages are disabled, we cannot assume the + * memory region to be physically contiguous. + * Lookup for each element. + */ + return rte_mem_virt2phy(elt); + } } - /** * Check the consistency of mempool objects. * -- 1.7.2.5