Eric Dumazet [off-list ref] writes:
On Mon, 2015-10-05 at 17:31 +0100, Rainer Weikusat wrote:
quoted
atomic_long_set(&u->inflight, 0);
INIT_LIST_HEAD(&u->link);
@@ -2135,8 +2139,16 @@ static unsigned int unix_poll(struct fil
static unsigned int unix_dgram_poll(struct file *file, struct socket *sock,
poll_table *wait)
{
- struct sock *sk = sock->sk, *other;
- unsigned int mask, writable;
+ struct sock *sk = sock->sk, *other, *pp;
+ struct unix_sock *u;
+ unsigned int mask, writable, dead;
+
+ u = unix_sk(sk);
+ pp = u->poll_peer;
+ if (pp) {
+ u->poll_peer = NULL;
+ sock_put(pp);
+ }
This looks racy.
Multiple threads could use poll() at the same time,
and you would have too many sock_put()
That's one of the reasons why I wrote "might work": The use of a single
structure member without any locking for the sock_poll_wait suggests
that this is taken care of in some other way, as does the absence of any
comment about that in the 'public' LDDs ("Linux Device Drivers"),
however, I don't really know if this is true. If not, this simple idea
can't work.