aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/xen-netback/netback.c
diff options
context:
space:
mode:
authorZoltan Kiss <zoltan.kiss@citrix.com>2014-03-06 16:48:31 -0500
committerDavid S. Miller <davem@davemloft.net>2014-03-07 15:57:21 -0500
commite9275f5e2df1b2098a8cc405d87b88b9affd73e6 (patch)
tree05898b0d8dab616b2936783964cae4f77b06af84 /drivers/net/xen-netback/netback.c
parent093507885ae5dc0288af07fbb922d2f85b3a88a6 (diff)
xen-netback: Aggregate TX unmap operations
Unmapping causes TLB flushing, therefore we should make it in the largest possible batches. However we shouldn't starve the guest for too long. So if the guest has space for at least two big packets and we don't have at least a quarter ring to unmap, delay it for at most 1 milisec. Signed-off-by: Zoltan Kiss <zoltan.kiss@citrix.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/xen-netback/netback.c')
-rw-r--r--drivers/net/xen-netback/netback.c34
1 files changed, 33 insertions, 1 deletions
diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c
index 8518a0d1f6f9..bc943205a691 100644
--- a/drivers/net/xen-netback/netback.c
+++ b/drivers/net/xen-netback/netback.c
@@ -133,6 +133,11 @@ static inline pending_ring_idx_t pending_index(unsigned i)
133 return i & (MAX_PENDING_REQS-1); 133 return i & (MAX_PENDING_REQS-1);
134} 134}
135 135
136static inline pending_ring_idx_t nr_free_slots(struct xen_netif_tx_back_ring *ring)
137{
138 return ring->nr_ents - (ring->sring->req_prod - ring->rsp_prod_pvt);
139}
140
136bool xenvif_rx_ring_slots_available(struct xenvif *vif, int needed) 141bool xenvif_rx_ring_slots_available(struct xenvif *vif, int needed)
137{ 142{
138 RING_IDX prod, cons; 143 RING_IDX prod, cons;
@@ -1716,9 +1721,36 @@ static inline int tx_work_todo(struct xenvif *vif)
1716 return 0; 1721 return 0;
1717} 1722}
1718 1723
1724static void xenvif_dealloc_delay(unsigned long data)
1725{
1726 struct xenvif *vif = (struct xenvif *)data;
1727
1728 vif->dealloc_delay_timed_out = true;
1729 wake_up(&vif->dealloc_wq);
1730}
1731
1719static inline bool tx_dealloc_work_todo(struct xenvif *vif) 1732static inline bool tx_dealloc_work_todo(struct xenvif *vif)
1720{ 1733{
1721 return vif->dealloc_cons != vif->dealloc_prod; 1734 if (vif->dealloc_cons != vif->dealloc_prod) {
1735 if ((nr_free_slots(&vif->tx) > 2 * XEN_NETBK_LEGACY_SLOTS_MAX) &&
1736 (vif->dealloc_prod - vif->dealloc_cons < MAX_PENDING_REQS / 4) &&
1737 !vif->dealloc_delay_timed_out) {
1738 if (!timer_pending(&vif->dealloc_delay)) {
1739 vif->dealloc_delay.function =
1740 xenvif_dealloc_delay;
1741 vif->dealloc_delay.data = (unsigned long)vif;
1742 mod_timer(&vif->dealloc_delay,
1743 jiffies + msecs_to_jiffies(1));
1744
1745 }
1746 return false;
1747 }
1748 del_timer_sync(&vif->dealloc_delay);
1749 vif->dealloc_delay_timed_out = false;
1750 return true;
1751 }
1752
1753 return false;
1722} 1754}
1723 1755
1724void xenvif_unmap_frontend_rings(struct xenvif *vif) 1756void xenvif_unmap_frontend_rings(struct xenvif *vif)