Commit 7782040b authored by Paolo Abeni's avatar Paolo Abeni Committed by David S. Miller
Browse files

unix: uses an atomic type for scm files accounting



So the scm_stat_{add,del} helper can be invoked with no
additional lock held.

This clean-up the code a bit and will make the next
patch easier.

Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
Reviewed-by: default avatarKirill Tkhai <ktkhai@virtuozzo.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent e9553762
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -42,7 +42,7 @@ struct unix_skb_parms {
} __randomize_layout;

struct scm_stat {
	u32 nr_fds;
	atomic_t nr_fds;
};

#define UNIXCB(skb)	(*(struct unix_skb_parms *)&((skb)->cb))
+6 −15
Original line number Diff line number Diff line
@@ -690,7 +690,8 @@ static void unix_show_fdinfo(struct seq_file *m, struct socket *sock)

	if (sk) {
		u = unix_sk(sock->sk);
		seq_printf(m, "scm_fds: %u\n", READ_ONCE(u->scm_stat.nr_fds));
		seq_printf(m, "scm_fds: %u\n",
			   atomic_read(&u->scm_stat.nr_fds));
	}
}
#else
@@ -1602,10 +1603,8 @@ static void scm_stat_add(struct sock *sk, struct sk_buff *skb)
	struct scm_fp_list *fp = UNIXCB(skb).fp;
	struct unix_sock *u = unix_sk(sk);

	lockdep_assert_held(&sk->sk_receive_queue.lock);

	if (unlikely(fp && fp->count))
		u->scm_stat.nr_fds += fp->count;
		atomic_add(fp->count, &u->scm_stat.nr_fds);
}

static void scm_stat_del(struct sock *sk, struct sk_buff *skb)
@@ -1613,10 +1612,8 @@ static void scm_stat_del(struct sock *sk, struct sk_buff *skb)
	struct scm_fp_list *fp = UNIXCB(skb).fp;
	struct unix_sock *u = unix_sk(sk);

	lockdep_assert_held(&sk->sk_receive_queue.lock);

	if (unlikely(fp && fp->count))
		u->scm_stat.nr_fds -= fp->count;
		atomic_sub(fp->count, &u->scm_stat.nr_fds);
}

/*
@@ -1805,10 +1802,8 @@ restart_locked:
	if (sock_flag(other, SOCK_RCVTSTAMP))
		__net_timestamp(skb);
	maybe_add_creds(skb, sock, other);
	spin_lock(&other->sk_receive_queue.lock);
	scm_stat_add(other, skb);
	__skb_queue_tail(&other->sk_receive_queue, skb);
	spin_unlock(&other->sk_receive_queue.lock);
	skb_queue_tail(&other->sk_receive_queue, skb);
	unix_state_unlock(other);
	other->sk_data_ready(other);
	sock_put(other);
@@ -1910,10 +1905,8 @@ static int unix_stream_sendmsg(struct socket *sock, struct msghdr *msg,
			goto pipe_err_free;

		maybe_add_creds(skb, sock, other);
		spin_lock(&other->sk_receive_queue.lock);
		scm_stat_add(other, skb);
		__skb_queue_tail(&other->sk_receive_queue, skb);
		spin_unlock(&other->sk_receive_queue.lock);
		skb_queue_tail(&other->sk_receive_queue, skb);
		unix_state_unlock(other);
		other->sk_data_ready(other);
		sent += size;
@@ -2409,9 +2402,7 @@ unlock:
			sk_peek_offset_bwd(sk, chunk);

			if (UNIXCB(skb).fp) {
				spin_lock(&sk->sk_receive_queue.lock);
				scm_stat_del(sk, skb);
				spin_unlock(&sk->sk_receive_queue.lock);
				unix_detach_fds(&scm, skb);
			}