Skip to content

Commit 7822dd4

Browse files
zdenek-bouskaanguy11
authored andcommitted
igc: Fix HW RX timestamp when passed by ZC XDP
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]>
1 parent 61fb097 commit 7822dd4

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
@@ -2701,8 +2701,9 @@ static int igc_clean_rx_irq(struct igc_q_vector *q_vector, const int budget)
27012701
}
27022702

27032703
static struct sk_buff *igc_construct_skb_zc(struct igc_ring *ring,
2704-
struct xdp_buff *xdp)
2704+
struct igc_xdp_buff *ctx)
27052705
{
2706+
struct xdp_buff *xdp = &ctx->xdp;
27062707
unsigned int totalsize = xdp->data_end - xdp->data_meta;
27072708
unsigned int metasize = xdp->data - xdp->data_meta;
27082709
struct sk_buff *skb;
@@ -2721,27 +2722,28 @@ static struct sk_buff *igc_construct_skb_zc(struct igc_ring *ring,
27212722
__skb_pull(skb, metasize);
27222723
}
27232724

2725+
if (ctx->rx_ts) {
2726+
skb_shinfo(skb)->tx_flags |= SKBTX_HW_TSTAMP_NETDEV;
2727+
skb_hwtstamps(skb)->netdev_data = ctx->rx_ts;
2728+
}
2729+
27242730
return skb;
27252731
}
27262732

27272733
static void igc_dispatch_skb_zc(struct igc_q_vector *q_vector,
27282734
union igc_adv_rx_desc *desc,
2729-
struct xdp_buff *xdp,
2730-
ktime_t timestamp)
2735+
struct igc_xdp_buff *ctx)
27312736
{
27322737
struct igc_ring *ring = q_vector->rx.ring;
27332738
struct sk_buff *skb;
27342739

2735-
skb = igc_construct_skb_zc(ring, xdp);
2740+
skb = igc_construct_skb_zc(ring, ctx);
27362741
if (!skb) {
27372742
ring->rx_stats.alloc_failed++;
27382743
set_bit(IGC_RING_FLAG_RX_ALLOC_FAILED, &ring->flags);
27392744
return;
27402745
}
27412746

2742-
if (timestamp)
2743-
skb_hwtstamps(skb)->hwtstamp = timestamp;
2744-
27452747
if (igc_cleanup_headers(ring, desc, skb))
27462748
return;
27472749

@@ -2777,7 +2779,6 @@ static int igc_clean_rx_irq_zc(struct igc_q_vector *q_vector, const int budget)
27772779
union igc_adv_rx_desc *desc;
27782780
struct igc_rx_buffer *bi;
27792781
struct igc_xdp_buff *ctx;
2780-
ktime_t timestamp = 0;
27812782
unsigned int size;
27822783
int res;
27832784

@@ -2807,6 +2808,8 @@ static int igc_clean_rx_irq_zc(struct igc_q_vector *q_vector, const int budget)
28072808
*/
28082809
bi->xdp->data_meta += IGC_TS_HDR_LEN;
28092810
size -= IGC_TS_HDR_LEN;
2811+
} else {
2812+
ctx->rx_ts = NULL;
28102813
}
28112814

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

0 commit comments

Comments
 (0)