diff options
Diffstat (limited to 'drivers/net/xen-netback/interface.c')
| -rw-r--r-- | drivers/net/xen-netback/interface.c | 31 |
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); |
