diff --git a/debian/changelog b/debian/changelog index 757ba2b67..109c22a45 100644 --- a/debian/changelog +++ b/debian/changelog @@ -34,6 +34,8 @@ linux (3.16.7-ckt2-2) UNRELEASED; urgency=medium - [/orion5x]: Make SERIO and dependants modular * [arhmf] Add device-tree for LinkSprite pcDuino V3. Patch from Karsten Merker (Closes: #774067) + * [xen] More netback fixes (including reintroducing support for + feature-rx-notify, which was regressed by the fix to #767261). -- Ben Hutchings Sat, 13 Dec 2014 11:45:48 +0000 diff --git a/debian/patches/bugfix/all/netback-don-t-store-invalid-vif-pointer.patch b/debian/patches/bugfix/all/netback-don-t-store-invalid-vif-pointer.patch new file mode 100644 index 000000000..57644a3b1 --- /dev/null +++ b/debian/patches/bugfix/all/netback-don-t-store-invalid-vif-pointer.patch @@ -0,0 +1,50 @@ +From e67d8dd0e2c1b8b4573a6a3f05f609be230dfaff Mon Sep 17 00:00:00 2001 +From: Jan Beulich +Date: Tue, 9 Dec 2014 11:47:04 +0000 +Subject: [PATCH 3/4] netback: don't store invalid vif pointer +Origin: https://git.kernel.org/linus/f15650b7f94879667f253bc32de7431c1baf2d6e + +When xenvif_alloc() fails, it returns a non-NULL error indicator. To +avoid eventual races, we shouldn't store that into struct backend_info +as readers of it only check for NULL. + +Signed-off-by: Jan Beulich +Acked-by: Ian Campbell +Signed-off-by: David S. Miller +--- + drivers/net/xen-netback/xenbus.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +diff --git a/drivers/net/xen-netback/xenbus.c b/drivers/net/xen-netback/xenbus.c +index 0b4f1c7..cc8f8ba 100644 +--- a/drivers/net/xen-netback/xenbus.c ++++ b/drivers/net/xen-netback/xenbus.c +@@ -404,6 +404,7 @@ static int backend_create_xenvif(struct backend_info *be) + int err; + long handle; + struct xenbus_device *dev = be->dev; ++ struct xenvif *vif; + + if (be->vif != NULL) + return 0; +@@ -414,13 +415,13 @@ static int backend_create_xenvif(struct backend_info *be) + return (err < 0) ? err : -EINVAL; + } + +- be->vif = xenvif_alloc(&dev->dev, dev->otherend_id, handle); +- if (IS_ERR(be->vif)) { +- err = PTR_ERR(be->vif); +- be->vif = NULL; ++ vif = xenvif_alloc(&dev->dev, dev->otherend_id, handle); ++ if (IS_ERR(vif)) { ++ err = PTR_ERR(vif); + xenbus_dev_fatal(dev, err, "creating interface"); + return err; + } ++ be->vif = vif; + + kobject_uevent(&dev->dev.kobj, KOBJ_ONLINE); + return 0; +-- +1.7.10.4 + diff --git a/debian/patches/bugfix/all/xen-netback-Disable-NAPI-after-disabling-interrupts.patch b/debian/patches/bugfix/all/xen-netback-Disable-NAPI-after-disabling-interrupts.patch new file mode 100644 index 000000000..0f861dfa3 --- /dev/null +++ b/debian/patches/bugfix/all/xen-netback-Disable-NAPI-after-disabling-interrupts.patch @@ -0,0 +1,38 @@ +From bafb73e2d50d3addd0f79e09ea3f2e2950505733 Mon Sep 17 00:00:00 2001 +From: Zoltan Kiss +Date: Tue, 28 Oct 2014 15:29:30 +0000 +Subject: [PATCH 1/4] xen-netback: Disable NAPI after disabling interrupts +Origin: https://git.kernel.org/linus/8fe78989c3445a221cfcc54964e7e62718883615 + +Otherwise the interrupt handler still calls napi_complete. Although it +won't schedule NAPI again as either NAPI_STATE_DISABLE or +NAPI_STATE_SCHED is set, it is just unnecessary, and it makes more +sense to do this way. + +Signed-off-by: Zoltan Kiss +Signed-off-by: David Vrabel +Acked-by: Wei Liu +Signed-off-by: David S. Miller +--- + drivers/net/xen-netback/interface.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/xen-netback/interface.c b/drivers/net/xen-netback/interface.c +index 21d8db8..ddcb757 100644 +--- a/drivers/net/xen-netback/interface.c ++++ b/drivers/net/xen-netback/interface.c +@@ -235,10 +235,10 @@ static void xenvif_down(struct xenvif *vif) + + for (queue_index = 0; queue_index < num_queues; ++queue_index) { + queue = &vif->queues[queue_index]; +- napi_disable(&queue->napi); + disable_irq(queue->tx_irq); + if (queue->tx_irq != queue->rx_irq) + disable_irq(queue->rx_irq); ++ napi_disable(&queue->napi); + del_timer_sync(&queue->credit_timeout); + } + } +-- +1.7.10.4 + diff --git a/debian/patches/bugfix/all/xen-netback-do-not-report-success-if-backend_create_.patch b/debian/patches/bugfix/all/xen-netback-do-not-report-success-if-backend_create_.patch new file mode 100644 index 000000000..f94a170b4 --- /dev/null +++ b/debian/patches/bugfix/all/xen-netback-do-not-report-success-if-backend_create_.patch @@ -0,0 +1,84 @@ +From 0a640486cd7694015eaa7221714f9a2ce654f7a7 Mon Sep 17 00:00:00 2001 +From: Alexey Khoroshilov +Date: Mon, 24 Nov 2014 13:58:00 +0300 +Subject: [PATCH 2/4] xen-netback: do not report success if + backend_create_xenvif() fails +Origin: https://git.kernel.org/linus/2dd34339ac6305c4f2f4e589b858212e339d31e9 + +If xenvif_alloc() or xenbus_scanf() fail in backend_create_xenvif(), +xenbus is left in offline mode but netback_probe() reports success. + +The patch implements propagation of error code for backend_create_xenvif(). + +Found by Linux Driver Verification project (linuxtesting.org). + +Signed-off-by: Alexey Khoroshilov +Acked-by: Wei Liu +Signed-off-by: David S. Miller +--- + drivers/net/xen-netback/xenbus.c | 15 +++++++++------ + 1 file changed, 9 insertions(+), 6 deletions(-) + +diff --git a/drivers/net/xen-netback/xenbus.c b/drivers/net/xen-netback/xenbus.c +index 396b3d9..0b4f1c7 100644 +--- a/drivers/net/xen-netback/xenbus.c ++++ b/drivers/net/xen-netback/xenbus.c +@@ -39,7 +39,7 @@ struct backend_info { + static int connect_rings(struct backend_info *be, struct xenvif_queue *queue); + static void connect(struct backend_info *be); + static int read_xenbus_vif_flags(struct backend_info *be); +-static void backend_create_xenvif(struct backend_info *be); ++static int backend_create_xenvif(struct backend_info *be); + static void unregister_hotplug_status_watch(struct backend_info *be); + static void set_backend_state(struct backend_info *be, + enum xenbus_state state); +@@ -352,7 +352,9 @@ static int netback_probe(struct xenbus_device *dev, + be->state = XenbusStateInitWait; + + /* This kicks hotplug scripts, so do it immediately. */ +- backend_create_xenvif(be); ++ err = backend_create_xenvif(be); ++ if (err) ++ goto fail; + + return 0; + +@@ -397,19 +399,19 @@ static int netback_uevent(struct xenbus_device *xdev, + } + + +-static void backend_create_xenvif(struct backend_info *be) ++static int backend_create_xenvif(struct backend_info *be) + { + int err; + long handle; + struct xenbus_device *dev = be->dev; + + if (be->vif != NULL) +- return; ++ return 0; + + err = xenbus_scanf(XBT_NIL, dev->nodename, "handle", "%li", &handle); + if (err != 1) { + xenbus_dev_fatal(dev, err, "reading handle"); +- return; ++ return (err < 0) ? err : -EINVAL; + } + + be->vif = xenvif_alloc(&dev->dev, dev->otherend_id, handle); +@@ -417,10 +419,11 @@ static void backend_create_xenvif(struct backend_info *be) + err = PTR_ERR(be->vif); + be->vif = NULL; + xenbus_dev_fatal(dev, err, "creating interface"); +- return; ++ return err; + } + + kobject_uevent(&dev->dev.kobj, KOBJ_ONLINE); ++ return 0; + } + + static void backend_disconnect(struct backend_info *be) +-- +1.7.10.4 + diff --git a/debian/patches/bugfix/all/xen-netback-support-frontends-without-feature-rx-not.patch b/debian/patches/bugfix/all/xen-netback-support-frontends-without-feature-rx-not.patch new file mode 100644 index 000000000..a211842a6 --- /dev/null +++ b/debian/patches/bugfix/all/xen-netback-support-frontends-without-feature-rx-not.patch @@ -0,0 +1,188 @@ +From 0baa6f7d5b0ed21b28768d151b1d74cb9b88dacf Mon Sep 17 00:00:00 2001 +From: David Vrabel +Date: Thu, 18 Dec 2014 11:13:06 +0000 +Subject: [PATCH 4/4] xen-netback: support frontends without feature-rx-notify + again +Origin: https://git.kernel.org/linus/26c0e102585d5a4d311f5d6eb7f524d288e7f6b7 + +Commit bc96f648df1bbc2729abbb84513cf4f64273a1f1 (xen-netback: make +feature-rx-notify mandatory) incorrectly assumed that there were no +frontends in use that did not support this feature. But the frontend +driver in MiniOS does not and since this is used by (qemu) stubdoms, +these stopped working. + +Netback sort of works as-is in this mode except: + +- If there are no Rx requests and the internal Rx queue fills, only + the drain timeout will wake the thread. The default drain timeout + of 10 s would give unacceptable pauses. + +- If an Rx stall was detected and the internal Rx queue is drained, + then the Rx thread would never wake. + +Handle these two cases (when feature-rx-notify is disabled) by: + +- Reducing the drain timeout to 30 ms. + +- Disabling Rx stall detection. + +Reported-by: John +Tested-by: John +Signed-off-by: David Vrabel +Reviewed-by: Wei Liu +Signed-off-by: David S. Miller +--- + drivers/net/xen-netback/common.h | 4 +++- + drivers/net/xen-netback/interface.c | 4 +++- + drivers/net/xen-netback/netback.c | 27 ++++++++++++++------------- + drivers/net/xen-netback/xenbus.c | 12 +++++++++--- + 4 files changed, 29 insertions(+), 18 deletions(-) + +diff --git a/drivers/net/xen-netback/common.h b/drivers/net/xen-netback/common.h +index 083ecc9..5f1fda4 100644 +--- a/drivers/net/xen-netback/common.h ++++ b/drivers/net/xen-netback/common.h +@@ -230,6 +230,8 @@ struct xenvif { + */ + bool disabled; + unsigned long status; ++ unsigned long drain_timeout; ++ unsigned long stall_timeout; + + /* Queues */ + struct xenvif_queue *queues; +@@ -328,7 +330,7 @@ irqreturn_t xenvif_interrupt(int irq, void *dev_id); + extern bool separate_tx_rx_irq; + + extern unsigned int rx_drain_timeout_msecs; +-extern unsigned int rx_drain_timeout_jiffies; ++extern unsigned int rx_stall_timeout_msecs; + extern unsigned int xenvif_max_queues; + + #ifdef CONFIG_DEBUG_FS +diff --git a/drivers/net/xen-netback/interface.c b/drivers/net/xen-netback/interface.c +index ddcb757..af047c2 100644 +--- a/drivers/net/xen-netback/interface.c ++++ b/drivers/net/xen-netback/interface.c +@@ -166,7 +166,7 @@ static int xenvif_start_xmit(struct sk_buff *skb, struct net_device *dev) + goto drop; + + cb = XENVIF_RX_CB(skb); +- cb->expires = jiffies + rx_drain_timeout_jiffies; ++ cb->expires = jiffies + vif->drain_timeout; + + xenvif_rx_queue_tail(queue, skb); + xenvif_kick_thread(queue); +@@ -414,6 +414,8 @@ struct xenvif *xenvif_alloc(struct device *parent, domid_t domid, + vif->ip_csum = 1; + vif->dev = dev; + vif->disabled = false; ++ vif->drain_timeout = msecs_to_jiffies(rx_drain_timeout_msecs); ++ vif->stall_timeout = msecs_to_jiffies(rx_stall_timeout_msecs); + + /* Start out with no queues. */ + vif->queues = NULL; +diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c +index 6563f07..c39aace 100644 +--- a/drivers/net/xen-netback/netback.c ++++ b/drivers/net/xen-netback/netback.c +@@ -60,14 +60,12 @@ module_param(separate_tx_rx_irq, bool, 0644); + */ + unsigned int rx_drain_timeout_msecs = 10000; + module_param(rx_drain_timeout_msecs, uint, 0444); +-unsigned int rx_drain_timeout_jiffies; + + /* The length of time before the frontend is considered unresponsive + * because it isn't providing Rx slots. + */ +-static unsigned int rx_stall_timeout_msecs = 60000; ++unsigned int rx_stall_timeout_msecs = 60000; + module_param(rx_stall_timeout_msecs, uint, 0444); +-static unsigned int rx_stall_timeout_jiffies; + + unsigned int xenvif_max_queues; + module_param_named(max_queues, xenvif_max_queues, uint, 0644); +@@ -2022,7 +2020,7 @@ static bool xenvif_rx_queue_stalled(struct xenvif_queue *queue) + return !queue->stalled + && prod - cons < XEN_NETBK_RX_SLOTS_MAX + && time_after(jiffies, +- queue->last_rx_time + rx_stall_timeout_jiffies); ++ queue->last_rx_time + queue->vif->stall_timeout); + } + + static bool xenvif_rx_queue_ready(struct xenvif_queue *queue) +@@ -2040,8 +2038,9 @@ static bool xenvif_have_rx_work(struct xenvif_queue *queue) + { + return (!skb_queue_empty(&queue->rx_queue) + && xenvif_rx_ring_slots_available(queue, XEN_NETBK_RX_SLOTS_MAX)) +- || xenvif_rx_queue_stalled(queue) +- || xenvif_rx_queue_ready(queue) ++ || (queue->vif->stall_timeout && ++ (xenvif_rx_queue_stalled(queue) ++ || xenvif_rx_queue_ready(queue))) + || kthread_should_stop() + || queue->vif->disabled; + } +@@ -2094,6 +2093,9 @@ int xenvif_kthread_guest_rx(void *data) + struct xenvif_queue *queue = data; + struct xenvif *vif = queue->vif; + ++ if (!vif->stall_timeout) ++ xenvif_queue_carrier_on(queue); ++ + for (;;) { + xenvif_wait_for_rx_work(queue); + +@@ -2120,10 +2122,12 @@ int xenvif_kthread_guest_rx(void *data) + * while it's probably not responsive, drop the + * carrier so packets are dropped earlier. + */ +- if (xenvif_rx_queue_stalled(queue)) +- xenvif_queue_carrier_off(queue); +- else if (xenvif_rx_queue_ready(queue)) +- xenvif_queue_carrier_on(queue); ++ if (vif->stall_timeout) { ++ if (xenvif_rx_queue_stalled(queue)) ++ xenvif_queue_carrier_off(queue); ++ else if (xenvif_rx_queue_ready(queue)) ++ xenvif_queue_carrier_on(queue); ++ } + + /* Queued packets may have foreign pages from other + * domains. These cannot be queued indefinitely as +@@ -2194,9 +2198,6 @@ static int __init netback_init(void) + if (rc) + goto failed_init; + +- rx_drain_timeout_jiffies = msecs_to_jiffies(rx_drain_timeout_msecs); +- rx_stall_timeout_jiffies = msecs_to_jiffies(rx_stall_timeout_msecs); +- + #ifdef CONFIG_DEBUG_FS + xen_netback_dbg_root = debugfs_create_dir("xen-netback", NULL); + if (IS_ERR_OR_NULL(xen_netback_dbg_root)) +diff --git a/drivers/net/xen-netback/xenbus.c b/drivers/net/xen-netback/xenbus.c +index cc8f8ba..60f7c7d 100644 +--- a/drivers/net/xen-netback/xenbus.c ++++ b/drivers/net/xen-netback/xenbus.c +@@ -887,9 +887,15 @@ static int read_xenbus_vif_flags(struct backend_info *be) + return -EOPNOTSUPP; + + if (xenbus_scanf(XBT_NIL, dev->otherend, +- "feature-rx-notify", "%d", &val) < 0 || val == 0) { +- xenbus_dev_fatal(dev, -EINVAL, "feature-rx-notify is mandatory"); +- return -EINVAL; ++ "feature-rx-notify", "%d", &val) < 0) ++ val = 0; ++ if (!val) { ++ /* - Reduce drain timeout to poll more frequently for ++ * Rx requests. ++ * - Disable Rx stall detection. ++ */ ++ be->vif->drain_timeout = msecs_to_jiffies(30); ++ be->vif->stall_timeout = 0; + } + + if (xenbus_scanf(XBT_NIL, dev->otherend, "feature-sg", +-- +1.7.10.4 + diff --git a/debian/patches/series b/debian/patches/series index 1c16f9dff..c42df5ba3 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -157,6 +157,10 @@ bugfix/all/xen-netback-move-netif_napi_add-before-binding-inter.patch bugfix/all/xen-netback-make-feature-rx-notify-mandatory.patch bugfix/all/xen-netback-fix-unlimited-guest-Rx-internal-queue-an.patch bugfix/all/xen-netback-reintroduce-guest-Rx-stall-detection.patch +bugfix/all/xen-netback-Disable-NAPI-after-disabling-interrupts.patch +bugfix/all/xen-netback-do-not-report-success-if-backend_create_.patch +bugfix/all/netback-don-t-store-invalid-vif-pointer.patch +bugfix/all/xen-netback-support-frontends-without-feature-rx-not.patch bugfix/all/of-fdt-memblock_reserve-memreserve-regions-in-the-ca.patch # memfd_create() & kdbus backport