diff options
Diffstat (limited to 'drivers/net/xen-netback/interface.c')
-rw-r--r-- | drivers/net/xen-netback/interface.c | 128 |
1 files changed, 121 insertions, 7 deletions
diff --git a/drivers/net/xen-netback/interface.c b/drivers/net/xen-netback/interface.c index 301cc037fda8..a6a8c1579eb9 100644 --- a/drivers/net/xen-netback/interface.c +++ b/drivers/net/xen-netback/interface.c | |||
@@ -38,6 +38,7 @@ | |||
38 | 38 | ||
39 | #include <xen/events.h> | 39 | #include <xen/events.h> |
40 | #include <asm/xen/hypercall.h> | 40 | #include <asm/xen/hypercall.h> |
41 | #include <xen/balloon.h> | ||
41 | 42 | ||
42 | #define XENVIF_QUEUE_LENGTH 32 | 43 | #define XENVIF_QUEUE_LENGTH 32 |
43 | #define XENVIF_NAPI_WEIGHT 64 | 44 | #define XENVIF_NAPI_WEIGHT 64 |
@@ -87,7 +88,8 @@ static int xenvif_poll(struct napi_struct *napi, int budget) | |||
87 | local_irq_save(flags); | 88 | local_irq_save(flags); |
88 | 89 | ||
89 | RING_FINAL_CHECK_FOR_REQUESTS(&vif->tx, more_to_do); | 90 | RING_FINAL_CHECK_FOR_REQUESTS(&vif->tx, more_to_do); |
90 | if (!more_to_do) | 91 | if (!(more_to_do && |
92 | xenvif_tx_pending_slots_available(vif))) | ||
91 | __napi_complete(napi); | 93 | __napi_complete(napi); |
92 | 94 | ||
93 | local_irq_restore(flags); | 95 | local_irq_restore(flags); |
@@ -113,6 +115,18 @@ static irqreturn_t xenvif_interrupt(int irq, void *dev_id) | |||
113 | return IRQ_HANDLED; | 115 | return IRQ_HANDLED; |
114 | } | 116 | } |
115 | 117 | ||
118 | static void xenvif_wake_queue(unsigned long data) | ||
119 | { | ||
120 | struct xenvif *vif = (struct xenvif *)data; | ||
121 | |||
122 | if (netif_queue_stopped(vif->dev)) { | ||
123 | netdev_err(vif->dev, "draining TX queue\n"); | ||
124 | vif->rx_queue_purge = true; | ||
125 | xenvif_kick_thread(vif); | ||
126 | netif_wake_queue(vif->dev); | ||
127 | } | ||
128 | } | ||
129 | |||
116 | static int xenvif_start_xmit(struct sk_buff *skb, struct net_device *dev) | 130 | static int xenvif_start_xmit(struct sk_buff *skb, struct net_device *dev) |
117 | { | 131 | { |
118 | struct xenvif *vif = netdev_priv(dev); | 132 | struct xenvif *vif = netdev_priv(dev); |
@@ -121,7 +135,9 @@ static int xenvif_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
121 | BUG_ON(skb->dev != dev); | 135 | BUG_ON(skb->dev != dev); |
122 | 136 | ||
123 | /* Drop the packet if vif is not ready */ | 137 | /* Drop the packet if vif is not ready */ |
124 | if (vif->task == NULL || !xenvif_schedulable(vif)) | 138 | if (vif->task == NULL || |
139 | vif->dealloc_task == NULL || | ||
140 | !xenvif_schedulable(vif)) | ||
125 | goto drop; | 141 | goto drop; |
126 | 142 | ||
127 | /* At best we'll need one slot for the header and one for each | 143 | /* At best we'll need one slot for the header and one for each |
@@ -139,8 +155,13 @@ static int xenvif_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
139 | * then turn off the queue to give the ring a chance to | 155 | * then turn off the queue to give the ring a chance to |
140 | * drain. | 156 | * drain. |
141 | */ | 157 | */ |
142 | if (!xenvif_rx_ring_slots_available(vif, min_slots_needed)) | 158 | if (!xenvif_rx_ring_slots_available(vif, min_slots_needed)) { |
159 | vif->wake_queue.function = xenvif_wake_queue; | ||
160 | vif->wake_queue.data = (unsigned long)vif; | ||
143 | xenvif_stop_queue(vif); | 161 | xenvif_stop_queue(vif); |
162 | mod_timer(&vif->wake_queue, | ||
163 | jiffies + rx_drain_timeout_jiffies); | ||
164 | } | ||
144 | 165 | ||
145 | skb_queue_tail(&vif->rx_queue, skb); | 166 | skb_queue_tail(&vif->rx_queue, skb); |
146 | xenvif_kick_thread(vif); | 167 | xenvif_kick_thread(vif); |
@@ -233,6 +254,28 @@ static const struct xenvif_stat { | |||
233 | "rx_gso_checksum_fixup", | 254 | "rx_gso_checksum_fixup", |
234 | offsetof(struct xenvif, rx_gso_checksum_fixup) | 255 | offsetof(struct xenvif, rx_gso_checksum_fixup) |
235 | }, | 256 | }, |
257 | /* If (sent != success + fail), there are probably packets never | ||
258 | * freed up properly! | ||
259 | */ | ||
260 | { | ||
261 | "tx_zerocopy_sent", | ||
262 | offsetof(struct xenvif, tx_zerocopy_sent), | ||
263 | }, | ||
264 | { | ||
265 | "tx_zerocopy_success", | ||
266 | offsetof(struct xenvif, tx_zerocopy_success), | ||
267 | }, | ||
268 | { | ||
269 | "tx_zerocopy_fail", | ||
270 | offsetof(struct xenvif, tx_zerocopy_fail) | ||
271 | }, | ||
272 | /* Number of packets exceeding MAX_SKB_FRAG slots. You should use | ||
273 | * a guest with the same MAX_SKB_FRAG | ||
274 | */ | ||
275 | { | ||
276 | "tx_frag_overflow", | ||
277 | offsetof(struct xenvif, tx_frag_overflow) | ||
278 | }, | ||
236 | }; | 279 | }; |
237 | 280 | ||
238 | static int xenvif_get_sset_count(struct net_device *dev, int string_set) | 281 | static int xenvif_get_sset_count(struct net_device *dev, int string_set) |
@@ -326,6 +369,8 @@ struct xenvif *xenvif_alloc(struct device *parent, domid_t domid, | |||
326 | init_timer(&vif->credit_timeout); | 369 | init_timer(&vif->credit_timeout); |
327 | vif->credit_window_start = get_jiffies_64(); | 370 | vif->credit_window_start = get_jiffies_64(); |
328 | 371 | ||
372 | init_timer(&vif->wake_queue); | ||
373 | |||
329 | dev->netdev_ops = &xenvif_netdev_ops; | 374 | dev->netdev_ops = &xenvif_netdev_ops; |
330 | dev->hw_features = NETIF_F_SG | | 375 | dev->hw_features = NETIF_F_SG | |
331 | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | | 376 | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | |
@@ -342,8 +387,27 @@ struct xenvif *xenvif_alloc(struct device *parent, domid_t domid, | |||
342 | vif->pending_prod = MAX_PENDING_REQS; | 387 | vif->pending_prod = MAX_PENDING_REQS; |
343 | for (i = 0; i < MAX_PENDING_REQS; i++) | 388 | for (i = 0; i < MAX_PENDING_REQS; i++) |
344 | vif->pending_ring[i] = i; | 389 | vif->pending_ring[i] = i; |
345 | for (i = 0; i < MAX_PENDING_REQS; i++) | 390 | spin_lock_init(&vif->callback_lock); |
346 | vif->mmap_pages[i] = NULL; | 391 | spin_lock_init(&vif->response_lock); |
392 | /* If ballooning is disabled, this will consume real memory, so you | ||
393 | * better enable it. The long term solution would be to use just a | ||
394 | * bunch of valid page descriptors, without dependency on ballooning | ||
395 | */ | ||
396 | err = alloc_xenballooned_pages(MAX_PENDING_REQS, | ||
397 | vif->mmap_pages, | ||
398 | false); | ||
399 | if (err) { | ||
400 | netdev_err(dev, "Could not reserve mmap_pages\n"); | ||
401 | return ERR_PTR(-ENOMEM); | ||
402 | } | ||
403 | for (i = 0; i < MAX_PENDING_REQS; i++) { | ||
404 | vif->pending_tx_info[i].callback_struct = (struct ubuf_info) | ||
405 | { .callback = xenvif_zerocopy_callback, | ||
406 | .ctx = NULL, | ||
407 | .desc = i }; | ||
408 | vif->grant_tx_handle[i] = NETBACK_INVALID_HANDLE; | ||
409 | } | ||
410 | init_timer(&vif->dealloc_delay); | ||
347 | 411 | ||
348 | /* | 412 | /* |
349 | * Initialise a dummy MAC address. We choose the numerically | 413 | * Initialise a dummy MAC address. We choose the numerically |
@@ -381,12 +445,14 @@ int xenvif_connect(struct xenvif *vif, unsigned long tx_ring_ref, | |||
381 | 445 | ||
382 | BUG_ON(vif->tx_irq); | 446 | BUG_ON(vif->tx_irq); |
383 | BUG_ON(vif->task); | 447 | BUG_ON(vif->task); |
448 | BUG_ON(vif->dealloc_task); | ||
384 | 449 | ||
385 | err = xenvif_map_frontend_rings(vif, tx_ring_ref, rx_ring_ref); | 450 | err = xenvif_map_frontend_rings(vif, tx_ring_ref, rx_ring_ref); |
386 | if (err < 0) | 451 | if (err < 0) |
387 | goto err; | 452 | goto err; |
388 | 453 | ||
389 | init_waitqueue_head(&vif->wq); | 454 | init_waitqueue_head(&vif->wq); |
455 | init_waitqueue_head(&vif->dealloc_wq); | ||
390 | 456 | ||
391 | if (tx_evtchn == rx_evtchn) { | 457 | if (tx_evtchn == rx_evtchn) { |
392 | /* feature-split-event-channels == 0 */ | 458 | /* feature-split-event-channels == 0 */ |
@@ -420,8 +486,8 @@ int xenvif_connect(struct xenvif *vif, unsigned long tx_ring_ref, | |||
420 | disable_irq(vif->rx_irq); | 486 | disable_irq(vif->rx_irq); |
421 | } | 487 | } |
422 | 488 | ||
423 | task = kthread_create(xenvif_kthread, | 489 | task = kthread_create(xenvif_kthread_guest_rx, |
424 | (void *)vif, "%s", vif->dev->name); | 490 | (void *)vif, "%s-guest-rx", vif->dev->name); |
425 | if (IS_ERR(task)) { | 491 | if (IS_ERR(task)) { |
426 | pr_warn("Could not allocate kthread for %s\n", vif->dev->name); | 492 | pr_warn("Could not allocate kthread for %s\n", vif->dev->name); |
427 | err = PTR_ERR(task); | 493 | err = PTR_ERR(task); |
@@ -430,6 +496,16 @@ int xenvif_connect(struct xenvif *vif, unsigned long tx_ring_ref, | |||
430 | 496 | ||
431 | vif->task = task; | 497 | vif->task = task; |
432 | 498 | ||
499 | task = kthread_create(xenvif_dealloc_kthread, | ||
500 | (void *)vif, "%s-dealloc", vif->dev->name); | ||
501 | if (IS_ERR(task)) { | ||
502 | pr_warn("Could not allocate kthread for %s\n", vif->dev->name); | ||
503 | err = PTR_ERR(task); | ||
504 | goto err_rx_unbind; | ||
505 | } | ||
506 | |||
507 | vif->dealloc_task = task; | ||
508 | |||
433 | rtnl_lock(); | 509 | rtnl_lock(); |
434 | if (!vif->can_sg && vif->dev->mtu > ETH_DATA_LEN) | 510 | if (!vif->can_sg && vif->dev->mtu > ETH_DATA_LEN) |
435 | dev_set_mtu(vif->dev, ETH_DATA_LEN); | 511 | dev_set_mtu(vif->dev, ETH_DATA_LEN); |
@@ -440,6 +516,7 @@ int xenvif_connect(struct xenvif *vif, unsigned long tx_ring_ref, | |||
440 | rtnl_unlock(); | 516 | rtnl_unlock(); |
441 | 517 | ||
442 | wake_up_process(vif->task); | 518 | wake_up_process(vif->task); |
519 | wake_up_process(vif->dealloc_task); | ||
443 | 520 | ||
444 | return 0; | 521 | return 0; |
445 | 522 | ||
@@ -473,10 +550,17 @@ void xenvif_disconnect(struct xenvif *vif) | |||
473 | xenvif_carrier_off(vif); | 550 | xenvif_carrier_off(vif); |
474 | 551 | ||
475 | if (vif->task) { | 552 | if (vif->task) { |
553 | del_timer_sync(&vif->wake_queue); | ||
476 | kthread_stop(vif->task); | 554 | kthread_stop(vif->task); |
477 | vif->task = NULL; | 555 | vif->task = NULL; |
478 | } | 556 | } |
479 | 557 | ||
558 | if (vif->dealloc_task) { | ||
559 | del_timer_sync(&vif->dealloc_delay); | ||
560 | kthread_stop(vif->dealloc_task); | ||
561 | vif->dealloc_task = NULL; | ||
562 | } | ||
563 | |||
480 | if (vif->tx_irq) { | 564 | if (vif->tx_irq) { |
481 | if (vif->tx_irq == vif->rx_irq) | 565 | if (vif->tx_irq == vif->rx_irq) |
482 | unbind_from_irqhandler(vif->tx_irq, vif); | 566 | unbind_from_irqhandler(vif->tx_irq, vif); |
@@ -492,6 +576,36 @@ void xenvif_disconnect(struct xenvif *vif) | |||
492 | 576 | ||
493 | void xenvif_free(struct xenvif *vif) | 577 | void xenvif_free(struct xenvif *vif) |
494 | { | 578 | { |
579 | int i, unmap_timeout = 0; | ||
580 | /* Here we want to avoid timeout messages if an skb can be legitimatly | ||
581 | * stucked somewhere else. Realisticly this could be an another vif's | ||
582 | * internal or QDisc queue. That another vif also has this | ||
583 | * rx_drain_timeout_msecs timeout, but the timer only ditches the | ||
584 | * internal queue. After that, the QDisc queue can put in worst case | ||
585 | * XEN_NETIF_RX_RING_SIZE / MAX_SKB_FRAGS skbs into that another vif's | ||
586 | * internal queue, so we need several rounds of such timeouts until we | ||
587 | * can be sure that no another vif should have skb's from us. We are | ||
588 | * not sending more skb's, so newly stucked packets are not interesting | ||
589 | * for us here. | ||
590 | */ | ||
591 | unsigned int worst_case_skb_lifetime = (rx_drain_timeout_msecs/1000) * | ||
592 | DIV_ROUND_UP(XENVIF_QUEUE_LENGTH, (XEN_NETIF_RX_RING_SIZE / MAX_SKB_FRAGS)); | ||
593 | |||
594 | for (i = 0; i < MAX_PENDING_REQS; ++i) { | ||
595 | if (vif->grant_tx_handle[i] != NETBACK_INVALID_HANDLE) { | ||
596 | unmap_timeout++; | ||
597 | schedule_timeout(msecs_to_jiffies(1000)); | ||
598 | if (unmap_timeout > worst_case_skb_lifetime && | ||
599 | net_ratelimit()) | ||
600 | netdev_err(vif->dev, | ||
601 | "Page still granted! Index: %x\n", | ||
602 | i); | ||
603 | i = -1; | ||
604 | } | ||
605 | } | ||
606 | |||
607 | free_xenballooned_pages(MAX_PENDING_REQS, vif->mmap_pages); | ||
608 | |||
495 | netif_napi_del(&vif->napi); | 609 | netif_napi_del(&vif->napi); |
496 | 610 | ||
497 | unregister_netdev(vif->dev); | 611 | unregister_netdev(vif->dev); |