Commit e3390b30 authored by Eric Dumazet's avatar Eric Dumazet Committed by David S. Miller
Browse files

net: annotate data-races around sk->sk_tsflags



sk->sk_tsflags can be read locklessly, add corresponding annotations.

Fixes: b9f40e21 ("net-timestamp: move timestamp flags out of sk_flags")
Signed-off-by: default avatarEric Dumazet <edumazet@google.com>
Cc: Willem de Bruijn <willemb@google.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 9531e4a8
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -94,7 +94,7 @@ static inline void ipcm_init_sk(struct ipcm_cookie *ipcm,
	ipcm_init(ipcm);

	ipcm->sockc.mark = READ_ONCE(inet->sk.sk_mark);
	ipcm->sockc.tsflags = inet->sk.sk_tsflags;
	ipcm->sockc.tsflags = READ_ONCE(inet->sk.sk_tsflags);
	ipcm->oif = READ_ONCE(inet->sk.sk_bound_dev_if);
	ipcm->addr = inet->inet_saddr;
	ipcm->protocol = inet->inet_num;
+10 −7
Original line number Diff line number Diff line
@@ -1906,7 +1906,9 @@ struct sockcm_cookie {
static inline void sockcm_init(struct sockcm_cookie *sockc,
			       const struct sock *sk)
{
	*sockc = (struct sockcm_cookie) { .tsflags = sk->sk_tsflags };
	*sockc = (struct sockcm_cookie) {
		.tsflags = READ_ONCE(sk->sk_tsflags)
	};
}

int __sock_cmsg_send(struct sock *sk, struct cmsghdr *cmsg,
@@ -2701,9 +2703,9 @@ void __sock_recv_wifi_status(struct msghdr *msg, struct sock *sk,
static inline void
sock_recv_timestamp(struct msghdr *msg, struct sock *sk, struct sk_buff *skb)
{
	ktime_t kt = skb->tstamp;
	struct skb_shared_hwtstamps *hwtstamps = skb_hwtstamps(skb);

	u32 tsflags = READ_ONCE(sk->sk_tsflags);
	ktime_t kt = skb->tstamp;
	/*
	 * generate control messages if
	 * - receive time stamping in software requested
@@ -2711,10 +2713,10 @@ sock_recv_timestamp(struct msghdr *msg, struct sock *sk, struct sk_buff *skb)
	 * - hardware time stamps available and wanted
	 */
	if (sock_flag(sk, SOCK_RCVTSTAMP) ||
	    (sk->sk_tsflags & SOF_TIMESTAMPING_RX_SOFTWARE) ||
	    (kt && sk->sk_tsflags & SOF_TIMESTAMPING_SOFTWARE) ||
	    (tsflags & SOF_TIMESTAMPING_RX_SOFTWARE) ||
	    (kt && tsflags & SOF_TIMESTAMPING_SOFTWARE) ||
	    (hwtstamps->hwtstamp &&
	     (sk->sk_tsflags & SOF_TIMESTAMPING_RAW_HARDWARE)))
	     (tsflags & SOF_TIMESTAMPING_RAW_HARDWARE)))
		__sock_recv_timestamp(msg, sk, skb);
	else
		sock_write_timestamp(sk, kt);
@@ -2736,7 +2738,8 @@ static inline void sock_recv_cmsgs(struct msghdr *msg, struct sock *sk,
#define TSFLAGS_ANY	  (SOF_TIMESTAMPING_SOFTWARE			| \
			   SOF_TIMESTAMPING_RAW_HARDWARE)

	if (sk->sk_flags & FLAGS_RECV_CMSGS || sk->sk_tsflags & TSFLAGS_ANY)
	if (sk->sk_flags & FLAGS_RECV_CMSGS ||
	    READ_ONCE(sk->sk_tsflags) & TSFLAGS_ANY)
		__sock_recv_cmsgs(msg, sk, skb);
	else if (unlikely(sock_flag(sk, SOCK_TIMESTAMP)))
		sock_write_timestamp(sk, skb->tstamp);
+6 −4
Original line number Diff line number Diff line
@@ -974,6 +974,7 @@ static void __j1939_sk_errqueue(struct j1939_session *session, struct sock *sk,
	struct sock_exterr_skb *serr;
	struct sk_buff *skb;
	char *state = "UNK";
	u32 tsflags;
	int err;

	jsk = j1939_sk(sk);
@@ -981,13 +982,14 @@ static void __j1939_sk_errqueue(struct j1939_session *session, struct sock *sk,
	if (!(jsk->state & J1939_SOCK_ERRQUEUE))
		return;

	tsflags = READ_ONCE(sk->sk_tsflags);
	switch (type) {
	case J1939_ERRQUEUE_TX_ACK:
		if (!(sk->sk_tsflags & SOF_TIMESTAMPING_TX_ACK))
		if (!(tsflags & SOF_TIMESTAMPING_TX_ACK))
			return;
		break;
	case J1939_ERRQUEUE_TX_SCHED:
		if (!(sk->sk_tsflags & SOF_TIMESTAMPING_TX_SCHED))
		if (!(tsflags & SOF_TIMESTAMPING_TX_SCHED))
			return;
		break;
	case J1939_ERRQUEUE_TX_ABORT:
@@ -997,7 +999,7 @@ static void __j1939_sk_errqueue(struct j1939_session *session, struct sock *sk,
	case J1939_ERRQUEUE_RX_DPO:
		fallthrough;
	case J1939_ERRQUEUE_RX_ABORT:
		if (!(sk->sk_tsflags & SOF_TIMESTAMPING_RX_SOFTWARE))
		if (!(tsflags & SOF_TIMESTAMPING_RX_SOFTWARE))
			return;
		break;
	default:
@@ -1054,7 +1056,7 @@ static void __j1939_sk_errqueue(struct j1939_session *session, struct sock *sk,
	}

	serr->opt_stats = true;
	if (sk->sk_tsflags & SOF_TIMESTAMPING_OPT_ID)
	if (tsflags & SOF_TIMESTAMPING_OPT_ID)
		serr->ee.ee_data = session->tskey;

	netdev_dbg(session->priv->ndev, "%s: 0x%p tskey: %i, state: %s\n",
+6 −4
Original line number Diff line number Diff line
@@ -5207,7 +5207,7 @@ static void __skb_complete_tx_timestamp(struct sk_buff *skb,
	serr->ee.ee_info = tstype;
	serr->opt_stats = opt_stats;
	serr->header.h4.iif = skb->dev ? skb->dev->ifindex : 0;
	if (sk->sk_tsflags & SOF_TIMESTAMPING_OPT_ID) {
	if (READ_ONCE(sk->sk_tsflags) & SOF_TIMESTAMPING_OPT_ID) {
		serr->ee.ee_data = skb_shinfo(skb)->tskey;
		if (sk_is_tcp(sk))
			serr->ee.ee_data -= atomic_read(&sk->sk_tskey);
@@ -5263,21 +5263,23 @@ void __skb_tstamp_tx(struct sk_buff *orig_skb,
{
	struct sk_buff *skb;
	bool tsonly, opt_stats = false;
	u32 tsflags;

	if (!sk)
		return;

	if (!hwtstamps && !(sk->sk_tsflags & SOF_TIMESTAMPING_OPT_TX_SWHW) &&
	tsflags = READ_ONCE(sk->sk_tsflags);
	if (!hwtstamps && !(tsflags & SOF_TIMESTAMPING_OPT_TX_SWHW) &&
	    skb_shinfo(orig_skb)->tx_flags & SKBTX_IN_PROGRESS)
		return;

	tsonly = sk->sk_tsflags & SOF_TIMESTAMPING_OPT_TSONLY;
	tsonly = tsflags & SOF_TIMESTAMPING_OPT_TSONLY;
	if (!skb_may_tx_timestamp(sk, tsonly))
		return;

	if (tsonly) {
#ifdef CONFIG_INET
		if ((sk->sk_tsflags & SOF_TIMESTAMPING_OPT_STATS) &&
		if ((tsflags & SOF_TIMESTAMPING_OPT_STATS) &&
		    sk_is_tcp(sk)) {
			skb = tcp_get_timestamping_opt_stats(sk, orig_skb,
							     ack_skb);
+2 −2
Original line number Diff line number Diff line
@@ -937,7 +937,7 @@ int sock_set_timestamping(struct sock *sk, int optname,
			return ret;
	}

	sk->sk_tsflags = val;
	WRITE_ONCE(sk->sk_tsflags, val);
	sock_valbool_flag(sk, SOCK_TSTAMP_NEW, optname == SO_TIMESTAMPING_NEW);

	if (val & SOF_TIMESTAMPING_RX_SOFTWARE)
@@ -1719,7 +1719,7 @@ int sk_getsockopt(struct sock *sk, int level, int optname,

	case SO_TIMESTAMPING_OLD:
		lv = sizeof(v.timestamping);
		v.timestamping.flags = sk->sk_tsflags;
		v.timestamping.flags = READ_ONCE(sk->sk_tsflags);
		v.timestamping.bind_phc = sk->sk_bind_phc;
		break;

Loading