Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 09c2d251 authored by Willem de Bruijn's avatar Willem de Bruijn Committed by David S. Miller
Browse files

net-timestamp: add key to disambiguate concurrent datagrams



Datagrams timestamped on transmission can coexist in the kernel stack
and be reordered in packet scheduling. When reading looped datagrams
from the socket error queue it is not always possible to unique
correlate looped data with original send() call (for application
level retransmits). Even if possible, it may be expensive and complex,
requiring packet inspection.

Introduce a data-independent ID mechanism to associate timestamps with
send calls. Pass an ID alongside the timestamp in field ee_data of
sock_extended_err.

The ID is a simple 32 bit unsigned int that is associated with the
socket and incremented on each send() call for which software tx
timestamp generation is enabled.

The feature is enabled only if SOF_TIMESTAMPING_OPT_ID is set, to
avoid changing ee_data for existing applications that expect it 0.
The counter is reset each time the flag is reenabled. Reenabling
does not change the ID of already submitted data. It is possible
to receive out of order IDs if the timestamp stream is not quiesced
first.

Signed-off-by: default avatarWillem de Bruijn <willemb@google.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent b9f40e21
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -278,6 +278,7 @@ struct skb_shared_info {
	unsigned short  gso_type;
	struct sk_buff	*frag_list;
	struct skb_shared_hwtstamps hwtstamps;
	u32		tskey;
	__be32          ip6_frag_id;

	/*
+2 −0
Original line number Diff line number Diff line
@@ -280,6 +280,7 @@ struct cg_proto;
  *	@sk_timer: sock cleanup timer
  *	@sk_stamp: time stamp of last packet received
  *	@sk_tsflags: SO_TIMESTAMPING socket options
  *	@sk_tskey: counter to disambiguate concurrent tstamp requests
  *	@sk_socket: Identd and reporting IO signals
  *	@sk_user_data: RPC layer private data
  *	@sk_frag: cached page frag
@@ -414,6 +415,7 @@ struct sock {
	struct timer_list	sk_timer;
	ktime_t			sk_stamp;
	u16			sk_tsflags;
	u32			sk_tskey;
	struct socket		*sk_socket;
	void			*sk_user_data;
	struct page_frag	sk_frag;
+5 −3
Original line number Diff line number Diff line
@@ -20,9 +20,11 @@ enum {
	SOF_TIMESTAMPING_SOFTWARE = (1<<4),
	SOF_TIMESTAMPING_SYS_HARDWARE = (1<<5),
	SOF_TIMESTAMPING_RAW_HARDWARE = (1<<6),
	SOF_TIMESTAMPING_MASK =
	(SOF_TIMESTAMPING_RAW_HARDWARE - 1) |
	SOF_TIMESTAMPING_RAW_HARDWARE
	SOF_TIMESTAMPING_OPT_ID = (1<<7),

	SOF_TIMESTAMPING_LAST = SOF_TIMESTAMPING_OPT_ID,
	SOF_TIMESTAMPING_MASK = (SOF_TIMESTAMPING_LAST - 1) |
				 SOF_TIMESTAMPING_LAST
};

/**
+2 −0
Original line number Diff line number Diff line
@@ -3522,6 +3522,8 @@ void skb_tstamp_tx(struct sk_buff *orig_skb,
	serr->ee.ee_errno = ENOMSG;
	serr->ee.ee_origin = SO_EE_ORIGIN_TIMESTAMPING;
	serr->ee.ee_info = SCM_TSTAMP_SND;
	if (sk->sk_tsflags & SOF_TIMESTAMPING_OPT_ID)
		serr->ee.ee_data = skb_shinfo(skb)->tskey;

	err = sock_queue_err_skb(sk, skb);

+3 −0
Original line number Diff line number Diff line
@@ -848,6 +848,9 @@ set_rcvbuf:
			ret = -EINVAL;
			break;
		}
		if (val & SOF_TIMESTAMPING_OPT_ID &&
		    !(sk->sk_tsflags & SOF_TIMESTAMPING_OPT_ID))
			sk->sk_tskey = 0;
		sk->sk_tsflags = val;
		if (val & SOF_TIMESTAMPING_RX_SOFTWARE)
			sock_enable_timestamp(sk,
Loading