Thread (18 messages) 18 messages, 6 authors, 2d ago

Re: [PATCH net 2/6] igc: only strip RX timestamp header from first buffer

flat view

From: Paul Moses <hidden>
Date: 2026-10-07 16:02:46
Also in: stable




On Monday, October 5th, 2026 at 6:02 PM, netdev-bot+sashiko@kernel.org [off-list ref] wrote:
Thank you for your contribution! Sashiko AI review found 1 potential
issue(s) to consider.

Critical: 0 · High: 1 · Medium: 0 · Low: 0

If you believe none of the issues are legitimate, please reply to each
issue of Medium severity or higher and explain why the AI is wrong.
If any of them are legitimate and you plan to respin, please let patchwork
know by including "pw-bot: cr" as a separate line at the end of your reply
(one such reply per series is enough).

- [High] In igc_clean_rx_irq()
  (drivers/net/ethernet/intel/igc/igc_main.c), the new `!skb && TSIP`…

--

igc: only strip RX timestamp header from first buffer

This commit changes igc_clean_rx_irq() so that the inline RX timestamp
header is consumed only when skb is NULL. The commit treats skb == NULL as
the marker for the first buffer of a packet. As a result, continuation
descriptors that still report TSIP no longer have IGC_TS_HDR_LEN
subtracted from their size.

Link: https://lore.kernel.org/all/20260625-igb-rx-ts-fix-v3-1-99b3efa08dca@aweta.nl/ (local)
quoted
diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c
index 95f7747b347b1..b94a08791102c 100644
--- a/drivers/net/ethernet/intel/igc/igc_main.c
+++ b/drivers/net/ethernet/intel/igc/igc_main.c
@@ -2658,7 +2658,8 @@ static int igc_clean_rx_irq(struct igc_q_vector *q_vector, const int budget)

 		pktbuf = page_address(rx_buffer->page) + rx_buffer->page_offset;

-		if (igc_test_staterr(rx_desc, IGC_RXDADV_STAT_TSIP)) {
+		if (!skb &&
+		    igc_test_staterr(rx_desc, IGC_RXDADV_STAT_TSIP)) {
 			ctx.rx_ts = pktbuf;
 			pkt_offset = IGC_TS_HDR_LEN;
 			size -= IGC_TS_HDR_LEN;
[Severity: High]
Is skb == NULL a reliable first-buffer test when an XDP program is
attached?

Suppose the XDP program returns a non-PASS verdict (DROP/ABORTED, TX or
REDIRECT) for the first buffer of a frame that spans several descriptors.
In that case igc_clean_rx_irq() never builds an skb:

	if (xdp_res) {
		switch (xdp_res) {
		case IGC_XDP_CONSUMED:
			rx_buffer->pagecnt_bias++;
			break;
		...
	}
	...
	/* fetch next buffer in frame if non-eop */
	if (igc_is_non_eop(rx_ring, rx_desc))
		continue;

skb stays NULL, so the next descriptor is handled as if it started a new
frame. The commit message says continuation descriptors keep TSIP, so
that descriptor passes the new !skb && TSIP check as well. Then:

  - ctx.rx_ts points at payload data
  - 16 bytes of payload are skipped
  - the XDP program runs again on data from the middle of the frame

The igc_fpe_handle_mpacket() continue path can also leave skb NULL across
a non-EOP descriptor.

What happens if the last fragment holds fewer than IGC_TS_HDR_LEN bytes?
Can size -= IGC_TS_HDR_LEN wrap there?

xdp_prepare_buff() takes data_len as an int, so data_end would end up
before data. On XDP_PASS, igc_build_skb() then does:

	unsigned int size = xdp->data_end - xdp->data;
	unsigned int truesize = igc_get_rx_frame_truesize(rx_ring, size);
	...
	__skb_put(skb, size);
	...
	igc_rx_buffer_flip(rx_buffer, truesize);

This would produce an skb with len around 4G and tail past end. The rx
page would also be flipped by a wrong truesize, so the hardware could DMA
into memory that the skb still owns.

Even without the wrap, wouldn't the mid-frame payload reach the stack as
its own frame after the real frame was dropped?

These multi-descriptor frames look reachable with XDP attached when
PAGE_SIZE >= 8192. igc_set_rx_mode() caps RLPML only for small pages:

#if (PAGE_SIZE < 8192)
	if (adapter->max_frame_size <= IGC_MAX_FRAME_BUILD_SKB)
		rlpml = IGC_MAX_FRAME_BUILD_SKB;
#endif
	wr32(IGC_RLPML, rlpml);

So RLPML stays at MAX_JUMBO_FRAME_SIZE on those systems. At the same time:

  - igc_configure_rx_ring() uses IGC_RXBUFFER_3072 buffers when XDP is
    enabled
  - igc_xdp_set_prog() checks only dev->mtu > ETH_DATA_LEN, not the frame
    size the hardware accepts

With RX timestamping enabled, a remote peer sending a frame larger than
3056 bytes would take this path.

Could the frame-start state be tracked separately from skb? One option is
to discard descriptors through EOP after a non-PASS verdict. Another is to
cap RLPML whenever XDP is enabled.

--
Sashiko AI review · https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20261001222443.3500206-1-anthony.l.nguyen%40intel.com
This seems maybe legit, but considering the fixes would be entirely independent 
of one another and that this is a theoretical scenario affecting exotic system 
configurations, I'd rather not entangle it with a real user facing issue.

I have some idea and maybe hardware to try to reproduce, but nothing setup 
currently.

More appropriate to be a followup patch. 

Thanks
Paul
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help