diff options
| -rw-r--r-- | drivers/net/xen-netback/common.h | 4 | ||||
| -rw-r--r-- | drivers/net/xen-netback/interface.c | 4 | ||||
| -rw-r--r-- | drivers/net/xen-netback/netback.c | 27 | ||||
| -rw-r--r-- | 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 083ecc93fe5e..5f1fda44882b 100644 --- a/drivers/net/xen-netback/common.h +++ b/drivers/net/xen-netback/common.h | |||
| @@ -230,6 +230,8 @@ struct xenvif { | |||
| 230 | */ | 230 | */ |
| 231 | bool disabled; | 231 | bool disabled; |
| 232 | unsigned long status; | 232 | unsigned long status; |
| 233 | unsigned long drain_timeout; | ||
| 234 | unsigned long stall_timeout; | ||
| 233 | 235 | ||
| 234 | /* Queues */ | 236 | /* Queues */ |
| 235 | struct xenvif_queue *queues; | 237 | struct xenvif_queue *queues; |
| @@ -328,7 +330,7 @@ irqreturn_t xenvif_interrupt(int irq, void *dev_id); | |||
| 328 | extern bool separate_tx_rx_irq; | 330 | extern bool separate_tx_rx_irq; |
| 329 | 331 | ||
| 330 | extern unsigned int rx_drain_timeout_msecs; | 332 | extern unsigned int rx_drain_timeout_msecs; |
| 331 | extern unsigned int rx_drain_timeout_jiffies; | 333 | extern unsigned int rx_stall_timeout_msecs; |
| 332 | extern unsigned int xenvif_max_queues; | 334 | extern unsigned int xenvif_max_queues; |
| 333 | 335 | ||
| 334 | #ifdef CONFIG_DEBUG_FS | 336 | #ifdef CONFIG_DEBUG_FS |
diff --git a/drivers/net/xen-netback/interface.c b/drivers/net/xen-netback/interface.c index a6a32d337bbb..9259a732e8a4 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) | |||
| 166 | goto drop; | 166 | goto drop; |
| 167 | 167 | ||
| 168 | cb = XENVIF_RX_CB(skb); | 168 | cb = XENVIF_RX_CB(skb); |
| 169 | cb->expires = jiffies + rx_drain_timeout_jiffies; | 169 | cb->expires = jiffies + vif->drain_timeout; |
| 170 | 170 | ||
| 171 | xenvif_rx_queue_tail(queue, skb); | 171 | xenvif_rx_queue_tail(queue, skb); |
| 172 | xenvif_kick_thread(queue); | 172 | xenvif_kick_thread(queue); |
| @@ -414,6 +414,8 @@ struct xenvif *xenvif_alloc(struct device *parent, domid_t domid, | |||
| 414 | vif->ip_csum = 1; | 414 | vif->ip_csum = 1; |
| 415 | vif->dev = dev; | 415 | vif->dev = dev; |
| 416 | vif->disabled = false; | 416 | vif->disabled = false; |
| 417 | vif->drain_timeout = msecs_to_jiffies(rx_drain_timeout_msecs); | ||
| 418 | vif->stall_timeout = msecs_to_jiffies(rx_stall_timeout_msecs); | ||
| 417 | 419 | ||
| 418 | /* Start out with no queues. */ | 420 | /* Start out with no queues. */ |
| 419 | vif->queues = NULL; | 421 | vif->queues = NULL; |
diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c index 4a509f715fe8..908e65e9b821 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); | |||
| 60 | */ | 60 | */ |
| 61 | unsigned int rx_drain_timeout_msecs = 10000; | 61 | unsigned int rx_drain_timeout_msecs = 10000; |
| 62 | module_param(rx_drain_timeout_msecs, uint, 0444); | 62 | module_param(rx_drain_timeout_msecs, uint, 0444); |
| 63 | unsigned int rx_drain_timeout_jiffies; | ||
| 64 | 63 | ||
| 65 | /* The length of time before the frontend is considered unresponsive | 64 | /* The length of time before the frontend is considered unresponsive |
| 66 | * because it isn't providing Rx slots. | 65 | * because it isn't providing Rx slots. |
| 67 | */ | 66 | */ |
| 68 | static unsigned int rx_stall_timeout_msecs = 60000; | 67 | unsigned int rx_stall_timeout_msecs = 60000; |
| 69 | module_param(rx_stall_timeout_msecs, uint, 0444); | 68 | module_param(rx_stall_timeout_msecs, uint, 0444); |
| 70 | static unsigned int rx_stall_timeout_jiffies; | ||
| 71 | 69 | ||
| 72 | unsigned int xenvif_max_queues; | 70 | unsigned int xenvif_max_queues; |
| 73 | module_param_named(max_queues, xenvif_max_queues, uint, 0644); | 71 | module_param_named(max_queues, xenvif_max_queues, uint, 0644); |
| @@ -2020,7 +2018,7 @@ static bool xenvif_rx_queue_stalled(struct xenvif_queue *queue) | |||
| 2020 | return !queue->stalled | 2018 | return !queue->stalled |
| 2021 | && prod - cons < XEN_NETBK_RX_SLOTS_MAX | 2019 | && prod - cons < XEN_NETBK_RX_SLOTS_MAX |
| 2022 | && time_after(jiffies, | 2020 | && time_after(jiffies, |
| 2023 | queue->last_rx_time + rx_stall_timeout_jiffies); | 2021 | queue->last_rx_time + queue->vif->stall_timeout); |
| 2024 | } | 2022 | } |
| 2025 | 2023 | ||
| 2026 | static bool xenvif_rx_queue_ready(struct xenvif_queue *queue) | 2024 | static bool xenvif_rx_queue_ready(struct xenvif_queue *queue) |
| @@ -2038,8 +2036,9 @@ static bool xenvif_have_rx_work(struct xenvif_queue *queue) | |||
| 2038 | { | 2036 | { |
| 2039 | return (!skb_queue_empty(&queue->rx_queue) | 2037 | return (!skb_queue_empty(&queue->rx_queue) |
| 2040 | && xenvif_rx_ring_slots_available(queue, XEN_NETBK_RX_SLOTS_MAX)) | 2038 | && xenvif_rx_ring_slots_available(queue, XEN_NETBK_RX_SLOTS_MAX)) |
| 2041 | || xenvif_rx_queue_stalled(queue) | 2039 | || (queue->vif->stall_timeout && |
| 2042 | || xenvif_rx_queue_ready(queue) | 2040 | (xenvif_rx_queue_stalled(queue) |
| 2041 | || xenvif_rx_queue_ready(queue))) | ||
| 2043 | || kthread_should_stop() | 2042 | || kthread_should_stop() |
| 2044 | || queue->vif->disabled; | 2043 | || queue->vif->disabled; |
| 2045 | } | 2044 | } |
| @@ -2092,6 +2091,9 @@ int xenvif_kthread_guest_rx(void *data) | |||
| 2092 | struct xenvif_queue *queue = data; | 2091 | struct xenvif_queue *queue = data; |
| 2093 | struct xenvif *vif = queue->vif; | 2092 | struct xenvif *vif = queue->vif; |
| 2094 | 2093 | ||
| 2094 | if (!vif->stall_timeout) | ||
| 2095 | xenvif_queue_carrier_on(queue); | ||
| 2096 | |||
| 2095 | for (;;) { | 2097 | for (;;) { |
| 2096 | xenvif_wait_for_rx_work(queue); | 2098 | xenvif_wait_for_rx_work(queue); |
| 2097 | 2099 | ||
| @@ -2118,10 +2120,12 @@ int xenvif_kthread_guest_rx(void *data) | |||
| 2118 | * while it's probably not responsive, drop the | 2120 | * while it's probably not responsive, drop the |
| 2119 | * carrier so packets are dropped earlier. | 2121 | * carrier so packets are dropped earlier. |
| 2120 | */ | 2122 | */ |
| 2121 | if (xenvif_rx_queue_stalled(queue)) | 2123 | if (vif->stall_timeout) { |
| 2122 | xenvif_queue_carrier_off(queue); | 2124 | if (xenvif_rx_queue_stalled(queue)) |
| 2123 | else if (xenvif_rx_queue_ready(queue)) | 2125 | xenvif_queue_carrier_off(queue); |
| 2124 | xenvif_queue_carrier_on(queue); | 2126 | else if (xenvif_rx_queue_ready(queue)) |
| 2127 | xenvif_queue_carrier_on(queue); | ||
| 2128 | } | ||
| 2125 | 2129 | ||
| 2126 | /* Queued packets may have foreign pages from other | 2130 | /* Queued packets may have foreign pages from other |
| 2127 | * domains. These cannot be queued indefinitely as | 2131 | * domains. These cannot be queued indefinitely as |
| @@ -2192,9 +2196,6 @@ static int __init netback_init(void) | |||
| 2192 | if (rc) | 2196 | if (rc) |
| 2193 | goto failed_init; | 2197 | goto failed_init; |
| 2194 | 2198 | ||
| 2195 | rx_drain_timeout_jiffies = msecs_to_jiffies(rx_drain_timeout_msecs); | ||
| 2196 | rx_stall_timeout_jiffies = msecs_to_jiffies(rx_stall_timeout_msecs); | ||
| 2197 | |||
| 2198 | #ifdef CONFIG_DEBUG_FS | 2199 | #ifdef CONFIG_DEBUG_FS |
| 2199 | xen_netback_dbg_root = debugfs_create_dir("xen-netback", NULL); | 2200 | xen_netback_dbg_root = debugfs_create_dir("xen-netback", NULL); |
| 2200 | if (IS_ERR_OR_NULL(xen_netback_dbg_root)) | 2201 | 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 d44cd19169bd..efbaf2ae1999 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) | |||
| 887 | return -EOPNOTSUPP; | 887 | return -EOPNOTSUPP; |
| 888 | 888 | ||
| 889 | if (xenbus_scanf(XBT_NIL, dev->otherend, | 889 | if (xenbus_scanf(XBT_NIL, dev->otherend, |
| 890 | "feature-rx-notify", "%d", &val) < 0 || val == 0) { | 890 | "feature-rx-notify", "%d", &val) < 0) |
| 891 | xenbus_dev_fatal(dev, -EINVAL, "feature-rx-notify is mandatory"); | 891 | val = 0; |
| 892 | return -EINVAL; | 892 | if (!val) { |
| 893 | /* - Reduce drain timeout to poll more frequently for | ||
| 894 | * Rx requests. | ||
| 895 | * - Disable Rx stall detection. | ||
| 896 | */ | ||
| 897 | be->vif->drain_timeout = msecs_to_jiffies(30); | ||
| 898 | be->vif->stall_timeout = 0; | ||
| 893 | } | 899 | } |
| 894 | 900 | ||
| 895 | if (xenbus_scanf(XBT_NIL, dev->otherend, "feature-sg", | 901 | if (xenbus_scanf(XBT_NIL, dev->otherend, "feature-sg", |
