diff options
author | David Vrabel <david.vrabel@citrix.com> | 2015-03-11 11:27:59 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-03-11 23:30:44 -0400 |
commit | c8a4d29988edb0db9ee80669f2e5e21bd9f7e0d0 (patch) | |
tree | ed2c40642f474a6e7b4adbaf54ddcdfd1ddbf8ff /drivers/net/xen-netback/netback.c | |
parent | b1cb59cf2efe7971d3d72a7b963d09a512d994c9 (diff) |
xen-netback: notify immediately after pushing Tx response.
This fixes a performance regression introduced by
7fbb9d8415d4a51cf542e87cf3a717a9f7e6aedc (xen-netback: release pending
index before pushing Tx responses)
Moving the notify outside of the spin locks means it can be delayed a
long time (if the dealloc thread is descheduled or there is an
interrupt or softirq).
Signed-off-by: David Vrabel <david.vrabel@citrix.com>
Reviewed-by: Zoltan Kiss <zoltan.kiss@linaro.org>
Acked-by: Wei Liu <wei.liu2@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.c | 23 |
1 files changed, 12 insertions, 11 deletions
diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c index cab9f5257f57..997cf0901ac2 100644 --- a/drivers/net/xen-netback/netback.c +++ b/drivers/net/xen-netback/netback.c | |||
@@ -96,6 +96,7 @@ static void xenvif_idx_release(struct xenvif_queue *queue, u16 pending_idx, | |||
96 | static void make_tx_response(struct xenvif_queue *queue, | 96 | static void make_tx_response(struct xenvif_queue *queue, |
97 | struct xen_netif_tx_request *txp, | 97 | struct xen_netif_tx_request *txp, |
98 | s8 st); | 98 | s8 st); |
99 | static void push_tx_responses(struct xenvif_queue *queue); | ||
99 | 100 | ||
100 | static inline int tx_work_todo(struct xenvif_queue *queue); | 101 | static inline int tx_work_todo(struct xenvif_queue *queue); |
101 | 102 | ||
@@ -655,15 +656,10 @@ static void xenvif_tx_err(struct xenvif_queue *queue, | |||
655 | unsigned long flags; | 656 | unsigned long flags; |
656 | 657 | ||
657 | do { | 658 | do { |
658 | int notify; | ||
659 | |||
660 | spin_lock_irqsave(&queue->response_lock, flags); | 659 | spin_lock_irqsave(&queue->response_lock, flags); |
661 | make_tx_response(queue, txp, XEN_NETIF_RSP_ERROR); | 660 | make_tx_response(queue, txp, XEN_NETIF_RSP_ERROR); |
662 | RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&queue->tx, notify); | 661 | push_tx_responses(queue); |
663 | spin_unlock_irqrestore(&queue->response_lock, flags); | 662 | spin_unlock_irqrestore(&queue->response_lock, flags); |
664 | if (notify) | ||
665 | notify_remote_via_irq(queue->tx_irq); | ||
666 | |||
667 | if (cons == end) | 663 | if (cons == end) |
668 | break; | 664 | break; |
669 | txp = RING_GET_REQUEST(&queue->tx, cons++); | 665 | txp = RING_GET_REQUEST(&queue->tx, cons++); |
@@ -1657,7 +1653,6 @@ static void xenvif_idx_release(struct xenvif_queue *queue, u16 pending_idx, | |||
1657 | { | 1653 | { |
1658 | struct pending_tx_info *pending_tx_info; | 1654 | struct pending_tx_info *pending_tx_info; |
1659 | pending_ring_idx_t index; | 1655 | pending_ring_idx_t index; |
1660 | int notify; | ||
1661 | unsigned long flags; | 1656 | unsigned long flags; |
1662 | 1657 | ||
1663 | pending_tx_info = &queue->pending_tx_info[pending_idx]; | 1658 | pending_tx_info = &queue->pending_tx_info[pending_idx]; |
@@ -1673,12 +1668,9 @@ static void xenvif_idx_release(struct xenvif_queue *queue, u16 pending_idx, | |||
1673 | index = pending_index(queue->pending_prod++); | 1668 | index = pending_index(queue->pending_prod++); |
1674 | queue->pending_ring[index] = pending_idx; | 1669 | queue->pending_ring[index] = pending_idx; |
1675 | 1670 | ||
1676 | RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&queue->tx, notify); | 1671 | push_tx_responses(queue); |
1677 | 1672 | ||
1678 | spin_unlock_irqrestore(&queue->response_lock, flags); | 1673 | spin_unlock_irqrestore(&queue->response_lock, flags); |
1679 | |||
1680 | if (notify) | ||
1681 | notify_remote_via_irq(queue->tx_irq); | ||
1682 | } | 1674 | } |
1683 | 1675 | ||
1684 | 1676 | ||
@@ -1699,6 +1691,15 @@ static void make_tx_response(struct xenvif_queue *queue, | |||
1699 | queue->tx.rsp_prod_pvt = ++i; | 1691 | queue->tx.rsp_prod_pvt = ++i; |
1700 | } | 1692 | } |
1701 | 1693 | ||
1694 | static void push_tx_responses(struct xenvif_queue *queue) | ||
1695 | { | ||
1696 | int notify; | ||
1697 | |||
1698 | RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&queue->tx, notify); | ||
1699 | if (notify) | ||
1700 | notify_remote_via_irq(queue->tx_irq); | ||
1701 | } | ||
1702 | |||
1702 | static struct xen_netif_rx_response *make_rx_response(struct xenvif_queue *queue, | 1703 | static struct xen_netif_rx_response *make_rx_response(struct xenvif_queue *queue, |
1703 | u16 id, | 1704 | u16 id, |
1704 | s8 st, | 1705 | s8 st, |