aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorWei Liu <wei.liu2@citrix.com>2017-06-21 05:21:22 -0400
committerDavid S. Miller <davem@davemloft.net>2017-06-22 11:15:42 -0400
commitdfa523ae9f2542bee4cddaea37b3be3e157f6e6b (patch)
tree3c31b603c04bad0bb51c19305488cc12140ff7cb /drivers
parent191cdb3822e5df6b3c8b9f8cb8c4bf93f6cc90c7 (diff)
xen-netback: correctly schedule rate-limited queues
Add a flag to indicate if a queue is rate-limited. Test the flag in NAPI poll handler and avoid rescheduling the queue if true, otherwise we risk locking up the host. The rescheduling will be done in the timer callback function. Reported-by: Jean-Louis Dupond <jean-louis@dupond.be> Signed-off-by: Wei Liu <wei.liu2@citrix.com> Tested-by: Jean-Louis Dupond <jean-louis@dupond.be> Reviewed-by: Paul Durrant <paul.durrant@citrix.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/xen-netback/common.h1
-rw-r--r--drivers/net/xen-netback/interface.c6
-rw-r--r--drivers/net/xen-netback/netback.c6
3 files changed, 11 insertions, 2 deletions
diff --git a/drivers/net/xen-netback/common.h b/drivers/net/xen-netback/common.h
index 530586be05b4..5b1d2e8402d9 100644
--- a/drivers/net/xen-netback/common.h
+++ b/drivers/net/xen-netback/common.h
@@ -199,6 +199,7 @@ struct xenvif_queue { /* Per-queue data for xenvif */
199 unsigned long remaining_credit; 199 unsigned long remaining_credit;
200 struct timer_list credit_timeout; 200 struct timer_list credit_timeout;
201 u64 credit_window_start; 201 u64 credit_window_start;
202 bool rate_limited;
202 203
203 /* Statistics */ 204 /* Statistics */
204 struct xenvif_stats stats; 205 struct xenvif_stats stats;
diff --git a/drivers/net/xen-netback/interface.c b/drivers/net/xen-netback/interface.c
index 8397f6c92451..e322a862ddfe 100644
--- a/drivers/net/xen-netback/interface.c
+++ b/drivers/net/xen-netback/interface.c
@@ -106,7 +106,11 @@ static int xenvif_poll(struct napi_struct *napi, int budget)
106 106
107 if (work_done < budget) { 107 if (work_done < budget) {
108 napi_complete_done(napi, work_done); 108 napi_complete_done(napi, work_done);
109 xenvif_napi_schedule_or_enable_events(queue); 109 /* If the queue is rate-limited, it shall be
110 * rescheduled in the timer callback.
111 */
112 if (likely(!queue->rate_limited))
113 xenvif_napi_schedule_or_enable_events(queue);
110 } 114 }
111 115
112 return work_done; 116 return work_done;
diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c
index 602d408fa25e..5042ff8d449a 100644
--- a/drivers/net/xen-netback/netback.c
+++ b/drivers/net/xen-netback/netback.c
@@ -180,6 +180,7 @@ static void tx_add_credit(struct xenvif_queue *queue)
180 max_credit = ULONG_MAX; /* wrapped: clamp to ULONG_MAX */ 180 max_credit = ULONG_MAX; /* wrapped: clamp to ULONG_MAX */
181 181
182 queue->remaining_credit = min(max_credit, max_burst); 182 queue->remaining_credit = min(max_credit, max_burst);
183 queue->rate_limited = false;
183} 184}
184 185
185void xenvif_tx_credit_callback(unsigned long data) 186void xenvif_tx_credit_callback(unsigned long data)
@@ -686,8 +687,10 @@ static bool tx_credit_exceeded(struct xenvif_queue *queue, unsigned size)
686 msecs_to_jiffies(queue->credit_usec / 1000); 687 msecs_to_jiffies(queue->credit_usec / 1000);
687 688
688 /* Timer could already be pending in rare cases. */ 689 /* Timer could already be pending in rare cases. */
689 if (timer_pending(&queue->credit_timeout)) 690 if (timer_pending(&queue->credit_timeout)) {
691 queue->rate_limited = true;
690 return true; 692 return true;
693 }
691 694
692 /* Passed the point where we can replenish credit? */ 695 /* Passed the point where we can replenish credit? */
693 if (time_after_eq64(now, next_credit)) { 696 if (time_after_eq64(now, next_credit)) {
@@ -702,6 +705,7 @@ static bool tx_credit_exceeded(struct xenvif_queue *queue, unsigned size)
702 mod_timer(&queue->credit_timeout, 705 mod_timer(&queue->credit_timeout,
703 next_credit); 706 next_credit);
704 queue->credit_window_start = next_credit; 707 queue->credit_window_start = next_credit;
708 queue->rate_limited = true;
705 709
706 return true; 710 return true;
707 } 711 }