Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

cxgb3: Correct comparisons and calculations using skb->tail and skb-transport_header

This corrects an regression introduced by "net: Use 16bits for *_headers
fields of struct skbuff" when NET_SKBUFF_DATA_USES_OFFSET is not set. In
that case skb->tail will be a pointer whereas skb->transport_header
will be an offset from head. This is corrected by using wrappers that
ensure that comparisons and calculations are always made using pointers.

Signed-off-by: Simon Horman <horms@verge.net.au>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Simon Horman and committed by
David S. Miller
be8b678c 25b6e148

+5 -6
+5 -6
drivers/net/ethernet/chelsio/cxgb3/sge.c
··· 1584 1584 p = dui->addr; 1585 1585 1586 1586 if (skb->tail - skb->transport_header) 1587 - pci_unmap_single(dui->pdev, *p++, 1588 - skb->tail - skb->transport_header, 1589 - PCI_DMA_TODEVICE); 1587 + pci_unmap_single(dui->pdev, *p++, skb_tail_pointer(skb) - 1588 + skb_transport_header(skb), PCI_DMA_TODEVICE); 1590 1589 1591 1590 si = skb_shinfo(skb); 1592 1591 for (i = 0; i < si->nr_frags; i++) ··· 1646 1647 flits = skb_transport_offset(skb) / 8; 1647 1648 sgp = ndesc == 1 ? (struct sg_ent *)&d->flit[flits] : sgl; 1648 1649 sgl_flits = write_sgl(skb, sgp, skb_transport_header(skb), 1649 - skb->tail - skb->transport_header, 1650 - addr); 1650 + skb_tail_pointer(skb) - 1651 + skb_transport_header(skb), addr); 1651 1652 if (need_skb_unmap()) { 1652 1653 setup_deferred_unmapping(skb, adap->pdev, sgp, sgl_flits); 1653 1654 skb->destructor = deferred_unmap_destructor; ··· 1673 1674 1674 1675 flits = skb_transport_offset(skb) / 8; /* headers */ 1675 1676 cnt = skb_shinfo(skb)->nr_frags; 1676 - if (skb->tail != skb->transport_header) 1677 + if (skb_tail_pointer(skb) != skb_transport_header(skb)) 1677 1678 cnt++; 1678 1679 return flits_to_desc(flits + sgl_len(cnt)); 1679 1680 }