aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/xen-netback
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2013-07-12 06:34:42 -0400
committerThomas Gleixner <tglx@linutronix.de>2013-07-12 06:34:42 -0400
commitf2006e27396f55276f24434f56e208d86e7f9908 (patch)
tree71896db916d33888b4286f80117d3cac0da40e6d /drivers/net/xen-netback
parente399eb56a6110e13f97e644658648602e2b08de7 (diff)
parent9903883f1dd6e86f286b7bfa6e4b423f98c1cd9e (diff)
Merge branch 'linus' into timers/urgent
Get upstream changes so we can apply fixes against them Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'drivers/net/xen-netback')
-rw-r--r--drivers/net/xen-netback/common.h14
-rw-r--r--drivers/net/xen-netback/interface.c102
-rw-r--r--drivers/net/xen-netback/netback.c42
-rw-r--r--drivers/net/xen-netback/xenbus.c53
4 files changed, 172 insertions, 39 deletions
diff --git a/drivers/net/xen-netback/common.h b/drivers/net/xen-netback/common.h
index 9d7f1723dd8f..8a4d77ee9c5b 100644
--- a/drivers/net/xen-netback/common.h
+++ b/drivers/net/xen-netback/common.h
@@ -57,8 +57,12 @@ struct xenvif {
57 57
58 u8 fe_dev_addr[6]; 58 u8 fe_dev_addr[6];
59 59
60 /* Physical parameters of the comms window. */ 60 /* When feature-split-event-channels = 0, tx_irq = rx_irq. */
61 unsigned int irq; 61 unsigned int tx_irq;
62 unsigned int rx_irq;
63 /* Only used when feature-split-event-channels = 1 */
64 char tx_irq_name[IFNAMSIZ+4]; /* DEVNAME-tx */
65 char rx_irq_name[IFNAMSIZ+4]; /* DEVNAME-rx */
62 66
63 /* List of frontends to notify after a batch of frames sent. */ 67 /* List of frontends to notify after a batch of frames sent. */
64 struct list_head notify_list; 68 struct list_head notify_list;
@@ -113,13 +117,15 @@ struct xenvif *xenvif_alloc(struct device *parent,
113 unsigned int handle); 117 unsigned int handle);
114 118
115int xenvif_connect(struct xenvif *vif, unsigned long tx_ring_ref, 119int xenvif_connect(struct xenvif *vif, unsigned long tx_ring_ref,
116 unsigned long rx_ring_ref, unsigned int evtchn); 120 unsigned long rx_ring_ref, unsigned int tx_evtchn,
121 unsigned int rx_evtchn);
117void xenvif_disconnect(struct xenvif *vif); 122void xenvif_disconnect(struct xenvif *vif);
118 123
119void xenvif_get(struct xenvif *vif); 124void xenvif_get(struct xenvif *vif);
120void xenvif_put(struct xenvif *vif); 125void xenvif_put(struct xenvif *vif);
121 126
122int xenvif_xenbus_init(void); 127int xenvif_xenbus_init(void);
128void xenvif_xenbus_fini(void);
123 129
124int xenvif_schedulable(struct xenvif *vif); 130int xenvif_schedulable(struct xenvif *vif);
125 131
@@ -157,4 +163,6 @@ void xenvif_carrier_off(struct xenvif *vif);
157/* Returns number of ring slots required to send an skb to the frontend */ 163/* Returns number of ring slots required to send an skb to the frontend */
158unsigned int xen_netbk_count_skb_slots(struct xenvif *vif, struct sk_buff *skb); 164unsigned int xen_netbk_count_skb_slots(struct xenvif *vif, struct sk_buff *skb);
159 165
166extern bool separate_tx_rx_irq;
167
160#endif /* __XEN_NETBACK__COMMON_H__ */ 168#endif /* __XEN_NETBACK__COMMON_H__ */
diff --git a/drivers/net/xen-netback/interface.c b/drivers/net/xen-netback/interface.c
index d98414168485..087d2db0389d 100644
--- a/drivers/net/xen-netback/interface.c
+++ b/drivers/net/xen-netback/interface.c
@@ -60,21 +60,39 @@ static int xenvif_rx_schedulable(struct xenvif *vif)
60 return xenvif_schedulable(vif) && !xen_netbk_rx_ring_full(vif); 60 return xenvif_schedulable(vif) && !xen_netbk_rx_ring_full(vif);
61} 61}
62 62
63static irqreturn_t xenvif_interrupt(int irq, void *dev_id) 63static irqreturn_t xenvif_tx_interrupt(int irq, void *dev_id)
64{ 64{
65 struct xenvif *vif = dev_id; 65 struct xenvif *vif = dev_id;
66 66
67 if (vif->netbk == NULL) 67 if (vif->netbk == NULL)
68 return IRQ_NONE; 68 return IRQ_HANDLED;
69 69
70 xen_netbk_schedule_xenvif(vif); 70 xen_netbk_schedule_xenvif(vif);
71 71
72 return IRQ_HANDLED;
73}
74
75static irqreturn_t xenvif_rx_interrupt(int irq, void *dev_id)
76{
77 struct xenvif *vif = dev_id;
78
79 if (vif->netbk == NULL)
80 return IRQ_HANDLED;
81
72 if (xenvif_rx_schedulable(vif)) 82 if (xenvif_rx_schedulable(vif))
73 netif_wake_queue(vif->dev); 83 netif_wake_queue(vif->dev);
74 84
75 return IRQ_HANDLED; 85 return IRQ_HANDLED;
76} 86}
77 87
88static irqreturn_t xenvif_interrupt(int irq, void *dev_id)
89{
90 xenvif_tx_interrupt(irq, dev_id);
91 xenvif_rx_interrupt(irq, dev_id);
92
93 return IRQ_HANDLED;
94}
95
78static int xenvif_start_xmit(struct sk_buff *skb, struct net_device *dev) 96static int xenvif_start_xmit(struct sk_buff *skb, struct net_device *dev)
79{ 97{
80 struct xenvif *vif = netdev_priv(dev); 98 struct xenvif *vif = netdev_priv(dev);
@@ -125,13 +143,17 @@ static struct net_device_stats *xenvif_get_stats(struct net_device *dev)
125static void xenvif_up(struct xenvif *vif) 143static void xenvif_up(struct xenvif *vif)
126{ 144{
127 xen_netbk_add_xenvif(vif); 145 xen_netbk_add_xenvif(vif);
128 enable_irq(vif->irq); 146 enable_irq(vif->tx_irq);
147 if (vif->tx_irq != vif->rx_irq)
148 enable_irq(vif->rx_irq);
129 xen_netbk_check_rx_xenvif(vif); 149 xen_netbk_check_rx_xenvif(vif);
130} 150}
131 151
132static void xenvif_down(struct xenvif *vif) 152static void xenvif_down(struct xenvif *vif)
133{ 153{
134 disable_irq(vif->irq); 154 disable_irq(vif->tx_irq);
155 if (vif->tx_irq != vif->rx_irq)
156 disable_irq(vif->rx_irq);
135 del_timer_sync(&vif->credit_timeout); 157 del_timer_sync(&vif->credit_timeout);
136 xen_netbk_deschedule_xenvif(vif); 158 xen_netbk_deschedule_xenvif(vif);
137 xen_netbk_remove_xenvif(vif); 159 xen_netbk_remove_xenvif(vif);
@@ -308,25 +330,52 @@ struct xenvif *xenvif_alloc(struct device *parent, domid_t domid,
308} 330}
309 331
310int xenvif_connect(struct xenvif *vif, unsigned long tx_ring_ref, 332int xenvif_connect(struct xenvif *vif, unsigned long tx_ring_ref,
311 unsigned long rx_ring_ref, unsigned int evtchn) 333 unsigned long rx_ring_ref, unsigned int tx_evtchn,
334 unsigned int rx_evtchn)
312{ 335{
313 int err = -ENOMEM; 336 int err = -ENOMEM;
314 337
315 /* Already connected through? */ 338 /* Already connected through? */
316 if (vif->irq) 339 if (vif->tx_irq)
317 return 0; 340 return 0;
318 341
342 __module_get(THIS_MODULE);
343
319 err = xen_netbk_map_frontend_rings(vif, tx_ring_ref, rx_ring_ref); 344 err = xen_netbk_map_frontend_rings(vif, tx_ring_ref, rx_ring_ref);
320 if (err < 0) 345 if (err < 0)
321 goto err; 346 goto err;
322 347
323 err = bind_interdomain_evtchn_to_irqhandler( 348 if (tx_evtchn == rx_evtchn) {
324 vif->domid, evtchn, xenvif_interrupt, 0, 349 /* feature-split-event-channels == 0 */
325 vif->dev->name, vif); 350 err = bind_interdomain_evtchn_to_irqhandler(
326 if (err < 0) 351 vif->domid, tx_evtchn, xenvif_interrupt, 0,
327 goto err_unmap; 352 vif->dev->name, vif);
328 vif->irq = err; 353 if (err < 0)
329 disable_irq(vif->irq); 354 goto err_unmap;
355 vif->tx_irq = vif->rx_irq = err;
356 disable_irq(vif->tx_irq);
357 } else {
358 /* feature-split-event-channels == 1 */
359 snprintf(vif->tx_irq_name, sizeof(vif->tx_irq_name),
360 "%s-tx", vif->dev->name);
361 err = bind_interdomain_evtchn_to_irqhandler(
362 vif->domid, tx_evtchn, xenvif_tx_interrupt, 0,
363 vif->tx_irq_name, vif);
364 if (err < 0)
365 goto err_unmap;
366 vif->tx_irq = err;
367 disable_irq(vif->tx_irq);
368
369 snprintf(vif->rx_irq_name, sizeof(vif->rx_irq_name),
370 "%s-rx", vif->dev->name);
371 err = bind_interdomain_evtchn_to_irqhandler(
372 vif->domid, rx_evtchn, xenvif_rx_interrupt, 0,
373 vif->rx_irq_name, vif);
374 if (err < 0)
375 goto err_tx_unbind;
376 vif->rx_irq = err;
377 disable_irq(vif->rx_irq);
378 }
330 379
331 xenvif_get(vif); 380 xenvif_get(vif);
332 381
@@ -340,9 +389,13 @@ int xenvif_connect(struct xenvif *vif, unsigned long tx_ring_ref,
340 rtnl_unlock(); 389 rtnl_unlock();
341 390
342 return 0; 391 return 0;
392err_tx_unbind:
393 unbind_from_irqhandler(vif->tx_irq, vif);
394 vif->tx_irq = 0;
343err_unmap: 395err_unmap:
344 xen_netbk_unmap_frontend_rings(vif); 396 xen_netbk_unmap_frontend_rings(vif);
345err: 397err:
398 module_put(THIS_MODULE);
346 return err; 399 return err;
347} 400}
348 401
@@ -360,18 +413,37 @@ void xenvif_carrier_off(struct xenvif *vif)
360 413
361void xenvif_disconnect(struct xenvif *vif) 414void xenvif_disconnect(struct xenvif *vif)
362{ 415{
416 /* Disconnect funtion might get called by generic framework
417 * even before vif connects, so we need to check if we really
418 * need to do a module_put.
419 */
420 int need_module_put = 0;
421
363 if (netif_carrier_ok(vif->dev)) 422 if (netif_carrier_ok(vif->dev))
364 xenvif_carrier_off(vif); 423 xenvif_carrier_off(vif);
365 424
366 atomic_dec(&vif->refcnt); 425 atomic_dec(&vif->refcnt);
367 wait_event(vif->waiting_to_free, atomic_read(&vif->refcnt) == 0); 426 wait_event(vif->waiting_to_free, atomic_read(&vif->refcnt) == 0);
368 427
369 if (vif->irq) 428 if (vif->tx_irq) {
370 unbind_from_irqhandler(vif->irq, vif); 429 if (vif->tx_irq == vif->rx_irq)
430 unbind_from_irqhandler(vif->tx_irq, vif);
431 else {
432 unbind_from_irqhandler(vif->tx_irq, vif);
433 unbind_from_irqhandler(vif->rx_irq, vif);
434 }
435 /* vif->irq is valid, we had a module_get in
436 * xenvif_connect.
437 */
438 need_module_put = 1;
439 }
371 440
372 unregister_netdev(vif->dev); 441 unregister_netdev(vif->dev);
373 442
374 xen_netbk_unmap_frontend_rings(vif); 443 xen_netbk_unmap_frontend_rings(vif);
375 444
376 free_netdev(vif->dev); 445 free_netdev(vif->dev);
446
447 if (need_module_put)
448 module_put(THIS_MODULE);
377} 449}
diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c
index 8c20935d72c9..64828de25d9a 100644
--- a/drivers/net/xen-netback/netback.c
+++ b/drivers/net/xen-netback/netback.c
@@ -47,6 +47,13 @@
47#include <asm/xen/hypercall.h> 47#include <asm/xen/hypercall.h>
48#include <asm/xen/page.h> 48#include <asm/xen/page.h>
49 49
50/* Provide an option to disable split event channels at load time as
51 * event channels are limited resource. Split event channels are
52 * enabled by default.
53 */
54bool separate_tx_rx_irq = 1;
55module_param(separate_tx_rx_irq, bool, 0644);
56
50/* 57/*
51 * This is the maximum slots a skb can have. If a guest sends a skb 58 * This is the maximum slots a skb can have. If a guest sends a skb
52 * which exceeds this limit it is considered malicious. 59 * which exceeds this limit it is considered malicious.
@@ -783,7 +790,7 @@ static void xen_netbk_rx_action(struct xen_netbk *netbk)
783 } 790 }
784 791
785 list_for_each_entry_safe(vif, tmp, &notify, notify_list) { 792 list_for_each_entry_safe(vif, tmp, &notify, notify_list) {
786 notify_remote_via_irq(vif->irq); 793 notify_remote_via_irq(vif->rx_irq);
787 list_del_init(&vif->notify_list); 794 list_del_init(&vif->notify_list);
788 xenvif_put(vif); 795 xenvif_put(vif);
789 } 796 }
@@ -1763,7 +1770,7 @@ static void make_tx_response(struct xenvif *vif,
1763 vif->tx.rsp_prod_pvt = ++i; 1770 vif->tx.rsp_prod_pvt = ++i;
1764 RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&vif->tx, notify); 1771 RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&vif->tx, notify);
1765 if (notify) 1772 if (notify)
1766 notify_remote_via_irq(vif->irq); 1773 notify_remote_via_irq(vif->tx_irq);
1767} 1774}
1768 1775
1769static struct xen_netif_rx_response *make_rx_response(struct xenvif *vif, 1776static struct xen_netif_rx_response *make_rx_response(struct xenvif *vif,
@@ -1883,9 +1890,8 @@ static int __init netback_init(void)
1883 return -ENODEV; 1890 return -ENODEV;
1884 1891
1885 if (fatal_skb_slots < XEN_NETBK_LEGACY_SLOTS_MAX) { 1892 if (fatal_skb_slots < XEN_NETBK_LEGACY_SLOTS_MAX) {
1886 printk(KERN_INFO 1893 pr_info("fatal_skb_slots too small (%d), bump it to XEN_NETBK_LEGACY_SLOTS_MAX (%d)\n",
1887 "xen-netback: fatal_skb_slots too small (%d), bump it to XEN_NETBK_LEGACY_SLOTS_MAX (%d)\n", 1894 fatal_skb_slots, XEN_NETBK_LEGACY_SLOTS_MAX);
1888 fatal_skb_slots, XEN_NETBK_LEGACY_SLOTS_MAX);
1889 fatal_skb_slots = XEN_NETBK_LEGACY_SLOTS_MAX; 1895 fatal_skb_slots = XEN_NETBK_LEGACY_SLOTS_MAX;
1890 } 1896 }
1891 1897
@@ -1914,7 +1920,7 @@ static int __init netback_init(void)
1914 "netback/%u", group); 1920 "netback/%u", group);
1915 1921
1916 if (IS_ERR(netbk->task)) { 1922 if (IS_ERR(netbk->task)) {
1917 printk(KERN_ALERT "kthread_create() fails at netback\n"); 1923 pr_alert("kthread_create() fails at netback\n");
1918 del_timer(&netbk->net_timer); 1924 del_timer(&netbk->net_timer);
1919 rc = PTR_ERR(netbk->task); 1925 rc = PTR_ERR(netbk->task);
1920 goto failed_init; 1926 goto failed_init;
@@ -1940,10 +1946,6 @@ static int __init netback_init(void)
1940failed_init: 1946failed_init:
1941 while (--group >= 0) { 1947 while (--group >= 0) {
1942 struct xen_netbk *netbk = &xen_netbk[group]; 1948 struct xen_netbk *netbk = &xen_netbk[group];
1943 for (i = 0; i < MAX_PENDING_REQS; i++) {
1944 if (netbk->mmap_pages[i])
1945 __free_page(netbk->mmap_pages[i]);
1946 }
1947 del_timer(&netbk->net_timer); 1949 del_timer(&netbk->net_timer);
1948 kthread_stop(netbk->task); 1950 kthread_stop(netbk->task);
1949 } 1951 }
@@ -1954,5 +1956,25 @@ failed_init:
1954 1956
1955module_init(netback_init); 1957module_init(netback_init);
1956 1958
1959static void __exit netback_fini(void)
1960{
1961 int i, j;
1962
1963 xenvif_xenbus_fini();
1964
1965 for (i = 0; i < xen_netbk_group_nr; i++) {
1966 struct xen_netbk *netbk = &xen_netbk[i];
1967 del_timer_sync(&netbk->net_timer);
1968 kthread_stop(netbk->task);
1969 for (j = 0; j < MAX_PENDING_REQS; j++) {
1970 if (netbk->mmap_pages[j])
1971 __free_page(netbk->mmap_pages[j]);
1972 }
1973 }
1974
1975 vfree(xen_netbk);
1976}
1977module_exit(netback_fini);
1978
1957MODULE_LICENSE("Dual BSD/GPL"); 1979MODULE_LICENSE("Dual BSD/GPL");
1958MODULE_ALIAS("xen-backend:vif"); 1980MODULE_ALIAS("xen-backend:vif");
diff --git a/drivers/net/xen-netback/xenbus.c b/drivers/net/xen-netback/xenbus.c
index 410018c4c528..1fe48fe364ed 100644
--- a/drivers/net/xen-netback/xenbus.c
+++ b/drivers/net/xen-netback/xenbus.c
@@ -122,6 +122,16 @@ static int netback_probe(struct xenbus_device *dev,
122 goto fail; 122 goto fail;
123 } 123 }
124 124
125 /*
126 * Split event channels support, this is optional so it is not
127 * put inside the above loop.
128 */
129 err = xenbus_printf(XBT_NIL, dev->nodename,
130 "feature-split-event-channels",
131 "%u", separate_tx_rx_irq);
132 if (err)
133 pr_debug("Error writing feature-split-event-channels\n");
134
125 err = xenbus_switch_state(dev, XenbusStateInitWait); 135 err = xenbus_switch_state(dev, XenbusStateInitWait);
126 if (err) 136 if (err)
127 goto fail; 137 goto fail;
@@ -135,7 +145,7 @@ abort_transaction:
135 xenbus_transaction_end(xbt, 1); 145 xenbus_transaction_end(xbt, 1);
136 xenbus_dev_fatal(dev, err, "%s", message); 146 xenbus_dev_fatal(dev, err, "%s", message);
137fail: 147fail:
138 pr_debug("failed"); 148 pr_debug("failed\n");
139 netback_remove(dev); 149 netback_remove(dev);
140 return err; 150 return err;
141} 151}
@@ -218,15 +228,14 @@ static void frontend_changed(struct xenbus_device *dev,
218{ 228{
219 struct backend_info *be = dev_get_drvdata(&dev->dev); 229 struct backend_info *be = dev_get_drvdata(&dev->dev);
220 230
221 pr_debug("frontend state %s", xenbus_strstate(frontend_state)); 231 pr_debug("frontend state %s\n", xenbus_strstate(frontend_state));
222 232
223 be->frontend_state = frontend_state; 233 be->frontend_state = frontend_state;
224 234
225 switch (frontend_state) { 235 switch (frontend_state) {
226 case XenbusStateInitialising: 236 case XenbusStateInitialising:
227 if (dev->state == XenbusStateClosed) { 237 if (dev->state == XenbusStateClosed) {
228 printk(KERN_INFO "%s: %s: prepare for reconnect\n", 238 pr_info("%s: prepare for reconnect\n", dev->nodename);
229 __func__, dev->nodename);
230 xenbus_switch_state(dev, XenbusStateInitWait); 239 xenbus_switch_state(dev, XenbusStateInitWait);
231 } 240 }
232 break; 241 break;
@@ -393,21 +402,36 @@ static int connect_rings(struct backend_info *be)
393 struct xenvif *vif = be->vif; 402 struct xenvif *vif = be->vif;
394 struct xenbus_device *dev = be->dev; 403 struct xenbus_device *dev = be->dev;
395 unsigned long tx_ring_ref, rx_ring_ref; 404 unsigned long tx_ring_ref, rx_ring_ref;
396 unsigned int evtchn, rx_copy; 405 unsigned int tx_evtchn, rx_evtchn, rx_copy;
397 int err; 406 int err;
398 int val; 407 int val;
399 408
400 err = xenbus_gather(XBT_NIL, dev->otherend, 409 err = xenbus_gather(XBT_NIL, dev->otherend,
401 "tx-ring-ref", "%lu", &tx_ring_ref, 410 "tx-ring-ref", "%lu", &tx_ring_ref,
402 "rx-ring-ref", "%lu", &rx_ring_ref, 411 "rx-ring-ref", "%lu", &rx_ring_ref, NULL);
403 "event-channel", "%u", &evtchn, NULL);
404 if (err) { 412 if (err) {
405 xenbus_dev_fatal(dev, err, 413 xenbus_dev_fatal(dev, err,
406 "reading %s/ring-ref and event-channel", 414 "reading %s/ring-ref",
407 dev->otherend); 415 dev->otherend);
408 return err; 416 return err;
409 } 417 }
410 418
419 /* Try split event channels first, then single event channel. */
420 err = xenbus_gather(XBT_NIL, dev->otherend,
421 "event-channel-tx", "%u", &tx_evtchn,
422 "event-channel-rx", "%u", &rx_evtchn, NULL);
423 if (err < 0) {
424 err = xenbus_scanf(XBT_NIL, dev->otherend,
425 "event-channel", "%u", &tx_evtchn);
426 if (err < 0) {
427 xenbus_dev_fatal(dev, err,
428 "reading %s/event-channel(-tx/rx)",
429 dev->otherend);
430 return err;
431 }
432 rx_evtchn = tx_evtchn;
433 }
434
411 err = xenbus_scanf(XBT_NIL, dev->otherend, "request-rx-copy", "%u", 435 err = xenbus_scanf(XBT_NIL, dev->otherend, "request-rx-copy", "%u",
412 &rx_copy); 436 &rx_copy);
413 if (err == -ENOENT) { 437 if (err == -ENOENT) {
@@ -454,11 +478,13 @@ static int connect_rings(struct backend_info *be)
454 vif->csum = !val; 478 vif->csum = !val;
455 479
456 /* Map the shared frame, irq etc. */ 480 /* Map the shared frame, irq etc. */
457 err = xenvif_connect(vif, tx_ring_ref, rx_ring_ref, evtchn); 481 err = xenvif_connect(vif, tx_ring_ref, rx_ring_ref,
482 tx_evtchn, rx_evtchn);
458 if (err) { 483 if (err) {
459 xenbus_dev_fatal(dev, err, 484 xenbus_dev_fatal(dev, err,
460 "mapping shared-frames %lu/%lu port %u", 485 "mapping shared-frames %lu/%lu port tx %u rx %u",
461 tx_ring_ref, rx_ring_ref, evtchn); 486 tx_ring_ref, rx_ring_ref,
487 tx_evtchn, rx_evtchn);
462 return err; 488 return err;
463 } 489 }
464 return 0; 490 return 0;
@@ -485,3 +511,8 @@ int xenvif_xenbus_init(void)
485{ 511{
486 return xenbus_register_backend(&netback_driver); 512 return xenbus_register_backend(&netback_driver);
487} 513}
514
515void xenvif_xenbus_fini(void)
516{
517 return xenbus_unregister_driver(&netback_driver);
518}