@@ -418,9 +418,6 @@ static struct smb_direct_transport *alloc_transport(struct rdma_cm_id *cm_id)
418418
419419 sc -> ib .dev = sc -> rdma .cm_id -> device ;
420420
421- INIT_WORK (& sc -> recv_io .posted .refill_work ,
422- smb_direct_post_recv_credits );
423- INIT_WORK (& sc -> idle .immediate_work , smb_direct_send_immediate_work );
424421 INIT_DELAYED_WORK (& sc -> idle .timer_work , smb_direct_idle_connection_timer );
425422
426423 conn = ksmbd_conn_alloc ();
@@ -469,6 +466,9 @@ static void free_transport(struct smb_direct_transport *t)
469466 disable_delayed_work_sync (& sc -> idle .timer_work );
470467 disable_work_sync (& sc -> idle .immediate_work );
471468
469+ if (sc -> rdma .cm_id )
470+ rdma_lock_handler (sc -> rdma .cm_id );
471+
472472 if (sc -> ib .qp ) {
473473 ib_drain_qp (sc -> ib .qp );
474474 sc -> ib .qp = NULL ;
@@ -497,8 +497,10 @@ static void free_transport(struct smb_direct_transport *t)
497497 ib_free_cq (sc -> ib .recv_cq );
498498 if (sc -> ib .pd )
499499 ib_dealloc_pd (sc -> ib .pd );
500- if (sc -> rdma .cm_id )
500+ if (sc -> rdma .cm_id ) {
501+ rdma_unlock_handler (sc -> rdma .cm_id );
501502 rdma_destroy_id (sc -> rdma .cm_id );
503+ }
502504
503505 smb_direct_destroy_pools (sc );
504506 ksmbd_conn_free (KSMBD_TRANS (t )-> conn );
@@ -1727,10 +1729,10 @@ static int smb_direct_cm_handler(struct rdma_cm_id *cm_id,
17271729 }
17281730 case RDMA_CM_EVENT_DEVICE_REMOVAL :
17291731 case RDMA_CM_EVENT_DISCONNECTED : {
1730- ib_drain_qp (sc -> ib .qp );
1731-
17321732 sc -> status = SMBDIRECT_SOCKET_DISCONNECTED ;
17331733 smb_direct_disconnect_rdma_work (& sc -> disconnect_work );
1734+ if (sc -> ib .qp )
1735+ ib_drain_qp (sc -> ib .qp );
17341736 break ;
17351737 }
17361738 case RDMA_CM_EVENT_CONNECT_ERROR : {
@@ -1904,7 +1906,6 @@ static int smb_direct_prepare_negotiation(struct smbdirect_socket *sc)
19041906 goto out_err ;
19051907 }
19061908
1907- smb_direct_post_recv_credits (& sc -> recv_io .posted .refill_work );
19081909 return 0 ;
19091910out_err :
19101911 put_recvmsg (sc , recvmsg );
@@ -2249,8 +2250,8 @@ static int smb_direct_prepare(struct ksmbd_transport *t)
22492250 return - ECONNABORTED ;
22502251
22512252 ret = smb_direct_check_recvmsg (recvmsg );
2252- if (ret == - ECONNABORTED )
2253- goto out ;
2253+ if (ret )
2254+ goto put ;
22542255
22552256 req = (struct smbdirect_negotiate_req * )recvmsg -> packet ;
22562257 sp -> max_recv_size = min_t (int , sp -> max_recv_size ,
@@ -2265,14 +2266,38 @@ static int smb_direct_prepare(struct ksmbd_transport *t)
22652266 sc -> recv_io .credits .target = min_t (u16 , sc -> recv_io .credits .target , sp -> recv_credit_max );
22662267 sc -> recv_io .credits .target = max_t (u16 , sc -> recv_io .credits .target , 1 );
22672268
2268- ret = smb_direct_send_negotiate_response (sc , ret );
2269- out :
2269+ put :
22702270 spin_lock_irqsave (& sc -> recv_io .reassembly .lock , flags );
22712271 sc -> recv_io .reassembly .queue_length -- ;
22722272 list_del (& recvmsg -> list );
22732273 spin_unlock_irqrestore (& sc -> recv_io .reassembly .lock , flags );
22742274 put_recvmsg (sc , recvmsg );
22752275
2276+ if (ret == - ECONNABORTED )
2277+ return ret ;
2278+
2279+ if (ret )
2280+ goto respond ;
2281+
2282+ /*
2283+ * We negotiated with success, so we need to refill the recv queue.
2284+ * We do that with sc->idle.immediate_work still being disabled
2285+ * via smbdirect_socket_init(), so that queue_work(sc->workqueue,
2286+ * &sc->idle.immediate_work) in smb_direct_post_recv_credits()
2287+ * is a no-op.
2288+ *
2289+ * The message that grants the credits to the client is
2290+ * the negotiate response.
2291+ */
2292+ INIT_WORK (& sc -> recv_io .posted .refill_work , smb_direct_post_recv_credits );
2293+ smb_direct_post_recv_credits (& sc -> recv_io .posted .refill_work );
2294+ if (unlikely (sc -> first_error ))
2295+ return sc -> first_error ;
2296+ INIT_WORK (& sc -> idle .immediate_work , smb_direct_send_immediate_work );
2297+
2298+ respond :
2299+ ret = smb_direct_send_negotiate_response (sc , ret );
2300+
22762301 return ret ;
22772302}
22782303
0 commit comments