Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 5 Dec 2016 23:46:21 +0000 (UTC)
From:      John Baldwin <jhb@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org
Subject:   svn commit: r309579 - in stable: 10/sys/dev/cxgbe 11/sys/dev/cxgbe
Message-ID:  <201612052346.uB5NkLEV054556@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jhb
Date: Mon Dec  5 23:46:21 2016
New Revision: 309579
URL: https://svnweb.freebsd.org/changeset/base/309579

Log:
  MFC 307876:
  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.

Modified:
  stable/11/sys/dev/cxgbe/t4_sge.c
Directory Properties:
  stable/11/   (props changed)

Changes in other areas also in this revision:
Modified:
  stable/10/sys/dev/cxgbe/t4_sge.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/11/sys/dev/cxgbe/t4_sge.c
==============================================================================
--- stable/11/sys/dev/cxgbe/t4_sge.c	Mon Dec  5 23:35:37 2016	(r309578)
+++ stable/11/sys/dev/cxgbe/t4_sge.c	Mon Dec  5 23:46:21 2016	(r309579)
@@ -2101,24 +2101,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.
@@ -2126,24 +2108,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?201612052346.uB5NkLEV054556>