aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/xen-netback/interface.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/xen-netback/interface.c')
-rw-r--r--drivers/net/xen-netback/interface.c31
1 files changed, 23 insertions, 8 deletions
diff --git a/drivers/net/xen-netback/interface.c b/drivers/net/xen-netback/interface.c
index 2329cccf1fa6..fff8cddfed81 100644
--- a/drivers/net/xen-netback/interface.c
+++ b/drivers/net/xen-netback/interface.c
@@ -34,6 +34,7 @@
34#include <linux/ethtool.h> 34#include <linux/ethtool.h>
35#include <linux/rtnetlink.h> 35#include <linux/rtnetlink.h>
36#include <linux/if_vlan.h> 36#include <linux/if_vlan.h>
37#include <linux/vmalloc.h>
37 38
38#include <xen/events.h> 39#include <xen/events.h>
39#include <asm/xen/hypercall.h> 40#include <asm/xen/hypercall.h>
@@ -307,6 +308,15 @@ struct xenvif *xenvif_alloc(struct device *parent, domid_t domid,
307 SET_NETDEV_DEV(dev, parent); 308 SET_NETDEV_DEV(dev, parent);
308 309
309 vif = netdev_priv(dev); 310 vif = netdev_priv(dev);
311
312 vif->grant_copy_op = vmalloc(sizeof(struct gnttab_copy) *
313 MAX_GRANT_COPY_OPS);
314 if (vif->grant_copy_op == NULL) {
315 pr_warn("Could not allocate grant copy space for %s\n", name);
316 free_netdev(dev);
317 return ERR_PTR(-ENOMEM);
318 }
319
310 vif->domid = domid; 320 vif->domid = domid;
311 vif->handle = handle; 321 vif->handle = handle;
312 vif->can_sg = 1; 322 vif->can_sg = 1;
@@ -368,11 +378,11 @@ int xenvif_connect(struct xenvif *vif, unsigned long tx_ring_ref,
368 unsigned long rx_ring_ref, unsigned int tx_evtchn, 378 unsigned long rx_ring_ref, unsigned int tx_evtchn,
369 unsigned int rx_evtchn) 379 unsigned int rx_evtchn)
370{ 380{
381 struct task_struct *task;
371 int err = -ENOMEM; 382 int err = -ENOMEM;
372 383
373 /* Already connected through? */ 384 BUG_ON(vif->tx_irq);
374 if (vif->tx_irq) 385 BUG_ON(vif->task);
375 return 0;
376 386
377 err = xenvif_map_frontend_rings(vif, tx_ring_ref, rx_ring_ref); 387 err = xenvif_map_frontend_rings(vif, tx_ring_ref, rx_ring_ref);
378 if (err < 0) 388 if (err < 0)
@@ -411,14 +421,16 @@ int xenvif_connect(struct xenvif *vif, unsigned long tx_ring_ref,
411 } 421 }
412 422
413 init_waitqueue_head(&vif->wq); 423 init_waitqueue_head(&vif->wq);
414 vif->task = kthread_create(xenvif_kthread, 424 task = kthread_create(xenvif_kthread,
415 (void *)vif, "%s", vif->dev->name); 425 (void *)vif, "%s", vif->dev->name);
416 if (IS_ERR(vif->task)) { 426 if (IS_ERR(task)) {
417 pr_warn("Could not allocate kthread for %s\n", vif->dev->name); 427 pr_warn("Could not allocate kthread for %s\n", vif->dev->name);
418 err = PTR_ERR(vif->task); 428 err = PTR_ERR(task);
419 goto err_rx_unbind; 429 goto err_rx_unbind;
420 } 430 }
421 431
432 vif->task = task;
433
422 rtnl_lock(); 434 rtnl_lock();
423 if (!vif->can_sg && vif->dev->mtu > ETH_DATA_LEN) 435 if (!vif->can_sg && vif->dev->mtu > ETH_DATA_LEN)
424 dev_set_mtu(vif->dev, ETH_DATA_LEN); 436 dev_set_mtu(vif->dev, ETH_DATA_LEN);
@@ -461,8 +473,10 @@ void xenvif_disconnect(struct xenvif *vif)
461 if (netif_carrier_ok(vif->dev)) 473 if (netif_carrier_ok(vif->dev))
462 xenvif_carrier_off(vif); 474 xenvif_carrier_off(vif);
463 475
464 if (vif->task) 476 if (vif->task) {
465 kthread_stop(vif->task); 477 kthread_stop(vif->task);
478 vif->task = NULL;
479 }
466 480
467 if (vif->tx_irq) { 481 if (vif->tx_irq) {
468 if (vif->tx_irq == vif->rx_irq) 482 if (vif->tx_irq == vif->rx_irq)
@@ -483,6 +497,7 @@ void xenvif_free(struct xenvif *vif)
483 497
484 unregister_netdev(vif->dev); 498 unregister_netdev(vif->dev);
485 499
500 vfree(vif->grant_copy_op);
486 free_netdev(vif->dev); 501 free_netdev(vif->dev);
487 502
488 module_put(THIS_MODULE); 503 module_put(THIS_MODULE);