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
This commit is contained in:
parent
d67ec19c3e
commit
77e9044c47
@ -2110,24 +2110,6 @@ m_advance(struct mbuf **pm, int *poffset, int len)
|
|||||||
return ((void *)p);
|
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
|
* 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.
|
* must have at least one mbuf that's not empty.
|
||||||
@ -2135,24 +2117,25 @@ same_paddr(char *a, char *b)
|
|||||||
static inline int
|
static inline int
|
||||||
count_mbuf_nsegs(struct mbuf *m)
|
count_mbuf_nsegs(struct mbuf *m)
|
||||||
{
|
{
|
||||||
char *prev_end, *start;
|
vm_paddr_t lastb, next;
|
||||||
|
vm_offset_t va;
|
||||||
int len, nsegs;
|
int len, nsegs;
|
||||||
|
|
||||||
MPASS(m != NULL);
|
MPASS(m != NULL);
|
||||||
|
|
||||||
nsegs = 0;
|
nsegs = 0;
|
||||||
prev_end = NULL;
|
lastb = 0;
|
||||||
for (; m; m = m->m_next) {
|
for (; m; m = m->m_next) {
|
||||||
|
|
||||||
len = m->m_len;
|
len = m->m_len;
|
||||||
if (__predict_false(len == 0))
|
if (__predict_false(len == 0))
|
||||||
continue;
|
continue;
|
||||||
start = mtod(m, char *);
|
va = mtod(m, vm_offset_t);
|
||||||
|
next = pmap_kextract(va);
|
||||||
nsegs += sglist_count(start, len);
|
nsegs += sglist_count(m->m_data, len);
|
||||||
if (same_paddr(prev_end, start))
|
if (lastb + 1 == next)
|
||||||
nsegs--;
|
nsegs--;
|
||||||
prev_end = start + len;
|
lastb = pmap_kextract(va + len - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
MPASS(nsegs > 0);
|
MPASS(nsegs > 0);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user