aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/xen-netback/interface.c
diff options
context:
space:
mode:
authorPaul Moore <pmoore@redhat.com>2014-01-28 14:44:16 -0500
committerPaul Moore <pmoore@redhat.com>2014-02-05 10:39:48 -0500
commit825e587af2e90e9b953849f3347a01d8f383d577 (patch)
treee48942a05882da47544e179c6a0c920e00137a6a /drivers/net/xen-netback/interface.c
parent8ed814602876bec9bad2649ca17f34b499357a1c (diff)
parentd8ec26d7f8287f5788a494f56e8814210f0e64be (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.c54
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);