Hi Siang, I tested this patch series on 6.13 with Intel I226-LM (rev 04). I also applied patch "selftests/bpf: Actuate tx_metadata_len in xdp_hw_metadata" [1] and "selftests/bpf: Enable Tx hwtstamp in xdp_hw_metadata" [2] so that TX timestamps work. HW RX-timestamp was small (0.5956 instead of 1737373125.5956): HW RX-time: 595572448 (sec:0.5956) delta to User RX-time sec:1737373124.9873 (1737373124987318.750 usec) XDP RX-time: 1737373125582798388 (sec:1737373125.5828) delta to User RX-time sec:0.0001 (92.733 usec) Igc's raw HW RX-timestamp in front of frame data was overwritten by BPF program on line 90 in tools/testing/selftests/bpf: meta->hint_valid = 0; "HW timestamp has been copied into local variable" comment is outdated on line 2813 in drivers/net/ethernet/intel/igc/igc_main.c after commit 069b142f5819 igc: Add support for PTP .getcyclesx64() [3]. Workaround is to add unused data to xdp_meta struct: --- a/tools/testing/selftests/bpf/xdp_metadata.h +++ b/tools/testing/selftests/bpf/xdp_metadata.h @@ -49,4 +49,5 @@ struct xdp_meta { __s32 rx_vlan_tag_err; }; enum xdp_meta_field hint_valid; + __u8 avoid_IGC_TS_HDR_LEN[16]; }; But Launch time still does not work: HW Launch-time: 1737374407515922696 (sec:1737374407.5159) delta to HW TX-complete-time sec:-0.9999 (-999923.649 usec) Command "sudo ethtool -X enp1s0 start 1 equal 1" was in v4 [4] but is not in v6. Was that intentional? After executing it Launch time feature works: HW Launch-time: 1737374618088557111 (sec:1737374618.0886) delta to HW TX-complete-time sec:0.0000 (0.012 usec) Thank you for XDP launch time support! [1] https://lore.kernel.org/linux-kernel/20241205044258.3155799-1-yoong.siang.song@xxxxxxxxx/ [2] https://lore.kernel.org/linux-kernel/20241205051936.3156307-1-yoong.siang.song@xxxxxxxxx/ [3] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=069b142f58196bd9f47b35e493255741e2c663c7 [4] https://lore.kernel.org/linux-kernel/20250106135724.9749-1-yoong.siang.song@xxxxxxxxx/ Best regards, Zdenek Bouska -- Siemens, s.r.o Foundational Technologies > -----Original Message----- > From: Song Yoong Siang <yoong.siang.song@xxxxxxxxx> > Sent: Thursday, January 16, 2025 4:54 PM > To: David S . Miller <davem@xxxxxxxxxxxxx>; Eric Dumazet > <edumazet@xxxxxxxxxx>; Jakub Kicinski <kuba@xxxxxxxxxx>; Paolo Abeni > <pabeni@xxxxxxxxxx>; Simon Horman <horms@xxxxxxxxxx>; Willem de Bruijn > <willemb@xxxxxxxxxx>; Bezdeka, Florian (FT RPD CED OES-DE) > <florian.bezdeka@xxxxxxxxxxx>; Donald Hunter > <donald.hunter@xxxxxxxxx>; Jonathan Corbet <corbet@xxxxxxx>; Bjorn > Topel <bjorn@xxxxxxxxxx>; Magnus Karlsson <magnus.karlsson@xxxxxxxxx>; > Maciej Fijalkowski <maciej.fijalkowski@xxxxxxxxx>; Jonathan Lemon > <jonathan.lemon@xxxxxxxxx>; Andrew Lunn <andrew+netdev@xxxxxxx>; > Alexei Starovoitov <ast@xxxxxxxxxx>; Daniel Borkmann > <daniel@xxxxxxxxxxxxx>; Jesper Dangaard Brouer <hawk@xxxxxxxxxx>; John > Fastabend <john.fastabend@xxxxxxxxx>; Joe Damato <jdamato@xxxxxxxxxx>; > Stanislav Fomichev <sdf@xxxxxxxxxxx>; Xuan Zhuo > <xuanzhuo@xxxxxxxxxxxxxxxxx>; Mina Almasry <almasrymina@xxxxxxxxxx>; > Daniel Jurgens <danielj@xxxxxxxxxx>; Song Yoong Siang > <yoong.siang.song@xxxxxxxxx>; Andrii Nakryiko <andrii@xxxxxxxxxx>; Eduard > Zingerman <eddyz87@xxxxxxxxx>; Mykola Lysenko <mykolal@xxxxxx>; > Martin KaFai Lau <martin.lau@xxxxxxxxx>; Song Liu <song@xxxxxxxxxx>; > Yonghong Song <yonghong.song@xxxxxxxxx>; KP Singh > <kpsingh@xxxxxxxxxx>; Hao Luo <haoluo@xxxxxxxxxx>; Jiri Olsa > <jolsa@xxxxxxxxxx>; Shuah Khan <shuah@xxxxxxxxxx>; Alexandre Torgue > <alexandre.torgue@xxxxxxxxxxx>; Jose Abreu <joabreu@xxxxxxxxxxxx>; > Maxime Coquelin <mcoquelin.stm32@xxxxxxxxx>; Tony Nguyen > <anthony.l.nguyen@xxxxxxxxx>; Przemek Kitszel > <przemyslaw.kitszel@xxxxxxxxx> > Cc: netdev@xxxxxxxxxxxxxxx; linux-kernel@xxxxxxxxxxxxxxx; linux- > doc@xxxxxxxxxxxxxxx; bpf@xxxxxxxxxxxxxxx; linux-kselftest@xxxxxxxxxxxxxxx; > linux-stm32@xxxxxxxxxxxxxxxxxxxxxxxxxxxx; linux-arm- > kernel@xxxxxxxxxxxxxxxxxxx; intel-wired-lan@xxxxxxxxxxxxxxxx; xdp-hints@xdp- > project.net > Subject: [PATCH bpf-next v6 4/4] igc: Add launch time support to XDP ZC > > Enable Launch Time Control (LTC) support to XDP zero copy via XDP Tx > metadata framework. > > This patch is tested with tools/testing/selftests/bpf/xdp_hw_metadata on > Intel I225-LM Ethernet controller. Below are the test steps and result. > > Test Steps: > 1. At DUT, start xdp_hw_metadata selftest application: > $ sudo ./xdp_hw_metadata enp2s0 -l 1000000000 -L 1 > > 2. At Link Partner, send an UDP packet with VLAN priority 1 to port 9091 of > DUT. > > When launch time is set to 1s in the future, the delta between launch time and > transmit hardware timestamp is equal to 0.016us, as shown in result > below: > 0x562ff5dc8880: rx_desc[4]->addr=84110 addr=84110 comp_addr=84110 > EoP > rx_hash: 0xE343384 with RSS type:0x1 > HW RX-time: 1734578015467548904 (sec:1734578015.4675) delta to > User RX-time sec:0.0002 (183.103 usec) > XDP RX-time: 1734578015467651698 (sec:1734578015.4677) delta to > User RX-time sec:0.0001 (80.309 usec) > No rx_vlan_tci or rx_vlan_proto, err=-95 > 0x562ff5dc8880: ping-pong with csum=561c (want c7dd) csum_start=34 > csum_offset=6 > HW RX-time: 1734578015467548904 (sec:1734578015.4675) delta to HW > Launch-time sec:1.0000 (1000000.000 usec) > 0x562ff5dc8880: complete tx idx=4 addr=4018 > HW Launch-time: 1734578016467548904 (sec:1734578016.4675) delta > to HW TX-complete-time sec:0.0000 (0.016 usec) > HW TX-complete-time: 1734578016467548920 (sec:1734578016.4675) > delta to User TX-complete-time sec:0.0000 (32.546 usec) > XDP RX-time: 1734578015467651698 (sec:1734578015.4677) delta to > User TX-complete-time sec:0.9999 (999929.768 usec) > HW RX-time: 1734578015467548904 (sec:1734578015.4675) delta to HW > TX-complete-time sec:1.0000 (1000000.016 usec) > 0x562ff5dc8880: complete rx idx=132 addr=84110 > > Signed-off-by: Song Yoong Siang <yoong.siang.song@xxxxxxxxx> > --- > drivers/net/ethernet/intel/igc/igc_main.c | 78 ++++++++++++++++------- > 1 file changed, 56 insertions(+), 22 deletions(-) > > diff --git a/drivers/net/ethernet/intel/igc/igc_main.c > b/drivers/net/ethernet/intel/igc/igc_main.c > index 27872bdea9bd..6857f5f5b4b2 100644 > --- a/drivers/net/ethernet/intel/igc/igc_main.c > +++ b/drivers/net/ethernet/intel/igc/igc_main.c > @@ -1566,6 +1566,26 @@ static bool igc_request_tx_tstamp(struct > igc_adapter *adapter, struct sk_buff *s > return false; > } > > +static void igc_insert_empty_packet(struct igc_ring *tx_ring) { > + struct igc_tx_buffer *empty_info; > + struct sk_buff *empty; > + void *data; > + > + empty_info = &tx_ring->tx_buffer_info[tx_ring->next_to_use]; > + empty = alloc_skb(IGC_EMPTY_FRAME_SIZE, GFP_ATOMIC); > + if (!empty) > + return; > + > + data = skb_put(empty, IGC_EMPTY_FRAME_SIZE); > + memset(data, 0, IGC_EMPTY_FRAME_SIZE); > + > + igc_tx_ctxtdesc(tx_ring, 0, false, 0, 0, 0); > + > + if (igc_init_tx_empty_descriptor(tx_ring, empty, empty_info) < 0) > + dev_kfree_skb_any(empty); > +} > + > static netdev_tx_t igc_xmit_frame_ring(struct sk_buff *skb, > struct igc_ring *tx_ring) > { > @@ -1603,26 +1623,8 @@ static netdev_tx_t igc_xmit_frame_ring(struct > sk_buff *skb, > skb->tstamp = ktime_set(0, 0); > launch_time = igc_tx_launchtime(tx_ring, txtime, &first_flag, > &insert_empty); > > - if (insert_empty) { > - struct igc_tx_buffer *empty_info; > - struct sk_buff *empty; > - void *data; > - > - empty_info = &tx_ring->tx_buffer_info[tx_ring->next_to_use]; > - empty = alloc_skb(IGC_EMPTY_FRAME_SIZE, GFP_ATOMIC); > - if (!empty) > - goto done; > - > - data = skb_put(empty, IGC_EMPTY_FRAME_SIZE); > - memset(data, 0, IGC_EMPTY_FRAME_SIZE); > - > - igc_tx_ctxtdesc(tx_ring, 0, false, 0, 0, 0); > - > - if (igc_init_tx_empty_descriptor(tx_ring, > - empty, > - empty_info) < 0) > - dev_kfree_skb_any(empty); > - } > + if (insert_empty) > + igc_insert_empty_packet(tx_ring); > > done: > /* record the location of the first descriptor for this packet */ @@ - > 2955,9 +2957,33 @@ static u64 igc_xsk_fill_timestamp(void *_priv) > return *(u64 *)_priv; > } > > +static void igc_xsk_request_launch_time(u64 launch_time, void *_priv) { > + struct igc_metadata_request *meta_req = _priv; > + struct igc_ring *tx_ring = meta_req->tx_ring; > + __le32 launch_time_offset; > + bool insert_empty = false; > + bool first_flag = false; > + > + if (!tx_ring->launchtime_enable) > + return; > + > + launch_time_offset = igc_tx_launchtime(tx_ring, > + ns_to_ktime(launch_time), > + &first_flag, &insert_empty); > + if (insert_empty) { > + igc_insert_empty_packet(tx_ring); > + meta_req->tx_buffer = > + &tx_ring->tx_buffer_info[tx_ring->next_to_use]; > + } > + > + igc_tx_ctxtdesc(tx_ring, launch_time_offset, first_flag, 0, 0, 0); } > + > const struct xsk_tx_metadata_ops igc_xsk_tx_metadata_ops = { > .tmo_request_timestamp = igc_xsk_request_timestamp, > .tmo_fill_timestamp = igc_xsk_fill_timestamp, > + .tmo_request_launch_time = igc_xsk_request_launch_time, > }; > > static void igc_xdp_xmit_zc(struct igc_ring *ring) @@ -2980,7 +3006,7 @@ > static void igc_xdp_xmit_zc(struct igc_ring *ring) > ntu = ring->next_to_use; > budget = igc_desc_unused(ring); > > - while (xsk_tx_peek_desc(pool, &xdp_desc) && budget--) { > + while (xsk_tx_peek_desc(pool, &xdp_desc) && budget >= 4) { > struct igc_metadata_request meta_req; > struct xsk_tx_metadata *meta = NULL; > struct igc_tx_buffer *bi; > @@ -3004,6 +3030,12 @@ static void igc_xdp_xmit_zc(struct igc_ring *ring) > xsk_tx_metadata_request(meta, &igc_xsk_tx_metadata_ops, > &meta_req); > > + /* xsk_tx_metadata_request() may have updated next_to_use > */ > + ntu = ring->next_to_use; > + > + /* xsk_tx_metadata_request() may have updated Tx buffer > info */ > + bi = meta_req.tx_buffer; > + > tx_desc = IGC_TX_DESC(ring, ntu); > tx_desc->read.cmd_type_len = > cpu_to_le32(meta_req.cmd_type); > tx_desc->read.olinfo_status = cpu_to_le32(olinfo_status); > @@ -3021,9 +3053,11 @@ static void igc_xdp_xmit_zc(struct igc_ring *ring) > ntu++; > if (ntu == ring->count) > ntu = 0; > + > + ring->next_to_use = ntu; > + budget = igc_desc_unused(ring); > } > > - ring->next_to_use = ntu; > if (tx_desc) { > igc_flush_tx_descriptors(ring); > xsk_tx_release(pool); > -- > 2.34.1 >