Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 24 Oct 2016 19:09:56 +0000 (UTC)
From:      Navdeep Parhar <np@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r307876 - head/sys/dev/cxgbe
Message-ID:  <201610241909.u9OJ9uoh067464@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: np
Date: Mon Oct 24 19:09:56 2016
New Revision: 307876
URL: https://svnweb.freebsd.org/changeset/base/307876

Log:
  cxgbe(4): Fix bug in the calculation of the number of physically
  contiguous regions in an mbuf chain.
  
  If the payload of an mbuf ends at a page boundary count_mbuf_nsegs would
  incorrectly consider the next mbuf's payload physically contiguous based
  solely on a KVA comparison.
  
  MFC after:	1 week
  Sponsored by:	Chelsio Communications

Modified:
  head/sys/dev/cxgbe/t4_sge.c

Modified: head/sys/dev/cxgbe/t4_sge.c
==============================================================================
--- head/sys/dev/cxgbe/t4_sge.c	Mon Oct 24 18:27:24 2016	(r307875)
+++ head/sys/dev/cxgbe/t4_sge.c	Mon Oct 24 19:09:56 2016	(r307876)
@@ -2110,24 +2110,6 @@ m_advance(struct mbuf **pm, int *poffset
 	return ((void *)p);
 }
 
-static inline int
-same_paddr(char *a, char *b)
-{
-
-	if (a == b)
-		return (1);
-	else if (a != NULL && b != NULL) {
-		vm_offset_t x = (vm_offset_t)a;
-		vm_offset_t y = (vm_offset_t)b;
-
-		if ((x & PAGE_MASK) == (y & PAGE_MASK) &&
-		    pmap_kextract(x) == pmap_kextract(y))
-			return (1);
-	}
-
-	return (0);
-}
-
 /*
  * Can deal with empty mbufs in the chain that have m_len = 0, but the chain
  * must have at least one mbuf that's not empty.
@@ -2135,24 +2117,25 @@ same_paddr(char *a, char *b)
 static inline int
 count_mbuf_nsegs(struct mbuf *m)
 {
-	char *prev_end, *start;
+	vm_paddr_t lastb, next;
+	vm_offset_t va;
 	int len, nsegs;
 
 	MPASS(m != NULL);
 
 	nsegs = 0;
-	prev_end = NULL;
+	lastb = 0;
 	for (; m; m = m->m_next) {
 
 		len = m->m_len;
 		if (__predict_false(len == 0))
 			continue;
-		start = mtod(m, char *);
-
-		nsegs += sglist_count(start, len);
-		if (same_paddr(prev_end, start))
+		va = mtod(m, vm_offset_t);
+		next = pmap_kextract(va);
+		nsegs += sglist_count(m->m_data, len);
+		if (lastb + 1 == next)
 			nsegs--;
-		prev_end = start + len;
+		lastb = pmap_kextract(va + len - 1);
 	}
 
 	MPASS(nsegs > 0);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201610241909.u9OJ9uoh067464>