diff options
| author | Paul Moore <pmoore@redhat.com> | 2014-01-28 14:44:16 -0500 |
|---|---|---|
| committer | Paul Moore <pmoore@redhat.com> | 2014-02-05 10:39:48 -0500 |
| commit | 825e587af2e90e9b953849f3347a01d8f383d577 (patch) | |
| tree | e48942a05882da47544e179c6a0c920e00137a6a /drivers/net/xen-netback/interface.c | |
| parent | 8ed814602876bec9bad2649ca17f34b499357a1c (diff) | |
| parent | d8ec26d7f8287f5788a494f56e8814210f0e64be (diff) | |
Merge tag 'v3.13' into stable-3.14
Linux 3.13
Conflicts:
security/selinux/hooks.c
Trivial merge issue in selinux_inet_conn_request() likely due to me
including patches that I sent to the stable folks in my next tree
resulting in the patch hitting twice (I think). Thankfully it was an
easy fix this time, but regardless, lesson learned, I will not do that
again.
Diffstat (limited to 'drivers/net/xen-netback/interface.c')
| -rw-r--r-- | drivers/net/xen-netback/interface.c | 54 |
1 files changed, 37 insertions, 17 deletions
diff --git a/drivers/net/xen-netback/interface.c b/drivers/net/xen-netback/interface.c index 01bb854c7f62..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> |
| @@ -214,10 +215,14 @@ static netdev_features_t xenvif_fix_features(struct net_device *dev, | |||
| 214 | 215 | ||
| 215 | if (!vif->can_sg) | 216 | if (!vif->can_sg) |
| 216 | features &= ~NETIF_F_SG; | 217 | features &= ~NETIF_F_SG; |
| 217 | if (!vif->gso && !vif->gso_prefix) | 218 | if (~(vif->gso_mask | vif->gso_prefix_mask) & GSO_BIT(TCPV4)) |
| 218 | features &= ~NETIF_F_TSO; | 219 | features &= ~NETIF_F_TSO; |
| 219 | if (!vif->csum) | 220 | if (~(vif->gso_mask | vif->gso_prefix_mask) & GSO_BIT(TCPV6)) |
| 221 | features &= ~NETIF_F_TSO6; | ||
| 222 | if (!vif->ip_csum) | ||
| 220 | features &= ~NETIF_F_IP_CSUM; | 223 | features &= ~NETIF_F_IP_CSUM; |
| 224 | if (!vif->ipv6_csum) | ||
| 225 | features &= ~NETIF_F_IPV6_CSUM; | ||
| 221 | 226 | ||
| 222 | return features; | 227 | return features; |
| 223 | } | 228 | } |
| @@ -303,21 +308,31 @@ struct xenvif *xenvif_alloc(struct device *parent, domid_t domid, | |||
| 303 | SET_NETDEV_DEV(dev, parent); | 308 | SET_NETDEV_DEV(dev, parent); |
| 304 | 309 | ||
| 305 | 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 | |||
| 306 | vif->domid = domid; | 320 | vif->domid = domid; |
| 307 | vif->handle = handle; | 321 | vif->handle = handle; |
| 308 | vif->can_sg = 1; | 322 | vif->can_sg = 1; |
| 309 | vif->csum = 1; | 323 | vif->ip_csum = 1; |
| 310 | vif->dev = dev; | 324 | vif->dev = dev; |
| 311 | 325 | ||
| 312 | vif->credit_bytes = vif->remaining_credit = ~0UL; | 326 | vif->credit_bytes = vif->remaining_credit = ~0UL; |
| 313 | vif->credit_usec = 0UL; | 327 | vif->credit_usec = 0UL; |
| 314 | init_timer(&vif->credit_timeout); | 328 | init_timer(&vif->credit_timeout); |
| 315 | /* Initialize 'expires' now: it's used to track the credit window. */ | 329 | vif->credit_window_start = get_jiffies_64(); |
| 316 | vif->credit_timeout.expires = jiffies; | ||
| 317 | 330 | ||
| 318 | dev->netdev_ops = &xenvif_netdev_ops; | 331 | dev->netdev_ops = &xenvif_netdev_ops; |
| 319 | dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO; | 332 | dev->hw_features = NETIF_F_SG | |
| 320 | dev->features = dev->hw_features; | 333 | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | |
| 334 | NETIF_F_TSO | NETIF_F_TSO6; | ||
| 335 | dev->features = dev->hw_features | NETIF_F_RXCSUM; | ||
| 321 | SET_ETHTOOL_OPS(dev, &xenvif_ethtool_ops); | 336 | SET_ETHTOOL_OPS(dev, &xenvif_ethtool_ops); |
| 322 | 337 | ||
| 323 | dev->tx_queue_len = XENVIF_QUEUE_LENGTH; | 338 | dev->tx_queue_len = XENVIF_QUEUE_LENGTH; |
| @@ -363,11 +378,11 @@ int xenvif_connect(struct xenvif *vif, unsigned long tx_ring_ref, | |||
| 363 | unsigned long rx_ring_ref, unsigned int tx_evtchn, | 378 | unsigned long rx_ring_ref, unsigned int tx_evtchn, |
| 364 | unsigned int rx_evtchn) | 379 | unsigned int rx_evtchn) |
| 365 | { | 380 | { |
| 381 | struct task_struct *task; | ||
| 366 | int err = -ENOMEM; | 382 | int err = -ENOMEM; |
| 367 | 383 | ||
| 368 | /* Already connected through? */ | 384 | BUG_ON(vif->tx_irq); |
| 369 | if (vif->tx_irq) | 385 | BUG_ON(vif->task); |
| 370 | return 0; | ||
| 371 | 386 | ||
| 372 | 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); |
| 373 | if (err < 0) | 388 | if (err < 0) |
| @@ -406,14 +421,16 @@ int xenvif_connect(struct xenvif *vif, unsigned long tx_ring_ref, | |||
| 406 | } | 421 | } |
| 407 | 422 | ||
| 408 | init_waitqueue_head(&vif->wq); | 423 | init_waitqueue_head(&vif->wq); |
| 409 | vif->task = kthread_create(xenvif_kthread, | 424 | task = kthread_create(xenvif_kthread, |
| 410 | (void *)vif, "%s", vif->dev->name); | 425 | (void *)vif, "%s", vif->dev->name); |
| 411 | if (IS_ERR(vif->task)) { | 426 | if (IS_ERR(task)) { |
| 412 | 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); |
| 413 | err = PTR_ERR(vif->task); | 428 | err = PTR_ERR(task); |
| 414 | goto err_rx_unbind; | 429 | goto err_rx_unbind; |
| 415 | } | 430 | } |
| 416 | 431 | ||
| 432 | vif->task = task; | ||
| 433 | |||
| 417 | rtnl_lock(); | 434 | rtnl_lock(); |
| 418 | if (!vif->can_sg && vif->dev->mtu > ETH_DATA_LEN) | 435 | if (!vif->can_sg && vif->dev->mtu > ETH_DATA_LEN) |
| 419 | dev_set_mtu(vif->dev, ETH_DATA_LEN); | 436 | dev_set_mtu(vif->dev, ETH_DATA_LEN); |
| @@ -456,6 +473,11 @@ void xenvif_disconnect(struct xenvif *vif) | |||
| 456 | if (netif_carrier_ok(vif->dev)) | 473 | if (netif_carrier_ok(vif->dev)) |
| 457 | xenvif_carrier_off(vif); | 474 | xenvif_carrier_off(vif); |
| 458 | 475 | ||
| 476 | if (vif->task) { | ||
| 477 | kthread_stop(vif->task); | ||
| 478 | vif->task = NULL; | ||
| 479 | } | ||
| 480 | |||
| 459 | if (vif->tx_irq) { | 481 | if (vif->tx_irq) { |
| 460 | if (vif->tx_irq == vif->rx_irq) | 482 | if (vif->tx_irq == vif->rx_irq) |
| 461 | unbind_from_irqhandler(vif->tx_irq, vif); | 483 | unbind_from_irqhandler(vif->tx_irq, vif); |
| @@ -466,9 +488,6 @@ void xenvif_disconnect(struct xenvif *vif) | |||
| 466 | vif->tx_irq = 0; | 488 | vif->tx_irq = 0; |
| 467 | } | 489 | } |
| 468 | 490 | ||
| 469 | if (vif->task) | ||
| 470 | kthread_stop(vif->task); | ||
| 471 | |||
| 472 | xenvif_unmap_frontend_rings(vif); | 491 | xenvif_unmap_frontend_rings(vif); |
| 473 | } | 492 | } |
| 474 | 493 | ||
| @@ -478,6 +497,7 @@ void xenvif_free(struct xenvif *vif) | |||
| 478 | 497 | ||
| 479 | unregister_netdev(vif->dev); | 498 | unregister_netdev(vif->dev); |
| 480 | 499 | ||
| 500 | vfree(vif->grant_copy_op); | ||
| 481 | free_netdev(vif->dev); | 501 | free_netdev(vif->dev); |
| 482 | 502 | ||
| 483 | module_put(THIS_MODULE); | 503 | module_put(THIS_MODULE); |
