aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/ixl
diff options
context:
space:
mode:
authorEric Joyner <erj@FreeBSD.org>2017-07-13 22:12:41 +0000
committerEric Joyner <erj@FreeBSD.org>2017-07-13 22:12:41 +0000
commit3820007146e10e46357c0e688413ef95bf4e808f (patch)
tree9cc4dd12e86a0685042fcf2d0d1dd9a4d7d11bbf /sys/dev/ixl
parent27c8e6b81ed5838c47232322aebe407f1e432d4d (diff)
downloadsrc-3820007146e10e46357c0e688413ef95bf4e808f.tar.gz
src-3820007146e10e46357c0e688413ef95bf4e808f.zip
ixl(4)/ixlv(4): Stop leaking every busdma entry in receive path
From Brett: In short, busdma maps for received packets were not being unloaded in the interrupt handler before the packets were passed up the network stack. The fix was to add a busdma sync and unload for the two receive maps. This bug is significant for certain busdma providers, for example IOMMUs, where not unloading the maps means that 1) the IOMMU mappings that allow the NIC to DMA the received packets into host memory stay open indefinitely, potentially violating a desired security policy, and 2) resources such as device address space addresses and host memory for bookkeeping are never freed. Without an IOMMU or bounce buffering enabled for the ixl device, I don't think adding these calls will have any significant performance impact. With the IOMMU enabled, I have noticed a performance impact on the receive side, which is expected. Submitted by: Brett Gutstein <bgutstein@rice.edu> Reviewed by: erj@ MFC after: 1 week
Notes
Notes: svn path=/head/; revision=320972
Diffstat (limited to 'sys/dev/ixl')
-rw-r--r--sys/dev/ixl/ixl_txrx.c12
1 files changed, 12 insertions, 0 deletions
diff --git a/sys/dev/ixl/ixl_txrx.c b/sys/dev/ixl/ixl_txrx.c
index cfa58c75b05c..7cd3ebbf6690 100644
--- a/sys/dev/ixl/ixl_txrx.c
+++ b/sys/dev/ixl/ixl_txrx.c
@@ -1578,6 +1578,18 @@ ixl_rxeof(struct ixl_queue *que, int count)
else
vtag = 0;
+ /* Remove device access to the rx buffers. */
+ if (rbuf->m_head != NULL) {
+ bus_dmamap_sync(rxr->htag, rbuf->hmap,
+ BUS_DMASYNC_POSTREAD);
+ bus_dmamap_unload(rxr->htag, rbuf->hmap);
+ }
+ if (rbuf->m_pack != NULL) {
+ bus_dmamap_sync(rxr->ptag, rbuf->pmap,
+ BUS_DMASYNC_POSTREAD);
+ bus_dmamap_unload(rxr->ptag, rbuf->pmap);
+ }
+
/*
** Make sure bad packets are discarded,
** note that only EOP descriptor has valid