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

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

net-timestamp: move timestamp flags out of sk_flags



sk_flags is reaching its limit. New timestamping options will not fit.
Move all of them into a new field sk->sk_tsflags.

Added benefit is that this removes boilerplate code to convert between
SOF_TIMESTAMPING_.. and SOCK_TIMESTAMPING_.. in getsockopt/setsockopt.

SOCK_TIMESTAMPING_RX_SOFTWARE is also used to toggle the receive
timestamp logic (netstamp_needed). That can be simplified and this
last key removed, but will leave that for a separate patch.

Signed-off-by: default avatarWillem de Bruijn <willemb@google.com>

----

The u16 in sock can be moved into a 16-bit hole below sk_gso_max_segs,
though that scatters tstamp fields throughout the struct.
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent f24b9be5
Loading
Loading
Loading
Loading
+11 −18
Original line number Original line Diff line number Diff line
@@ -67,6 +67,7 @@
#include <linux/atomic.h>
#include <linux/atomic.h>
#include <net/dst.h>
#include <net/dst.h>
#include <net/checksum.h>
#include <net/checksum.h>
#include <linux/net_tstamp.h>


struct cgroup;
struct cgroup;
struct cgroup_subsys;
struct cgroup_subsys;
@@ -278,6 +279,7 @@ struct cg_proto;
  *	@sk_protinfo: private area, net family specific, when not using slab
  *	@sk_protinfo: private area, net family specific, when not using slab
  *	@sk_timer: sock cleanup timer
  *	@sk_timer: sock cleanup timer
  *	@sk_stamp: time stamp of last packet received
  *	@sk_stamp: time stamp of last packet received
  *	@sk_tsflags: SO_TIMESTAMPING socket options
  *	@sk_socket: Identd and reporting IO signals
  *	@sk_socket: Identd and reporting IO signals
  *	@sk_user_data: RPC layer private data
  *	@sk_user_data: RPC layer private data
  *	@sk_frag: cached page frag
  *	@sk_frag: cached page frag
@@ -411,6 +413,7 @@ struct sock {
	void			*sk_protinfo;
	void			*sk_protinfo;
	struct timer_list	sk_timer;
	struct timer_list	sk_timer;
	ktime_t			sk_stamp;
	ktime_t			sk_stamp;
	u16			sk_tsflags;
	struct socket		*sk_socket;
	struct socket		*sk_socket;
	void			*sk_user_data;
	void			*sk_user_data;
	struct page_frag	sk_frag;
	struct page_frag	sk_frag;
@@ -701,12 +704,7 @@ enum sock_flags {
	SOCK_LOCALROUTE, /* route locally only, %SO_DONTROUTE setting */
	SOCK_LOCALROUTE, /* route locally only, %SO_DONTROUTE setting */
	SOCK_QUEUE_SHRUNK, /* write queue has been shrunk recently */
	SOCK_QUEUE_SHRUNK, /* write queue has been shrunk recently */
	SOCK_MEMALLOC, /* VM depends on this socket for swapping */
	SOCK_MEMALLOC, /* VM depends on this socket for swapping */
	SOCK_TIMESTAMPING_TX_HARDWARE,  /* %SOF_TIMESTAMPING_TX_HARDWARE */
	SOCK_TIMESTAMPING_TX_SOFTWARE,  /* %SOF_TIMESTAMPING_TX_SOFTWARE */
	SOCK_TIMESTAMPING_RX_HARDWARE,  /* %SOF_TIMESTAMPING_RX_HARDWARE */
	SOCK_TIMESTAMPING_RX_SOFTWARE,  /* %SOF_TIMESTAMPING_RX_SOFTWARE */
	SOCK_TIMESTAMPING_RX_SOFTWARE,  /* %SOF_TIMESTAMPING_RX_SOFTWARE */
	SOCK_TIMESTAMPING_SOFTWARE,     /* %SOF_TIMESTAMPING_SOFTWARE */
	SOCK_TIMESTAMPING_RAW_HARDWARE, /* %SOF_TIMESTAMPING_RAW_HARDWARE */
	SOCK_FASYNC, /* fasync() active */
	SOCK_FASYNC, /* fasync() active */
	SOCK_RXQ_OVFL,
	SOCK_RXQ_OVFL,
	SOCK_ZEROCOPY, /* buffers from userspace */
	SOCK_ZEROCOPY, /* buffers from userspace */
@@ -2160,20 +2158,17 @@ sock_recv_timestamp(struct msghdr *msg, struct sock *sk, struct sk_buff *skb)


	/*
	/*
	 * generate control messages if
	 * generate control messages if
	 * - receive time stamping in software requested (SOCK_RCVTSTAMP
	 * - receive time stamping in software requested
	 *   or SOCK_TIMESTAMPING_RX_SOFTWARE)
	 * - software time stamp available and wanted
	 * - software time stamp available and wanted
	 *   (SOCK_TIMESTAMPING_SOFTWARE)
	 * - hardware time stamps available and wanted
	 * - hardware time stamps available and wanted
	 *   SOCK_TIMESTAMPING_RAW_HARDWARE
	 */
	 */
	if (sock_flag(sk, SOCK_RCVTSTAMP) ||
	if (sock_flag(sk, SOCK_RCVTSTAMP) ||
	    sock_flag(sk, SOCK_TIMESTAMPING_RX_SOFTWARE) ||
	    (sk->sk_tsflags & SOF_TIMESTAMPING_RX_SOFTWARE) ||
	    (kt.tv64 &&
	    (kt.tv64 &&
	     (sock_flag(sk, SOCK_TIMESTAMPING_SOFTWARE) ||
	     (sk->sk_tsflags & SOF_TIMESTAMPING_SOFTWARE ||
	      skb_shinfo(skb)->tx_flags & SKBTX_ANY_SW_TSTAMP)) ||
	      skb_shinfo(skb)->tx_flags & SKBTX_ANY_SW_TSTAMP)) ||
	    (hwtstamps->hwtstamp.tv64 &&
	    (hwtstamps->hwtstamp.tv64 &&
	     sock_flag(sk, SOCK_TIMESTAMPING_RAW_HARDWARE)))
	     (sk->sk_tsflags & SOF_TIMESTAMPING_RAW_HARDWARE)))
		__sock_recv_timestamp(msg, sk, skb);
		__sock_recv_timestamp(msg, sk, skb);
	else
	else
		sk->sk_stamp = kt;
		sk->sk_stamp = kt;
@@ -2189,11 +2184,11 @@ static inline void sock_recv_ts_and_drops(struct msghdr *msg, struct sock *sk,
					  struct sk_buff *skb)
					  struct sk_buff *skb)
{
{
#define FLAGS_TS_OR_DROPS ((1UL << SOCK_RXQ_OVFL)			| \
#define FLAGS_TS_OR_DROPS ((1UL << SOCK_RXQ_OVFL)			| \
			   (1UL << SOCK_RCVTSTAMP)			| \
			   (1UL << SOCK_RCVTSTAMP))
			   (1UL << SOCK_TIMESTAMPING_SOFTWARE)		| \
#define TSFLAGS_ANY	  (SOF_TIMESTAMPING_SOFTWARE			| \
			   (1UL << SOCK_TIMESTAMPING_RAW_HARDWARE))
			   SOF_TIMESTAMPING_RAW_HARDWARE)


	if (sk->sk_flags & FLAGS_TS_OR_DROPS)
	if (sk->sk_flags & FLAGS_TS_OR_DROPS || sk->sk_tsflags & TSFLAGS_ANY)
		__sock_recv_ts_and_drops(msg, sk, skb);
		__sock_recv_ts_and_drops(msg, sk, skb);
	else
	else
		sk->sk_stamp = skb->tstamp;
		sk->sk_stamp = skb->tstamp;
@@ -2203,8 +2198,6 @@ static inline void sock_recv_ts_and_drops(struct msghdr *msg, struct sock *sk,
 * sock_tx_timestamp - checks whether the outgoing packet is to be time stamped
 * sock_tx_timestamp - checks whether the outgoing packet is to be time stamped
 * @sk:		socket sending this packet
 * @sk:		socket sending this packet
 * @tx_flags:	filled with instructions for time stamping
 * @tx_flags:	filled with instructions for time stamping
 *
 * Currently only depends on SOCK_TIMESTAMPING* flags.
 */
 */
void sock_tx_timestamp(struct sock *sk, __u8 *tx_flags);
void sock_tx_timestamp(struct sock *sk, __u8 *tx_flags);


+2 −23
Original line number Original line Diff line number Diff line
@@ -848,22 +848,13 @@ int sock_setsockopt(struct socket *sock, int level, int optname,
			ret = -EINVAL;
			ret = -EINVAL;
			break;
			break;
		}
		}
		sock_valbool_flag(sk, SOCK_TIMESTAMPING_TX_HARDWARE,
		sk->sk_tsflags = val;
				  val & SOF_TIMESTAMPING_TX_HARDWARE);
		sock_valbool_flag(sk, SOCK_TIMESTAMPING_TX_SOFTWARE,
				  val & SOF_TIMESTAMPING_TX_SOFTWARE);
		sock_valbool_flag(sk, SOCK_TIMESTAMPING_RX_HARDWARE,
				  val & SOF_TIMESTAMPING_RX_HARDWARE);
		if (val & SOF_TIMESTAMPING_RX_SOFTWARE)
		if (val & SOF_TIMESTAMPING_RX_SOFTWARE)
			sock_enable_timestamp(sk,
			sock_enable_timestamp(sk,
					      SOCK_TIMESTAMPING_RX_SOFTWARE);
					      SOCK_TIMESTAMPING_RX_SOFTWARE);
		else
		else
			sock_disable_timestamp(sk,
			sock_disable_timestamp(sk,
					       (1UL << SOCK_TIMESTAMPING_RX_SOFTWARE));
					       (1UL << SOCK_TIMESTAMPING_RX_SOFTWARE));
		sock_valbool_flag(sk, SOCK_TIMESTAMPING_SOFTWARE,
				  val & SOF_TIMESTAMPING_SOFTWARE);
		sock_valbool_flag(sk, SOCK_TIMESTAMPING_RAW_HARDWARE,
				  val & SOF_TIMESTAMPING_RAW_HARDWARE);
		break;
		break;


	case SO_RCVLOWAT:
	case SO_RCVLOWAT:
@@ -1089,19 +1080,7 @@ int sock_getsockopt(struct socket *sock, int level, int optname,
		break;
		break;


	case SO_TIMESTAMPING:
	case SO_TIMESTAMPING:
		v.val = 0;
		v.val = sk->sk_tsflags;
		if (sock_flag(sk, SOCK_TIMESTAMPING_TX_HARDWARE))
			v.val |= SOF_TIMESTAMPING_TX_HARDWARE;
		if (sock_flag(sk, SOCK_TIMESTAMPING_TX_SOFTWARE))
			v.val |= SOF_TIMESTAMPING_TX_SOFTWARE;
		if (sock_flag(sk, SOCK_TIMESTAMPING_RX_HARDWARE))
			v.val |= SOF_TIMESTAMPING_RX_HARDWARE;
		if (sock_flag(sk, SOCK_TIMESTAMPING_RX_SOFTWARE))
			v.val |= SOF_TIMESTAMPING_RX_SOFTWARE;
		if (sock_flag(sk, SOCK_TIMESTAMPING_SOFTWARE))
			v.val |= SOF_TIMESTAMPING_SOFTWARE;
		if (sock_flag(sk, SOCK_TIMESTAMPING_RAW_HARDWARE))
			v.val |= SOF_TIMESTAMPING_RAW_HARDWARE;
		break;
		break;


	case SO_RCVTIMEO:
	case SO_RCVTIMEO:
+4 −4
Original line number Original line Diff line number Diff line
@@ -613,9 +613,9 @@ EXPORT_SYMBOL(sock_release);
void sock_tx_timestamp(struct sock *sk, __u8 *tx_flags)
void sock_tx_timestamp(struct sock *sk, __u8 *tx_flags)
{
{
	*tx_flags = 0;
	*tx_flags = 0;
	if (sock_flag(sk, SOCK_TIMESTAMPING_TX_HARDWARE))
	if (sk->sk_tsflags & SOF_TIMESTAMPING_TX_HARDWARE)
		*tx_flags |= SKBTX_HW_TSTAMP;
		*tx_flags |= SKBTX_HW_TSTAMP;
	if (sock_flag(sk, SOCK_TIMESTAMPING_TX_SOFTWARE))
	if (sk->sk_tsflags & SOF_TIMESTAMPING_TX_SOFTWARE)
		*tx_flags |= SKBTX_SW_TSTAMP;
		*tx_flags |= SKBTX_SW_TSTAMP;
	if (sock_flag(sk, SOCK_WIFI_STATUS))
	if (sock_flag(sk, SOCK_WIFI_STATUS))
		*tx_flags |= SKBTX_WIFI_STATUS;
		*tx_flags |= SKBTX_WIFI_STATUS;
@@ -723,12 +723,12 @@ void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk,
	}
	}


	memset(&tss, 0, sizeof(tss));
	memset(&tss, 0, sizeof(tss));
	if ((sock_flag(sk, SOCK_TIMESTAMPING_SOFTWARE) ||
	if ((sk->sk_tsflags & SOF_TIMESTAMPING_SOFTWARE ||
	     skb_shinfo(skb)->tx_flags & SKBTX_ANY_SW_TSTAMP) &&
	     skb_shinfo(skb)->tx_flags & SKBTX_ANY_SW_TSTAMP) &&
	    ktime_to_timespec_cond(skb->tstamp, tss.ts + 0))
	    ktime_to_timespec_cond(skb->tstamp, tss.ts + 0))
		empty = 0;
		empty = 0;
	if (shhwtstamps &&
	if (shhwtstamps &&
	    sock_flag(sk, SOCK_TIMESTAMPING_RAW_HARDWARE) &&
	    (sk->sk_tsflags & SOF_TIMESTAMPING_RAW_HARDWARE) &&
	    ktime_to_timespec_cond(shhwtstamps->hwtstamp, tss.ts + 2))
	    ktime_to_timespec_cond(shhwtstamps->hwtstamp, tss.ts + 2))
		empty = 0;
		empty = 0;
	if (!empty)
	if (!empty)