]> www.infradead.org Git - users/hch/misc.git/commitdiff
bpf: Add BPF_SOCK_OPS_TSTAMP_SCHED_CB callback
authorJason Xing <kerneljasonxing@gmail.com>
Thu, 20 Feb 2025 07:29:34 +0000 (15:29 +0800)
committerMartin KaFai Lau <martin.lau@kernel.org>
Thu, 20 Feb 2025 22:29:24 +0000 (14:29 -0800)
Support SCM_TSTAMP_SCHED case for bpf timestamping.

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

A new SKBTX_BPF flag is added to mark skb_shinfo(skb)->tx_flags,
ensuring that the new BPF timestamping and the current user
space's SO_TIMESTAMPING do not interfere with each other.

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-7-kerneljasonxing@gmail.com
include/linux/skbuff.h
include/uapi/linux/bpf.h
net/core/dev.c
net/core/skbuff.c
tools/include/uapi/linux/bpf.h

index bb2b751d274acff931281a72e8b4b0c699b4e8af..52f6e033e704e28be931976eaf102838da20af4a 100644 (file)
@@ -489,10 +489,14 @@ enum {
 
        /* generate software time stamp when entering packet scheduling */
        SKBTX_SCHED_TSTAMP = 1 << 6,
+
+       /* used for bpf extension when a bpf program is loaded */
+       SKBTX_BPF = 1 << 7,
 };
 
 #define SKBTX_ANY_SW_TSTAMP    (SKBTX_SW_TSTAMP    | \
-                                SKBTX_SCHED_TSTAMP)
+                                SKBTX_SCHED_TSTAMP | \
+                                SKBTX_BPF)
 #define SKBTX_ANY_TSTAMP       (SKBTX_HW_TSTAMP | \
                                 SKBTX_HW_TSTAMP_USE_CYCLES | \
                                 SKBTX_ANY_SW_TSTAMP)
index 4e0632848440b910088ab54e2679f35bee42d1e3..bb62fe25b2d0246a9993d8ef6bd0cc2c29bf2d26 100644 (file)
@@ -7031,6 +7031,11 @@ enum {
                                         * by the kernel or the
                                         * earlier bpf-progs.
                                         */
+       BPF_SOCK_OPS_TSTAMP_SCHED_CB,   /* Called when skb is passing
+                                        * through dev layer 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 d5ab9a4b318ea4926c200ef20dae01eaafa18c6b..436f2bdfb2d5328a5b56126c6e61747aaec2f15f 100644 (file)
@@ -4501,7 +4501,8 @@ int __dev_queue_xmit(struct sk_buff *skb, struct net_device *sb_dev)
        skb_reset_mac_header(skb);
        skb_assert_len(skb);
 
-       if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_SCHED_TSTAMP))
+       if (unlikely(skb_shinfo(skb)->tx_flags &
+                    (SKBTX_SCHED_TSTAMP | SKBTX_BPF)))
                __skb_tstamp_tx(skb, NULL, NULL, skb->sk, SCM_TSTAMP_SCHED);
 
        /* Disable soft irqs for various locks below. Also
index 341a3290e898217a73e51e55c8afe826fd8e87d2..3206f7708974f40528647c87fac9aca01f34d044 100644 (file)
@@ -5556,6 +5556,23 @@ static bool skb_tstamp_tx_report_so_timestamping(struct sk_buff *skb,
        return false;
 }
 
+static void skb_tstamp_tx_report_bpf_timestamping(struct sk_buff *skb,
+                                                 struct sock *sk,
+                                                 int tstype)
+{
+       int op;
+
+       switch (tstype) {
+       case SCM_TSTAMP_SCHED:
+               op = BPF_SOCK_OPS_TSTAMP_SCHED_CB;
+               break;
+       default:
+               return;
+       }
+
+       bpf_skops_tx_timestamping(sk, skb, op);
+}
+
 void __skb_tstamp_tx(struct sk_buff *orig_skb,
                     const struct sk_buff *ack_skb,
                     struct skb_shared_hwtstamps *hwtstamps,
@@ -5568,6 +5585,9 @@ void __skb_tstamp_tx(struct sk_buff *orig_skb,
        if (!sk)
                return;
 
+       if (skb_shinfo(orig_skb)->tx_flags & SKBTX_BPF)
+               skb_tstamp_tx_report_bpf_timestamping(orig_skb, sk, tstype);
+
        if (!skb_tstamp_tx_report_so_timestamping(orig_skb, hwtstamps, tstype))
                return;
 
index 4e0632848440b910088ab54e2679f35bee42d1e3..bb62fe25b2d0246a9993d8ef6bd0cc2c29bf2d26 100644 (file)
@@ -7031,6 +7031,11 @@ enum {
                                         * by the kernel or the
                                         * earlier bpf-progs.
                                         */
+       BPF_SOCK_OPS_TSTAMP_SCHED_CB,   /* Called when skb is passing
+                                        * through dev layer 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