Parcourir la source

net/rpmsg: unblock reader threads operating on errored sockets

The rpmsg_proto driver is used to provide a socket interface
to userspace under the AF_RPMSG address family, and is used
by the TI IPC MessageQ stack. The typical usage for receiving
messages include a thread blocked on a select() call with
appropriate socket fds, followed by a recvfrom() on the fd
returned/marked ready by select().

The rpmsg_sock_poll() function implements the logic needed
by the select() call, and marks a socket ready only when there
is data to be read currently. Any reader thread waiting on the
select() call to return is currently not unblocked when a remote
processor goes through an error recovery, and can remain blocked
forever as its remote processor peer thread may never send it
another message. Enhance the rpmsg_proto driver so that a waiting
thread can be unblocked by waking it up during the process of
marking the open sockets with the error status RPMSG_ERROR. This
is achieved by using the socket's .sk_error_report() ops, and is
preferred over the .sk_state_change() ops to wakeup only a single
exclusive thread.

Signed-off-by: Suman Anna <s-anna@ti.com>
Suman Anna il y a 6 ans
Parent
commit
e90fa6b23e
1 fichiers modifiés avec 5 ajouts et 1 suppressions
  1. 5 1
      net/rpmsg/rpmsg_proto.c

+ 5 - 1
net/rpmsg/rpmsg_proto.c

@@ -280,6 +280,8 @@ static __poll_t rpmsg_sock_poll(struct file *file, struct socket *sock,
 	/* exceptional events? */
 	if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue))
 		mask |= EPOLLERR;
+	if (sk->sk_state == RPMSG_ERROR)
+		mask |= EPOLLERR;
 	if (sk->sk_shutdown & RCV_SHUTDOWN)
 		mask |= EPOLLRDHUP;
 	if (sk->sk_shutdown == SHUTDOWN_MASK)
@@ -664,8 +666,10 @@ static void rpmsg_proto_remove(struct rpmsg_device *rpdev)
 			rpsk->endpt = NULL;
 		}
 		release_sock(&rpsk->sk);
-		if (endpt)
+		if (endpt) {
 			rpmsg_destroy_ept(endpt);
+			rpsk->sk.sk_error_report(&rpsk->sk);
+		}
 	}
 	kfree(sk_list);
 	rpdev->ept->priv = NULL;