From patchwork Thu Apr 7 11:00:00 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Burakov, Anatoly" X-Patchwork-Id: 11968 Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [IPv6:::1]) by dpdk.org (Postfix) with ESMTP id 606E029D2; Thu, 7 Apr 2016 13:00:15 +0200 (CEST) Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by dpdk.org (Postfix) with ESMTP id EBCD0E07 for ; Thu, 7 Apr 2016 13:00:13 +0200 (CEST) Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga101.fm.intel.com with ESMTP; 07 Apr 2016 04:00:03 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.24,449,1455004800"; d="scan'208";a="940240121" Received: from irvmail001.ir.intel.com ([163.33.26.43]) by fmsmga001.fm.intel.com with ESMTP; 07 Apr 2016 04:00:02 -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 u37B00Qt023136; Thu, 7 Apr 2016 12:00:00 +0100 Received: from sivswdev01.ir.intel.com (localhost [127.0.0.1]) by sivswdev01.ir.intel.com with ESMTP id u37B00vb024194; Thu, 7 Apr 2016 12:00:00 +0100 Received: (from aburakov@localhost) by sivswdev01.ir.intel.com with id u37B00vR024190; Thu, 7 Apr 2016 12:00:00 +0100 From: Anatoly Burakov To: dev@dpdk.org Cc: david.verbeiren@intel.com, thomas.monjalon@6wind.com Date: Thu, 7 Apr 2016 12:00:00 +0100 Message-Id: <1460026800-24159-1-git-send-email-anatoly.burakov@intel.com> X-Mailer: git-send-email 1.7.4.1 In-Reply-To: <1450564772-20000-1-git-send-email-david.verbeiren@intel.com> References: <1450564772-20000-1-git-send-email-david.verbeiren@intel.com> Subject: [dpdk-dev] [PATCH v2] ivshmem: avoid infinite loop when concatenating adjacent segments 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: , Errors-To: dev-bounces@dpdk.org Sender: "dev" This patch aligns the logic used to check for the presence of adjacent segments in has_adjacent_segments() with the logic used in cleanup_segments() when actually deciding to concatenate or not a pair of segments. Additionally, adjacent segments are no longer considered overlapping to avoid generating errors for segments that can happily coexist together. This fixes an infinite loop that happened when segments where adjacent in their physical or virtual addresses but not in their ioremap addresses: has_adjacent_segments() reported the presence of adjacent segments while cleanup_segments() was not considering them for concatenation, resulting in an infinite loop since the result of has_adjacent_segments() is used in the decision to continue looping in cleanup_segments(). Signed-off-by: David Verbeiren Signed-off-by: Anatoly Burakov --- lib/librte_eal/linuxapp/eal/eal_ivshmem.c | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/lib/librte_eal/linuxapp/eal/eal_ivshmem.c b/lib/librte_eal/linuxapp/eal/eal_ivshmem.c index 28ddf09..07aec69 100644 --- a/lib/librte_eal/linuxapp/eal/eal_ivshmem.c +++ b/lib/librte_eal/linuxapp/eal/eal_ivshmem.c @@ -184,21 +184,21 @@ overlap(const struct rte_memzone * mz1, const struct rte_memzone * mz2) i_end2 = mz2->ioremap_addr + mz2->len; /* check for overlap in virtual addresses */ - if (start1 >= start2 && start1 < end2) + if (start1 > start2 && start1 < end2) result |= VIRT; if (start2 >= start1 && start2 < end1) result |= VIRT; /* check for overlap in physical addresses */ - if (p_start1 >= p_start2 && p_start1 < p_end2) + if (p_start1 > p_start2 && p_start1 < p_end2) result |= PHYS; - if (p_start2 >= p_start1 && p_start2 < p_end1) + if (p_start2 > p_start1 && p_start2 < p_end1) result |= PHYS; /* check for overlap in ioremap addresses */ - if (i_start1 >= i_start2 && i_start1 < i_end2) + if (i_start1 > i_start2 && i_start1 < i_end2) result |= IOREMAP; - if (i_start2 >= i_start1 && i_start2 < i_end1) + if (i_start2 > i_start1 && i_start2 < i_end1) result |= IOREMAP; return result; @@ -254,17 +254,14 @@ adjacent(const struct rte_memzone * mz1, const struct rte_memzone * mz2) static int has_adjacent_segments(struct ivshmem_segment * ms, int len) { - int i, j, a; + int i, j; for (i = 0; i < len; i++) for (j = i + 1; j < len; j++) { - a = adjacent(&ms[i].entry.mz, &ms[j].entry.mz); - - /* check if segments are adjacent virtually and/or physically but - * not ioremap (since that would indicate that they are from - * different PCI devices and thus don't need to be concatenated. + /* we're only interested in fully adjacent segments; partially + * adjacent segments can coexist. */ - if ((a & (VIRT|PHYS)) > 0 && (a & IOREMAP) == 0) + if (adjacent(&ms[i].entry.mz, &ms[j].entry.mz) == FULL) return 1; } return 0;