public inbox for stable@vger.kernel.org
 help / color / mirror / Atom feed
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: stable@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	patches@lists.linux.dev, Martin Ottens <martin.ottens@fau.de>,
	Jamal Hadi Salim <jhs@mojatatu.com>,
	Jakub Kicinski <kuba@kernel.org>, Sasha Levin <sashal@kernel.org>
Subject: [PATCH 5.10 24/43] net/sched: netem: account for backlog updates from child qdisc
Date: Tue, 17 Dec 2024 18:07:15 +0100	[thread overview]
Message-ID: <20241217170521.429015129@linuxfoundation.org> (raw)
In-Reply-To: <20241217170520.459491270@linuxfoundation.org>

5.10-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Martin Ottens <martin.ottens@fau.de>

[ Upstream commit f8d4bc455047cf3903cd6f85f49978987dbb3027 ]

In general, 'qlen' of any classful qdisc should keep track of the
number of packets that the qdisc itself and all of its children holds.
In case of netem, 'qlen' only accounts for the packets in its internal
tfifo. When netem is used with a child qdisc, the child qdisc can use
'qdisc_tree_reduce_backlog' to inform its parent, netem, about created
or dropped SKBs. This function updates 'qlen' and the backlog statistics
of netem, but netem does not account for changes made by a child qdisc.
'qlen' then indicates the wrong number of packets in the tfifo.
If a child qdisc creates new SKBs during enqueue and informs its parent
about this, netem's 'qlen' value is increased. When netem dequeues the
newly created SKBs from the child, the 'qlen' in netem is not updated.
If 'qlen' reaches the configured sch->limit, the enqueue function stops
working, even though the tfifo is not full.

Reproduce the bug:
Ensure that the sender machine has GSO enabled. Configure netem as root
qdisc and tbf as its child on the outgoing interface of the machine
as follows:
$ tc qdisc add dev <oif> root handle 1: netem delay 100ms limit 100
$ tc qdisc add dev <oif> parent 1:0 tbf rate 50Mbit burst 1542 latency 50ms

Send bulk TCP traffic out via this interface, e.g., by running an iPerf3
client on the machine. Check the qdisc statistics:
$ tc -s qdisc show dev <oif>

Statistics after 10s of iPerf3 TCP test before the fix (note that
netem's backlog > limit, netem stopped accepting packets):
qdisc netem 1: root refcnt 2 limit 1000 delay 100ms
 Sent 2767766 bytes 1848 pkt (dropped 652, overlimits 0 requeues 0)
 backlog 4294528236b 1155p requeues 0
qdisc tbf 10: parent 1:1 rate 50Mbit burst 1537b lat 50ms
 Sent 2767766 bytes 1848 pkt (dropped 327, overlimits 7601 requeues 0)
 backlog 0b 0p requeues 0

Statistics after the fix:
qdisc netem 1: root refcnt 2 limit 1000 delay 100ms
 Sent 37766372 bytes 24974 pkt (dropped 9, overlimits 0 requeues 0)
 backlog 0b 0p requeues 0
qdisc tbf 10: parent 1:1 rate 50Mbit burst 1537b lat 50ms
 Sent 37766372 bytes 24974 pkt (dropped 327, overlimits 96017 requeues 0)
 backlog 0b 0p requeues 0

tbf segments the GSO SKBs (tbf_segment) and updates the netem's 'qlen'.
The interface fully stops transferring packets and "locks". In this case,
the child qdisc and tfifo are empty, but 'qlen' indicates the tfifo is at
its limit and no more packets are accepted.

This patch adds a counter for the entries in the tfifo. Netem's 'qlen' is
only decreased when a packet is returned by its dequeue function, and not
during enqueuing into the child qdisc. External updates to 'qlen' are thus
accounted for and only the behavior of the backlog statistics changes. As
in other qdiscs, 'qlen' then keeps track of  how many packets are held in
netem and all of its children. As before, sch->limit remains as the
maximum number of packets in the tfifo. The same applies to netem's
backlog statistics.

Fixes: 50612537e9ab ("netem: fix classful handling")
Signed-off-by: Martin Ottens <martin.ottens@fau.de>
Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
Link: https://patch.msgid.link/20241210131412.1837202-1-martin.ottens@fau.de
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/sched/sch_netem.c | 22 ++++++++++++++++------
 1 file changed, 16 insertions(+), 6 deletions(-)

diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c
index 93ed7bac9ee6..f459e34684ad 100644
--- a/net/sched/sch_netem.c
+++ b/net/sched/sch_netem.c
@@ -77,6 +77,8 @@ struct netem_sched_data {
 	struct sk_buff	*t_head;
 	struct sk_buff	*t_tail;
 
+	u32 t_len;
+
 	/* optional qdisc for classful handling (NULL at netem init) */
 	struct Qdisc	*qdisc;
 
@@ -373,6 +375,7 @@ static void tfifo_reset(struct Qdisc *sch)
 	rtnl_kfree_skbs(q->t_head, q->t_tail);
 	q->t_head = NULL;
 	q->t_tail = NULL;
+	q->t_len = 0;
 }
 
 static void tfifo_enqueue(struct sk_buff *nskb, struct Qdisc *sch)
@@ -402,6 +405,7 @@ static void tfifo_enqueue(struct sk_buff *nskb, struct Qdisc *sch)
 		rb_link_node(&nskb->rbnode, parent, p);
 		rb_insert_color(&nskb->rbnode, &q->t_root);
 	}
+	q->t_len++;
 	sch->q.qlen++;
 }
 
@@ -508,7 +512,7 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch,
 			1<<(prandom_u32() % 8);
 	}
 
-	if (unlikely(sch->q.qlen >= sch->limit)) {
+	if (unlikely(q->t_len >= sch->limit)) {
 		/* re-link segs, so that qdisc_drop_all() frees them all */
 		skb->next = segs;
 		qdisc_drop_all(skb, sch, to_free);
@@ -692,8 +696,8 @@ static struct sk_buff *netem_dequeue(struct Qdisc *sch)
 tfifo_dequeue:
 	skb = __qdisc_dequeue_head(&sch->q);
 	if (skb) {
-		qdisc_qstats_backlog_dec(sch, skb);
 deliver:
+		qdisc_qstats_backlog_dec(sch, skb);
 		qdisc_bstats_update(sch, skb);
 		return skb;
 	}
@@ -709,8 +713,7 @@ static struct sk_buff *netem_dequeue(struct Qdisc *sch)
 
 		if (time_to_send <= now && q->slot.slot_next <= now) {
 			netem_erase_head(q, skb);
-			sch->q.qlen--;
-			qdisc_qstats_backlog_dec(sch, skb);
+			q->t_len--;
 			skb->next = NULL;
 			skb->prev = NULL;
 			/* skb->dev shares skb->rbnode area,
@@ -737,16 +740,21 @@ static struct sk_buff *netem_dequeue(struct Qdisc *sch)
 					if (net_xmit_drop_count(err))
 						qdisc_qstats_drop(sch);
 					qdisc_tree_reduce_backlog(sch, 1, pkt_len);
+					sch->qstats.backlog -= pkt_len;
+					sch->q.qlen--;
 				}
 				goto tfifo_dequeue;
 			}
+			sch->q.qlen--;
 			goto deliver;
 		}
 
 		if (q->qdisc) {
 			skb = q->qdisc->ops->dequeue(q->qdisc);
-			if (skb)
+			if (skb) {
+				sch->q.qlen--;
 				goto deliver;
+			}
 		}
 
 		qdisc_watchdog_schedule_ns(&q->watchdog,
@@ -756,8 +764,10 @@ static struct sk_buff *netem_dequeue(struct Qdisc *sch)
 
 	if (q->qdisc) {
 		skb = q->qdisc->ops->dequeue(q->qdisc);
-		if (skb)
+		if (skb) {
+			sch->q.qlen--;
 			goto deliver;
+		}
 	}
 	return NULL;
 }
-- 
2.39.5




  parent reply	other threads:[~2024-12-17 17:11 UTC|newest]

Thread overview: 50+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-12-17 17:06 [PATCH 5.10 00/43] 5.10.232-rc1 review Greg Kroah-Hartman
2024-12-17 17:06 ` [PATCH 5.10 01/43] tcp: check space before adding MPTCP SYN options Greg Kroah-Hartman
2024-12-17 17:06 ` [PATCH 5.10 02/43] usb: host: max3421-hcd: Correctly abort a USB request Greg Kroah-Hartman
2024-12-17 17:06 ` [PATCH 5.10 03/43] ata: sata_highbank: fix OF node reference leak in highbank_initialize_phys() Greg Kroah-Hartman
2024-12-17 17:06 ` [PATCH 5.10 04/43] usb: dwc2: hcd: Fix GetPortStatus & SetPortFeature Greg Kroah-Hartman
2024-12-17 17:06 ` [PATCH 5.10 05/43] usb: ehci-hcd: fix call balance of clocks handling routines Greg Kroah-Hartman
2024-12-17 17:06 ` [PATCH 5.10 06/43] usb: gadget: u_serial: Fix the issue that gs_start_io crashed due to accessing null pointer Greg Kroah-Hartman
2024-12-17 17:06 ` [PATCH 5.10 07/43] xfs: dont drop errno values when we fail to ficlone the entire range Greg Kroah-Hartman
2024-12-17 17:06 ` [PATCH 5.10 08/43] xfs: fix scrub tracepoints when inode-rooted btrees are involved Greg Kroah-Hartman
2024-12-17 17:07 ` [PATCH 5.10 09/43] bpf, sockmap: Fix update element with same Greg Kroah-Hartman
2024-12-17 17:07 ` [PATCH 5.10 10/43] virtio/vsock: Fix accept_queue memory leak Greg Kroah-Hartman
2024-12-17 17:07 ` [PATCH 5.10 11/43] exfat: fix potential deadlock on __exfat_get_dentry_set Greg Kroah-Hartman
2024-12-17 17:07 ` [PATCH 5.10 12/43] acpi: nfit: vmalloc-out-of-bounds Read in acpi_nfit_ctl Greg Kroah-Hartman
2024-12-17 17:07 ` [PATCH 5.10 13/43] batman-adv: Do not send uninitialized TT changes Greg Kroah-Hartman
2024-12-17 17:07 ` [PATCH 5.10 14/43] batman-adv: Remove uninitialized data in full table TT response Greg Kroah-Hartman
2024-12-17 17:07 ` [PATCH 5.10 15/43] batman-adv: Do not let TT changes list grows indefinitely Greg Kroah-Hartman
2024-12-17 17:07 ` [PATCH 5.10 16/43] tipc: fix NULL deref in cleanup_bearer() Greg Kroah-Hartman
2024-12-17 17:07 ` [PATCH 5.10 17/43] selftests: mlxsw: sharedbuffer: Remove h1 ingress test case Greg Kroah-Hartman
2024-12-17 17:07 ` [PATCH 5.10 18/43] selftests: mlxsw: sharedbuffer: Remove duplicate test cases Greg Kroah-Hartman
2024-12-17 17:07 ` [PATCH 5.10 19/43] net: lapb: increase LAPB_HEADER_LEN Greg Kroah-Hartman
2024-12-17 17:07 ` [PATCH 5.10 20/43] ACPI: resource: Fix memory resource type union access Greg Kroah-Hartman
2024-12-17 17:07 ` [PATCH 5.10 21/43] cxgb4: use port number to set mac addr Greg Kroah-Hartman
2024-12-17 17:07 ` [PATCH 5.10 22/43] qca_spi: Fix clock speed for multiple QCA7000 Greg Kroah-Hartman
2024-12-17 17:07 ` [PATCH 5.10 23/43] qca_spi: Make driver probing reliable Greg Kroah-Hartman
2024-12-17 17:07 ` Greg Kroah-Hartman [this message]
2024-12-17 17:07 ` [PATCH 5.10 25/43] net: bonding, dummy, ifb, team: advertise NETIF_F_GSO_SOFTWARE Greg Kroah-Hartman
2024-12-17 17:07 ` [PATCH 5.10 26/43] bonding: Fix feature propagation of NETIF_F_GSO_ENCAP_ALL Greg Kroah-Hartman
2024-12-17 17:07 ` [PATCH 5.10 27/43] team: " Greg Kroah-Hartman
2024-12-17 17:07 ` [PATCH 5.10 28/43] ACPICA: events/evxfregn: dont release the ContextMutex that was never acquired Greg Kroah-Hartman
2024-12-17 17:07 ` [PATCH 5.10 29/43] blk-iocost: Avoid using clamp() on inuse in __propagate_weights() Greg Kroah-Hartman
2024-12-17 17:07 ` [PATCH 5.10 30/43] bpf: sync_linked_regs() must preserve subreg_def Greg Kroah-Hartman
2024-12-17 17:07 ` [PATCH 5.10 31/43] tracing/kprobes: Skip symbol counting logic for module symbols in create_local_trace_kprobe() Greg Kroah-Hartman
2024-12-17 17:07 ` [PATCH 5.10 32/43] drm/i915: Fix memory leak by correcting cache object name in error handler Greg Kroah-Hartman
2024-12-17 17:07 ` [PATCH 5.10 33/43] Revert "clocksource/drivers:sp804: Make user selectable" Greg Kroah-Hartman
2024-12-17 17:07 ` [PATCH 5.10 34/43] Revert "clkdev: remove CONFIG_CLKDEV_LOOKUP" Greg Kroah-Hartman
2024-12-17 17:07 ` [PATCH 5.10 35/43] xen/netfront: fix crash when removing device Greg Kroah-Hartman
2024-12-17 17:07 ` [PATCH 5.10 36/43] x86: make get_cpu_vendor() accessible from Xen code Greg Kroah-Hartman
2024-12-17 17:07 ` [PATCH 5.10 37/43] objtool/x86: allow syscall instruction Greg Kroah-Hartman
2024-12-17 17:07 ` [PATCH 5.10 38/43] x86/static-call: provide a way to do very early static-call updates Greg Kroah-Hartman
2024-12-17 17:07 ` [PATCH 5.10 39/43] x86/xen: dont do PV iret hypercall through hypercall page Greg Kroah-Hartman
2024-12-17 17:07 ` [PATCH 5.10 40/43] x86/xen: add central hypercall functions Greg Kroah-Hartman
2024-12-17 17:07 ` [PATCH 5.10 41/43] x86/xen: use new hypercall functions instead of hypercall page Greg Kroah-Hartman
2024-12-17 17:07 ` [PATCH 5.10 42/43] x86/xen: remove " Greg Kroah-Hartman
2024-12-17 17:07 ` [PATCH 5.10 43/43] ALSA: usb-audio: Fix a DMA to stack memory bug Greg Kroah-Hartman
2024-12-17 18:51 ` [PATCH 5.10 00/43] 5.10.232-rc1 review Florian Fainelli
2024-12-17 20:37 ` Pavel Machek
2024-12-18  9:17 ` Dominique Martinet
2024-12-18 12:38 ` Mark Brown
2024-12-18 17:20 ` Jon Hunter
2024-12-18 17:55 ` Naresh Kamboju

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20241217170521.429015129@linuxfoundation.org \
    --to=gregkh@linuxfoundation.org \
    --cc=jhs@mojatatu.com \
    --cc=kuba@kernel.org \
    --cc=martin.ottens@fau.de \
    --cc=patches@lists.linux.dev \
    --cc=sashal@kernel.org \
    --cc=stable@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox