From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 1BB6FA04C6 for ; Thu, 14 Nov 2019 14:58:28 +0100 (CET) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id D9A9B2C08; Thu, 14 Nov 2019 14:58:27 +0100 (CET) Received: from mga18.intel.com (mga18.intel.com [134.134.136.126]) by dpdk.org (Postfix) with ESMTP id 9DB91374; Thu, 14 Nov 2019 14:58:24 +0100 (CET) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga005.fm.intel.com ([10.253.24.32]) by orsmga106.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 14 Nov 2019 05:58:23 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.68,304,1569308400"; d="scan'208";a="404980508" Received: from silpixa00399498.ir.intel.com (HELO silpixa00399498.ger.corp.intel.com) ([10.237.223.151]) by fmsmga005.fm.intel.com with ESMTP; 14 Nov 2019 05:58:21 -0800 From: Anatoly Burakov To: dev@dpdk.org Cc: Olivier Matz , Andrew Rybchenko , david.marchand@redhat.com, stable@dpdk.org Date: Thu, 14 Nov 2019 13:58:20 +0000 Message-Id: <825d02ef7f7b6ab65a36d9fa4719847228537384.1573739893.git.anatoly.burakov@intel.com> X-Mailer: git-send-email 2.17.1 Subject: [dpdk-stable] [PATCH 1/2] mempool: use actual IOVA addresses when populating X-BeenThere: stable@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches for DPDK stable branches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: stable-bounces@dpdk.org Sender: "stable" Currently, when mempool is being populated, we get IOVA address of every segment using rte_mem_virt2iova(). This works for internal memory, but does not really work for external memory, and does not work on platforms which return RTE_BAD_IOVA as a result of this call (such as FreeBSD). Moreover, even when it works, the function in question will do unnecessary pagewalks in IOVA as PA mode, as it falls back to rte_mem_virt2phy() instead of just doing a lookup in internal memseg table. To fix it, replace the call to first attempt to look through the internal memseg table (this takes care of internal and external memory), and fall back to rte_mem_virt2iova() when unable to perform VA->IOVA translation via memseg table. Fixes: 66cc45e293ed ("mem: replace memseg with memseg lists") Cc: stable@dpdk.org Signed-off-by: Anatoly Burakov --- lib/librte_mempool/rte_mempool.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/lib/librte_mempool/rte_mempool.c b/lib/librte_mempool/rte_mempool.c index 40cae3eb67..8da2e471c7 100644 --- a/lib/librte_mempool/rte_mempool.c +++ b/lib/librte_mempool/rte_mempool.c @@ -356,6 +356,19 @@ rte_mempool_populate_iova(struct rte_mempool *mp, char *vaddr, return ret; } +static rte_iova_t +get_iova(void *addr) +{ + struct rte_memseg *ms; + + /* try registered memory first */ + ms = rte_mem_virt2memseg(addr, NULL); + if (ms == NULL || ms->iova == RTE_BAD_IOVA) + /* fall back to actual physical address */ + return rte_mem_virt2iova(addr); + return ms->iova + RTE_PTR_DIFF(addr, ms->addr); +} + /* Populate the mempool with a virtual area. Return the number of * objects added, or a negative value on error. */ @@ -375,7 +388,7 @@ rte_mempool_populate_virt(struct rte_mempool *mp, char *addr, for (off = 0; off < len && mp->populated_size < mp->size; off += phys_len) { - iova = rte_mem_virt2iova(addr + off); + iova = get_iova(addr + off); if (iova == RTE_BAD_IOVA && rte_eal_has_hugepages()) { ret = -EINVAL; @@ -391,7 +404,7 @@ rte_mempool_populate_virt(struct rte_mempool *mp, char *addr, phys_len = RTE_MIN(phys_len + pg_sz, len - off)) { rte_iova_t iova_tmp; - iova_tmp = rte_mem_virt2iova(addr + off + phys_len); + iova_tmp = get_iova(addr + off + phys_len); if (iova_tmp == RTE_BAD_IOVA || iova_tmp != iova + phys_len) -- 2.17.1