All the mail mirrored from lore.kernel.org
 help / color / mirror / Atom feed
* RE: [PATCH] net: sched: fix skb leak in dev_requeue_skb()
  2017-12-25  3:39 [PATCH] net: sched: fix skb leak in dev_requeue_skb() Wei Yongjun
@ 2017-12-25  3:38 ` weiyongjun (A)
  0 siblings, 0 replies; 2+ messages in thread
From: weiyongjun (A) @ 2017-12-25  3:38 UTC (permalink / raw
  To: John Fastabend, Jamal Hadi Salim, Cong Wang, Jiri Pirko
  Cc: netdev@vger.kernel.org

> When dev_requeue_skb() is called with bluked skb list, only the
> first skb of the list will be requeued to qdisc layer, and leak
> the others without free them.
> 
> TCP is broken due to skb leak since no free skb will be considered
> as still in the host queue and never be retransmitted. This happend
> when dev_requeue_skb() called from qdisc_restart().
>   qdisc_restart
>   |-- dequeue_skb
>   |-- sch_direct_xmit()
>       |-- dev_requeue_skb() <-- skb may bluked
> 
> Fix dev_requeue_skb() to requeue the full bluked list.
> 
> Fixes: a53851e2c321 ("net: sched: explicit locking in gso_cpu fallback")
> Signed-off-by: Wei Yongjun <weiyongjun1@huawei.com>

Sorry, I forgot the 'net-next' prefix, please ignore this one, I will resend it.


^ permalink raw reply	[flat|nested] 2+ messages in thread

* [PATCH] net: sched: fix skb leak in dev_requeue_skb()
@ 2017-12-25  3:39 Wei Yongjun
  2017-12-25  3:38 ` weiyongjun (A)
  0 siblings, 1 reply; 2+ messages in thread
From: Wei Yongjun @ 2017-12-25  3:39 UTC (permalink / raw
  To: John Fastabend, Jamal Hadi Salim, Cong Wang, Jiri Pirko
  Cc: Wei Yongjun, netdev

When dev_requeue_skb() is called with bluked skb list, only the
first skb of the list will be requeued to qdisc layer, and leak
the others without free them.

TCP is broken due to skb leak since no free skb will be considered
as still in the host queue and never be retransmitted. This happend
when dev_requeue_skb() called from qdisc_restart().
  qdisc_restart
  |-- dequeue_skb
  |-- sch_direct_xmit()
      |-- dev_requeue_skb() <-- skb may bluked

Fix dev_requeue_skb() to requeue the full bluked list.

Fixes: a53851e2c321 ("net: sched: explicit locking in gso_cpu fallback")
Signed-off-by: Wei Yongjun <weiyongjun1@huawei.com>

diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
index 981c08f..0df2dbf 100644
--- a/net/sched/sch_generic.c
+++ b/net/sched/sch_generic.c
@@ -111,10 +111,16 @@ static inline void qdisc_enqueue_skb_bad_txq(struct Qdisc *q,
 
 static inline int __dev_requeue_skb(struct sk_buff *skb, struct Qdisc *q)
 {
-	__skb_queue_head(&q->gso_skb, skb);
-	q->qstats.requeues++;
-	qdisc_qstats_backlog_inc(q, skb);
-	q->q.qlen++;	/* it's still part of the queue */
+	while (skb) {
+		struct sk_buff *next = skb->next;
+
+		__skb_queue_tail(&q->gso_skb, skb);
+		q->qstats.requeues++;
+		qdisc_qstats_backlog_inc(q, skb);
+		q->q.qlen++;	/* it's still part of the queue */
+
+		skb = next;
+	}
 	__netif_schedule(q);
 
 	return 0;
@@ -124,13 +130,20 @@ static inline int dev_requeue_skb_locked(struct sk_buff *skb, struct Qdisc *q)
 {
 	spinlock_t *lock = qdisc_lock(q);
 
-	spin_lock(lock);
-	__skb_queue_tail(&q->gso_skb, skb);
-	spin_unlock(lock);
+	while (skb) {
+		struct sk_buff *next = skb->next;
+
+		spin_lock(lock);
+		__skb_queue_tail(&q->gso_skb, skb);
+		spin_unlock(lock);
+
+		qdisc_qstats_cpu_requeues_inc(q);
+		qdisc_qstats_cpu_backlog_inc(q, skb);
+		qdisc_qstats_cpu_qlen_inc(q);
+
+		skb = next;
+	}
 
-	qdisc_qstats_cpu_requeues_inc(q);
-	qdisc_qstats_cpu_backlog_inc(q, skb);
-	qdisc_qstats_cpu_qlen_inc(q);
 	__netif_schedule(q);
 
 	return 0;
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2017-12-25  3:38 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-12-25  3:39 [PATCH] net: sched: fix skb leak in dev_requeue_skb() Wei Yongjun
2017-12-25  3:38 ` weiyongjun (A)

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.