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

Commit c1cbe4b7 authored by Benjamin LaHaise's avatar Benjamin LaHaise Committed by David S. Miller
Browse files

[NET]: Avoid atomic xchg() for non-error case



It also looks like there were 2 places where the test on sk_err was
missing from the event wait logic (in sk_stream_wait_connect and
sk_stream_wait_memory), while the rest of the sock_error() users look
to be doing the right thing.  This version of the patch fixes those,
and cleans up a few places that were testing ->sk_err directly.

Signed-off-by: default avatarBenjamin LaHaise <benjamin.c.lahaise@intel.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent f1f71e03
Loading
Loading
Loading
Loading
+4 −1
Original line number Original line Diff line number Diff line
@@ -1166,7 +1166,10 @@ static inline int sock_queue_err_skb(struct sock *sk, struct sk_buff *skb)
 
 
static inline int sock_error(struct sock *sk)
static inline int sock_error(struct sock *sk)
{
{
	int err = xchg(&sk->sk_err, 0);
	int err;
	if (likely(!sk->sk_err))
		return 0;
	err = xchg(&sk->sk_err, 0);
	return -err;
	return -err;
}
}


+2 −3
Original line number Original line Diff line number Diff line
@@ -287,11 +287,10 @@ int bt_sock_wait_state(struct sock *sk, int state, unsigned long timeo)
		timeo = schedule_timeout(timeo);
		timeo = schedule_timeout(timeo);
		lock_sock(sk);
		lock_sock(sk);


		if (sk->sk_err) {
		err = sock_error(sk);
		err = sock_error(sk);
		if (err)
			break;
			break;
	}
	}
	}
	set_current_state(TASK_RUNNING);
	set_current_state(TASK_RUNNING);
	remove_wait_queue(sk->sk_sleep, &wait);
	remove_wait_queue(sk->sk_sleep, &wait);
	return err;
	return err;
+3 −2
Original line number Original line Diff line number Diff line
@@ -767,8 +767,9 @@ static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct ms


	BT_DBG("sock %p, sk %p", sock, sk);
	BT_DBG("sock %p, sk %p", sock, sk);


	if (sk->sk_err)
	err = sock_error(sk);
		return sock_error(sk);
	if (err)
		return err;


	if (msg->msg_flags & MSG_OOB)
	if (msg->msg_flags & MSG_OOB)
		return -EOPNOTSUPP;
		return -EOPNOTSUPP;
+3 −2
Original line number Original line Diff line number Diff line
@@ -637,8 +637,9 @@ static int sco_sock_sendmsg(struct kiocb *iocb, struct socket *sock,


	BT_DBG("sock %p, sk %p", sock, sk);
	BT_DBG("sock %p, sk %p", sock, sk);


	if (sk->sk_err)
	err = sock_error(sk);
		return sock_error(sk);
	if (err)
		return err;


	if (msg->msg_flags & MSG_OOB)
	if (msg->msg_flags & MSG_OOB)
		return -EOPNOTSUPP;
		return -EOPNOTSUPP;
+7 −3
Original line number Original line Diff line number Diff line
@@ -55,8 +55,9 @@ int sk_stream_wait_connect(struct sock *sk, long *timeo_p)
	int done;
	int done;


	do {
	do {
		if (sk->sk_err)
		int err = sock_error(sk);
			return sock_error(sk);
		if (err)
			return err;
		if ((1 << sk->sk_state) & ~(TCPF_SYN_SENT | TCPF_SYN_RECV))
		if ((1 << sk->sk_state) & ~(TCPF_SYN_SENT | TCPF_SYN_RECV))
			return -EPIPE;
			return -EPIPE;
		if (!*timeo_p)
		if (!*timeo_p)
@@ -67,6 +68,7 @@ int sk_stream_wait_connect(struct sock *sk, long *timeo_p)
		prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE);
		prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE);
		sk->sk_write_pending++;
		sk->sk_write_pending++;
		done = sk_wait_event(sk, timeo_p,
		done = sk_wait_event(sk, timeo_p,
				     !sk->sk_err &&
				     !((1 << sk->sk_state) & 
				     !((1 << sk->sk_state) & 
				       ~(TCPF_ESTABLISHED | TCPF_CLOSE_WAIT)));
				       ~(TCPF_ESTABLISHED | TCPF_CLOSE_WAIT)));
		finish_wait(sk->sk_sleep, &wait);
		finish_wait(sk->sk_sleep, &wait);
@@ -137,7 +139,9 @@ int sk_stream_wait_memory(struct sock *sk, long *timeo_p)


		set_bit(SOCK_NOSPACE, &sk->sk_socket->flags);
		set_bit(SOCK_NOSPACE, &sk->sk_socket->flags);
		sk->sk_write_pending++;
		sk->sk_write_pending++;
		sk_wait_event(sk, &current_timeo, sk_stream_memory_free(sk) &&
		sk_wait_event(sk, &current_timeo, !sk->sk_err && 
						  !(sk->sk_shutdown & SEND_SHUTDOWN) &&
						  sk_stream_memory_free(sk) &&
						  vm_wait);
						  vm_wait);
		sk->sk_write_pending--;
		sk->sk_write_pending--;


Loading