aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/xen-netback/netback.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/xen-netback/netback.c')
-rw-r--r--drivers/net/xen-netback/netback.c36
1 files changed, 27 insertions, 9 deletions
diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c
index aa2093325be1..08f65996534c 100644
--- a/drivers/net/xen-netback/netback.c
+++ b/drivers/net/xen-netback/netback.c
@@ -1525,10 +1525,12 @@ static int xenvif_handle_frag_list(struct xenvif_queue *queue, struct sk_buff *s
1525 /* remove traces of mapped pages and frag_list */ 1525 /* remove traces of mapped pages and frag_list */
1526 skb_frag_list_init(skb); 1526 skb_frag_list_init(skb);
1527 uarg = skb_shinfo(skb)->destructor_arg; 1527 uarg = skb_shinfo(skb)->destructor_arg;
1528 /* increase inflight counter to offset decrement in callback */
1529 atomic_inc(&queue->inflight_packets);
1528 uarg->callback(uarg, true); 1530 uarg->callback(uarg, true);
1529 skb_shinfo(skb)->destructor_arg = NULL; 1531 skb_shinfo(skb)->destructor_arg = NULL;
1530 1532
1531 skb_shinfo(nskb)->tx_flags |= SKBTX_DEV_ZEROCOPY; 1533 xenvif_skb_zerocopy_prepare(queue, nskb);
1532 kfree_skb(nskb); 1534 kfree_skb(nskb);
1533 1535
1534 return 0; 1536 return 0;
@@ -1589,7 +1591,7 @@ static int xenvif_tx_submit(struct xenvif_queue *queue)
1589 if (net_ratelimit()) 1591 if (net_ratelimit())
1590 netdev_err(queue->vif->dev, 1592 netdev_err(queue->vif->dev,
1591 "Not enough memory to consolidate frag_list!\n"); 1593 "Not enough memory to consolidate frag_list!\n");
1592 skb_shinfo(skb)->tx_flags |= SKBTX_DEV_ZEROCOPY; 1594 xenvif_skb_zerocopy_prepare(queue, skb);
1593 kfree_skb(skb); 1595 kfree_skb(skb);
1594 continue; 1596 continue;
1595 } 1597 }
@@ -1609,7 +1611,7 @@ static int xenvif_tx_submit(struct xenvif_queue *queue)
1609 "Can't setup checksum in net_tx_action\n"); 1611 "Can't setup checksum in net_tx_action\n");
1610 /* We have to set this flag to trigger the callback */ 1612 /* We have to set this flag to trigger the callback */
1611 if (skb_shinfo(skb)->destructor_arg) 1613 if (skb_shinfo(skb)->destructor_arg)
1612 skb_shinfo(skb)->tx_flags |= SKBTX_DEV_ZEROCOPY; 1614 xenvif_skb_zerocopy_prepare(queue, skb);
1613 kfree_skb(skb); 1615 kfree_skb(skb);
1614 continue; 1616 continue;
1615 } 1617 }
@@ -1641,7 +1643,7 @@ static int xenvif_tx_submit(struct xenvif_queue *queue)
1641 * skb. E.g. the __pskb_pull_tail earlier can do such thing. 1643 * skb. E.g. the __pskb_pull_tail earlier can do such thing.
1642 */ 1644 */
1643 if (skb_shinfo(skb)->destructor_arg) { 1645 if (skb_shinfo(skb)->destructor_arg) {
1644 skb_shinfo(skb)->tx_flags |= SKBTX_DEV_ZEROCOPY; 1646 xenvif_skb_zerocopy_prepare(queue, skb);
1645 queue->stats.tx_zerocopy_sent++; 1647 queue->stats.tx_zerocopy_sent++;
1646 } 1648 }
1647 1649
@@ -1681,6 +1683,7 @@ void xenvif_zerocopy_callback(struct ubuf_info *ubuf, bool zerocopy_success)
1681 queue->stats.tx_zerocopy_success++; 1683 queue->stats.tx_zerocopy_success++;
1682 else 1684 else
1683 queue->stats.tx_zerocopy_fail++; 1685 queue->stats.tx_zerocopy_fail++;
1686 xenvif_skb_zerocopy_complete(queue);
1684} 1687}
1685 1688
1686static inline void xenvif_tx_dealloc_action(struct xenvif_queue *queue) 1689static inline void xenvif_tx_dealloc_action(struct xenvif_queue *queue)
@@ -2025,9 +2028,15 @@ int xenvif_kthread_guest_rx(void *data)
2025 * context so we defer it here, if this thread is 2028 * context so we defer it here, if this thread is
2026 * associated with queue 0. 2029 * associated with queue 0.
2027 */ 2030 */
2028 if (unlikely(queue->vif->disabled && queue->id == 0)) 2031 if (unlikely(queue->vif->disabled && queue->id == 0)) {
2029 xenvif_carrier_off(queue->vif); 2032 xenvif_carrier_off(queue->vif);
2030 else if (unlikely(test_and_clear_bit(QUEUE_STATUS_RX_PURGE_EVENT, 2033 } else if (unlikely(queue->vif->disabled)) {
2034 /* kthread_stop() would be called upon this thread soon,
2035 * be a bit proactive
2036 */
2037 skb_queue_purge(&queue->rx_queue);
2038 queue->rx_last_skb_slots = 0;
2039 } else if (unlikely(test_and_clear_bit(QUEUE_STATUS_RX_PURGE_EVENT,
2031 &queue->status))) { 2040 &queue->status))) {
2032 xenvif_rx_purge_event(queue); 2041 xenvif_rx_purge_event(queue);
2033 } else if (!netif_carrier_ok(queue->vif->dev)) { 2042 } else if (!netif_carrier_ok(queue->vif->dev)) {
@@ -2052,15 +2061,24 @@ int xenvif_kthread_guest_rx(void *data)
2052 return 0; 2061 return 0;
2053} 2062}
2054 2063
2064static bool xenvif_dealloc_kthread_should_stop(struct xenvif_queue *queue)
2065{
2066 /* Dealloc thread must remain running until all inflight
2067 * packets complete.
2068 */
2069 return kthread_should_stop() &&
2070 !atomic_read(&queue->inflight_packets);
2071}
2072
2055int xenvif_dealloc_kthread(void *data) 2073int xenvif_dealloc_kthread(void *data)
2056{ 2074{
2057 struct xenvif_queue *queue = data; 2075 struct xenvif_queue *queue = data;
2058 2076
2059 while (!kthread_should_stop()) { 2077 for (;;) {
2060 wait_event_interruptible(queue->dealloc_wq, 2078 wait_event_interruptible(queue->dealloc_wq,
2061 tx_dealloc_work_todo(queue) || 2079 tx_dealloc_work_todo(queue) ||
2062 kthread_should_stop()); 2080 xenvif_dealloc_kthread_should_stop(queue));
2063 if (kthread_should_stop()) 2081 if (xenvif_dealloc_kthread_should_stop(queue))
2064 break; 2082 break;
2065 2083
2066 xenvif_tx_dealloc_action(queue); 2084 xenvif_tx_dealloc_action(queue);