mirror of
https://github.com/torvalds/linux.git
synced 2026-05-29 09:33:31 +02:00
smb: client: let smbd_{destroy,disconnect_rdma_{work,connection}}() wake up all wait queues
This is important in order to let all waiters notice a broken connection.
We also go via smbd_disconnect_rdma_{work,connection}() for broken
connections.
Cc: Steve French <smfrench@gmail.com>
Cc: Tom Talpey <tom@talpey.com>
Cc: Long Li <longli@microsoft.com>
Acked-by: Namjae Jeon <linkinjeon@kernel.org>
Cc: linux-cifs@vger.kernel.org
Cc: samba-technical@lists.samba.org
Signed-off-by: Stefan Metzmacher <metze@samba.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
This commit is contained in:
parent
0cb7ed37af
commit
1b128ec1c7
|
|
@ -165,6 +165,21 @@ do { \
|
|||
#define log_rdma_mr(level, fmt, args...) \
|
||||
log_rdma(level, LOG_RDMA_MR, fmt, ##args)
|
||||
|
||||
static void smbd_disconnect_wake_up_all(struct smbdirect_socket *sc)
|
||||
{
|
||||
/*
|
||||
* Wake up all waiters in all wait queues
|
||||
* in order to notice the broken connection.
|
||||
*/
|
||||
wake_up_all(&sc->status_wait);
|
||||
wake_up_all(&sc->send_io.credits.wait_queue);
|
||||
wake_up_all(&sc->send_io.pending.dec_wait_queue);
|
||||
wake_up_all(&sc->send_io.pending.zero_wait_queue);
|
||||
wake_up_all(&sc->recv_io.reassembly.wait_queue);
|
||||
wake_up_all(&sc->mr_io.ready.wait_queue);
|
||||
wake_up_all(&sc->mr_io.cleanup.wait_queue);
|
||||
}
|
||||
|
||||
static void smbd_disconnect_rdma_work(struct work_struct *work)
|
||||
{
|
||||
struct smbdirect_socket *sc =
|
||||
|
|
@ -216,6 +231,12 @@ static void smbd_disconnect_rdma_work(struct work_struct *work)
|
|||
case SMBDIRECT_SOCKET_DESTROYED:
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Wake up all waiters in all wait queues
|
||||
* in order to notice the broken connection.
|
||||
*/
|
||||
smbd_disconnect_wake_up_all(sc);
|
||||
}
|
||||
|
||||
static void smbd_disconnect_rdma_connection(struct smbdirect_socket *sc)
|
||||
|
|
@ -273,6 +294,12 @@ static void smbd_disconnect_rdma_connection(struct smbdirect_socket *sc)
|
|||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Wake up all waiters in all wait queues
|
||||
* in order to notice the broken connection.
|
||||
*/
|
||||
smbd_disconnect_wake_up_all(sc);
|
||||
|
||||
queue_work(sc->workqueue, &sc->disconnect_work);
|
||||
}
|
||||
|
||||
|
|
@ -306,14 +333,14 @@ static int smbd_conn_upcall(
|
|||
log_rdma_event(ERR, "connecting failed event=%s\n", event_name);
|
||||
WARN_ON_ONCE(sc->status != SMBDIRECT_SOCKET_RESOLVE_ADDR_RUNNING);
|
||||
sc->status = SMBDIRECT_SOCKET_RESOLVE_ADDR_FAILED;
|
||||
wake_up_all(&sc->status_wait);
|
||||
smbd_disconnect_rdma_work(&sc->disconnect_work);
|
||||
break;
|
||||
|
||||
case RDMA_CM_EVENT_ROUTE_ERROR:
|
||||
log_rdma_event(ERR, "connecting failed event=%s\n", event_name);
|
||||
WARN_ON_ONCE(sc->status != SMBDIRECT_SOCKET_RESOLVE_ROUTE_RUNNING);
|
||||
sc->status = SMBDIRECT_SOCKET_RESOLVE_ROUTE_FAILED;
|
||||
wake_up_all(&sc->status_wait);
|
||||
smbd_disconnect_rdma_work(&sc->disconnect_work);
|
||||
break;
|
||||
|
||||
case RDMA_CM_EVENT_ESTABLISHED:
|
||||
|
|
@ -408,7 +435,7 @@ static int smbd_conn_upcall(
|
|||
log_rdma_event(ERR, "connecting failed event=%s\n", event_name);
|
||||
WARN_ON_ONCE(sc->status != SMBDIRECT_SOCKET_RDMA_CONNECT_RUNNING);
|
||||
sc->status = SMBDIRECT_SOCKET_RDMA_CONNECT_FAILED;
|
||||
wake_up_all(&sc->status_wait);
|
||||
smbd_disconnect_rdma_work(&sc->disconnect_work);
|
||||
break;
|
||||
|
||||
case RDMA_CM_EVENT_DEVICE_REMOVAL:
|
||||
|
|
@ -416,17 +443,10 @@ static int smbd_conn_upcall(
|
|||
/* This happens when we fail the negotiation */
|
||||
if (sc->status == SMBDIRECT_SOCKET_NEGOTIATE_FAILED) {
|
||||
log_rdma_event(ERR, "event=%s during negotiation\n", event_name);
|
||||
sc->status = SMBDIRECT_SOCKET_DISCONNECTED;
|
||||
smbd_disconnect_rdma_work(&sc->disconnect_work);
|
||||
wake_up_all(&sc->status_wait);
|
||||
break;
|
||||
}
|
||||
|
||||
sc->status = SMBDIRECT_SOCKET_DISCONNECTED;
|
||||
smbd_disconnect_rdma_work(&sc->disconnect_work);
|
||||
wake_up_all(&sc->status_wait);
|
||||
wake_up_all(&sc->recv_io.reassembly.wait_queue);
|
||||
wake_up_all(&sc->send_io.credits.wait_queue);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
@ -674,7 +694,7 @@ static void recv_done(struct ib_cq *cq, struct ib_wc *wc)
|
|||
WARN_ON_ONCE(sc->status != SMBDIRECT_SOCKET_NEGOTIATE_RUNNING);
|
||||
if (!negotiate_done) {
|
||||
sc->status = SMBDIRECT_SOCKET_NEGOTIATE_FAILED;
|
||||
wake_up_all(&sc->status_wait);
|
||||
smbd_disconnect_rdma_connection(sc);
|
||||
} else {
|
||||
sc->status = SMBDIRECT_SOCKET_CONNECTED;
|
||||
wake_up(&sc->status_wait);
|
||||
|
|
@ -1569,6 +1589,15 @@ void smbd_destroy(struct TCP_Server_Info *server)
|
|||
sc->status == SMBDIRECT_SOCKET_DISCONNECTED);
|
||||
}
|
||||
|
||||
/*
|
||||
* Wake up all waiters in all wait queues
|
||||
* in order to notice the broken connection.
|
||||
*
|
||||
* Most likely this was already called via
|
||||
* smbd_disconnect_rdma_work(), but call it again...
|
||||
*/
|
||||
smbd_disconnect_wake_up_all(sc);
|
||||
|
||||
log_rdma_event(INFO, "cancelling recv_io.posted.refill_work\n");
|
||||
disable_work_sync(&sc->recv_io.posted.refill_work);
|
||||
|
||||
|
|
@ -1609,7 +1638,6 @@ void smbd_destroy(struct TCP_Server_Info *server)
|
|||
* path when sending data, and then release memory registrations.
|
||||
*/
|
||||
log_rdma_event(INFO, "freeing mr list\n");
|
||||
wake_up_all(&sc->mr_io.ready.wait_queue);
|
||||
while (atomic_read(&sc->mr_io.used.count)) {
|
||||
cifs_server_unlock(server);
|
||||
msleep(1000);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user