Commit 4d25ca2d authored by Abhishek Chauhan's avatar Abhishek Chauhan Committed by Martin KaFai Lau
Browse files

net: Rename mono_delivery_time to tstamp_type for scalabilty



mono_delivery_time was added to check if skb->tstamp has delivery
time in mono clock base (i.e. EDT) otherwise skb->tstamp has
timestamp in ingress and delivery_time at egress.

Renaming the bitfield from mono_delivery_time to tstamp_type is for
extensibilty for other timestamps such as userspace timestamp
(i.e. SO_TXTIME) set via sock opts.

As we are renaming the mono_delivery_time to tstamp_type, it makes
sense to start assigning tstamp_type based on enum defined
in this commit.

Earlier we used bool arg flag to check if the tstamp is mono in
function skb_set_delivery_time, Now the signature of the functions
accepts tstamp_type to distinguish between mono and real time.

Also skb_set_delivery_type_by_clockid is a new function which accepts
clockid to determine the tstamp_type.

In future tstamp_type:1 can be extended to support userspace timestamp
by increasing the bitfield.

Signed-off-by: default avatarAbhishek Chauhan <quic_abchauha@quicinc.com>
Reviewed-by: default avatarWillem de Bruijn <willemb@google.com>
Reviewed-by: default avatarMartin KaFai Lau <martin.lau@kernel.org>
Link: https://lore.kernel.org/r/20240509211834.3235191-2-quic_abchauha@quicinc.com


Signed-off-by: default avatarMartin KaFai Lau <martin.lau@kernel.org>
parent a87f34e7
Loading
Loading
Loading
Loading
+39 −13
Original line number Diff line number Diff line
@@ -706,6 +706,11 @@ typedef unsigned int sk_buff_data_t;
typedef unsigned char *sk_buff_data_t;
#endif

enum skb_tstamp_type {
	SKB_CLOCK_REALTIME,
	SKB_CLOCK_MONOTONIC,
};

/**
 * DOC: Basic sk_buff geometry
 *
@@ -823,10 +828,8 @@ typedef unsigned char *sk_buff_data_t;
 *	@dst_pending_confirm: need to confirm neighbour
 *	@decrypted: Decrypted SKB
 *	@slow_gro: state present at GRO time, slower prepare step required
 *	@mono_delivery_time: When set, skb->tstamp has the
 *		delivery_time in mono clock base (i.e. EDT).  Otherwise, the
 *		skb->tstamp has the (rcv) timestamp at ingress and
 *		delivery_time at egress.
 *	@tstamp_type: When set, skb->tstamp has the
 *		delivery_time clock base of skb->tstamp.
 *	@napi_id: id of the NAPI struct this skb came from
 *	@sender_cpu: (aka @napi_id) source CPU in XPS
 *	@alloc_cpu: CPU which did the skb allocation.
@@ -954,7 +957,7 @@ struct sk_buff {
	/* private: */
	__u8			__mono_tc_offset[0];
	/* public: */
	__u8			mono_delivery_time:1;	/* See SKB_MONO_DELIVERY_TIME_MASK */
	__u8			tstamp_type:1;	/* See skb_tstamp_type */
#ifdef CONFIG_NET_XGRESS
	__u8			tc_at_ingress:1;	/* See TC_AT_INGRESS_MASK */
	__u8			tc_skip_classify:1;
@@ -4183,7 +4186,7 @@ static inline void skb_get_new_timestampns(const struct sk_buff *skb,
static inline void __net_timestamp(struct sk_buff *skb)
{
	skb->tstamp = ktime_get_real();
	skb->mono_delivery_time = 0;
	skb->tstamp_type = SKB_CLOCK_REALTIME;
}

static inline ktime_t net_timedelta(ktime_t t)
@@ -4192,10 +4195,33 @@ static inline ktime_t net_timedelta(ktime_t t)
}

static inline void skb_set_delivery_time(struct sk_buff *skb, ktime_t kt,
					 bool mono)
					 u8 tstamp_type)
{
	skb->tstamp = kt;
	skb->mono_delivery_time = kt && mono;

	if (kt)
		skb->tstamp_type = tstamp_type;
	else
		skb->tstamp_type = SKB_CLOCK_REALTIME;
}

static inline void skb_set_delivery_type_by_clockid(struct sk_buff *skb,
						    ktime_t kt, clockid_t clockid)
{
	u8 tstamp_type = SKB_CLOCK_REALTIME;

	switch (clockid) {
	case CLOCK_REALTIME:
		break;
	case CLOCK_MONOTONIC:
		tstamp_type = SKB_CLOCK_MONOTONIC;
		break;
	default:
		WARN_ON_ONCE(1);
		kt = 0;
	}

	skb_set_delivery_time(skb, kt, tstamp_type);
}

DECLARE_STATIC_KEY_FALSE(netstamp_needed_key);
@@ -4205,8 +4231,8 @@ DECLARE_STATIC_KEY_FALSE(netstamp_needed_key);
 */
static inline void skb_clear_delivery_time(struct sk_buff *skb)
{
	if (skb->mono_delivery_time) {
		skb->mono_delivery_time = 0;
	if (skb->tstamp_type) {
		skb->tstamp_type = SKB_CLOCK_REALTIME;
		if (static_branch_unlikely(&netstamp_needed_key))
			skb->tstamp = ktime_get_real();
		else
@@ -4216,7 +4242,7 @@ static inline void skb_clear_delivery_time(struct sk_buff *skb)

static inline void skb_clear_tstamp(struct sk_buff *skb)
{
	if (skb->mono_delivery_time)
	if (skb->tstamp_type)
		return;

	skb->tstamp = 0;
@@ -4224,7 +4250,7 @@ static inline void skb_clear_tstamp(struct sk_buff *skb)

static inline ktime_t skb_tstamp(const struct sk_buff *skb)
{
	if (skb->mono_delivery_time)
	if (skb->tstamp_type)
		return 0;

	return skb->tstamp;
@@ -4232,7 +4258,7 @@ static inline ktime_t skb_tstamp(const struct sk_buff *skb)

static inline ktime_t skb_tstamp_cond(const struct sk_buff *skb, bool cond)
{
	if (!skb->mono_delivery_time && skb->tstamp)
	if (skb->tstamp_type != SKB_CLOCK_MONOTONIC && skb->tstamp)
		return skb->tstamp;

	if (static_branch_unlikely(&netstamp_needed_key) || cond)
+2 −2
Original line number Diff line number Diff line
@@ -76,7 +76,7 @@ struct frag_v6_compare_key {
 * @stamp: timestamp of the last received fragment
 * @len: total length of the original datagram
 * @meat: length of received fragments so far
 * @mono_delivery_time: stamp has a mono delivery time (EDT)
 * @tstamp_type: stamp has a mono delivery time (EDT)
 * @flags: fragment queue flags
 * @max_size: maximum received fragment size
 * @fqdir: pointer to struct fqdir
@@ -97,7 +97,7 @@ struct inet_frag_queue {
	ktime_t			stamp;
	int			len;
	int			meat;
	u8			mono_delivery_time;
	u8			tstamp_type;
	__u8			flags;
	u16			max_size;
	struct fqdir		*fqdir;
+3 −3
Original line number Diff line number Diff line
@@ -32,7 +32,7 @@ static int nf_br_ip_fragment(struct net *net, struct sock *sk,
					   struct sk_buff *))
{
	int frag_max_size = BR_INPUT_SKB_CB(skb)->frag_max_size;
	bool mono_delivery_time = skb->mono_delivery_time;
	u8 tstamp_type = skb->tstamp_type;
	unsigned int hlen, ll_rs, mtu;
	ktime_t tstamp = skb->tstamp;
	struct ip_frag_state state;
@@ -82,7 +82,7 @@ static int nf_br_ip_fragment(struct net *net, struct sock *sk,
			if (iter.frag)
				ip_fraglist_prepare(skb, &iter);

			skb_set_delivery_time(skb, tstamp, mono_delivery_time);
			skb_set_delivery_time(skb, tstamp, tstamp_type);
			err = output(net, sk, data, skb);
			if (err || !iter.frag)
				break;
@@ -113,7 +113,7 @@ static int nf_br_ip_fragment(struct net *net, struct sock *sk,
			goto blackhole;
		}

		skb_set_delivery_time(skb2, tstamp, mono_delivery_time);
		skb_set_delivery_time(skb2, tstamp, tstamp_type);
		err = output(net, sk, data, skb2);
		if (err)
			goto blackhole;
+1 −1
Original line number Diff line number Diff line
@@ -2160,7 +2160,7 @@ EXPORT_SYMBOL(net_disable_timestamp);
static inline void net_timestamp_set(struct sk_buff *skb)
{
	skb->tstamp = 0;
	skb->mono_delivery_time = 0;
	skb->tstamp_type = SKB_CLOCK_REALTIME;
	if (static_branch_unlikely(&netstamp_needed_key))
		skb->tstamp = ktime_get_real();
}
+5 −5
Original line number Diff line number Diff line
@@ -7730,13 +7730,13 @@ BPF_CALL_3(bpf_skb_set_tstamp, struct sk_buff *, skb,
		if (!tstamp)
			return -EINVAL;
		skb->tstamp = tstamp;
		skb->mono_delivery_time = 1;
		skb->tstamp_type = SKB_CLOCK_MONOTONIC;
		break;
	case BPF_SKB_TSTAMP_UNSPEC:
		if (tstamp)
			return -EINVAL;
		skb->tstamp = 0;
		skb->mono_delivery_time = 0;
		skb->tstamp_type = SKB_CLOCK_REALTIME;
		break;
	default:
		return -EINVAL;
@@ -9443,7 +9443,7 @@ static struct bpf_insn *bpf_convert_tstamp_read(const struct bpf_prog *prog,
					TC_AT_INGRESS_MASK | SKB_MONO_DELIVERY_TIME_MASK);
		*insn++ = BPF_JMP32_IMM(BPF_JNE, tmp_reg,
					TC_AT_INGRESS_MASK | SKB_MONO_DELIVERY_TIME_MASK, 2);
		/* skb->tc_at_ingress && skb->mono_delivery_time,
		/* skb->tc_at_ingress && skb->tstamp_type,
		 * read 0 as the (rcv) timestamp.
		 */
		*insn++ = BPF_MOV64_IMM(value_reg, 0);
@@ -9468,7 +9468,7 @@ static struct bpf_insn *bpf_convert_tstamp_write(const struct bpf_prog *prog,
	 * the bpf prog is aware the tstamp could have delivery time.
	 * Thus, write skb->tstamp as is if tstamp_type_access is true.
	 * Otherwise, writing at ingress will have to clear the
	 * mono_delivery_time bit also.
	 * skb->tstamp_type bit also.
	 */
	if (!prog->tstamp_type_access) {
		__u8 tmp_reg = BPF_REG_AX;
@@ -9478,7 +9478,7 @@ static struct bpf_insn *bpf_convert_tstamp_write(const struct bpf_prog *prog,
		*insn++ = BPF_JMP32_IMM(BPF_JSET, tmp_reg, TC_AT_INGRESS_MASK, 1);
		/* goto <store> */
		*insn++ = BPF_JMP_A(2);
		/* <clear>: mono_delivery_time */
		/* <clear>: skb->tstamp_type */
		*insn++ = BPF_ALU32_IMM(BPF_AND, tmp_reg, ~SKB_MONO_DELIVERY_TIME_MASK);
		*insn++ = BPF_STX_MEM(BPF_B, skb_reg, tmp_reg, SKB_BF_MONO_TC_OFFSET);
	}
Loading