Skip to content

Commit 8dce278

Browse files
Ursula Braundavem330
Ursula Braun
authored andcommitted
net/smc: smc_poll improvements
Increase the socket refcount during poll wait. Take the socket lock before checking socket state. For a listening socket return a mask independent of state SMC_ACTIVE and cover errors or closed state as well. Get rid of the accept_q loop in smc_accept_poll(). Signed-off-by: Ursula Braun <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent da05bf2 commit 8dce278

File tree

1 file changed

+40
-34
lines changed

1 file changed

+40
-34
lines changed

net/smc/af_smc.c

Lines changed: 40 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1122,21 +1122,15 @@ static int smc_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
11221122

11231123
static unsigned int smc_accept_poll(struct sock *parent)
11241124
{
1125-
struct smc_sock *isk;
1126-
struct sock *sk;
1127-
1128-
lock_sock(parent);
1129-
list_for_each_entry(isk, &smc_sk(parent)->accept_q, accept_q) {
1130-
sk = (struct sock *)isk;
1125+
struct smc_sock *isk = smc_sk(parent);
1126+
int mask = 0;
11311127

1132-
if (sk->sk_state == SMC_ACTIVE) {
1133-
release_sock(parent);
1134-
return POLLIN | POLLRDNORM;
1135-
}
1136-
}
1137-
release_sock(parent);
1128+
spin_lock(&isk->accept_q_lock);
1129+
if (!list_empty(&isk->accept_q))
1130+
mask = POLLIN | POLLRDNORM;
1131+
spin_unlock(&isk->accept_q_lock);
11381132

1139-
return 0;
1133+
return mask;
11401134
}
11411135

11421136
static unsigned int smc_poll(struct file *file, struct socket *sock,
@@ -1147,9 +1141,15 @@ static unsigned int smc_poll(struct file *file, struct socket *sock,
11471141
struct smc_sock *smc;
11481142
int rc;
11491143

1144+
if (!sk)
1145+
return POLLNVAL;
1146+
11501147
smc = smc_sk(sock->sk);
1148+
sock_hold(sk);
1149+
lock_sock(sk);
11511150
if ((sk->sk_state == SMC_INIT) || smc->use_fallback) {
11521151
/* delegate to CLC child sock */
1152+
release_sock(sk);
11531153
mask = smc->clcsock->ops->poll(file, smc->clcsock, wait);
11541154
/* if non-blocking connect finished ... */
11551155
lock_sock(sk);
@@ -1161,37 +1161,43 @@ static unsigned int smc_poll(struct file *file, struct socket *sock,
11611161
rc = smc_connect_rdma(smc);
11621162
if (rc < 0)
11631163
mask |= POLLERR;
1164-
else
1165-
/* success cases including fallback */
1166-
mask |= POLLOUT | POLLWRNORM;
1164+
/* success cases including fallback */
1165+
mask |= POLLOUT | POLLWRNORM;
11671166
}
11681167
}
1169-
release_sock(sk);
11701168
} else {
1171-
sock_poll_wait(file, sk_sleep(sk), wait);
1172-
if (sk->sk_state == SMC_LISTEN)
1173-
/* woken up by sk_data_ready in smc_listen_work() */
1174-
mask |= smc_accept_poll(sk);
1169+
if (sk->sk_state != SMC_CLOSED) {
1170+
release_sock(sk);
1171+
sock_poll_wait(file, sk_sleep(sk), wait);
1172+
lock_sock(sk);
1173+
}
11751174
if (sk->sk_err)
11761175
mask |= POLLERR;
1177-
if (atomic_read(&smc->conn.sndbuf_space) ||
1178-
(sk->sk_shutdown & SEND_SHUTDOWN)) {
1179-
mask |= POLLOUT | POLLWRNORM;
1180-
} else {
1181-
sk_set_bit(SOCKWQ_ASYNC_NOSPACE, sk);
1182-
set_bit(SOCK_NOSPACE, &sk->sk_socket->flags);
1183-
}
1184-
if (atomic_read(&smc->conn.bytes_to_rcv))
1185-
mask |= POLLIN | POLLRDNORM;
11861176
if ((sk->sk_shutdown == SHUTDOWN_MASK) ||
11871177
(sk->sk_state == SMC_CLOSED))
11881178
mask |= POLLHUP;
1189-
if (sk->sk_shutdown & RCV_SHUTDOWN)
1190-
mask |= POLLIN | POLLRDNORM | POLLRDHUP;
1191-
if (sk->sk_state == SMC_APPCLOSEWAIT1)
1192-
mask |= POLLIN;
1179+
if (sk->sk_state == SMC_LISTEN) {
1180+
/* woken up by sk_data_ready in smc_listen_work() */
1181+
mask = smc_accept_poll(sk);
1182+
} else {
1183+
if (atomic_read(&smc->conn.sndbuf_space) ||
1184+
sk->sk_shutdown & SEND_SHUTDOWN) {
1185+
mask |= POLLOUT | POLLWRNORM;
1186+
} else {
1187+
sk_set_bit(SOCKWQ_ASYNC_NOSPACE, sk);
1188+
set_bit(SOCK_NOSPACE, &sk->sk_socket->flags);
1189+
}
1190+
if (atomic_read(&smc->conn.bytes_to_rcv))
1191+
mask |= POLLIN | POLLRDNORM;
1192+
if (sk->sk_shutdown & RCV_SHUTDOWN)
1193+
mask |= POLLIN | POLLRDNORM | POLLRDHUP;
1194+
if (sk->sk_state == SMC_APPCLOSEWAIT1)
1195+
mask |= POLLIN;
1196+
}
11931197

11941198
}
1199+
release_sock(sk);
1200+
sock_put(sk);
11951201

11961202
return mask;
11971203
}

0 commit comments

Comments
 (0)