* [PATCH 01/18] smb: smbdirect/client: introduce SMBDIRECT_SOCKET_ERROR
2025-09-21 21:44 [PATCH 00/18] smbdirect/client/server: improved error handling and other small improvements Stefan Metzmacher
@ 2025-09-21 21:44 ` Stefan Metzmacher
2025-09-21 21:44 ` [PATCH 02/18] smb: smbdirect: let smbdirect_socket_init() initialize all [delayed_]work_structs as disabled Stefan Metzmacher
` (16 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Stefan Metzmacher @ 2025-09-21 21:44 UTC (permalink / raw)
To: linux-cifs, samba-technical
Cc: metze, Steve French, Tom Talpey, Long Li, Namjae Jeon,
Steve French
This will be used to turn SMBDIRECT_SOCKET_CONNECTED into an
error within smbd_disconnect_rdma_connection() on the client
and smb_direct_disconnect_rdma_connection() on the server.
We do this in a single commit with the client as otherwise it
won't build because the enum value is not handled in the
switch statement.
Cc: Steve French <smfrench@gmail.com>
Cc: Tom Talpey <tom@talpey.com>
Cc: Long Li <longli@microsoft.com>
Cc: 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>
---
fs/smb/client/smbdirect.c | 1 +
fs/smb/common/smbdirect/smbdirect_socket.h | 3 +++
2 files changed, 4 insertions(+)
diff --git a/fs/smb/client/smbdirect.c b/fs/smb/client/smbdirect.c
index e0a01b3b396a..7e0d2ecaa37e 100644
--- a/fs/smb/client/smbdirect.c
+++ b/fs/smb/client/smbdirect.c
@@ -186,6 +186,7 @@ static void smbd_disconnect_rdma_work(struct work_struct *work)
case SMBDIRECT_SOCKET_NEGOTIATE_RUNNING:
case SMBDIRECT_SOCKET_NEGOTIATE_FAILED:
case SMBDIRECT_SOCKET_CONNECTED:
+ case SMBDIRECT_SOCKET_ERROR:
sc->status = SMBDIRECT_SOCKET_DISCONNECTING;
rdma_disconnect(sc->rdma.cm_id);
break;
diff --git a/fs/smb/common/smbdirect/smbdirect_socket.h b/fs/smb/common/smbdirect/smbdirect_socket.h
index 91eb02fb1600..b4970d7e42ad 100644
--- a/fs/smb/common/smbdirect/smbdirect_socket.h
+++ b/fs/smb/common/smbdirect/smbdirect_socket.h
@@ -23,6 +23,7 @@ enum smbdirect_socket_status {
SMBDIRECT_SOCKET_NEGOTIATE_RUNNING,
SMBDIRECT_SOCKET_NEGOTIATE_FAILED,
SMBDIRECT_SOCKET_CONNECTED,
+ SMBDIRECT_SOCKET_ERROR,
SMBDIRECT_SOCKET_DISCONNECTING,
SMBDIRECT_SOCKET_DISCONNECTED,
SMBDIRECT_SOCKET_DESTROYED
@@ -60,6 +61,8 @@ const char *smbdirect_socket_status_string(enum smbdirect_socket_status status)
return "NEGOTIATE_FAILED";
case SMBDIRECT_SOCKET_CONNECTED:
return "CONNECTED";
+ case SMBDIRECT_SOCKET_ERROR:
+ return "ERROR";
case SMBDIRECT_SOCKET_DISCONNECTING:
return "DISCONNECTING";
case SMBDIRECT_SOCKET_DISCONNECTED:
--
2.43.0
^ permalink raw reply related [flat|nested] 19+ messages in thread* [PATCH 02/18] smb: smbdirect: let smbdirect_socket_init() initialize all [delayed_]work_structs as disabled
2025-09-21 21:44 [PATCH 00/18] smbdirect/client/server: improved error handling and other small improvements Stefan Metzmacher
2025-09-21 21:44 ` [PATCH 01/18] smb: smbdirect/client: introduce SMBDIRECT_SOCKET_ERROR Stefan Metzmacher
@ 2025-09-21 21:44 ` Stefan Metzmacher
2025-09-21 21:44 ` [PATCH 03/18] smb: smbdirect: introduce smbdirect_socket.first_error Stefan Metzmacher
` (15 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Stefan Metzmacher @ 2025-09-21 21:44 UTC (permalink / raw)
To: linux-cifs, samba-technical
Cc: metze, Steve French, Tom Talpey, Long Li, Namjae Jeon,
Steve French
This safer to start with and allows common code not care about if the
caller uses these or not. E.g. sc->mr_io.recovery_work is only used
on the client...
Note disable_[delayed_]work_sync() requires a valid function pointer
in INIT_[DELAYED_]WORK(). The non _sync() version don't require it,
but as we need to use the _sync() version on cleanup we better use
it here too, it won't block anyway here...
Cc: Steve French <smfrench@gmail.com>
Cc: Tom Talpey <tom@talpey.com>
Cc: Long Li <longli@microsoft.com>
Cc: 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>
---
fs/smb/common/smbdirect/smbdirect_socket.h | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/fs/smb/common/smbdirect/smbdirect_socket.h b/fs/smb/common/smbdirect/smbdirect_socket.h
index b4970d7e42ad..5e25abc02364 100644
--- a/fs/smb/common/smbdirect/smbdirect_socket.h
+++ b/fs/smb/common/smbdirect/smbdirect_socket.h
@@ -310,6 +310,14 @@ struct smbdirect_socket {
} statistics;
};
+static void __smbdirect_socket_disabled_work(struct work_struct *work)
+{
+ /*
+ * Should never be called as disable_[delayed_]work_sync() was used.
+ */
+ WARN_ON_ONCE(1);
+}
+
static __always_inline void smbdirect_socket_init(struct smbdirect_socket *sc)
{
/*
@@ -320,6 +328,14 @@ static __always_inline void smbdirect_socket_init(struct smbdirect_socket *sc)
init_waitqueue_head(&sc->status_wait);
+ INIT_WORK(&sc->disconnect_work, __smbdirect_socket_disabled_work);
+ disable_work_sync(&sc->disconnect_work);
+
+ INIT_WORK(&sc->idle.immediate_work, __smbdirect_socket_disabled_work);
+ disable_work_sync(&sc->idle.immediate_work);
+ INIT_DELAYED_WORK(&sc->idle.timer_work, __smbdirect_socket_disabled_work);
+ disable_delayed_work_sync(&sc->idle.timer_work);
+
atomic_set(&sc->send_io.credits.count, 0);
init_waitqueue_head(&sc->send_io.credits.wait_queue);
@@ -331,6 +347,8 @@ static __always_inline void smbdirect_socket_init(struct smbdirect_socket *sc)
spin_lock_init(&sc->recv_io.free.lock);
atomic_set(&sc->recv_io.posted.count, 0);
+ INIT_WORK(&sc->recv_io.posted.refill_work, __smbdirect_socket_disabled_work);
+ disable_work_sync(&sc->recv_io.posted.refill_work);
atomic_set(&sc->recv_io.credits.count, 0);
@@ -346,6 +364,8 @@ static __always_inline void smbdirect_socket_init(struct smbdirect_socket *sc)
atomic_set(&sc->mr_io.ready.count, 0);
init_waitqueue_head(&sc->mr_io.ready.wait_queue);
atomic_set(&sc->mr_io.used.count, 0);
+ INIT_WORK(&sc->mr_io.recovery_work, __smbdirect_socket_disabled_work);
+ disable_work_sync(&sc->mr_io.recovery_work);
init_waitqueue_head(&sc->mr_io.cleanup.wait_queue);
}
--
2.43.0
^ permalink raw reply related [flat|nested] 19+ messages in thread* [PATCH 03/18] smb: smbdirect: introduce smbdirect_socket.first_error
2025-09-21 21:44 [PATCH 00/18] smbdirect/client/server: improved error handling and other small improvements Stefan Metzmacher
2025-09-21 21:44 ` [PATCH 01/18] smb: smbdirect/client: introduce SMBDIRECT_SOCKET_ERROR Stefan Metzmacher
2025-09-21 21:44 ` [PATCH 02/18] smb: smbdirect: let smbdirect_socket_init() initialize all [delayed_]work_structs as disabled Stefan Metzmacher
@ 2025-09-21 21:44 ` Stefan Metzmacher
2025-09-21 21:44 ` [PATCH 04/18] smb: client: let smbd_disconnect_rdma_connection() set SMBDIRECT_SOCKET_ERROR Stefan Metzmacher
` (14 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Stefan Metzmacher @ 2025-09-21 21:44 UTC (permalink / raw)
To: linux-cifs, samba-technical
Cc: metze, Steve French, Tom Talpey, Long Li, Namjae Jeon,
Steve French
This will be used when a connected conection gets the first error.
Cc: Steve French <smfrench@gmail.com>
Cc: Tom Talpey <tom@talpey.com>
Cc: Long Li <longli@microsoft.com>
Cc: 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>
---
fs/smb/common/smbdirect/smbdirect_socket.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/fs/smb/common/smbdirect/smbdirect_socket.h b/fs/smb/common/smbdirect/smbdirect_socket.h
index 5e25abc02364..db22a1d0546b 100644
--- a/fs/smb/common/smbdirect/smbdirect_socket.h
+++ b/fs/smb/common/smbdirect/smbdirect_socket.h
@@ -83,6 +83,7 @@ enum smbdirect_keepalive_status {
struct smbdirect_socket {
enum smbdirect_socket_status status;
wait_queue_head_t status_wait;
+ int first_error;
/*
* This points to the workqueue to
--
2.43.0
^ permalink raw reply related [flat|nested] 19+ messages in thread* [PATCH 04/18] smb: client: let smbd_disconnect_rdma_connection() set SMBDIRECT_SOCKET_ERROR...
2025-09-21 21:44 [PATCH 00/18] smbdirect/client/server: improved error handling and other small improvements Stefan Metzmacher
` (2 preceding siblings ...)
2025-09-21 21:44 ` [PATCH 03/18] smb: smbdirect: introduce smbdirect_socket.first_error Stefan Metzmacher
@ 2025-09-21 21:44 ` Stefan Metzmacher
2025-09-21 21:44 ` [PATCH 05/18] smb: client: fill in smbdirect_socket.first_error on error Stefan Metzmacher
` (13 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Stefan Metzmacher @ 2025-09-21 21:44 UTC (permalink / raw)
To: linux-cifs, samba-technical
Cc: metze, Steve French, Tom Talpey, Long Li, Namjae Jeon,
Steve French
smbd_disconnect_rdma_connection() should turn the status into
an error state instead of leaving it as is until
smbd_disconnect_rdma_work() is running.
Cc: Steve French <smfrench@gmail.com>
Cc: Tom Talpey <tom@talpey.com>
Cc: Long Li <longli@microsoft.com>
Cc: 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>
---
fs/smb/client/smbdirect.c | 40 +++++++++++++++++++++++++++++++++++++++
1 file changed, 40 insertions(+)
diff --git a/fs/smb/client/smbdirect.c b/fs/smb/client/smbdirect.c
index 7e0d2ecaa37e..38934e330096 100644
--- a/fs/smb/client/smbdirect.c
+++ b/fs/smb/client/smbdirect.c
@@ -217,6 +217,46 @@ static void smbd_disconnect_rdma_work(struct work_struct *work)
static void smbd_disconnect_rdma_connection(struct smbdirect_socket *sc)
{
+ switch (sc->status) {
+ case SMBDIRECT_SOCKET_RESOLVE_ADDR_FAILED:
+ case SMBDIRECT_SOCKET_RESOLVE_ROUTE_FAILED:
+ case SMBDIRECT_SOCKET_RDMA_CONNECT_FAILED:
+ case SMBDIRECT_SOCKET_NEGOTIATE_FAILED:
+ case SMBDIRECT_SOCKET_ERROR:
+ case SMBDIRECT_SOCKET_DISCONNECTING:
+ case SMBDIRECT_SOCKET_DISCONNECTED:
+ case SMBDIRECT_SOCKET_DESTROYED:
+ /*
+ * Keep the current error status
+ */
+ break;
+
+ case SMBDIRECT_SOCKET_RESOLVE_ADDR_NEEDED:
+ case SMBDIRECT_SOCKET_RESOLVE_ADDR_RUNNING:
+ sc->status = SMBDIRECT_SOCKET_RESOLVE_ADDR_FAILED;
+ break;
+
+ case SMBDIRECT_SOCKET_RESOLVE_ROUTE_NEEDED:
+ case SMBDIRECT_SOCKET_RESOLVE_ROUTE_RUNNING:
+ sc->status = SMBDIRECT_SOCKET_RESOLVE_ROUTE_FAILED;
+ break;
+
+ case SMBDIRECT_SOCKET_RDMA_CONNECT_NEEDED:
+ case SMBDIRECT_SOCKET_RDMA_CONNECT_RUNNING:
+ sc->status = SMBDIRECT_SOCKET_RDMA_CONNECT_FAILED;
+ break;
+
+ case SMBDIRECT_SOCKET_NEGOTIATE_NEEDED:
+ case SMBDIRECT_SOCKET_NEGOTIATE_RUNNING:
+ sc->status = SMBDIRECT_SOCKET_NEGOTIATE_FAILED;
+ break;
+
+ case SMBDIRECT_SOCKET_CREATED:
+ case SMBDIRECT_SOCKET_CONNECTED:
+ sc->status = SMBDIRECT_SOCKET_ERROR;
+ break;
+ }
+
queue_work(sc->workqueue, &sc->disconnect_work);
}
--
2.43.0
^ permalink raw reply related [flat|nested] 19+ messages in thread* [PATCH 05/18] smb: client: fill in smbdirect_socket.first_error on error
2025-09-21 21:44 [PATCH 00/18] smbdirect/client/server: improved error handling and other small improvements Stefan Metzmacher
` (3 preceding siblings ...)
2025-09-21 21:44 ` [PATCH 04/18] smb: client: let smbd_disconnect_rdma_connection() set SMBDIRECT_SOCKET_ERROR Stefan Metzmacher
@ 2025-09-21 21:44 ` Stefan Metzmacher
2025-09-21 21:44 ` [PATCH 06/18] smb: client: let smbd_disconnect_rdma_connection() disable all work but disconnect_work Stefan Metzmacher
` (12 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Stefan Metzmacher @ 2025-09-21 21:44 UTC (permalink / raw)
To: linux-cifs, samba-technical
Cc: metze, Steve French, Tom Talpey, Long Li, Namjae Jeon,
Steve French
For now we just use -ECONNABORTED, but it will get more detailed
later.
Cc: Steve French <smfrench@gmail.com>
Cc: Tom Talpey <tom@talpey.com>
Cc: Long Li <longli@microsoft.com>
Cc: 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>
---
fs/smb/client/smbdirect.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/fs/smb/client/smbdirect.c b/fs/smb/client/smbdirect.c
index 38934e330096..73beb681ac0b 100644
--- a/fs/smb/client/smbdirect.c
+++ b/fs/smb/client/smbdirect.c
@@ -181,6 +181,9 @@ static void smbd_disconnect_rdma_work(struct work_struct *work)
disable_work(&sc->idle.immediate_work);
disable_delayed_work(&sc->idle.timer_work);
+ if (sc->first_error == 0)
+ sc->first_error = -ECONNABORTED;
+
switch (sc->status) {
case SMBDIRECT_SOCKET_NEGOTIATE_NEEDED:
case SMBDIRECT_SOCKET_NEGOTIATE_RUNNING:
@@ -217,6 +220,9 @@ static void smbd_disconnect_rdma_work(struct work_struct *work)
static void smbd_disconnect_rdma_connection(struct smbdirect_socket *sc)
{
+ if (sc->first_error == 0)
+ sc->first_error = -ECONNABORTED;
+
switch (sc->status) {
case SMBDIRECT_SOCKET_RESOLVE_ADDR_FAILED:
case SMBDIRECT_SOCKET_RESOLVE_ROUTE_FAILED:
--
2.43.0
^ permalink raw reply related [flat|nested] 19+ messages in thread* [PATCH 06/18] smb: client: let smbd_disconnect_rdma_connection() disable all work but disconnect_work
2025-09-21 21:44 [PATCH 00/18] smbdirect/client/server: improved error handling and other small improvements Stefan Metzmacher
` (4 preceding siblings ...)
2025-09-21 21:44 ` [PATCH 05/18] smb: client: fill in smbdirect_socket.first_error on error Stefan Metzmacher
@ 2025-09-21 21:44 ` Stefan Metzmacher
2025-09-21 21:44 ` [PATCH 07/18] smb: client: let smbd_{destroy,disconnect_rdma_{work,connection}}() wake up all wait queues Stefan Metzmacher
` (11 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Stefan Metzmacher @ 2025-09-21 21:44 UTC (permalink / raw)
To: linux-cifs, samba-technical
Cc: metze, Steve French, Tom Talpey, Long Li, Namjae Jeon,
Steve French
There's no point run these if we already know the connection
is broken.
Cc: Steve French <smfrench@gmail.com>
Cc: Tom Talpey <tom@talpey.com>
Cc: Long Li <longli@microsoft.com>
Cc: 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>
---
fs/smb/client/smbdirect.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/fs/smb/client/smbdirect.c b/fs/smb/client/smbdirect.c
index 73beb681ac0b..b39e60086c6a 100644
--- a/fs/smb/client/smbdirect.c
+++ b/fs/smb/client/smbdirect.c
@@ -220,6 +220,16 @@ static void smbd_disconnect_rdma_work(struct work_struct *work)
static void smbd_disconnect_rdma_connection(struct smbdirect_socket *sc)
{
+ /*
+ * make sure other work (than disconnect_work) is
+ * not queued again but here we don't block and avoid
+ * disable[_delayed]_work_sync()
+ */
+ disable_work(&sc->recv_io.posted.refill_work);
+ disable_work(&sc->mr_io.recovery_work);
+ disable_work(&sc->idle.immediate_work);
+ disable_delayed_work(&sc->idle.timer_work);
+
if (sc->first_error == 0)
sc->first_error = -ECONNABORTED;
--
2.43.0
^ permalink raw reply related [flat|nested] 19+ messages in thread* [PATCH 07/18] smb: client: let smbd_{destroy,disconnect_rdma_{work,connection}}() wake up all wait queues
2025-09-21 21:44 [PATCH 00/18] smbdirect/client/server: improved error handling and other small improvements Stefan Metzmacher
` (5 preceding siblings ...)
2025-09-21 21:44 ` [PATCH 06/18] smb: client: let smbd_disconnect_rdma_connection() disable all work but disconnect_work Stefan Metzmacher
@ 2025-09-21 21:44 ` Stefan Metzmacher
2025-09-21 21:44 ` [PATCH 08/18] smb: client: make consitent use of spin_lock_irq{save,restore}() in smbdirect.c Stefan Metzmacher
` (10 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Stefan Metzmacher @ 2025-09-21 21:44 UTC (permalink / raw)
To: linux-cifs, samba-technical
Cc: metze, Steve French, Tom Talpey, Long Li, Namjae Jeon,
Steve French
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>
Cc: 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>
---
fs/smb/client/smbdirect.c | 52 ++++++++++++++++++++++++++++++---------
1 file changed, 40 insertions(+), 12 deletions(-)
diff --git a/fs/smb/client/smbdirect.c b/fs/smb/client/smbdirect.c
index b39e60086c6a..00be4afaee52 100644
--- a/fs/smb/client/smbdirect.c
+++ b/fs/smb/client/smbdirect.c
@@ -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);
--
2.43.0
^ permalink raw reply related [flat|nested] 19+ messages in thread* [PATCH 08/18] smb: client: make consitent use of spin_lock_irq{save,restore}() in smbdirect.c
2025-09-21 21:44 [PATCH 00/18] smbdirect/client/server: improved error handling and other small improvements Stefan Metzmacher
` (6 preceding siblings ...)
2025-09-21 21:44 ` [PATCH 07/18] smb: client: let smbd_{destroy,disconnect_rdma_{work,connection}}() wake up all wait queues Stefan Metzmacher
@ 2025-09-21 21:44 ` Stefan Metzmacher
2025-09-21 21:44 ` [PATCH 09/18] smb: client: allocate smbdirect workqueue at the beginning of _smbd_get_connection() Stefan Metzmacher
` (9 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Stefan Metzmacher @ 2025-09-21 21:44 UTC (permalink / raw)
To: linux-cifs, samba-technical
Cc: metze, Steve French, Tom Talpey, Long Li, Namjae Jeon,
Steve French
There is a mix of using spin_lock(), spin_lock_irq() and
spin_lock_irqsave() and it seems at least enqueue_reassembly() was wrong
in using just spin_lock() as it's called via recv_done() from a SOFTIRQ
as we're using IB_POLL_SOFTIRQ.
And Documentation/kernel-hacking/locking.rst section
"Cheat Sheet For Locking" says:
- Otherwise (== data can be touched in an interrupt), use
spin_lock_irqsave() and
spin_unlock_irqrestore().
So in order to keep it simple and safe we use that version
now. It will help merging functions into common code and
have consistent locking in all cases.
Cc: Steve French <smfrench@gmail.com>
Cc: Tom Talpey <tom@talpey.com>
Cc: Long Li <longli@microsoft.com>
Cc: 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>
---
fs/smb/client/smbdirect.c | 26 +++++++++++++++-----------
1 file changed, 15 insertions(+), 11 deletions(-)
diff --git a/fs/smb/client/smbdirect.c b/fs/smb/client/smbdirect.c
index 00be4afaee52..5bc316248058 100644
--- a/fs/smb/client/smbdirect.c
+++ b/fs/smb/client/smbdirect.c
@@ -1397,7 +1397,9 @@ static void enqueue_reassembly(
struct smbdirect_recv_io *response,
int data_length)
{
- spin_lock(&sc->recv_io.reassembly.lock);
+ unsigned long flags;
+
+ spin_lock_irqsave(&sc->recv_io.reassembly.lock, flags);
list_add_tail(&response->list, &sc->recv_io.reassembly.list);
sc->recv_io.reassembly.queue_length++;
/*
@@ -1408,7 +1410,7 @@ static void enqueue_reassembly(
*/
virt_wmb();
sc->recv_io.reassembly.data_length += data_length;
- spin_unlock(&sc->recv_io.reassembly.lock);
+ spin_unlock_irqrestore(&sc->recv_io.reassembly.lock, flags);
sc->statistics.enqueue_reassembly_queue++;
}
@@ -2076,6 +2078,7 @@ int smbd_recv(struct smbd_connection *info, struct msghdr *msg)
if (sc->recv_io.reassembly.data_length >= size) {
int queue_length;
int queue_removed = 0;
+ unsigned long flags;
/*
* Need to make sure reassembly_data_length is read before
@@ -2135,11 +2138,11 @@ int smbd_recv(struct smbd_connection *info, struct msghdr *msg)
if (queue_length)
list_del(&response->list);
else {
- spin_lock_irq(
- &sc->recv_io.reassembly.lock);
+ spin_lock_irqsave(
+ &sc->recv_io.reassembly.lock, flags);
list_del(&response->list);
- spin_unlock_irq(
- &sc->recv_io.reassembly.lock);
+ spin_unlock_irqrestore(
+ &sc->recv_io.reassembly.lock, flags);
}
queue_removed++;
sc->statistics.dequeue_reassembly_queue++;
@@ -2157,10 +2160,10 @@ int smbd_recv(struct smbd_connection *info, struct msghdr *msg)
to_read, data_read, offset);
}
- spin_lock_irq(&sc->recv_io.reassembly.lock);
+ spin_lock_irqsave(&sc->recv_io.reassembly.lock, flags);
sc->recv_io.reassembly.data_length -= data_read;
sc->recv_io.reassembly.queue_length -= queue_removed;
- spin_unlock_irq(&sc->recv_io.reassembly.lock);
+ spin_unlock_irqrestore(&sc->recv_io.reassembly.lock, flags);
sc->recv_io.reassembly.first_entry_offset = offset;
log_read(INFO, "returning to thread data_read=%d reassembly_data_length=%d first_entry_offset=%d\n",
@@ -2432,6 +2435,7 @@ static int allocate_mr_list(struct smbdirect_socket *sc)
static struct smbdirect_mr_io *get_mr(struct smbdirect_socket *sc)
{
struct smbdirect_mr_io *ret;
+ unsigned long flags;
int rc;
again:
rc = wait_event_interruptible(sc->mr_io.ready.wait_queue,
@@ -2447,18 +2451,18 @@ static struct smbdirect_mr_io *get_mr(struct smbdirect_socket *sc)
return NULL;
}
- spin_lock(&sc->mr_io.all.lock);
+ spin_lock_irqsave(&sc->mr_io.all.lock, flags);
list_for_each_entry(ret, &sc->mr_io.all.list, list) {
if (ret->state == SMBDIRECT_MR_READY) {
ret->state = SMBDIRECT_MR_REGISTERED;
- spin_unlock(&sc->mr_io.all.lock);
+ spin_unlock_irqrestore(&sc->mr_io.all.lock, flags);
atomic_dec(&sc->mr_io.ready.count);
atomic_inc(&sc->mr_io.used.count);
return ret;
}
}
- spin_unlock(&sc->mr_io.all.lock);
+ spin_unlock_irqrestore(&sc->mr_io.all.lock, flags);
/*
* It is possible that we could fail to get MR because other processes may
* try to acquire a MR at the same time. If this is the case, retry it.
--
2.43.0
^ permalink raw reply related [flat|nested] 19+ messages in thread* [PATCH 09/18] smb: client: allocate smbdirect workqueue at the beginning of _smbd_get_connection()
2025-09-21 21:44 [PATCH 00/18] smbdirect/client/server: improved error handling and other small improvements Stefan Metzmacher
` (7 preceding siblings ...)
2025-09-21 21:44 ` [PATCH 08/18] smb: client: make consitent use of spin_lock_irq{save,restore}() in smbdirect.c Stefan Metzmacher
@ 2025-09-21 21:44 ` Stefan Metzmacher
2025-09-21 21:44 ` [PATCH 10/18] smb: client: defer calling ib_alloc_pd() after we are connected Stefan Metzmacher
` (8 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Stefan Metzmacher @ 2025-09-21 21:44 UTC (permalink / raw)
To: linux-cifs, samba-technical
Cc: metze, Steve French, Tom Talpey, Long Li, Namjae Jeon,
Steve French
This will simplify further changes when moving to common code.
Cc: Steve French <smfrench@gmail.com>
Cc: Tom Talpey <tom@talpey.com>
Cc: Long Li <longli@microsoft.com>
Cc: 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>
---
fs/smb/client/smbdirect.c | 27 ++++++++++++++-------------
1 file changed, 14 insertions(+), 13 deletions(-)
diff --git a/fs/smb/client/smbdirect.c b/fs/smb/client/smbdirect.c
index 5bc316248058..e6012523e422 100644
--- a/fs/smb/client/smbdirect.c
+++ b/fs/smb/client/smbdirect.c
@@ -1703,10 +1703,9 @@ int smbd_reconnect(struct TCP_Server_Info *server)
return -ENOENT;
}
-static void destroy_caches_and_workqueue(struct smbdirect_socket *sc)
+static void destroy_caches(struct smbdirect_socket *sc)
{
destroy_receive_buffers(sc);
- destroy_workqueue(sc->workqueue);
mempool_destroy(sc->recv_io.mem.pool);
kmem_cache_destroy(sc->recv_io.mem.cache);
mempool_destroy(sc->send_io.mem.pool);
@@ -1714,7 +1713,7 @@ static void destroy_caches_and_workqueue(struct smbdirect_socket *sc)
}
#define MAX_NAME_LEN 80
-static int allocate_caches_and_workqueue(struct smbdirect_socket *sc)
+static int allocate_caches(struct smbdirect_socket *sc)
{
struct smbdirect_socket_parameters *sp = &sc->parameters;
char name[MAX_NAME_LEN];
@@ -1760,21 +1759,14 @@ static int allocate_caches_and_workqueue(struct smbdirect_socket *sc)
if (!sc->recv_io.mem.pool)
goto out3;
- scnprintf(name, MAX_NAME_LEN, "smbd_%p", sc);
- sc->workqueue = create_workqueue(name);
- if (!sc->workqueue)
- goto out4;
-
rc = allocate_receive_buffers(sc, sp->recv_credit_max);
if (rc) {
log_rdma_event(ERR, "failed to allocate receive buffers\n");
- goto out5;
+ goto out4;
}
return 0;
-out5:
- destroy_workqueue(sc->workqueue);
out4:
mempool_destroy(sc->recv_io.mem.pool);
out3:
@@ -1799,12 +1791,19 @@ static struct smbd_connection *_smbd_get_connection(
struct sockaddr_in *addr_in = (struct sockaddr_in *) dstaddr;
struct ib_port_immutable port_immutable;
__be32 ird_ord_hdr[2];
+ char wq_name[80];
+ struct workqueue_struct *workqueue;
info = kzalloc(sizeof(struct smbd_connection), GFP_KERNEL);
if (!info)
return NULL;
sc = &info->socket;
+ scnprintf(wq_name, ARRAY_SIZE(wq_name), "smbd_%p", sc);
+ workqueue = create_workqueue(wq_name);
+ if (!workqueue)
+ goto create_wq_failed;
smbdirect_socket_init(sc);
+ sc->workqueue = workqueue;
sp = &sc->parameters;
INIT_WORK(&sc->disconnect_work, smbd_disconnect_rdma_work);
@@ -1946,7 +1945,7 @@ static struct smbd_connection *_smbd_get_connection(
log_rdma_event(INFO, "rdma_connect connected\n");
- rc = allocate_caches_and_workqueue(sc);
+ rc = allocate_caches(sc);
if (rc) {
log_rdma_event(ERR, "cache allocation failed\n");
goto allocate_cache_failed;
@@ -1986,7 +1985,7 @@ static struct smbd_connection *_smbd_get_connection(
negotiation_failed:
disable_delayed_work_sync(&sc->idle.timer_work);
- destroy_caches_and_workqueue(sc);
+ destroy_caches(sc);
sc->status = SMBDIRECT_SOCKET_NEGOTIATE_FAILED;
rdma_disconnect(sc->rdma.cm_id);
wait_event(sc->status_wait,
@@ -2008,6 +2007,8 @@ static struct smbd_connection *_smbd_get_connection(
rdma_destroy_id(sc->rdma.cm_id);
create_id_failed:
+ destroy_workqueue(sc->workqueue);
+create_wq_failed:
kfree(info);
return NULL;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 19+ messages in thread* [PATCH 10/18] smb: client: defer calling ib_alloc_pd() after we are connected
2025-09-21 21:44 [PATCH 00/18] smbdirect/client/server: improved error handling and other small improvements Stefan Metzmacher
` (8 preceding siblings ...)
2025-09-21 21:44 ` [PATCH 09/18] smb: client: allocate smbdirect workqueue at the beginning of _smbd_get_connection() Stefan Metzmacher
@ 2025-09-21 21:44 ` Stefan Metzmacher
2025-09-21 21:44 ` [PATCH 11/18] smb: client: let smbd_post_send_iter() call ib_dma_map_single() for the header first Stefan Metzmacher
` (7 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Stefan Metzmacher @ 2025-09-21 21:44 UTC (permalink / raw)
To: linux-cifs, samba-technical
Cc: metze, Steve French, Tom Talpey, Long Li, Namjae Jeon,
Steve French
The protection domain is not needed until we're connected.
This makes further changes easier to follow...
Cc: Steve French <smfrench@gmail.com>
Cc: Tom Talpey <tom@talpey.com>
Cc: Long Li <longli@microsoft.com>
Cc: 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>
---
fs/smb/client/smbdirect.c | 19 +++++++++++--------
1 file changed, 11 insertions(+), 8 deletions(-)
diff --git a/fs/smb/client/smbdirect.c b/fs/smb/client/smbdirect.c
index e6012523e422..d5e2b3009294 100644
--- a/fs/smb/client/smbdirect.c
+++ b/fs/smb/client/smbdirect.c
@@ -926,13 +926,6 @@ static int smbd_ia_open(
if (sc->ib.dev->attrs.kernel_cap_flags & IBK_SG_GAPS_REG)
sc->mr_io.type = IB_MR_TYPE_SG_GAPS;
- sc->ib.pd = ib_alloc_pd(sc->ib.dev, 0);
- if (IS_ERR(sc->ib.pd)) {
- rc = PTR_ERR(sc->ib.pd);
- log_rdma_event(ERR, "ib_alloc_pd() returned %d\n", rc);
- goto out2;
- }
-
return 0;
out2:
@@ -1858,6 +1851,14 @@ static struct smbd_connection *_smbd_get_connection(
goto config_failed;
}
+ sc->ib.pd = ib_alloc_pd(sc->ib.dev, 0);
+ if (IS_ERR(sc->ib.pd)) {
+ rc = PTR_ERR(sc->ib.pd);
+ sc->ib.pd = NULL;
+ log_rdma_event(ERR, "ib_alloc_pd() returned %d\n", rc);
+ goto alloc_pd_failed;
+ }
+
sc->ib.send_cq =
ib_alloc_cq_any(sc->ib.dev, sc,
sp->send_credit_target, IB_POLL_SOFTIRQ);
@@ -2002,8 +2003,10 @@ static struct smbd_connection *_smbd_get_connection(
if (sc->ib.recv_cq)
ib_free_cq(sc->ib.recv_cq);
-config_failed:
ib_dealloc_pd(sc->ib.pd);
+
+alloc_pd_failed:
+config_failed:
rdma_destroy_id(sc->rdma.cm_id);
create_id_failed:
--
2.43.0
^ permalink raw reply related [flat|nested] 19+ messages in thread* [PATCH 11/18] smb: client: let smbd_post_send_iter() call ib_dma_map_single() for the header first
2025-09-21 21:44 [PATCH 00/18] smbdirect/client/server: improved error handling and other small improvements Stefan Metzmacher
` (9 preceding siblings ...)
2025-09-21 21:44 ` [PATCH 10/18] smb: client: defer calling ib_alloc_pd() after we are connected Stefan Metzmacher
@ 2025-09-21 21:44 ` Stefan Metzmacher
2025-09-21 21:44 ` [PATCH 12/18] smb: server: let smb_direct_disconnect_rdma_connection() set SMBDIRECT_SOCKET_ERROR Stefan Metzmacher
` (6 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Stefan Metzmacher @ 2025-09-21 21:44 UTC (permalink / raw)
To: linux-cifs, samba-technical
Cc: metze, Steve French, Tom Talpey, Long Li, Namjae Jeon,
Steve French
This will simplify further changes, the important part is that
request->num_sge >= 1 is only set if request->sge[0].* is valid.
Note that ib_dma_sync_single_for_device() is called in
smbd_post_send() for each sge, so the device will still
see the packet header even if it's modified after calling
ib_dma_map_single().
Cc: Steve French <smfrench@gmail.com>
Cc: Tom Talpey <tom@talpey.com>
Cc: Long Li <longli@microsoft.com>
Cc: 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>
---
fs/smb/client/smbdirect.c | 43 +++++++++++++++++++--------------------
1 file changed, 21 insertions(+), 22 deletions(-)
diff --git a/fs/smb/client/smbdirect.c b/fs/smb/client/smbdirect.c
index d5e2b3009294..0b93e54565f6 100644
--- a/fs/smb/client/smbdirect.c
+++ b/fs/smb/client/smbdirect.c
@@ -1158,10 +1158,30 @@ static int smbd_post_send_iter(struct smbdirect_socket *sc,
request->socket = sc;
memset(request->sge, 0, sizeof(request->sge));
+ /* Map the packet to DMA */
+ header_length = sizeof(struct smbdirect_data_transfer);
+ /* If this is a packet without payload, don't send padding */
+ if (!iter)
+ header_length = offsetof(struct smbdirect_data_transfer, padding);
+
+ packet = smbdirect_send_io_payload(request);
+ request->sge[0].addr = ib_dma_map_single(sc->ib.dev,
+ (void *)packet,
+ header_length,
+ DMA_TO_DEVICE);
+ if (ib_dma_mapping_error(sc->ib.dev, request->sge[0].addr)) {
+ rc = -EIO;
+ goto err_dma;
+ }
+
+ request->sge[0].length = header_length;
+ request->sge[0].lkey = sc->ib.pd->local_dma_lkey;
+ request->num_sge = 1;
+
/* Fill in the data payload to find out how much data we can add */
if (iter) {
struct smb_extract_to_rdma extract = {
- .nr_sge = 1,
+ .nr_sge = request->num_sge,
.max_sge = SMBDIRECT_SEND_IO_MAX_SGE,
.sge = request->sge,
.device = sc->ib.dev,
@@ -1180,11 +1200,9 @@ static int smbd_post_send_iter(struct smbdirect_socket *sc,
*_remaining_data_length -= data_length;
} else {
data_length = 0;
- request->num_sge = 1;
}
/* Fill in the packet header */
- packet = smbdirect_send_io_payload(request);
packet->credits_requested = cpu_to_le16(sp->send_credit_target);
new_credits = manage_credits_prior_sending(sc);
@@ -1211,25 +1229,6 @@ static int smbd_post_send_iter(struct smbdirect_socket *sc,
le32_to_cpu(packet->data_length),
le32_to_cpu(packet->remaining_data_length));
- /* Map the packet to DMA */
- header_length = sizeof(struct smbdirect_data_transfer);
- /* If this is a packet without payload, don't send padding */
- if (!data_length)
- header_length = offsetof(struct smbdirect_data_transfer, padding);
-
- request->sge[0].addr = ib_dma_map_single(sc->ib.dev,
- (void *)packet,
- header_length,
- DMA_TO_DEVICE);
- if (ib_dma_mapping_error(sc->ib.dev, request->sge[0].addr)) {
- rc = -EIO;
- request->sge[0].addr = 0;
- goto err_dma;
- }
-
- request->sge[0].length = header_length;
- request->sge[0].lkey = sc->ib.pd->local_dma_lkey;
-
rc = smbd_post_send(sc, request);
if (!rc)
return 0;
--
2.43.0
^ permalink raw reply related [flat|nested] 19+ messages in thread* [PATCH 12/18] smb: server: let smb_direct_disconnect_rdma_connection() set SMBDIRECT_SOCKET_ERROR...
2025-09-21 21:44 [PATCH 00/18] smbdirect/client/server: improved error handling and other small improvements Stefan Metzmacher
` (10 preceding siblings ...)
2025-09-21 21:44 ` [PATCH 11/18] smb: client: let smbd_post_send_iter() call ib_dma_map_single() for the header first Stefan Metzmacher
@ 2025-09-21 21:44 ` Stefan Metzmacher
2025-09-21 21:45 ` [PATCH 13/18] smb: server: fill in smbdirect_socket.first_error on error Stefan Metzmacher
` (5 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Stefan Metzmacher @ 2025-09-21 21:44 UTC (permalink / raw)
To: linux-cifs, samba-technical
Cc: metze, Steve French, Tom Talpey, Long Li, Namjae Jeon,
Steve French
smb_direct_disconnect_rdma_connection() should turn the status into
an error state instead of leaving it as is until
smb_direct_disconnect_rdma_work() is running.
Cc: Steve French <smfrench@gmail.com>
Cc: Tom Talpey <tom@talpey.com>
Cc: Long Li <longli@microsoft.com>
Cc: 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>
---
fs/smb/server/transport_rdma.c | 40 ++++++++++++++++++++++++++++++++++
1 file changed, 40 insertions(+)
diff --git a/fs/smb/server/transport_rdma.c b/fs/smb/server/transport_rdma.c
index a61898ea2a3f..67345c58bfe9 100644
--- a/fs/smb/server/transport_rdma.c
+++ b/fs/smb/server/transport_rdma.c
@@ -259,6 +259,46 @@ static void smb_direct_disconnect_rdma_work(struct work_struct *work)
static void
smb_direct_disconnect_rdma_connection(struct smbdirect_socket *sc)
{
+ switch (sc->status) {
+ case SMBDIRECT_SOCKET_RESOLVE_ADDR_FAILED:
+ case SMBDIRECT_SOCKET_RESOLVE_ROUTE_FAILED:
+ case SMBDIRECT_SOCKET_RDMA_CONNECT_FAILED:
+ case SMBDIRECT_SOCKET_NEGOTIATE_FAILED:
+ case SMBDIRECT_SOCKET_ERROR:
+ case SMBDIRECT_SOCKET_DISCONNECTING:
+ case SMBDIRECT_SOCKET_DISCONNECTED:
+ case SMBDIRECT_SOCKET_DESTROYED:
+ /*
+ * Keep the current error status
+ */
+ break;
+
+ case SMBDIRECT_SOCKET_RESOLVE_ADDR_NEEDED:
+ case SMBDIRECT_SOCKET_RESOLVE_ADDR_RUNNING:
+ sc->status = SMBDIRECT_SOCKET_RESOLVE_ADDR_FAILED;
+ break;
+
+ case SMBDIRECT_SOCKET_RESOLVE_ROUTE_NEEDED:
+ case SMBDIRECT_SOCKET_RESOLVE_ROUTE_RUNNING:
+ sc->status = SMBDIRECT_SOCKET_RESOLVE_ROUTE_FAILED;
+ break;
+
+ case SMBDIRECT_SOCKET_RDMA_CONNECT_NEEDED:
+ case SMBDIRECT_SOCKET_RDMA_CONNECT_RUNNING:
+ sc->status = SMBDIRECT_SOCKET_RDMA_CONNECT_FAILED;
+ break;
+
+ case SMBDIRECT_SOCKET_NEGOTIATE_NEEDED:
+ case SMBDIRECT_SOCKET_NEGOTIATE_RUNNING:
+ sc->status = SMBDIRECT_SOCKET_NEGOTIATE_FAILED;
+ break;
+
+ case SMBDIRECT_SOCKET_CREATED:
+ case SMBDIRECT_SOCKET_CONNECTED:
+ sc->status = SMBDIRECT_SOCKET_ERROR;
+ break;
+ }
+
queue_work(sc->workqueue, &sc->disconnect_work);
}
--
2.43.0
^ permalink raw reply related [flat|nested] 19+ messages in thread* [PATCH 13/18] smb: server: fill in smbdirect_socket.first_error on error
2025-09-21 21:44 [PATCH 00/18] smbdirect/client/server: improved error handling and other small improvements Stefan Metzmacher
` (11 preceding siblings ...)
2025-09-21 21:44 ` [PATCH 12/18] smb: server: let smb_direct_disconnect_rdma_connection() set SMBDIRECT_SOCKET_ERROR Stefan Metzmacher
@ 2025-09-21 21:45 ` Stefan Metzmacher
2025-09-21 21:45 ` [PATCH 14/18] smb: server: let smb_direct_disconnect_rdma_connection() disable all work but disconnect_work Stefan Metzmacher
` (4 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Stefan Metzmacher @ 2025-09-21 21:45 UTC (permalink / raw)
To: linux-cifs, samba-technical
Cc: metze, Namjae Jeon, Steve French, Tom Talpey, Steve French
For now we just use -ECONNABORTED, but it will get more detailed
later.
Cc: Namjae Jeon <linkinjeon@kernel.org>
Cc: Steve French <smfrench@gmail.com>
Cc: Tom Talpey <tom@talpey.com>
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>
---
fs/smb/server/transport_rdma.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/fs/smb/server/transport_rdma.c b/fs/smb/server/transport_rdma.c
index 67345c58bfe9..44fa0af21b45 100644
--- a/fs/smb/server/transport_rdma.c
+++ b/fs/smb/server/transport_rdma.c
@@ -222,6 +222,9 @@ static void smb_direct_disconnect_rdma_work(struct work_struct *work)
disable_delayed_work(&sc->idle.timer_work);
disable_work(&sc->idle.immediate_work);
+ if (sc->first_error == 0)
+ sc->first_error = -ECONNABORTED;
+
switch (sc->status) {
case SMBDIRECT_SOCKET_NEGOTIATE_NEEDED:
case SMBDIRECT_SOCKET_NEGOTIATE_RUNNING:
@@ -259,6 +262,9 @@ static void smb_direct_disconnect_rdma_work(struct work_struct *work)
static void
smb_direct_disconnect_rdma_connection(struct smbdirect_socket *sc)
{
+ if (sc->first_error == 0)
+ sc->first_error = -ECONNABORTED;
+
switch (sc->status) {
case SMBDIRECT_SOCKET_RESOLVE_ADDR_FAILED:
case SMBDIRECT_SOCKET_RESOLVE_ROUTE_FAILED:
--
2.43.0
^ permalink raw reply related [flat|nested] 19+ messages in thread* [PATCH 14/18] smb: server: let smb_direct_disconnect_rdma_connection() disable all work but disconnect_work
2025-09-21 21:44 [PATCH 00/18] smbdirect/client/server: improved error handling and other small improvements Stefan Metzmacher
` (12 preceding siblings ...)
2025-09-21 21:45 ` [PATCH 13/18] smb: server: fill in smbdirect_socket.first_error on error Stefan Metzmacher
@ 2025-09-21 21:45 ` Stefan Metzmacher
2025-09-21 21:45 ` [PATCH 15/18] smb: server: let {free_transport,smb_direct_disconnect_rdma_{work,connection}}() wake up all wait queues Stefan Metzmacher
` (3 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Stefan Metzmacher @ 2025-09-21 21:45 UTC (permalink / raw)
To: linux-cifs, samba-technical
Cc: metze, Namjae Jeon, Steve French, Tom Talpey, Steve French
There's no point run these if we already know the connection
is broken.
Cc: Namjae Jeon <linkinjeon@kernel.org>
Cc: Steve French <smfrench@gmail.com>
Cc: Tom Talpey <tom@talpey.com>
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>
---
fs/smb/server/transport_rdma.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/fs/smb/server/transport_rdma.c b/fs/smb/server/transport_rdma.c
index 44fa0af21b45..cd4398ae8b98 100644
--- a/fs/smb/server/transport_rdma.c
+++ b/fs/smb/server/transport_rdma.c
@@ -262,6 +262,15 @@ static void smb_direct_disconnect_rdma_work(struct work_struct *work)
static void
smb_direct_disconnect_rdma_connection(struct smbdirect_socket *sc)
{
+ /*
+ * make sure other work (than disconnect_work) is
+ * not queued again but here we don't block and avoid
+ * disable[_delayed]_work_sync()
+ */
+ disable_work(&sc->recv_io.posted.refill_work);
+ disable_work(&sc->idle.immediate_work);
+ disable_delayed_work(&sc->idle.timer_work);
+
if (sc->first_error == 0)
sc->first_error = -ECONNABORTED;
--
2.43.0
^ permalink raw reply related [flat|nested] 19+ messages in thread* [PATCH 15/18] smb: server: let {free_transport,smb_direct_disconnect_rdma_{work,connection}}() wake up all wait queues
2025-09-21 21:44 [PATCH 00/18] smbdirect/client/server: improved error handling and other small improvements Stefan Metzmacher
` (13 preceding siblings ...)
2025-09-21 21:45 ` [PATCH 14/18] smb: server: let smb_direct_disconnect_rdma_connection() disable all work but disconnect_work Stefan Metzmacher
@ 2025-09-21 21:45 ` Stefan Metzmacher
2025-09-21 21:45 ` [PATCH 16/18] smb: server: make consitent use of spin_lock_irq{save,restore}() in transport_rdma.c Stefan Metzmacher
` (2 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Stefan Metzmacher @ 2025-09-21 21:45 UTC (permalink / raw)
To: linux-cifs, samba-technical
Cc: metze, Namjae Jeon, Steve French, Tom Talpey, Steve French
This is important in order to let all waiters notice a broken connection.
We also go via smb_direct_disconnect_rdma_{work,connection}() for broken
connections.
Cc: Namjae Jeon <linkinjeon@kernel.org>
Cc: Steve French <smfrench@gmail.com>
Cc: Tom Talpey <tom@talpey.com>
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>
---
fs/smb/server/transport_rdma.c | 40 +++++++++++++++++++++++++++++-----
1 file changed, 34 insertions(+), 6 deletions(-)
diff --git a/fs/smb/server/transport_rdma.c b/fs/smb/server/transport_rdma.c
index cd4398ae8b98..ba4dfdcb321a 100644
--- a/fs/smb/server/transport_rdma.c
+++ b/fs/smb/server/transport_rdma.c
@@ -207,6 +207,19 @@ static struct smbdirect_recv_io *get_first_reassembly(struct smbdirect_socket *s
return NULL;
}
+static void smb_direct_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.zero_wait_queue);
+ wake_up_all(&sc->recv_io.reassembly.wait_queue);
+ wake_up_all(&sc->rw_io.credits.wait_queue);
+}
+
static void smb_direct_disconnect_rdma_work(struct work_struct *work)
{
struct smbdirect_socket *sc =
@@ -257,6 +270,12 @@ static void smb_direct_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.
+ */
+ smb_direct_disconnect_wake_up_all(sc);
}
static void
@@ -314,6 +333,12 @@ smb_direct_disconnect_rdma_connection(struct smbdirect_socket *sc)
break;
}
+ /*
+ * Wake up all waiters in all wait queues
+ * in order to notice the broken connection.
+ */
+ smb_direct_disconnect_wake_up_all(sc);
+
queue_work(sc->workqueue, &sc->disconnect_work);
}
@@ -421,8 +446,14 @@ static void free_transport(struct smb_direct_transport *t)
sc->status == SMBDIRECT_SOCKET_DISCONNECTED);
}
- wake_up_all(&sc->send_io.credits.wait_queue);
- wake_up_all(&sc->send_io.pending.zero_wait_queue);
+ /*
+ * Wake up all waiters in all wait queues
+ * in order to notice the broken connection.
+ *
+ * Most likely this was already called via
+ * smb_direct_disconnect_rdma_work(), but call it again...
+ */
+ smb_direct_disconnect_wake_up_all(sc);
disable_work_sync(&sc->recv_io.posted.refill_work);
disable_delayed_work_sync(&sc->idle.timer_work);
@@ -1644,14 +1675,11 @@ static int smb_direct_cm_handler(struct rdma_cm_id *cm_id,
sc->status = SMBDIRECT_SOCKET_DISCONNECTED;
smb_direct_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;
}
case RDMA_CM_EVENT_CONNECT_ERROR: {
sc->status = SMBDIRECT_SOCKET_DISCONNECTED;
- wake_up_all(&sc->status_wait);
+ smb_direct_disconnect_rdma_work(&sc->disconnect_work);
break;
}
default:
--
2.43.0
^ permalink raw reply related [flat|nested] 19+ messages in thread* [PATCH 16/18] smb: server: make consitent use of spin_lock_irq{save,restore}() in transport_rdma.c
2025-09-21 21:44 [PATCH 00/18] smbdirect/client/server: improved error handling and other small improvements Stefan Metzmacher
` (14 preceding siblings ...)
2025-09-21 21:45 ` [PATCH 15/18] smb: server: let {free_transport,smb_direct_disconnect_rdma_{work,connection}}() wake up all wait queues Stefan Metzmacher
@ 2025-09-21 21:45 ` Stefan Metzmacher
2025-09-21 21:45 ` [PATCH 17/18] smb: server: make use of ib_alloc_cq_any() instead of ib_alloc_cq() Stefan Metzmacher
2025-09-21 21:45 ` [PATCH 18/18] smb: server: let smb_direct_flush_send_list() invalidate a remote key first Stefan Metzmacher
17 siblings, 0 replies; 19+ messages in thread
From: Stefan Metzmacher @ 2025-09-21 21:45 UTC (permalink / raw)
To: linux-cifs, samba-technical
Cc: metze, Namjae Jeon, Steve French, Tom Talpey, Steve French
There is a mix of using spin_lock() and spin_lock_irq(), which
is confusing as IB_POLL_WORKQUEUE is used and no code would
be called from any interrupt. So using spin_lock() or even
mutexes would be ok.
But we'll soon share common code with the client, which uses
IB_POLL_SOFTIRQ.
And Documentation/kernel-hacking/locking.rst section
"Cheat Sheet For Locking" says:
- Otherwise (== data can be touched in an interrupt), use
spin_lock_irqsave() and
spin_unlock_irqrestore().
So in order to keep it simple and safe we use that version
now. It will help merging functions into common code and
have consistent locking in all cases.
Cc: Namjae Jeon <linkinjeon@kernel.org>
Cc: Steve French <smfrench@gmail.com>
Cc: Tom Talpey <tom@talpey.com>
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>
---
fs/smb/server/transport_rdma.c | 39 +++++++++++++++++++++-------------
1 file changed, 24 insertions(+), 15 deletions(-)
diff --git a/fs/smb/server/transport_rdma.c b/fs/smb/server/transport_rdma.c
index ba4dfdcb321a..f9734d7025b4 100644
--- a/fs/smb/server/transport_rdma.c
+++ b/fs/smb/server/transport_rdma.c
@@ -150,21 +150,24 @@ static struct
smbdirect_recv_io *get_free_recvmsg(struct smbdirect_socket *sc)
{
struct smbdirect_recv_io *recvmsg = NULL;
+ unsigned long flags;
- spin_lock(&sc->recv_io.free.lock);
+ spin_lock_irqsave(&sc->recv_io.free.lock, flags);
if (!list_empty(&sc->recv_io.free.list)) {
recvmsg = list_first_entry(&sc->recv_io.free.list,
struct smbdirect_recv_io,
list);
list_del(&recvmsg->list);
}
- spin_unlock(&sc->recv_io.free.lock);
+ spin_unlock_irqrestore(&sc->recv_io.free.lock, flags);
return recvmsg;
}
static void put_recvmsg(struct smbdirect_socket *sc,
struct smbdirect_recv_io *recvmsg)
{
+ unsigned long flags;
+
if (likely(recvmsg->sge.length != 0)) {
ib_dma_unmap_single(sc->ib.dev,
recvmsg->sge.addr,
@@ -173,9 +176,9 @@ static void put_recvmsg(struct smbdirect_socket *sc,
recvmsg->sge.length = 0;
}
- spin_lock(&sc->recv_io.free.lock);
+ spin_lock_irqsave(&sc->recv_io.free.lock, flags);
list_add(&recvmsg->list, &sc->recv_io.free.list);
- spin_unlock(&sc->recv_io.free.lock);
+ spin_unlock_irqrestore(&sc->recv_io.free.lock, flags);
queue_work(sc->workqueue, &sc->recv_io.posted.refill_work);
}
@@ -184,7 +187,9 @@ static void enqueue_reassembly(struct smbdirect_socket *sc,
struct smbdirect_recv_io *recvmsg,
int data_length)
{
- spin_lock(&sc->recv_io.reassembly.lock);
+ unsigned long flags;
+
+ spin_lock_irqsave(&sc->recv_io.reassembly.lock, flags);
list_add_tail(&recvmsg->list, &sc->recv_io.reassembly.list);
sc->recv_io.reassembly.queue_length++;
/*
@@ -195,7 +200,7 @@ static void enqueue_reassembly(struct smbdirect_socket *sc,
*/
virt_wmb();
sc->recv_io.reassembly.data_length += data_length;
- spin_unlock(&sc->recv_io.reassembly.lock);
+ spin_unlock_irqrestore(&sc->recv_io.reassembly.lock, flags);
}
static struct smbdirect_recv_io *get_first_reassembly(struct smbdirect_socket *sc)
@@ -468,14 +473,16 @@ static void free_transport(struct smb_direct_transport *t)
ksmbd_debug(RDMA, "drain the reassembly queue\n");
do {
- spin_lock(&sc->recv_io.reassembly.lock);
+ unsigned long flags;
+
+ spin_lock_irqsave(&sc->recv_io.reassembly.lock, flags);
recvmsg = get_first_reassembly(sc);
if (recvmsg) {
list_del(&recvmsg->list);
- spin_unlock(&sc->recv_io.reassembly.lock);
+ spin_unlock_irqrestore(&sc->recv_io.reassembly.lock, flags);
put_recvmsg(sc, recvmsg);
} else {
- spin_unlock(&sc->recv_io.reassembly.lock);
+ spin_unlock_irqrestore(&sc->recv_io.reassembly.lock, flags);
}
} while (recvmsg);
sc->recv_io.reassembly.data_length = 0;
@@ -768,6 +775,7 @@ static int smb_direct_read(struct ksmbd_transport *t, char *buf,
if (sc->recv_io.reassembly.data_length >= size) {
int queue_length;
int queue_removed = 0;
+ unsigned long flags;
/*
* Need to make sure reassembly_data_length is read before
@@ -823,9 +831,9 @@ static int smb_direct_read(struct ksmbd_transport *t, char *buf,
if (queue_length) {
list_del(&recvmsg->list);
} else {
- spin_lock_irq(&sc->recv_io.reassembly.lock);
+ spin_lock_irqsave(&sc->recv_io.reassembly.lock, flags);
list_del(&recvmsg->list);
- spin_unlock_irq(&sc->recv_io.reassembly.lock);
+ spin_unlock_irqrestore(&sc->recv_io.reassembly.lock, flags);
}
queue_removed++;
put_recvmsg(sc, recvmsg);
@@ -838,10 +846,10 @@ static int smb_direct_read(struct ksmbd_transport *t, char *buf,
data_read += to_copy;
}
- spin_lock_irq(&sc->recv_io.reassembly.lock);
+ spin_lock_irqsave(&sc->recv_io.reassembly.lock, flags);
sc->recv_io.reassembly.data_length -= data_read;
sc->recv_io.reassembly.queue_length -= queue_removed;
- spin_unlock_irq(&sc->recv_io.reassembly.lock);
+ spin_unlock_irqrestore(&sc->recv_io.reassembly.lock, flags);
sc->recv_io.reassembly.first_entry_offset = offset;
ksmbd_debug(RDMA,
@@ -2107,6 +2115,7 @@ static int smb_direct_prepare(struct ksmbd_transport *t)
struct smbdirect_socket_parameters *sp = &sc->parameters;
struct smbdirect_recv_io *recvmsg;
struct smbdirect_negotiate_req *req;
+ unsigned long flags;
int ret;
/*
@@ -2153,10 +2162,10 @@ static int smb_direct_prepare(struct ksmbd_transport *t)
ret = smb_direct_send_negotiate_response(sc, ret);
out:
- spin_lock_irq(&sc->recv_io.reassembly.lock);
+ spin_lock_irqsave(&sc->recv_io.reassembly.lock, flags);
sc->recv_io.reassembly.queue_length--;
list_del(&recvmsg->list);
- spin_unlock_irq(&sc->recv_io.reassembly.lock);
+ spin_unlock_irqrestore(&sc->recv_io.reassembly.lock, flags);
put_recvmsg(sc, recvmsg);
return ret;
--
2.43.0
^ permalink raw reply related [flat|nested] 19+ messages in thread* [PATCH 17/18] smb: server: make use of ib_alloc_cq_any() instead of ib_alloc_cq()
2025-09-21 21:44 [PATCH 00/18] smbdirect/client/server: improved error handling and other small improvements Stefan Metzmacher
` (15 preceding siblings ...)
2025-09-21 21:45 ` [PATCH 16/18] smb: server: make consitent use of spin_lock_irq{save,restore}() in transport_rdma.c Stefan Metzmacher
@ 2025-09-21 21:45 ` Stefan Metzmacher
2025-09-21 21:45 ` [PATCH 18/18] smb: server: let smb_direct_flush_send_list() invalidate a remote key first Stefan Metzmacher
17 siblings, 0 replies; 19+ messages in thread
From: Stefan Metzmacher @ 2025-09-21 21:45 UTC (permalink / raw)
To: linux-cifs, samba-technical
Cc: metze, Namjae Jeon, Steve French, Tom Talpey, Steve French
commit 20cf4e026730 ("rdma: Enable ib_alloc_cq to spread work over a
device's comp_vectors") happened before ksmbd was upstreamed,
but after the out of tree ksmbd (a.k.a. cifsd) was developed.
So we still used ib_alloc_cq().
Cc: Namjae Jeon <linkinjeon@kernel.org>
Cc: Steve French <smfrench@gmail.com>
Cc: Tom Talpey <tom@talpey.com>
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>
---
fs/smb/server/transport_rdma.c | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/fs/smb/server/transport_rdma.c b/fs/smb/server/transport_rdma.c
index f9734d7025b4..e78347831d2f 100644
--- a/fs/smb/server/transport_rdma.c
+++ b/fs/smb/server/transport_rdma.c
@@ -2037,9 +2037,10 @@ static int smb_direct_create_qpair(struct smbdirect_socket *sc,
return ret;
}
- sc->ib.send_cq = ib_alloc_cq(sc->ib.dev, sc,
- sp->send_credit_target + cap->max_rdma_ctxs,
- 0, IB_POLL_WORKQUEUE);
+ sc->ib.send_cq = ib_alloc_cq_any(sc->ib.dev, sc,
+ sp->send_credit_target +
+ cap->max_rdma_ctxs,
+ IB_POLL_WORKQUEUE);
if (IS_ERR(sc->ib.send_cq)) {
pr_err("Can't create RDMA send CQ\n");
ret = PTR_ERR(sc->ib.send_cq);
@@ -2047,8 +2048,9 @@ static int smb_direct_create_qpair(struct smbdirect_socket *sc,
goto err;
}
- sc->ib.recv_cq = ib_alloc_cq(sc->ib.dev, sc,
- sp->recv_credit_max, 0, IB_POLL_WORKQUEUE);
+ sc->ib.recv_cq = ib_alloc_cq_any(sc->ib.dev, sc,
+ sp->recv_credit_max,
+ IB_POLL_WORKQUEUE);
if (IS_ERR(sc->ib.recv_cq)) {
pr_err("Can't create RDMA recv CQ\n");
ret = PTR_ERR(sc->ib.recv_cq);
--
2.43.0
^ permalink raw reply related [flat|nested] 19+ messages in thread* [PATCH 18/18] smb: server: let smb_direct_flush_send_list() invalidate a remote key first
2025-09-21 21:44 [PATCH 00/18] smbdirect/client/server: improved error handling and other small improvements Stefan Metzmacher
` (16 preceding siblings ...)
2025-09-21 21:45 ` [PATCH 17/18] smb: server: make use of ib_alloc_cq_any() instead of ib_alloc_cq() Stefan Metzmacher
@ 2025-09-21 21:45 ` Stefan Metzmacher
17 siblings, 0 replies; 19+ messages in thread
From: Stefan Metzmacher @ 2025-09-21 21:45 UTC (permalink / raw)
To: linux-cifs, samba-technical
Cc: metze, Namjae Jeon, Steve French, Tom Talpey, Steve French
If we want to invalidate a remote key we should do that as soon as
possible, so do it in the first send work request.
Cc: Namjae Jeon <linkinjeon@kernel.org>
Cc: Steve French <smfrench@gmail.com>
Cc: Tom Talpey <tom@talpey.com>
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>
---
fs/smb/server/transport_rdma.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/fs/smb/server/transport_rdma.c b/fs/smb/server/transport_rdma.c
index e78347831d2f..27e3fc5139cc 100644
--- a/fs/smb/server/transport_rdma.c
+++ b/fs/smb/server/transport_rdma.c
@@ -1017,12 +1017,15 @@ static int smb_direct_flush_send_list(struct smbdirect_socket *sc,
struct smbdirect_send_io,
sibling_list);
+ if (send_ctx->need_invalidate_rkey) {
+ first->wr.opcode = IB_WR_SEND_WITH_INV;
+ first->wr.ex.invalidate_rkey = send_ctx->remote_key;
+ send_ctx->need_invalidate_rkey = false;
+ send_ctx->remote_key = 0;
+ }
+
last->wr.send_flags = IB_SEND_SIGNALED;
last->wr.wr_cqe = &last->cqe;
- if (is_last && send_ctx->need_invalidate_rkey) {
- last->wr.opcode = IB_WR_SEND_WITH_INV;
- last->wr.ex.invalidate_rkey = send_ctx->remote_key;
- }
ret = smb_direct_post_send(sc, &first->wr);
if (!ret) {
--
2.43.0
^ permalink raw reply related [flat|nested] 19+ messages in thread