Skip to content

Commit 7c37101

Browse files
Wei Liugregkh
authored andcommitted
xen-netback: correctly schedule rate-limited queues
[ Upstream commit dfa523ae9f2542bee4cddaea37b3be3e157f6e6b ] 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> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 2933fb2 commit 7c37101

3 files changed

Lines changed: 11 additions & 2 deletions

File tree

drivers/net/xen-netback/common.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,7 @@ struct xenvif_queue { /* Per-queue data for xenvif */
201201
unsigned long remaining_credit;
202202
struct timer_list credit_timeout;
203203
u64 credit_window_start;
204+
bool rate_limited;
204205

205206
/* Statistics */
206207
struct xenvif_stats stats;

drivers/net/xen-netback/interface.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,11 @@ static int xenvif_poll(struct napi_struct *napi, int budget)
105105

106106
if (work_done < budget) {
107107
napi_complete(napi);
108-
xenvif_napi_schedule_or_enable_events(queue);
108+
/* If the queue is rate-limited, it shall be
109+
* rescheduled in the timer callback.
110+
*/
111+
if (likely(!queue->rate_limited))
112+
xenvif_napi_schedule_or_enable_events(queue);
109113
}
110114

111115
return work_done;

drivers/net/xen-netback/netback.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -687,6 +687,7 @@ static void tx_add_credit(struct xenvif_queue *queue)
687687
max_credit = ULONG_MAX; /* wrapped: clamp to ULONG_MAX */
688688

689689
queue->remaining_credit = min(max_credit, max_burst);
690+
queue->rate_limited = false;
690691
}
691692

692693
void xenvif_tx_credit_callback(unsigned long data)
@@ -1184,8 +1185,10 @@ static bool tx_credit_exceeded(struct xenvif_queue *queue, unsigned size)
11841185
msecs_to_jiffies(queue->credit_usec / 1000);
11851186

11861187
/* Timer could already be pending in rare cases. */
1187-
if (timer_pending(&queue->credit_timeout))
1188+
if (timer_pending(&queue->credit_timeout)) {
1189+
queue->rate_limited = true;
11881190
return true;
1191+
}
11891192

11901193
/* Passed the point where we can replenish credit? */
11911194
if (time_after_eq64(now, next_credit)) {
@@ -1200,6 +1203,7 @@ static bool tx_credit_exceeded(struct xenvif_queue *queue, unsigned size)
12001203
mod_timer(&queue->credit_timeout,
12011204
next_credit);
12021205
queue->credit_window_start = next_credit;
1206+
queue->rate_limited = true;
12031207

12041208
return true;
12051209
}

0 commit comments

Comments
 (0)