Skip to content

Commit be81992

Browse files
committed
xen/netback: don't queue unlimited number of packages
In case a guest isn't consuming incoming network traffic as fast as it is coming in, xen-netback is buffering network packages in unlimited numbers today. This can result in host OOM situations. Commit f48da8b ("xen-netback: fix unlimited guest Rx internal queue and carrier flapping") meant to introduce a mechanism to limit the amount of buffered data by stopping the Tx queue when reaching the data limit, but this doesn't work for cases like UDP. When hitting the limit don't queue further SKBs, but drop them instead. In order to be able to tell Rx packages have been dropped increment the rx_dropped statistics counter in this case. It should be noted that the old solution to continue queueing SKBs had the additional problem of an overflow of the 32-bit rx_queue_len value would result in intermittent Tx queue enabling. This is part of XSA-392 Fixes: f48da8b ("xen-netback: fix unlimited guest Rx internal queue and carrier flapping") Signed-off-by: Juergen Gross <jgross@suse.com> Reviewed-by: Jan Beulich <jbeulich@suse.com>
1 parent 6032046 commit be81992

1 file changed

Lines changed: 11 additions & 7 deletions

File tree

  • drivers/net/xen-netback

drivers/net/xen-netback/rx.c

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -88,16 +88,19 @@ void xenvif_rx_queue_tail(struct xenvif_queue *queue, struct sk_buff *skb)
8888

8989
spin_lock_irqsave(&queue->rx_queue.lock, flags);
9090

91-
if (skb_queue_empty(&queue->rx_queue))
92-
xenvif_update_needed_slots(queue, skb);
93-
94-
__skb_queue_tail(&queue->rx_queue, skb);
95-
96-
queue->rx_queue_len += skb->len;
97-
if (queue->rx_queue_len > queue->rx_queue_max) {
91+
if (queue->rx_queue_len >= queue->rx_queue_max) {
9892
struct net_device *dev = queue->vif->dev;
9993

10094
netif_tx_stop_queue(netdev_get_tx_queue(dev, queue->id));
95+
kfree_skb(skb);
96+
queue->vif->dev->stats.rx_dropped++;
97+
} else {
98+
if (skb_queue_empty(&queue->rx_queue))
99+
xenvif_update_needed_slots(queue, skb);
100+
101+
__skb_queue_tail(&queue->rx_queue, skb);
102+
103+
queue->rx_queue_len += skb->len;
101104
}
102105

103106
spin_unlock_irqrestore(&queue->rx_queue.lock, flags);
@@ -147,6 +150,7 @@ static void xenvif_rx_queue_drop_expired(struct xenvif_queue *queue)
147150
break;
148151
xenvif_rx_dequeue(queue);
149152
kfree_skb(skb);
153+
queue->vif->dev->stats.rx_dropped++;
150154
}
151155
}
152156

0 commit comments

Comments
 (0)