aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/xen-netback/xenbus.c
diff options
context:
space:
mode:
authorWei Liu <wei.liu2@citrix.com>2013-05-22 02:34:45 -0400
committerDavid S. Miller <davem@davemloft.net>2013-05-23 21:40:37 -0400
commite1f00a69ec26e3eb9847c61c665b8fb3f0c6b477 (patch)
tree5958617283d231a3a58229e0e78a4d4623a569a5 /drivers/net/xen-netback/xenbus.c
parent8892475386e819aa50856947948c546ccc964d96 (diff)
xen-netback: split event channels support for Xen backend driver
Netback and netfront only use one event channel to do TX / RX notification, which may cause unnecessary wake-up of processing routines. This patch adds a new feature called feature-split-event-channels to netback, enabling it to handle TX and RX events separately. Netback will use tx_irq to notify guest for TX completion, rx_irq for RX notification. If frontend doesn't support this feature, tx_irq equals to rx_irq. Signed-off-by: Wei Liu <wei.liu2@citrix.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/xen-netback/xenbus.c')
-rw-r--r--drivers/net/xen-netback/xenbus.c41
1 files changed, 34 insertions, 7 deletions
diff --git a/drivers/net/xen-netback/xenbus.c b/drivers/net/xen-netback/xenbus.c
index d230c145660c..04bd860d16a9 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");
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;
@@ -393,21 +403,36 @@ static int connect_rings(struct backend_info *be)
393 struct xenvif *vif = be->vif; 403 struct xenvif *vif = be->vif;
394 struct xenbus_device *dev = be->dev; 404 struct xenbus_device *dev = be->dev;
395 unsigned long tx_ring_ref, rx_ring_ref; 405 unsigned long tx_ring_ref, rx_ring_ref;
396 unsigned int evtchn, rx_copy; 406 unsigned int tx_evtchn, rx_evtchn, rx_copy;
397 int err; 407 int err;
398 int val; 408 int val;
399 409
400 err = xenbus_gather(XBT_NIL, dev->otherend, 410 err = xenbus_gather(XBT_NIL, dev->otherend,
401 "tx-ring-ref", "%lu", &tx_ring_ref, 411 "tx-ring-ref", "%lu", &tx_ring_ref,
402 "rx-ring-ref", "%lu", &rx_ring_ref, 412 "rx-ring-ref", "%lu", &rx_ring_ref, NULL);
403 "event-channel", "%u", &evtchn, NULL);
404 if (err) { 413 if (err) {
405 xenbus_dev_fatal(dev, err, 414 xenbus_dev_fatal(dev, err,
406 "reading %s/ring-ref and event-channel", 415 "reading %s/ring-ref",
407 dev->otherend); 416 dev->otherend);
408 return err; 417 return err;
409 } 418 }
410 419
420 /* Try split event channels first, then single event channel. */
421 err = xenbus_gather(XBT_NIL, dev->otherend,
422 "event-channel-tx", "%u", &tx_evtchn,
423 "event-channel-rx", "%u", &rx_evtchn, NULL);
424 if (err < 0) {
425 err = xenbus_scanf(XBT_NIL, dev->otherend,
426 "event-channel", "%u", &tx_evtchn);
427 if (err < 0) {
428 xenbus_dev_fatal(dev, err,
429 "reading %s/event-channel(-tx/rx)",
430 dev->otherend);
431 return err;
432 }
433 rx_evtchn = tx_evtchn;
434 }
435
411 err = xenbus_scanf(XBT_NIL, dev->otherend, "request-rx-copy", "%u", 436 err = xenbus_scanf(XBT_NIL, dev->otherend, "request-rx-copy", "%u",
412 &rx_copy); 437 &rx_copy);
413 if (err == -ENOENT) { 438 if (err == -ENOENT) {
@@ -454,11 +479,13 @@ static int connect_rings(struct backend_info *be)
454 vif->csum = !val; 479 vif->csum = !val;
455 480
456 /* Map the shared frame, irq etc. */ 481 /* Map the shared frame, irq etc. */
457 err = xenvif_connect(vif, tx_ring_ref, rx_ring_ref, evtchn); 482 err = xenvif_connect(vif, tx_ring_ref, rx_ring_ref,
483 tx_evtchn, rx_evtchn);
458 if (err) { 484 if (err) {
459 xenbus_dev_fatal(dev, err, 485 xenbus_dev_fatal(dev, err,
460 "mapping shared-frames %lu/%lu port %u", 486 "mapping shared-frames %lu/%lu port tx %u rx %u",
461 tx_ring_ref, rx_ring_ref, evtchn); 487 tx_ring_ref, rx_ring_ref,
488 tx_evtchn, rx_evtchn);
462 return err; 489 return err;
463 } 490 }
464 return 0; 491 return 0;