diff options
| author | Stefan Metzmacher <metze@samba.org> | 2025-08-27 15:54:35 +0200 | 
|---|---|---|
| committer | Steve French <stfrench@microsoft.com> | 2025-09-28 18:29:54 -0500 | 
| commit | 8aa23bae607e3bd5ced892afc26bfbe8945f531b (patch) | |
| tree | 539aa404cadaaff2dc5767d53d8e8ea1c3d92a0f /fs | |
| parent | 0491f26f8980d7a4028d3528df09e23f5a64adbe (diff) | |
smb: server: make consitent use of spin_lock_irq{save,restore}() in transport_rdma.c
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.
Acked-by: 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>
Diffstat (limited to 'fs')
| -rw-r--r-- | fs/smb/server/transport_rdma.c | 39 | 
1 files 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 @@ again:  	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 @@ again:  				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 @@ again:  			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; | 
