*/
WARN_ON_ONCE(in_interrupt());
- smbdirect_log_rdma_event(sc, SMBDIRECT_LOG_INFO,
- "cancelling and disable disconnect_work\n");
- disable_work_sync(&sc->disconnect_work);
+ /*
+ * First we try to disable the work
+ * without disable_work_sync() in a
+ * non blocking way, if it's already
+ * running it will be handles by
+ * disable_work_sync() below.
+ *
+ * Here we just want to make sure queue_work() in
+ * smbdirect_socket_schedule_cleanup_lvl()
+ * is a no-op.
+ */
+ disable_work(&sc->disconnect_work);
- smbdirect_log_rdma_event(sc, SMBDIRECT_LOG_INFO,
- "destroying rdma session\n");
- if (sc->status < SMBDIRECT_SOCKET_DISCONNECTING) {
+ if (!sc->first_error)
/*
* SMBDIRECT_LOG_INFO is enough here
* as this is the typical case where
smbdirect_socket_schedule_cleanup_lvl(sc,
SMBDIRECT_LOG_INFO,
-ESHUTDOWN);
+
+ smbdirect_log_rdma_event(sc, SMBDIRECT_LOG_INFO,
+ "cancelling and disable disconnect_work\n");
+ disable_work_sync(&sc->disconnect_work);
+
+ smbdirect_log_rdma_event(sc, SMBDIRECT_LOG_INFO,
+ "destroying rdma session\n");
+ if (sc->status < SMBDIRECT_SOCKET_DISCONNECTING)
smbdirect_socket_cleanup_work(&sc->disconnect_work);
- }
if (sc->status < SMBDIRECT_SOCKET_DISCONNECTED) {
smbdirect_log_rdma_event(sc, SMBDIRECT_LOG_INFO,
"wait for transport being disconnected\n");