From: Ding Meng <meng.ding@siemens.com>
To: anthony.l.nguyen@intel.com, przemyslaw.kitszel@intel.com,
andrew+netdev@lunn.ch, davem@davemloft.net, edumazet@google.com,
kuba@kernel.org, pabeni@redhat.com, jan.kiszka@siemens.com,
florian.bezdeka@siemens.com
Cc: intel-wired-lan@lists.osuosl.org, linux-kernel@vger.kernel.org,
netdev@vger.kernel.org, meng.ding@siemens.com,
wq.wang@siemens.com, pmenzel@molgen.mpg.de,
stable@vger.kernel.org,
Aleksandr Loktionov <aleksandr.loktionov@intel.com>,
Piotr Kwapulinski <piotr.kwapulinski@intel.com>
Subject: [Intel-wired-lan] [PATCH net v2] igc: Fix RX HW timestamp reporting when NET_RX_BUSY_POLL is disabled
Date: Tue, 30 Jun 2026 19:15:23 +0800 [thread overview]
Message-ID: <20260630112056.885071-1-meng.ding@siemens.com> (raw)
When CONFIG_NET_RX_BUSY_POLL is deactivated, fetching RX HW timestamps
from the NIC no longer works as expected, often resulting in incorrect
or negative values such as "HW raw -121948.050407424".
This occurs because disabling CONFIG_NET_RX_BUSY_POLL disables the
SKB NAPI mapping in __skb_mark_napi_id(). Consequently, get_timestamp()
fails to perform its driver lookup, and the igc driver's struct
net_device_ops::ndo_get_tstamp is never invoked.
Instead, get_timestamp() falls back to use shhwtstamps(skb)->hwtstamp,
a field that the driver has not populated. This results in incorrect
timestamps.
Fix this by populating the hwtstamp field with the correct timestamp
in the default timer when CONFIG_NET_RX_BUSY_POLL is disabled.
The "igc_adapter" is passed to igc_construct_skb() to enable
igc_ptp_rx_pktstamp() to access the necessary adapter details for
adjusting the timestamp.
Test case:
Disable CONFIG_NET_RX_BUSY_POLL.
Sender:
# tools/testing/selftests/net/timestamping en0 \
SOF_TIMESTAMPING_TX_HARDWARE PTPV2 IP_MULTICAST_LOOP
Receiver:
# tools/testing/selftests/net/timestamping en0 \
SOF_TIMESTAMPING_RX_HARDWARE SOF_TIMESTAMPING_RAW_HARDWARE PTPV2
Before patch, receiver prints
HW raw -121948.050407424
After patch, receiver prints
HW raw 1760648763.746974064
Fixes: 069b142f5819 ("igc: Add support for PTP .getcyclesx64()")
Cc: stable@vger.kernel.org
Co-developed-by: Florian Bezdeka <florian.bezdeka@siemens.com>
Signed-off-by: Florian Bezdeka <florian.bezdeka@siemens.com>
Signed-off-by: Ding Meng <meng.ding@siemens.com>
Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
Reviewed-by: Piotr Kwapulinski <piotr.kwapulinski@intel.com>
---
V2:
- update commit message(suggested by Paul Menzel):
add error log
explain why need to pass igc_adapter
add test case
- move variable declarations on top of the function
- Cc stable@vger.kernel.org
V1: https://lore.kernel.org/intel-wired-lan/20260622041718.6106-1-meng.ding@siemens.com/
---
drivers/net/ethernet/intel/igc/igc_main.c | 41 ++++++++++++++++-------
1 file changed, 29 insertions(+), 12 deletions(-)
diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c
index 8ac16808023..5c4beb8b5d4 100644
--- a/drivers/net/ethernet/intel/igc/igc_main.c
+++ b/drivers/net/ethernet/intel/igc/igc_main.c
@@ -1992,7 +1992,29 @@ static struct sk_buff *igc_build_skb(struct igc_ring *rx_ring,
return skb;
}
-static struct sk_buff *igc_construct_skb(struct igc_ring *rx_ring,
+static void igc_construct_skb_timestamps(struct igc_adapter *adapter,
+ struct sk_buff *skb,
+ struct igc_xdp_buff *ctx)
+{
+#ifndef CONFIG_NET_RX_BUSY_POLL
+ struct igc_inline_rx_tstamps *tstamps;
+#endif
+
+ if (!ctx->rx_ts)
+ return;
+
+#ifndef CONFIG_NET_RX_BUSY_POLL
+ tstamps = ctx->rx_ts;
+ skb_hwtstamps(skb)->hwtstamp = igc_ptp_rx_pktstamp(adapter,
+ tstamps->timer0);
+#else
+ skb_shinfo(skb)->tx_flags |= SKBTX_HW_TSTAMP_NETDEV;
+ skb_hwtstamps(skb)->netdev_data = ctx->rx_ts;
+#endif
+}
+
+static struct sk_buff *igc_construct_skb(struct igc_adapter *adapter,
+ struct igc_ring *rx_ring,
struct igc_rx_buffer *rx_buffer,
struct igc_xdp_buff *ctx)
{
@@ -2013,10 +2035,7 @@ static struct sk_buff *igc_construct_skb(struct igc_ring *rx_ring,
if (unlikely(!skb))
return NULL;
- if (ctx->rx_ts) {
- skb_shinfo(skb)->tx_flags |= SKBTX_HW_TSTAMP_NETDEV;
- skb_hwtstamps(skb)->netdev_data = ctx->rx_ts;
- }
+ igc_construct_skb_timestamps(adapter, skb, ctx);
/* Determine available headroom for copy */
headlen = size;
@@ -2686,7 +2705,7 @@ static int igc_clean_rx_irq(struct igc_q_vector *q_vector, const int budget)
else if (ring_uses_build_skb(rx_ring))
skb = igc_build_skb(rx_ring, rx_buffer, &ctx.xdp);
else
- skb = igc_construct_skb(rx_ring, rx_buffer, &ctx);
+ skb = igc_construct_skb(adapter, rx_ring, rx_buffer, &ctx);
/* exit if we failed to retrieve a buffer */
if (!xdp_res && !skb) {
@@ -2738,7 +2757,8 @@ static int igc_clean_rx_irq(struct igc_q_vector *q_vector, const int budget)
return total_packets;
}
-static struct sk_buff *igc_construct_skb_zc(struct igc_ring *ring,
+static struct sk_buff *igc_construct_skb_zc(struct igc_adapter *adapter,
+ struct igc_ring *ring,
struct igc_xdp_buff *ctx)
{
struct xdp_buff *xdp = &ctx->xdp;
@@ -2760,10 +2780,7 @@ static struct sk_buff *igc_construct_skb_zc(struct igc_ring *ring,
__skb_pull(skb, metasize);
}
- if (ctx->rx_ts) {
- skb_shinfo(skb)->tx_flags |= SKBTX_HW_TSTAMP_NETDEV;
- skb_hwtstamps(skb)->netdev_data = ctx->rx_ts;
- }
+ igc_construct_skb_timestamps(adapter, skb, ctx);
return skb;
}
@@ -2775,7 +2792,7 @@ static void igc_dispatch_skb_zc(struct igc_q_vector *q_vector,
struct igc_ring *ring = q_vector->rx.ring;
struct sk_buff *skb;
- skb = igc_construct_skb_zc(ring, ctx);
+ skb = igc_construct_skb_zc(q_vector->adapter, ring, ctx);
if (!skb) {
ring->rx_stats.alloc_failed++;
set_bit(IGC_RING_FLAG_RX_ALLOC_FAILED, &ring->flags);
base-commit: 4549871118cf616eecdd2d939f78e3b9e1dddc48
--
2.47.3
WARNING: multiple messages have this Message-ID (diff)
From: Ding Meng via Intel-wired-lan <intel-wired-lan@osuosl.org>
To: anthony.l.nguyen@intel.com, przemyslaw.kitszel@intel.com,
andrew+netdev@lunn.ch, davem@davemloft.net, edumazet@google.com,
kuba@kernel.org, pabeni@redhat.com, jan.kiszka@siemens.com,
florian.bezdeka@siemens.com
Cc: intel-wired-lan@lists.osuosl.org, linux-kernel@vger.kernel.org,
netdev@vger.kernel.org, meng.ding@siemens.com,
wq.wang@siemens.com, pmenzel@molgen.mpg.de,
stable@vger.kernel.org,
Aleksandr Loktionov <aleksandr.loktionov@intel.com>,
Piotr Kwapulinski <piotr.kwapulinski@intel.com>
Subject: [Intel-wired-lan] [PATCH net v2] igc: Fix RX HW timestamp reporting when NET_RX_BUSY_POLL is disabled
Date: Tue, 30 Jun 2026 19:15:23 +0800 [thread overview]
Message-ID: <20260630112056.885071-1-meng.ding@siemens.com> (raw)
When CONFIG_NET_RX_BUSY_POLL is deactivated, fetching RX HW timestamps
from the NIC no longer works as expected, often resulting in incorrect
or negative values such as "HW raw -121948.050407424".
This occurs because disabling CONFIG_NET_RX_BUSY_POLL disables the
SKB NAPI mapping in __skb_mark_napi_id(). Consequently, get_timestamp()
fails to perform its driver lookup, and the igc driver's struct
net_device_ops::ndo_get_tstamp is never invoked.
Instead, get_timestamp() falls back to use shhwtstamps(skb)->hwtstamp,
a field that the driver has not populated. This results in incorrect
timestamps.
Fix this by populating the hwtstamp field with the correct timestamp
in the default timer when CONFIG_NET_RX_BUSY_POLL is disabled.
The "igc_adapter" is passed to igc_construct_skb() to enable
igc_ptp_rx_pktstamp() to access the necessary adapter details for
adjusting the timestamp.
Test case:
Disable CONFIG_NET_RX_BUSY_POLL.
Sender:
# tools/testing/selftests/net/timestamping en0 \
SOF_TIMESTAMPING_TX_HARDWARE PTPV2 IP_MULTICAST_LOOP
Receiver:
# tools/testing/selftests/net/timestamping en0 \
SOF_TIMESTAMPING_RX_HARDWARE SOF_TIMESTAMPING_RAW_HARDWARE PTPV2
Before patch, receiver prints
HW raw -121948.050407424
After patch, receiver prints
HW raw 1760648763.746974064
Fixes: 069b142f5819 ("igc: Add support for PTP .getcyclesx64()")
Cc: stable@vger.kernel.org
Co-developed-by: Florian Bezdeka <florian.bezdeka@siemens.com>
Signed-off-by: Florian Bezdeka <florian.bezdeka@siemens.com>
Signed-off-by: Ding Meng <meng.ding@siemens.com>
Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
Reviewed-by: Piotr Kwapulinski <piotr.kwapulinski@intel.com>
---
V2:
- update commit message(suggested by Paul Menzel):
add error log
explain why need to pass igc_adapter
add test case
- move variable declarations on top of the function
- Cc stable@vger.kernel.org
V1: https://lore.kernel.org/intel-wired-lan/20260622041718.6106-1-meng.ding@siemens.com/
---
drivers/net/ethernet/intel/igc/igc_main.c | 41 ++++++++++++++++-------
1 file changed, 29 insertions(+), 12 deletions(-)
diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c
index 8ac16808023..5c4beb8b5d4 100644
--- a/drivers/net/ethernet/intel/igc/igc_main.c
+++ b/drivers/net/ethernet/intel/igc/igc_main.c
@@ -1992,7 +1992,29 @@ static struct sk_buff *igc_build_skb(struct igc_ring *rx_ring,
return skb;
}
-static struct sk_buff *igc_construct_skb(struct igc_ring *rx_ring,
+static void igc_construct_skb_timestamps(struct igc_adapter *adapter,
+ struct sk_buff *skb,
+ struct igc_xdp_buff *ctx)
+{
+#ifndef CONFIG_NET_RX_BUSY_POLL
+ struct igc_inline_rx_tstamps *tstamps;
+#endif
+
+ if (!ctx->rx_ts)
+ return;
+
+#ifndef CONFIG_NET_RX_BUSY_POLL
+ tstamps = ctx->rx_ts;
+ skb_hwtstamps(skb)->hwtstamp = igc_ptp_rx_pktstamp(adapter,
+ tstamps->timer0);
+#else
+ skb_shinfo(skb)->tx_flags |= SKBTX_HW_TSTAMP_NETDEV;
+ skb_hwtstamps(skb)->netdev_data = ctx->rx_ts;
+#endif
+}
+
+static struct sk_buff *igc_construct_skb(struct igc_adapter *adapter,
+ struct igc_ring *rx_ring,
struct igc_rx_buffer *rx_buffer,
struct igc_xdp_buff *ctx)
{
@@ -2013,10 +2035,7 @@ static struct sk_buff *igc_construct_skb(struct igc_ring *rx_ring,
if (unlikely(!skb))
return NULL;
- if (ctx->rx_ts) {
- skb_shinfo(skb)->tx_flags |= SKBTX_HW_TSTAMP_NETDEV;
- skb_hwtstamps(skb)->netdev_data = ctx->rx_ts;
- }
+ igc_construct_skb_timestamps(adapter, skb, ctx);
/* Determine available headroom for copy */
headlen = size;
@@ -2686,7 +2705,7 @@ static int igc_clean_rx_irq(struct igc_q_vector *q_vector, const int budget)
else if (ring_uses_build_skb(rx_ring))
skb = igc_build_skb(rx_ring, rx_buffer, &ctx.xdp);
else
- skb = igc_construct_skb(rx_ring, rx_buffer, &ctx);
+ skb = igc_construct_skb(adapter, rx_ring, rx_buffer, &ctx);
/* exit if we failed to retrieve a buffer */
if (!xdp_res && !skb) {
@@ -2738,7 +2757,8 @@ static int igc_clean_rx_irq(struct igc_q_vector *q_vector, const int budget)
return total_packets;
}
-static struct sk_buff *igc_construct_skb_zc(struct igc_ring *ring,
+static struct sk_buff *igc_construct_skb_zc(struct igc_adapter *adapter,
+ struct igc_ring *ring,
struct igc_xdp_buff *ctx)
{
struct xdp_buff *xdp = &ctx->xdp;
@@ -2760,10 +2780,7 @@ static struct sk_buff *igc_construct_skb_zc(struct igc_ring *ring,
__skb_pull(skb, metasize);
}
- if (ctx->rx_ts) {
- skb_shinfo(skb)->tx_flags |= SKBTX_HW_TSTAMP_NETDEV;
- skb_hwtstamps(skb)->netdev_data = ctx->rx_ts;
- }
+ igc_construct_skb_timestamps(adapter, skb, ctx);
return skb;
}
@@ -2775,7 +2792,7 @@ static void igc_dispatch_skb_zc(struct igc_q_vector *q_vector,
struct igc_ring *ring = q_vector->rx.ring;
struct sk_buff *skb;
- skb = igc_construct_skb_zc(ring, ctx);
+ skb = igc_construct_skb_zc(q_vector->adapter, ring, ctx);
if (!skb) {
ring->rx_stats.alloc_failed++;
set_bit(IGC_RING_FLAG_RX_ALLOC_FAILED, &ring->flags);
base-commit: 4549871118cf616eecdd2d939f78e3b9e1dddc48
--
2.47.3
next reply other threads:[~2026-06-30 11:32 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-30 11:15 Ding Meng [this message]
2026-06-30 11:15 ` [Intel-wired-lan] [PATCH net v2] igc: Fix RX HW timestamp reporting when NET_RX_BUSY_POLL is disabled Ding Meng via Intel-wired-lan
2026-09-02 11:25 ` Dahan, AvigailX
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=20260630112056.885071-1-meng.ding@siemens.com \
--to=meng.ding@siemens.com \
--cc=aleksandr.loktionov@intel.com \
--cc=andrew+netdev@lunn.ch \
--cc=anthony.l.nguyen@intel.com \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=florian.bezdeka@siemens.com \
--cc=intel-wired-lan@lists.osuosl.org \
--cc=jan.kiszka@siemens.com \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=piotr.kwapulinski@intel.com \
--cc=pmenzel@molgen.mpg.de \
--cc=przemyslaw.kitszel@intel.com \
--cc=stable@vger.kernel.org \
--cc=wq.wang@siemens.com \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.