Skip to content

Commit 1e45d60

Browse files
zdenek-bouskamehmetb0
authored andcommitted
igc: Fix HW RX timestamp when passed by ZC XDP
BugLink: https://bugs.launchpad.net/bugs/2104873 [ Upstream commit 7822dd4 ] Fixes HW RX timestamp in the following scenario: - AF_PACKET socket with enabled HW RX timestamps is created - AF_XDP socket with enabled zero copy is created - frame is forwarded to the BPF program, where the timestamp should still be readable (extracted by igc_xdp_rx_timestamp(), kfunc behind bpf_xdp_metadata_rx_timestamp()) - the frame got XDP_PASS from BPF program, redirecting to the stack - AF_PACKET socket receives the frame with HW RX timestamp Moves the skb timestamp setting from igc_dispatch_skb_zc() to igc_construct_skb_zc() so that igc_construct_skb_zc() is similar to igc_construct_skb(). This issue can also be reproduced by running: # tools/testing/selftests/bpf/xdp_hw_metadata enp1s0 When a frame with the wrong port 9092 (instead of 9091) is used: # echo -n xdp | nc -u -q1 192.168.10.9 9092 then the RX timestamp is missing and xdp_hw_metadata prints: skb hwtstamp is not found! With this fix or when copy mode is used: # tools/testing/selftests/bpf/xdp_hw_metadata -c enp1s0 then RX timestamp is found and xdp_hw_metadata prints: found skb hwtstamp = 1736509937.852786132 Fixes: 069b142 ("igc: Add support for PTP .getcyclesx64()") Signed-off-by: Zdenek Bouska <[email protected]> Acked-by: Vinicius Costa Gomes <[email protected]> Reviewed-by: Simon Horman <[email protected]> Reviewed-by: Florian Bezdeka <[email protected]> Reviewed-by: Song Yoong Siang <[email protected]> Tested-by: Mor Bar-Gabay <[email protected]> Signed-off-by: Tony Nguyen <[email protected]> Signed-off-by: Sasha Levin <[email protected]> Signed-off-by: Noah Wager <[email protected]> Signed-off-by: Mehmet Basaran <[email protected]>
1 parent 0ae386c commit 1e45d60

File tree

1 file changed

+12
-9
lines changed

1 file changed

+12
-9
lines changed

drivers/net/ethernet/intel/igc/igc_main.c

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2705,8 +2705,9 @@ static int igc_clean_rx_irq(struct igc_q_vector *q_vector, const int budget)
27052705
}
27062706

27072707
static struct sk_buff *igc_construct_skb_zc(struct igc_ring *ring,
2708-
struct xdp_buff *xdp)
2708+
struct igc_xdp_buff *ctx)
27092709
{
2710+
struct xdp_buff *xdp = &ctx->xdp;
27102711
unsigned int totalsize = xdp->data_end - xdp->data_meta;
27112712
unsigned int metasize = xdp->data - xdp->data_meta;
27122713
struct sk_buff *skb;
@@ -2725,26 +2726,27 @@ static struct sk_buff *igc_construct_skb_zc(struct igc_ring *ring,
27252726
__skb_pull(skb, metasize);
27262727
}
27272728

2729+
if (ctx->rx_ts) {
2730+
skb_shinfo(skb)->tx_flags |= SKBTX_HW_TSTAMP_NETDEV;
2731+
skb_hwtstamps(skb)->netdev_data = ctx->rx_ts;
2732+
}
2733+
27282734
return skb;
27292735
}
27302736

27312737
static void igc_dispatch_skb_zc(struct igc_q_vector *q_vector,
27322738
union igc_adv_rx_desc *desc,
2733-
struct xdp_buff *xdp,
2734-
ktime_t timestamp)
2739+
struct igc_xdp_buff *ctx)
27352740
{
27362741
struct igc_ring *ring = q_vector->rx.ring;
27372742
struct sk_buff *skb;
27382743

2739-
skb = igc_construct_skb_zc(ring, xdp);
2744+
skb = igc_construct_skb_zc(ring, ctx);
27402745
if (!skb) {
27412746
ring->rx_stats.alloc_failed++;
27422747
return;
27432748
}
27442749

2745-
if (timestamp)
2746-
skb_hwtstamps(skb)->hwtstamp = timestamp;
2747-
27482750
if (igc_cleanup_headers(ring, desc, skb))
27492751
return;
27502752

@@ -2780,7 +2782,6 @@ static int igc_clean_rx_irq_zc(struct igc_q_vector *q_vector, const int budget)
27802782
union igc_adv_rx_desc *desc;
27812783
struct igc_rx_buffer *bi;
27822784
struct igc_xdp_buff *ctx;
2783-
ktime_t timestamp = 0;
27842785
unsigned int size;
27852786
int res;
27862787

@@ -2810,6 +2811,8 @@ static int igc_clean_rx_irq_zc(struct igc_q_vector *q_vector, const int budget)
28102811
*/
28112812
bi->xdp->data_meta += IGC_TS_HDR_LEN;
28122813
size -= IGC_TS_HDR_LEN;
2814+
} else {
2815+
ctx->rx_ts = NULL;
28132816
}
28142817

28152818
bi->xdp->data_end = bi->xdp->data + size;
@@ -2818,7 +2821,7 @@ static int igc_clean_rx_irq_zc(struct igc_q_vector *q_vector, const int budget)
28182821
res = __igc_xdp_run_prog(adapter, prog, bi->xdp);
28192822
switch (res) {
28202823
case IGC_XDP_PASS:
2821-
igc_dispatch_skb_zc(q_vector, desc, bi->xdp, timestamp);
2824+
igc_dispatch_skb_zc(q_vector, desc, ctx);
28222825
fallthrough;
28232826
case IGC_XDP_CONSUMED:
28242827
xsk_buff_free(bi->xdp);

0 commit comments

Comments
 (0)