Revert "net: simplify sock_poll_wait"
This reverts commit dd979b4df8
.
This broke tcp_poll for SMC fallback: An AF_SMC socket establishes an
internal TCP socket for the initial handshake with the remote peer.
Whenever the SMC connection can not be established this TCP socket is
used as a fallback. All socket operations on the SMC socket are then
forwarded to the TCP socket. In case of poll, the file->private_data
pointer references the SMC socket because the TCP socket has no file
assigned. This causes tcp_poll to wait on the wrong socket.
Signed-off-by: Karsten Graul <kgraul@linux.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:

committed by
David S. Miller

parent
6b7a02f708
commit
89ab066d42
@@ -2059,14 +2059,20 @@ static inline bool skwq_has_sleeper(struct socket_wq *wq)
|
||||
/**
|
||||
* sock_poll_wait - place memory barrier behind the poll_wait call.
|
||||
* @filp: file
|
||||
* @sock: socket to wait on
|
||||
* @p: poll_table
|
||||
*
|
||||
* See the comments in the wq_has_sleeper function.
|
||||
*
|
||||
* Do not derive sock from filp->private_data here. An SMC socket establishes
|
||||
* an internal TCP socket that is used in the fallback case. All socket
|
||||
* operations on the SMC socket are then forwarded to the TCP socket. In case of
|
||||
* poll, the filp->private_data pointer references the SMC socket because the
|
||||
* TCP socket has no file assigned.
|
||||
*/
|
||||
static inline void sock_poll_wait(struct file *filp, poll_table *p)
|
||||
static inline void sock_poll_wait(struct file *filp, struct socket *sock,
|
||||
poll_table *p)
|
||||
{
|
||||
struct socket *sock = filp->private_data;
|
||||
|
||||
if (!poll_does_not_wait(p)) {
|
||||
poll_wait(filp, &sock->wq->wait, p);
|
||||
/* We need to be sure we are in sync with the
|
||||
|
Reference in New Issue
Block a user