]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
bpf: Add BPF_SOCK_OPS_TSTAMP_SND_HW_CB callback
authorJason Xing <kerneljasonxing@gmail.com>
Thu, 20 Feb 2025 07:29:36 +0000 (15:29 +0800)
committerMartin KaFai Lau <martin.lau@kernel.org>
Thu, 20 Feb 2025 22:29:36 +0000 (14:29 -0800)
Support hw SCM_TSTAMP_SND case for bpf timestamping.

Add a new sock_ops callback, BPF_SOCK_OPS_TSTAMP_SND_HW_CB. This
callback will occur at the same timestamping point as the user
space's hardware SCM_TSTAMP_SND. The BPF program can use it to
get the same SCM_TSTAMP_SND timestamp without modifying the
user-space application.

To avoid increasing the code complexity, replace SKBTX_HW_TSTAMP
with SKBTX_HW_TSTAMP_NOBPF instead of changing numerous callers
from driver side using SKBTX_HW_TSTAMP. The new definition of
SKBTX_HW_TSTAMP means the combination tests of socket timestamping
and bpf timestamping. After this patch, drivers can work under the
bpf timestamping.

Considering some drivers don't assign the skb with hardware
timestamp, this patch does the assignment and then BPF program
can acquire the hwstamp from skb directly.

Signed-off-by: Jason Xing <kerneljasonxing@gmail.com>
Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
Reviewed-by: Willem de Bruijn <willemb@google.com>
Link: https://patch.msgid.link/20250220072940.99994-9-kerneljasonxing@gmail.com
include/linux/skbuff.h
include/uapi/linux/bpf.h
net/core/skbuff.c
net/dsa/user.c
net/socket.c
tools/include/uapi/linux/bpf.h

index 76582500c5eae9afedcbca628a70c2f4b72f2c06..0b4f1889500d278be952322c0be2cd48235dbba8 100644 (file)
@@ -470,7 +470,7 @@ struct skb_shared_hwtstamps {
 /* Definitions for tx_flags in struct skb_shared_info */
 enum {
        /* generate hardware time stamp */
-       SKBTX_HW_TSTAMP = 1 << 0,
+       SKBTX_HW_TSTAMP_NOBPF = 1 << 0,
 
        /* generate software time stamp when queueing packet to NIC */
        SKBTX_SW_TSTAMP = 1 << 1,
@@ -494,6 +494,8 @@ enum {
        SKBTX_BPF = 1 << 7,
 };
 
+#define SKBTX_HW_TSTAMP                (SKBTX_HW_TSTAMP_NOBPF | SKBTX_BPF)
+
 #define SKBTX_ANY_SW_TSTAMP    (SKBTX_SW_TSTAMP    | \
                                 SKBTX_SCHED_TSTAMP | \
                                 SKBTX_BPF)
index abe8d6c30daec92dfc03453a0a2235c344c1c367..72045c2423963e6c37ca4fce902c71962247bc54 100644 (file)
@@ -7040,6 +7040,10 @@ enum {
                                         * to the nic when SK_BPF_CB_TX_TIMESTAMPING
                                         * feature is on.
                                         */
+       BPF_SOCK_OPS_TSTAMP_SND_HW_CB,  /* Called in hardware phase when
+                                        * SK_BPF_CB_TX_TIMESTAMPING feature
+                                        * is on.
+                                        */
 };
 
 /* List of TCP states. There is a build check in net/ipv4/tcp.c to detect
index 308db7dae1ab112c24fbcf9fa3efa66419d3fe43..77b8866f94c5390785d6aeff0d71520fc024c6b7 100644 (file)
@@ -5547,7 +5547,7 @@ static bool skb_tstamp_tx_report_so_timestamping(struct sk_buff *skb,
        case SCM_TSTAMP_SCHED:
                return skb_shinfo(skb)->tx_flags & SKBTX_SCHED_TSTAMP;
        case SCM_TSTAMP_SND:
-               return skb_shinfo(skb)->tx_flags & (hwtstamps ? SKBTX_HW_TSTAMP :
+               return skb_shinfo(skb)->tx_flags & (hwtstamps ? SKBTX_HW_TSTAMP_NOBPF :
                                                    SKBTX_SW_TSTAMP);
        case SCM_TSTAMP_ACK:
                return TCP_SKB_CB(skb)->txstamp_ack;
@@ -5568,9 +5568,12 @@ static void skb_tstamp_tx_report_bpf_timestamping(struct sk_buff *skb,
                op = BPF_SOCK_OPS_TSTAMP_SCHED_CB;
                break;
        case SCM_TSTAMP_SND:
-               if (hwtstamps)
-                       return;
-               op = BPF_SOCK_OPS_TSTAMP_SND_SW_CB;
+               if (hwtstamps) {
+                       op = BPF_SOCK_OPS_TSTAMP_SND_HW_CB;
+                       *skb_hwtstamps(skb) = *hwtstamps;
+               } else {
+                       op = BPF_SOCK_OPS_TSTAMP_SND_SW_CB;
+               }
                break;
        default:
                return;
index 2296a4ead02030745807a7d003c70b3be76e6847..804dc7dac4f2fee08043d09eaca44fa83e0f4d79 100644 (file)
@@ -897,7 +897,7 @@ static void dsa_skb_tx_timestamp(struct dsa_user_priv *p,
 {
        struct dsa_switch *ds = p->dp->ds;
 
-       if (!(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP))
+       if (!(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP_NOBPF))
                return;
 
        if (!ds->ops->port_txtstamp)
index 28bae5a942341b94afec01d5f2f43f710f8ed000..0545e9ea705815678f436cd26aaf229308ed3a1f 100644 (file)
@@ -681,7 +681,7 @@ void __sock_tx_timestamp(__u32 tsflags, __u8 *tx_flags)
        u8 flags = *tx_flags;
 
        if (tsflags & SOF_TIMESTAMPING_TX_HARDWARE) {
-               flags |= SKBTX_HW_TSTAMP;
+               flags |= SKBTX_HW_TSTAMP_NOBPF;
 
                /* PTP hardware clocks can provide a free running cycle counter
                 * as a time base for virtual clocks. Tell driver to use the
index abe8d6c30daec92dfc03453a0a2235c344c1c367..72045c2423963e6c37ca4fce902c71962247bc54 100644 (file)
@@ -7040,6 +7040,10 @@ enum {
                                         * to the nic when SK_BPF_CB_TX_TIMESTAMPING
                                         * feature is on.
                                         */
+       BPF_SOCK_OPS_TSTAMP_SND_HW_CB,  /* Called in hardware phase when
+                                        * SK_BPF_CB_TX_TIMESTAMPING feature
+                                        * is on.
+                                        */
 };
 
 /* List of TCP states. There is a build check in net/ipv4/tcp.c to detect