diff options
author | Karsten Graul <kgraul@linux.ibm.com> | 2018-10-23 14:40:39 +0300 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2018-11-04 16:50:51 +0300 |
commit | fd54c188b3391acc9a9bba329b10d4965e0ab812 (patch) | |
tree | 454d9ef9cb4d545fa99ff1162542ee905d49f624 /include/net/sock.h | |
parent | 4fb0dc97de1cd79399ab0c556f096d8db2bac278 (diff) | |
download | linux-fd54c188b3391acc9a9bba329b10d4965e0ab812.tar.xz |
Revert "net: simplify sock_poll_wait"
[ Upstream commit 89ab066d4229acd32e323f1569833302544a4186 ]
This reverts commit dd979b4df817e9976f18fb6f9d134d6bc4a3c317.
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>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'include/net/sock.h')
-rw-r--r-- | include/net/sock.h | 12 |
1 files changed, 9 insertions, 3 deletions
diff --git a/include/net/sock.h b/include/net/sock.h index 433f45fc2d68..c64a1cff9eb3 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -2057,14 +2057,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 |