1*38c8a9a5SSteve French // SPDX-License-Identifier: GPL-2.0-or-later 2*38c8a9a5SSteve French /* 3*38c8a9a5SSteve French * Copyright (C) 2017, Microsoft Corporation. 4*38c8a9a5SSteve French * Copyright (C) 2018, LG Electronics. 5*38c8a9a5SSteve French * 6*38c8a9a5SSteve French * Author(s): Long Li <longli@microsoft.com>, 7*38c8a9a5SSteve French * Hyunchul Lee <hyc.lee@gmail.com> 8*38c8a9a5SSteve French */ 9*38c8a9a5SSteve French 10*38c8a9a5SSteve French #define SUBMOD_NAME "smb_direct" 11*38c8a9a5SSteve French 12*38c8a9a5SSteve French #include <linux/kthread.h> 13*38c8a9a5SSteve French #include <linux/list.h> 14*38c8a9a5SSteve French #include <linux/mempool.h> 15*38c8a9a5SSteve French #include <linux/highmem.h> 16*38c8a9a5SSteve French #include <linux/scatterlist.h> 17*38c8a9a5SSteve French #include <rdma/ib_verbs.h> 18*38c8a9a5SSteve French #include <rdma/rdma_cm.h> 19*38c8a9a5SSteve French #include <rdma/rw.h> 20*38c8a9a5SSteve French 21*38c8a9a5SSteve French #include "glob.h" 22*38c8a9a5SSteve French #include "connection.h" 23*38c8a9a5SSteve French #include "smb_common.h" 24*38c8a9a5SSteve French #include "smbstatus.h" 25*38c8a9a5SSteve French #include "transport_rdma.h" 26*38c8a9a5SSteve French 27*38c8a9a5SSteve French #define SMB_DIRECT_PORT_IWARP 5445 28*38c8a9a5SSteve French #define SMB_DIRECT_PORT_INFINIBAND 445 29*38c8a9a5SSteve French 30*38c8a9a5SSteve French #define SMB_DIRECT_VERSION_LE cpu_to_le16(0x0100) 31*38c8a9a5SSteve French 32*38c8a9a5SSteve French /* SMB_DIRECT negotiation timeout in seconds */ 33*38c8a9a5SSteve French #define SMB_DIRECT_NEGOTIATE_TIMEOUT 120 34*38c8a9a5SSteve French 35*38c8a9a5SSteve French #define SMB_DIRECT_MAX_SEND_SGES 6 36*38c8a9a5SSteve French #define SMB_DIRECT_MAX_RECV_SGES 1 37*38c8a9a5SSteve French 38*38c8a9a5SSteve French /* 39*38c8a9a5SSteve French * Default maximum number of RDMA read/write outstanding on this connection 40*38c8a9a5SSteve French * This value is possibly decreased during QP creation on hardware limit 41*38c8a9a5SSteve French */ 42*38c8a9a5SSteve French #define SMB_DIRECT_CM_INITIATOR_DEPTH 8 43*38c8a9a5SSteve French 44*38c8a9a5SSteve French /* Maximum number of retries on data transfer operations */ 45*38c8a9a5SSteve French #define SMB_DIRECT_CM_RETRY 6 46*38c8a9a5SSteve French /* No need to retry on Receiver Not Ready since SMB_DIRECT manages credits */ 47*38c8a9a5SSteve French #define SMB_DIRECT_CM_RNR_RETRY 0 48*38c8a9a5SSteve French 49*38c8a9a5SSteve French /* 50*38c8a9a5SSteve French * User configurable initial values per SMB_DIRECT transport connection 51*38c8a9a5SSteve French * as defined in [MS-SMBD] 3.1.1.1 52*38c8a9a5SSteve French * Those may change after a SMB_DIRECT negotiation 53*38c8a9a5SSteve French */ 54*38c8a9a5SSteve French 55*38c8a9a5SSteve French /* Set 445 port to SMB Direct port by default */ 56*38c8a9a5SSteve French static int smb_direct_port = SMB_DIRECT_PORT_INFINIBAND; 57*38c8a9a5SSteve French 58*38c8a9a5SSteve French /* The local peer's maximum number of credits to grant to the peer */ 59*38c8a9a5SSteve French static int smb_direct_receive_credit_max = 255; 60*38c8a9a5SSteve French 61*38c8a9a5SSteve French /* The remote peer's credit request of local peer */ 62*38c8a9a5SSteve French static int smb_direct_send_credit_target = 255; 63*38c8a9a5SSteve French 64*38c8a9a5SSteve French /* The maximum single message size can be sent to remote peer */ 65*38c8a9a5SSteve French static int smb_direct_max_send_size = 1364; 66*38c8a9a5SSteve French 67*38c8a9a5SSteve French /* The maximum fragmented upper-layer payload receive size supported */ 68*38c8a9a5SSteve French static int smb_direct_max_fragmented_recv_size = 1024 * 1024; 69*38c8a9a5SSteve French 70*38c8a9a5SSteve French /* The maximum single-message size which can be received */ 71*38c8a9a5SSteve French static int smb_direct_max_receive_size = 1364; 72*38c8a9a5SSteve French 73*38c8a9a5SSteve French static int smb_direct_max_read_write_size = SMBD_DEFAULT_IOSIZE; 74*38c8a9a5SSteve French 75*38c8a9a5SSteve French static LIST_HEAD(smb_direct_device_list); 76*38c8a9a5SSteve French static DEFINE_RWLOCK(smb_direct_device_lock); 77*38c8a9a5SSteve French 78*38c8a9a5SSteve French struct smb_direct_device { 79*38c8a9a5SSteve French struct ib_device *ib_dev; 80*38c8a9a5SSteve French struct list_head list; 81*38c8a9a5SSteve French }; 82*38c8a9a5SSteve French 83*38c8a9a5SSteve French static struct smb_direct_listener { 84*38c8a9a5SSteve French struct rdma_cm_id *cm_id; 85*38c8a9a5SSteve French } smb_direct_listener; 86*38c8a9a5SSteve French 87*38c8a9a5SSteve French static struct workqueue_struct *smb_direct_wq; 88*38c8a9a5SSteve French 89*38c8a9a5SSteve French enum smb_direct_status { 90*38c8a9a5SSteve French SMB_DIRECT_CS_NEW = 0, 91*38c8a9a5SSteve French SMB_DIRECT_CS_CONNECTED, 92*38c8a9a5SSteve French SMB_DIRECT_CS_DISCONNECTING, 93*38c8a9a5SSteve French SMB_DIRECT_CS_DISCONNECTED, 94*38c8a9a5SSteve French }; 95*38c8a9a5SSteve French 96*38c8a9a5SSteve French struct smb_direct_transport { 97*38c8a9a5SSteve French struct ksmbd_transport transport; 98*38c8a9a5SSteve French 99*38c8a9a5SSteve French enum smb_direct_status status; 100*38c8a9a5SSteve French bool full_packet_received; 101*38c8a9a5SSteve French wait_queue_head_t wait_status; 102*38c8a9a5SSteve French 103*38c8a9a5SSteve French struct rdma_cm_id *cm_id; 104*38c8a9a5SSteve French struct ib_cq *send_cq; 105*38c8a9a5SSteve French struct ib_cq *recv_cq; 106*38c8a9a5SSteve French struct ib_pd *pd; 107*38c8a9a5SSteve French struct ib_qp *qp; 108*38c8a9a5SSteve French 109*38c8a9a5SSteve French int max_send_size; 110*38c8a9a5SSteve French int max_recv_size; 111*38c8a9a5SSteve French int max_fragmented_send_size; 112*38c8a9a5SSteve French int max_fragmented_recv_size; 113*38c8a9a5SSteve French int max_rdma_rw_size; 114*38c8a9a5SSteve French 115*38c8a9a5SSteve French spinlock_t reassembly_queue_lock; 116*38c8a9a5SSteve French struct list_head reassembly_queue; 117*38c8a9a5SSteve French int reassembly_data_length; 118*38c8a9a5SSteve French int reassembly_queue_length; 119*38c8a9a5SSteve French int first_entry_offset; 120*38c8a9a5SSteve French wait_queue_head_t wait_reassembly_queue; 121*38c8a9a5SSteve French 122*38c8a9a5SSteve French spinlock_t receive_credit_lock; 123*38c8a9a5SSteve French int recv_credits; 124*38c8a9a5SSteve French int count_avail_recvmsg; 125*38c8a9a5SSteve French int recv_credit_max; 126*38c8a9a5SSteve French int recv_credit_target; 127*38c8a9a5SSteve French 128*38c8a9a5SSteve French spinlock_t recvmsg_queue_lock; 129*38c8a9a5SSteve French struct list_head recvmsg_queue; 130*38c8a9a5SSteve French 131*38c8a9a5SSteve French spinlock_t empty_recvmsg_queue_lock; 132*38c8a9a5SSteve French struct list_head empty_recvmsg_queue; 133*38c8a9a5SSteve French 134*38c8a9a5SSteve French int send_credit_target; 135*38c8a9a5SSteve French atomic_t send_credits; 136*38c8a9a5SSteve French spinlock_t lock_new_recv_credits; 137*38c8a9a5SSteve French int new_recv_credits; 138*38c8a9a5SSteve French int max_rw_credits; 139*38c8a9a5SSteve French int pages_per_rw_credit; 140*38c8a9a5SSteve French atomic_t rw_credits; 141*38c8a9a5SSteve French 142*38c8a9a5SSteve French wait_queue_head_t wait_send_credits; 143*38c8a9a5SSteve French wait_queue_head_t wait_rw_credits; 144*38c8a9a5SSteve French 145*38c8a9a5SSteve French mempool_t *sendmsg_mempool; 146*38c8a9a5SSteve French struct kmem_cache *sendmsg_cache; 147*38c8a9a5SSteve French mempool_t *recvmsg_mempool; 148*38c8a9a5SSteve French struct kmem_cache *recvmsg_cache; 149*38c8a9a5SSteve French 150*38c8a9a5SSteve French wait_queue_head_t wait_send_pending; 151*38c8a9a5SSteve French atomic_t send_pending; 152*38c8a9a5SSteve French 153*38c8a9a5SSteve French struct delayed_work post_recv_credits_work; 154*38c8a9a5SSteve French struct work_struct send_immediate_work; 155*38c8a9a5SSteve French struct work_struct disconnect_work; 156*38c8a9a5SSteve French 157*38c8a9a5SSteve French bool negotiation_requested; 158*38c8a9a5SSteve French }; 159*38c8a9a5SSteve French 160*38c8a9a5SSteve French #define KSMBD_TRANS(t) ((struct ksmbd_transport *)&((t)->transport)) 161*38c8a9a5SSteve French 162*38c8a9a5SSteve French enum { 163*38c8a9a5SSteve French SMB_DIRECT_MSG_NEGOTIATE_REQ = 0, 164*38c8a9a5SSteve French SMB_DIRECT_MSG_DATA_TRANSFER 165*38c8a9a5SSteve French }; 166*38c8a9a5SSteve French 167*38c8a9a5SSteve French static struct ksmbd_transport_ops ksmbd_smb_direct_transport_ops; 168*38c8a9a5SSteve French 169*38c8a9a5SSteve French struct smb_direct_send_ctx { 170*38c8a9a5SSteve French struct list_head msg_list; 171*38c8a9a5SSteve French int wr_cnt; 172*38c8a9a5SSteve French bool need_invalidate_rkey; 173*38c8a9a5SSteve French unsigned int remote_key; 174*38c8a9a5SSteve French }; 175*38c8a9a5SSteve French 176*38c8a9a5SSteve French struct smb_direct_sendmsg { 177*38c8a9a5SSteve French struct smb_direct_transport *transport; 178*38c8a9a5SSteve French struct ib_send_wr wr; 179*38c8a9a5SSteve French struct list_head list; 180*38c8a9a5SSteve French int num_sge; 181*38c8a9a5SSteve French struct ib_sge sge[SMB_DIRECT_MAX_SEND_SGES]; 182*38c8a9a5SSteve French struct ib_cqe cqe; 183*38c8a9a5SSteve French u8 packet[]; 184*38c8a9a5SSteve French }; 185*38c8a9a5SSteve French 186*38c8a9a5SSteve French struct smb_direct_recvmsg { 187*38c8a9a5SSteve French struct smb_direct_transport *transport; 188*38c8a9a5SSteve French struct list_head list; 189*38c8a9a5SSteve French int type; 190*38c8a9a5SSteve French struct ib_sge sge; 191*38c8a9a5SSteve French struct ib_cqe cqe; 192*38c8a9a5SSteve French bool first_segment; 193*38c8a9a5SSteve French u8 packet[]; 194*38c8a9a5SSteve French }; 195*38c8a9a5SSteve French 196*38c8a9a5SSteve French struct smb_direct_rdma_rw_msg { 197*38c8a9a5SSteve French struct smb_direct_transport *t; 198*38c8a9a5SSteve French struct ib_cqe cqe; 199*38c8a9a5SSteve French int status; 200*38c8a9a5SSteve French struct completion *completion; 201*38c8a9a5SSteve French struct list_head list; 202*38c8a9a5SSteve French struct rdma_rw_ctx rw_ctx; 203*38c8a9a5SSteve French struct sg_table sgt; 204*38c8a9a5SSteve French struct scatterlist sg_list[]; 205*38c8a9a5SSteve French }; 206*38c8a9a5SSteve French 207*38c8a9a5SSteve French void init_smbd_max_io_size(unsigned int sz) 208*38c8a9a5SSteve French { 209*38c8a9a5SSteve French sz = clamp_val(sz, SMBD_MIN_IOSIZE, SMBD_MAX_IOSIZE); 210*38c8a9a5SSteve French smb_direct_max_read_write_size = sz; 211*38c8a9a5SSteve French } 212*38c8a9a5SSteve French 213*38c8a9a5SSteve French unsigned int get_smbd_max_read_write_size(void) 214*38c8a9a5SSteve French { 215*38c8a9a5SSteve French return smb_direct_max_read_write_size; 216*38c8a9a5SSteve French } 217*38c8a9a5SSteve French 218*38c8a9a5SSteve French static inline int get_buf_page_count(void *buf, int size) 219*38c8a9a5SSteve French { 220*38c8a9a5SSteve French return DIV_ROUND_UP((uintptr_t)buf + size, PAGE_SIZE) - 221*38c8a9a5SSteve French (uintptr_t)buf / PAGE_SIZE; 222*38c8a9a5SSteve French } 223*38c8a9a5SSteve French 224*38c8a9a5SSteve French static void smb_direct_destroy_pools(struct smb_direct_transport *transport); 225*38c8a9a5SSteve French static void smb_direct_post_recv_credits(struct work_struct *work); 226*38c8a9a5SSteve French static int smb_direct_post_send_data(struct smb_direct_transport *t, 227*38c8a9a5SSteve French struct smb_direct_send_ctx *send_ctx, 228*38c8a9a5SSteve French struct kvec *iov, int niov, 229*38c8a9a5SSteve French int remaining_data_length); 230*38c8a9a5SSteve French 231*38c8a9a5SSteve French static inline struct smb_direct_transport * 232*38c8a9a5SSteve French smb_trans_direct_transfort(struct ksmbd_transport *t) 233*38c8a9a5SSteve French { 234*38c8a9a5SSteve French return container_of(t, struct smb_direct_transport, transport); 235*38c8a9a5SSteve French } 236*38c8a9a5SSteve French 237*38c8a9a5SSteve French static inline void 238*38c8a9a5SSteve French *smb_direct_recvmsg_payload(struct smb_direct_recvmsg *recvmsg) 239*38c8a9a5SSteve French { 240*38c8a9a5SSteve French return (void *)recvmsg->packet; 241*38c8a9a5SSteve French } 242*38c8a9a5SSteve French 243*38c8a9a5SSteve French static inline bool is_receive_credit_post_required(int receive_credits, 244*38c8a9a5SSteve French int avail_recvmsg_count) 245*38c8a9a5SSteve French { 246*38c8a9a5SSteve French return receive_credits <= (smb_direct_receive_credit_max >> 3) && 247*38c8a9a5SSteve French avail_recvmsg_count >= (receive_credits >> 2); 248*38c8a9a5SSteve French } 249*38c8a9a5SSteve French 250*38c8a9a5SSteve French static struct 251*38c8a9a5SSteve French smb_direct_recvmsg *get_free_recvmsg(struct smb_direct_transport *t) 252*38c8a9a5SSteve French { 253*38c8a9a5SSteve French struct smb_direct_recvmsg *recvmsg = NULL; 254*38c8a9a5SSteve French 255*38c8a9a5SSteve French spin_lock(&t->recvmsg_queue_lock); 256*38c8a9a5SSteve French if (!list_empty(&t->recvmsg_queue)) { 257*38c8a9a5SSteve French recvmsg = list_first_entry(&t->recvmsg_queue, 258*38c8a9a5SSteve French struct smb_direct_recvmsg, 259*38c8a9a5SSteve French list); 260*38c8a9a5SSteve French list_del(&recvmsg->list); 261*38c8a9a5SSteve French } 262*38c8a9a5SSteve French spin_unlock(&t->recvmsg_queue_lock); 263*38c8a9a5SSteve French return recvmsg; 264*38c8a9a5SSteve French } 265*38c8a9a5SSteve French 266*38c8a9a5SSteve French static void put_recvmsg(struct smb_direct_transport *t, 267*38c8a9a5SSteve French struct smb_direct_recvmsg *recvmsg) 268*38c8a9a5SSteve French { 269*38c8a9a5SSteve French ib_dma_unmap_single(t->cm_id->device, recvmsg->sge.addr, 270*38c8a9a5SSteve French recvmsg->sge.length, DMA_FROM_DEVICE); 271*38c8a9a5SSteve French 272*38c8a9a5SSteve French spin_lock(&t->recvmsg_queue_lock); 273*38c8a9a5SSteve French list_add(&recvmsg->list, &t->recvmsg_queue); 274*38c8a9a5SSteve French spin_unlock(&t->recvmsg_queue_lock); 275*38c8a9a5SSteve French } 276*38c8a9a5SSteve French 277*38c8a9a5SSteve French static struct 278*38c8a9a5SSteve French smb_direct_recvmsg *get_empty_recvmsg(struct smb_direct_transport *t) 279*38c8a9a5SSteve French { 280*38c8a9a5SSteve French struct smb_direct_recvmsg *recvmsg = NULL; 281*38c8a9a5SSteve French 282*38c8a9a5SSteve French spin_lock(&t->empty_recvmsg_queue_lock); 283*38c8a9a5SSteve French if (!list_empty(&t->empty_recvmsg_queue)) { 284*38c8a9a5SSteve French recvmsg = list_first_entry(&t->empty_recvmsg_queue, 285*38c8a9a5SSteve French struct smb_direct_recvmsg, list); 286*38c8a9a5SSteve French list_del(&recvmsg->list); 287*38c8a9a5SSteve French } 288*38c8a9a5SSteve French spin_unlock(&t->empty_recvmsg_queue_lock); 289*38c8a9a5SSteve French return recvmsg; 290*38c8a9a5SSteve French } 291*38c8a9a5SSteve French 292*38c8a9a5SSteve French static void put_empty_recvmsg(struct smb_direct_transport *t, 293*38c8a9a5SSteve French struct smb_direct_recvmsg *recvmsg) 294*38c8a9a5SSteve French { 295*38c8a9a5SSteve French ib_dma_unmap_single(t->cm_id->device, recvmsg->sge.addr, 296*38c8a9a5SSteve French recvmsg->sge.length, DMA_FROM_DEVICE); 297*38c8a9a5SSteve French 298*38c8a9a5SSteve French spin_lock(&t->empty_recvmsg_queue_lock); 299*38c8a9a5SSteve French list_add_tail(&recvmsg->list, &t->empty_recvmsg_queue); 300*38c8a9a5SSteve French spin_unlock(&t->empty_recvmsg_queue_lock); 301*38c8a9a5SSteve French } 302*38c8a9a5SSteve French 303*38c8a9a5SSteve French static void enqueue_reassembly(struct smb_direct_transport *t, 304*38c8a9a5SSteve French struct smb_direct_recvmsg *recvmsg, 305*38c8a9a5SSteve French int data_length) 306*38c8a9a5SSteve French { 307*38c8a9a5SSteve French spin_lock(&t->reassembly_queue_lock); 308*38c8a9a5SSteve French list_add_tail(&recvmsg->list, &t->reassembly_queue); 309*38c8a9a5SSteve French t->reassembly_queue_length++; 310*38c8a9a5SSteve French /* 311*38c8a9a5SSteve French * Make sure reassembly_data_length is updated after list and 312*38c8a9a5SSteve French * reassembly_queue_length are updated. On the dequeue side 313*38c8a9a5SSteve French * reassembly_data_length is checked without a lock to determine 314*38c8a9a5SSteve French * if reassembly_queue_length and list is up to date 315*38c8a9a5SSteve French */ 316*38c8a9a5SSteve French virt_wmb(); 317*38c8a9a5SSteve French t->reassembly_data_length += data_length; 318*38c8a9a5SSteve French spin_unlock(&t->reassembly_queue_lock); 319*38c8a9a5SSteve French } 320*38c8a9a5SSteve French 321*38c8a9a5SSteve French static struct smb_direct_recvmsg *get_first_reassembly(struct smb_direct_transport *t) 322*38c8a9a5SSteve French { 323*38c8a9a5SSteve French if (!list_empty(&t->reassembly_queue)) 324*38c8a9a5SSteve French return list_first_entry(&t->reassembly_queue, 325*38c8a9a5SSteve French struct smb_direct_recvmsg, list); 326*38c8a9a5SSteve French else 327*38c8a9a5SSteve French return NULL; 328*38c8a9a5SSteve French } 329*38c8a9a5SSteve French 330*38c8a9a5SSteve French static void smb_direct_disconnect_rdma_work(struct work_struct *work) 331*38c8a9a5SSteve French { 332*38c8a9a5SSteve French struct smb_direct_transport *t = 333*38c8a9a5SSteve French container_of(work, struct smb_direct_transport, 334*38c8a9a5SSteve French disconnect_work); 335*38c8a9a5SSteve French 336*38c8a9a5SSteve French if (t->status == SMB_DIRECT_CS_CONNECTED) { 337*38c8a9a5SSteve French t->status = SMB_DIRECT_CS_DISCONNECTING; 338*38c8a9a5SSteve French rdma_disconnect(t->cm_id); 339*38c8a9a5SSteve French } 340*38c8a9a5SSteve French } 341*38c8a9a5SSteve French 342*38c8a9a5SSteve French static void 343*38c8a9a5SSteve French smb_direct_disconnect_rdma_connection(struct smb_direct_transport *t) 344*38c8a9a5SSteve French { 345*38c8a9a5SSteve French if (t->status == SMB_DIRECT_CS_CONNECTED) 346*38c8a9a5SSteve French queue_work(smb_direct_wq, &t->disconnect_work); 347*38c8a9a5SSteve French } 348*38c8a9a5SSteve French 349*38c8a9a5SSteve French static void smb_direct_send_immediate_work(struct work_struct *work) 350*38c8a9a5SSteve French { 351*38c8a9a5SSteve French struct smb_direct_transport *t = container_of(work, 352*38c8a9a5SSteve French struct smb_direct_transport, send_immediate_work); 353*38c8a9a5SSteve French 354*38c8a9a5SSteve French if (t->status != SMB_DIRECT_CS_CONNECTED) 355*38c8a9a5SSteve French return; 356*38c8a9a5SSteve French 357*38c8a9a5SSteve French smb_direct_post_send_data(t, NULL, NULL, 0, 0); 358*38c8a9a5SSteve French } 359*38c8a9a5SSteve French 360*38c8a9a5SSteve French static struct smb_direct_transport *alloc_transport(struct rdma_cm_id *cm_id) 361*38c8a9a5SSteve French { 362*38c8a9a5SSteve French struct smb_direct_transport *t; 363*38c8a9a5SSteve French struct ksmbd_conn *conn; 364*38c8a9a5SSteve French 365*38c8a9a5SSteve French t = kzalloc(sizeof(*t), GFP_KERNEL); 366*38c8a9a5SSteve French if (!t) 367*38c8a9a5SSteve French return NULL; 368*38c8a9a5SSteve French 369*38c8a9a5SSteve French t->cm_id = cm_id; 370*38c8a9a5SSteve French cm_id->context = t; 371*38c8a9a5SSteve French 372*38c8a9a5SSteve French t->status = SMB_DIRECT_CS_NEW; 373*38c8a9a5SSteve French init_waitqueue_head(&t->wait_status); 374*38c8a9a5SSteve French 375*38c8a9a5SSteve French spin_lock_init(&t->reassembly_queue_lock); 376*38c8a9a5SSteve French INIT_LIST_HEAD(&t->reassembly_queue); 377*38c8a9a5SSteve French t->reassembly_data_length = 0; 378*38c8a9a5SSteve French t->reassembly_queue_length = 0; 379*38c8a9a5SSteve French init_waitqueue_head(&t->wait_reassembly_queue); 380*38c8a9a5SSteve French init_waitqueue_head(&t->wait_send_credits); 381*38c8a9a5SSteve French init_waitqueue_head(&t->wait_rw_credits); 382*38c8a9a5SSteve French 383*38c8a9a5SSteve French spin_lock_init(&t->receive_credit_lock); 384*38c8a9a5SSteve French spin_lock_init(&t->recvmsg_queue_lock); 385*38c8a9a5SSteve French INIT_LIST_HEAD(&t->recvmsg_queue); 386*38c8a9a5SSteve French 387*38c8a9a5SSteve French spin_lock_init(&t->empty_recvmsg_queue_lock); 388*38c8a9a5SSteve French INIT_LIST_HEAD(&t->empty_recvmsg_queue); 389*38c8a9a5SSteve French 390*38c8a9a5SSteve French init_waitqueue_head(&t->wait_send_pending); 391*38c8a9a5SSteve French atomic_set(&t->send_pending, 0); 392*38c8a9a5SSteve French 393*38c8a9a5SSteve French spin_lock_init(&t->lock_new_recv_credits); 394*38c8a9a5SSteve French 395*38c8a9a5SSteve French INIT_DELAYED_WORK(&t->post_recv_credits_work, 396*38c8a9a5SSteve French smb_direct_post_recv_credits); 397*38c8a9a5SSteve French INIT_WORK(&t->send_immediate_work, smb_direct_send_immediate_work); 398*38c8a9a5SSteve French INIT_WORK(&t->disconnect_work, smb_direct_disconnect_rdma_work); 399*38c8a9a5SSteve French 400*38c8a9a5SSteve French conn = ksmbd_conn_alloc(); 401*38c8a9a5SSteve French if (!conn) 402*38c8a9a5SSteve French goto err; 403*38c8a9a5SSteve French conn->transport = KSMBD_TRANS(t); 404*38c8a9a5SSteve French KSMBD_TRANS(t)->conn = conn; 405*38c8a9a5SSteve French KSMBD_TRANS(t)->ops = &ksmbd_smb_direct_transport_ops; 406*38c8a9a5SSteve French return t; 407*38c8a9a5SSteve French err: 408*38c8a9a5SSteve French kfree(t); 409*38c8a9a5SSteve French return NULL; 410*38c8a9a5SSteve French } 411*38c8a9a5SSteve French 412*38c8a9a5SSteve French static void free_transport(struct smb_direct_transport *t) 413*38c8a9a5SSteve French { 414*38c8a9a5SSteve French struct smb_direct_recvmsg *recvmsg; 415*38c8a9a5SSteve French 416*38c8a9a5SSteve French wake_up_interruptible(&t->wait_send_credits); 417*38c8a9a5SSteve French 418*38c8a9a5SSteve French ksmbd_debug(RDMA, "wait for all send posted to IB to finish\n"); 419*38c8a9a5SSteve French wait_event(t->wait_send_pending, 420*38c8a9a5SSteve French atomic_read(&t->send_pending) == 0); 421*38c8a9a5SSteve French 422*38c8a9a5SSteve French cancel_work_sync(&t->disconnect_work); 423*38c8a9a5SSteve French cancel_delayed_work_sync(&t->post_recv_credits_work); 424*38c8a9a5SSteve French cancel_work_sync(&t->send_immediate_work); 425*38c8a9a5SSteve French 426*38c8a9a5SSteve French if (t->qp) { 427*38c8a9a5SSteve French ib_drain_qp(t->qp); 428*38c8a9a5SSteve French ib_mr_pool_destroy(t->qp, &t->qp->rdma_mrs); 429*38c8a9a5SSteve French ib_destroy_qp(t->qp); 430*38c8a9a5SSteve French } 431*38c8a9a5SSteve French 432*38c8a9a5SSteve French ksmbd_debug(RDMA, "drain the reassembly queue\n"); 433*38c8a9a5SSteve French do { 434*38c8a9a5SSteve French spin_lock(&t->reassembly_queue_lock); 435*38c8a9a5SSteve French recvmsg = get_first_reassembly(t); 436*38c8a9a5SSteve French if (recvmsg) { 437*38c8a9a5SSteve French list_del(&recvmsg->list); 438*38c8a9a5SSteve French spin_unlock(&t->reassembly_queue_lock); 439*38c8a9a5SSteve French put_recvmsg(t, recvmsg); 440*38c8a9a5SSteve French } else { 441*38c8a9a5SSteve French spin_unlock(&t->reassembly_queue_lock); 442*38c8a9a5SSteve French } 443*38c8a9a5SSteve French } while (recvmsg); 444*38c8a9a5SSteve French t->reassembly_data_length = 0; 445*38c8a9a5SSteve French 446*38c8a9a5SSteve French if (t->send_cq) 447*38c8a9a5SSteve French ib_free_cq(t->send_cq); 448*38c8a9a5SSteve French if (t->recv_cq) 449*38c8a9a5SSteve French ib_free_cq(t->recv_cq); 450*38c8a9a5SSteve French if (t->pd) 451*38c8a9a5SSteve French ib_dealloc_pd(t->pd); 452*38c8a9a5SSteve French if (t->cm_id) 453*38c8a9a5SSteve French rdma_destroy_id(t->cm_id); 454*38c8a9a5SSteve French 455*38c8a9a5SSteve French smb_direct_destroy_pools(t); 456*38c8a9a5SSteve French ksmbd_conn_free(KSMBD_TRANS(t)->conn); 457*38c8a9a5SSteve French kfree(t); 458*38c8a9a5SSteve French } 459*38c8a9a5SSteve French 460*38c8a9a5SSteve French static struct smb_direct_sendmsg 461*38c8a9a5SSteve French *smb_direct_alloc_sendmsg(struct smb_direct_transport *t) 462*38c8a9a5SSteve French { 463*38c8a9a5SSteve French struct smb_direct_sendmsg *msg; 464*38c8a9a5SSteve French 465*38c8a9a5SSteve French msg = mempool_alloc(t->sendmsg_mempool, GFP_KERNEL); 466*38c8a9a5SSteve French if (!msg) 467*38c8a9a5SSteve French return ERR_PTR(-ENOMEM); 468*38c8a9a5SSteve French msg->transport = t; 469*38c8a9a5SSteve French INIT_LIST_HEAD(&msg->list); 470*38c8a9a5SSteve French msg->num_sge = 0; 471*38c8a9a5SSteve French return msg; 472*38c8a9a5SSteve French } 473*38c8a9a5SSteve French 474*38c8a9a5SSteve French static void smb_direct_free_sendmsg(struct smb_direct_transport *t, 475*38c8a9a5SSteve French struct smb_direct_sendmsg *msg) 476*38c8a9a5SSteve French { 477*38c8a9a5SSteve French int i; 478*38c8a9a5SSteve French 479*38c8a9a5SSteve French if (msg->num_sge > 0) { 480*38c8a9a5SSteve French ib_dma_unmap_single(t->cm_id->device, 481*38c8a9a5SSteve French msg->sge[0].addr, msg->sge[0].length, 482*38c8a9a5SSteve French DMA_TO_DEVICE); 483*38c8a9a5SSteve French for (i = 1; i < msg->num_sge; i++) 484*38c8a9a5SSteve French ib_dma_unmap_page(t->cm_id->device, 485*38c8a9a5SSteve French msg->sge[i].addr, msg->sge[i].length, 486*38c8a9a5SSteve French DMA_TO_DEVICE); 487*38c8a9a5SSteve French } 488*38c8a9a5SSteve French mempool_free(msg, t->sendmsg_mempool); 489*38c8a9a5SSteve French } 490*38c8a9a5SSteve French 491*38c8a9a5SSteve French static int smb_direct_check_recvmsg(struct smb_direct_recvmsg *recvmsg) 492*38c8a9a5SSteve French { 493*38c8a9a5SSteve French switch (recvmsg->type) { 494*38c8a9a5SSteve French case SMB_DIRECT_MSG_DATA_TRANSFER: { 495*38c8a9a5SSteve French struct smb_direct_data_transfer *req = 496*38c8a9a5SSteve French (struct smb_direct_data_transfer *)recvmsg->packet; 497*38c8a9a5SSteve French struct smb2_hdr *hdr = (struct smb2_hdr *)(recvmsg->packet 498*38c8a9a5SSteve French + le32_to_cpu(req->data_offset)); 499*38c8a9a5SSteve French ksmbd_debug(RDMA, 500*38c8a9a5SSteve French "CreditGranted: %u, CreditRequested: %u, DataLength: %u, RemainingDataLength: %u, SMB: %x, Command: %u\n", 501*38c8a9a5SSteve French le16_to_cpu(req->credits_granted), 502*38c8a9a5SSteve French le16_to_cpu(req->credits_requested), 503*38c8a9a5SSteve French req->data_length, req->remaining_data_length, 504*38c8a9a5SSteve French hdr->ProtocolId, hdr->Command); 505*38c8a9a5SSteve French break; 506*38c8a9a5SSteve French } 507*38c8a9a5SSteve French case SMB_DIRECT_MSG_NEGOTIATE_REQ: { 508*38c8a9a5SSteve French struct smb_direct_negotiate_req *req = 509*38c8a9a5SSteve French (struct smb_direct_negotiate_req *)recvmsg->packet; 510*38c8a9a5SSteve French ksmbd_debug(RDMA, 511*38c8a9a5SSteve French "MinVersion: %u, MaxVersion: %u, CreditRequested: %u, MaxSendSize: %u, MaxRecvSize: %u, MaxFragmentedSize: %u\n", 512*38c8a9a5SSteve French le16_to_cpu(req->min_version), 513*38c8a9a5SSteve French le16_to_cpu(req->max_version), 514*38c8a9a5SSteve French le16_to_cpu(req->credits_requested), 515*38c8a9a5SSteve French le32_to_cpu(req->preferred_send_size), 516*38c8a9a5SSteve French le32_to_cpu(req->max_receive_size), 517*38c8a9a5SSteve French le32_to_cpu(req->max_fragmented_size)); 518*38c8a9a5SSteve French if (le16_to_cpu(req->min_version) > 0x0100 || 519*38c8a9a5SSteve French le16_to_cpu(req->max_version) < 0x0100) 520*38c8a9a5SSteve French return -EOPNOTSUPP; 521*38c8a9a5SSteve French if (le16_to_cpu(req->credits_requested) <= 0 || 522*38c8a9a5SSteve French le32_to_cpu(req->max_receive_size) <= 128 || 523*38c8a9a5SSteve French le32_to_cpu(req->max_fragmented_size) <= 524*38c8a9a5SSteve French 128 * 1024) 525*38c8a9a5SSteve French return -ECONNABORTED; 526*38c8a9a5SSteve French 527*38c8a9a5SSteve French break; 528*38c8a9a5SSteve French } 529*38c8a9a5SSteve French default: 530*38c8a9a5SSteve French return -EINVAL; 531*38c8a9a5SSteve French } 532*38c8a9a5SSteve French return 0; 533*38c8a9a5SSteve French } 534*38c8a9a5SSteve French 535*38c8a9a5SSteve French static void recv_done(struct ib_cq *cq, struct ib_wc *wc) 536*38c8a9a5SSteve French { 537*38c8a9a5SSteve French struct smb_direct_recvmsg *recvmsg; 538*38c8a9a5SSteve French struct smb_direct_transport *t; 539*38c8a9a5SSteve French 540*38c8a9a5SSteve French recvmsg = container_of(wc->wr_cqe, struct smb_direct_recvmsg, cqe); 541*38c8a9a5SSteve French t = recvmsg->transport; 542*38c8a9a5SSteve French 543*38c8a9a5SSteve French if (wc->status != IB_WC_SUCCESS || wc->opcode != IB_WC_RECV) { 544*38c8a9a5SSteve French if (wc->status != IB_WC_WR_FLUSH_ERR) { 545*38c8a9a5SSteve French pr_err("Recv error. status='%s (%d)' opcode=%d\n", 546*38c8a9a5SSteve French ib_wc_status_msg(wc->status), wc->status, 547*38c8a9a5SSteve French wc->opcode); 548*38c8a9a5SSteve French smb_direct_disconnect_rdma_connection(t); 549*38c8a9a5SSteve French } 550*38c8a9a5SSteve French put_empty_recvmsg(t, recvmsg); 551*38c8a9a5SSteve French return; 552*38c8a9a5SSteve French } 553*38c8a9a5SSteve French 554*38c8a9a5SSteve French ksmbd_debug(RDMA, "Recv completed. status='%s (%d)', opcode=%d\n", 555*38c8a9a5SSteve French ib_wc_status_msg(wc->status), wc->status, 556*38c8a9a5SSteve French wc->opcode); 557*38c8a9a5SSteve French 558*38c8a9a5SSteve French ib_dma_sync_single_for_cpu(wc->qp->device, recvmsg->sge.addr, 559*38c8a9a5SSteve French recvmsg->sge.length, DMA_FROM_DEVICE); 560*38c8a9a5SSteve French 561*38c8a9a5SSteve French switch (recvmsg->type) { 562*38c8a9a5SSteve French case SMB_DIRECT_MSG_NEGOTIATE_REQ: 563*38c8a9a5SSteve French if (wc->byte_len < sizeof(struct smb_direct_negotiate_req)) { 564*38c8a9a5SSteve French put_empty_recvmsg(t, recvmsg); 565*38c8a9a5SSteve French return; 566*38c8a9a5SSteve French } 567*38c8a9a5SSteve French t->negotiation_requested = true; 568*38c8a9a5SSteve French t->full_packet_received = true; 569*38c8a9a5SSteve French t->status = SMB_DIRECT_CS_CONNECTED; 570*38c8a9a5SSteve French enqueue_reassembly(t, recvmsg, 0); 571*38c8a9a5SSteve French wake_up_interruptible(&t->wait_status); 572*38c8a9a5SSteve French break; 573*38c8a9a5SSteve French case SMB_DIRECT_MSG_DATA_TRANSFER: { 574*38c8a9a5SSteve French struct smb_direct_data_transfer *data_transfer = 575*38c8a9a5SSteve French (struct smb_direct_data_transfer *)recvmsg->packet; 576*38c8a9a5SSteve French unsigned int data_length; 577*38c8a9a5SSteve French int avail_recvmsg_count, receive_credits; 578*38c8a9a5SSteve French 579*38c8a9a5SSteve French if (wc->byte_len < 580*38c8a9a5SSteve French offsetof(struct smb_direct_data_transfer, padding)) { 581*38c8a9a5SSteve French put_empty_recvmsg(t, recvmsg); 582*38c8a9a5SSteve French return; 583*38c8a9a5SSteve French } 584*38c8a9a5SSteve French 585*38c8a9a5SSteve French data_length = le32_to_cpu(data_transfer->data_length); 586*38c8a9a5SSteve French if (data_length) { 587*38c8a9a5SSteve French if (wc->byte_len < sizeof(struct smb_direct_data_transfer) + 588*38c8a9a5SSteve French (u64)data_length) { 589*38c8a9a5SSteve French put_empty_recvmsg(t, recvmsg); 590*38c8a9a5SSteve French return; 591*38c8a9a5SSteve French } 592*38c8a9a5SSteve French 593*38c8a9a5SSteve French if (t->full_packet_received) 594*38c8a9a5SSteve French recvmsg->first_segment = true; 595*38c8a9a5SSteve French 596*38c8a9a5SSteve French if (le32_to_cpu(data_transfer->remaining_data_length)) 597*38c8a9a5SSteve French t->full_packet_received = false; 598*38c8a9a5SSteve French else 599*38c8a9a5SSteve French t->full_packet_received = true; 600*38c8a9a5SSteve French 601*38c8a9a5SSteve French enqueue_reassembly(t, recvmsg, (int)data_length); 602*38c8a9a5SSteve French wake_up_interruptible(&t->wait_reassembly_queue); 603*38c8a9a5SSteve French 604*38c8a9a5SSteve French spin_lock(&t->receive_credit_lock); 605*38c8a9a5SSteve French receive_credits = --(t->recv_credits); 606*38c8a9a5SSteve French avail_recvmsg_count = t->count_avail_recvmsg; 607*38c8a9a5SSteve French spin_unlock(&t->receive_credit_lock); 608*38c8a9a5SSteve French } else { 609*38c8a9a5SSteve French put_empty_recvmsg(t, recvmsg); 610*38c8a9a5SSteve French 611*38c8a9a5SSteve French spin_lock(&t->receive_credit_lock); 612*38c8a9a5SSteve French receive_credits = --(t->recv_credits); 613*38c8a9a5SSteve French avail_recvmsg_count = ++(t->count_avail_recvmsg); 614*38c8a9a5SSteve French spin_unlock(&t->receive_credit_lock); 615*38c8a9a5SSteve French } 616*38c8a9a5SSteve French 617*38c8a9a5SSteve French t->recv_credit_target = 618*38c8a9a5SSteve French le16_to_cpu(data_transfer->credits_requested); 619*38c8a9a5SSteve French atomic_add(le16_to_cpu(data_transfer->credits_granted), 620*38c8a9a5SSteve French &t->send_credits); 621*38c8a9a5SSteve French 622*38c8a9a5SSteve French if (le16_to_cpu(data_transfer->flags) & 623*38c8a9a5SSteve French SMB_DIRECT_RESPONSE_REQUESTED) 624*38c8a9a5SSteve French queue_work(smb_direct_wq, &t->send_immediate_work); 625*38c8a9a5SSteve French 626*38c8a9a5SSteve French if (atomic_read(&t->send_credits) > 0) 627*38c8a9a5SSteve French wake_up_interruptible(&t->wait_send_credits); 628*38c8a9a5SSteve French 629*38c8a9a5SSteve French if (is_receive_credit_post_required(receive_credits, avail_recvmsg_count)) 630*38c8a9a5SSteve French mod_delayed_work(smb_direct_wq, 631*38c8a9a5SSteve French &t->post_recv_credits_work, 0); 632*38c8a9a5SSteve French break; 633*38c8a9a5SSteve French } 634*38c8a9a5SSteve French default: 635*38c8a9a5SSteve French break; 636*38c8a9a5SSteve French } 637*38c8a9a5SSteve French } 638*38c8a9a5SSteve French 639*38c8a9a5SSteve French static int smb_direct_post_recv(struct smb_direct_transport *t, 640*38c8a9a5SSteve French struct smb_direct_recvmsg *recvmsg) 641*38c8a9a5SSteve French { 642*38c8a9a5SSteve French struct ib_recv_wr wr; 643*38c8a9a5SSteve French int ret; 644*38c8a9a5SSteve French 645*38c8a9a5SSteve French recvmsg->sge.addr = ib_dma_map_single(t->cm_id->device, 646*38c8a9a5SSteve French recvmsg->packet, t->max_recv_size, 647*38c8a9a5SSteve French DMA_FROM_DEVICE); 648*38c8a9a5SSteve French ret = ib_dma_mapping_error(t->cm_id->device, recvmsg->sge.addr); 649*38c8a9a5SSteve French if (ret) 650*38c8a9a5SSteve French return ret; 651*38c8a9a5SSteve French recvmsg->sge.length = t->max_recv_size; 652*38c8a9a5SSteve French recvmsg->sge.lkey = t->pd->local_dma_lkey; 653*38c8a9a5SSteve French recvmsg->cqe.done = recv_done; 654*38c8a9a5SSteve French 655*38c8a9a5SSteve French wr.wr_cqe = &recvmsg->cqe; 656*38c8a9a5SSteve French wr.next = NULL; 657*38c8a9a5SSteve French wr.sg_list = &recvmsg->sge; 658*38c8a9a5SSteve French wr.num_sge = 1; 659*38c8a9a5SSteve French 660*38c8a9a5SSteve French ret = ib_post_recv(t->qp, &wr, NULL); 661*38c8a9a5SSteve French if (ret) { 662*38c8a9a5SSteve French pr_err("Can't post recv: %d\n", ret); 663*38c8a9a5SSteve French ib_dma_unmap_single(t->cm_id->device, 664*38c8a9a5SSteve French recvmsg->sge.addr, recvmsg->sge.length, 665*38c8a9a5SSteve French DMA_FROM_DEVICE); 666*38c8a9a5SSteve French smb_direct_disconnect_rdma_connection(t); 667*38c8a9a5SSteve French return ret; 668*38c8a9a5SSteve French } 669*38c8a9a5SSteve French return ret; 670*38c8a9a5SSteve French } 671*38c8a9a5SSteve French 672*38c8a9a5SSteve French static int smb_direct_read(struct ksmbd_transport *t, char *buf, 673*38c8a9a5SSteve French unsigned int size, int unused) 674*38c8a9a5SSteve French { 675*38c8a9a5SSteve French struct smb_direct_recvmsg *recvmsg; 676*38c8a9a5SSteve French struct smb_direct_data_transfer *data_transfer; 677*38c8a9a5SSteve French int to_copy, to_read, data_read, offset; 678*38c8a9a5SSteve French u32 data_length, remaining_data_length, data_offset; 679*38c8a9a5SSteve French int rc; 680*38c8a9a5SSteve French struct smb_direct_transport *st = smb_trans_direct_transfort(t); 681*38c8a9a5SSteve French 682*38c8a9a5SSteve French again: 683*38c8a9a5SSteve French if (st->status != SMB_DIRECT_CS_CONNECTED) { 684*38c8a9a5SSteve French pr_err("disconnected\n"); 685*38c8a9a5SSteve French return -ENOTCONN; 686*38c8a9a5SSteve French } 687*38c8a9a5SSteve French 688*38c8a9a5SSteve French /* 689*38c8a9a5SSteve French * No need to hold the reassembly queue lock all the time as we are 690*38c8a9a5SSteve French * the only one reading from the front of the queue. The transport 691*38c8a9a5SSteve French * may add more entries to the back of the queue at the same time 692*38c8a9a5SSteve French */ 693*38c8a9a5SSteve French if (st->reassembly_data_length >= size) { 694*38c8a9a5SSteve French int queue_length; 695*38c8a9a5SSteve French int queue_removed = 0; 696*38c8a9a5SSteve French 697*38c8a9a5SSteve French /* 698*38c8a9a5SSteve French * Need to make sure reassembly_data_length is read before 699*38c8a9a5SSteve French * reading reassembly_queue_length and calling 700*38c8a9a5SSteve French * get_first_reassembly. This call is lock free 701*38c8a9a5SSteve French * as we never read at the end of the queue which are being 702*38c8a9a5SSteve French * updated in SOFTIRQ as more data is received 703*38c8a9a5SSteve French */ 704*38c8a9a5SSteve French virt_rmb(); 705*38c8a9a5SSteve French queue_length = st->reassembly_queue_length; 706*38c8a9a5SSteve French data_read = 0; 707*38c8a9a5SSteve French to_read = size; 708*38c8a9a5SSteve French offset = st->first_entry_offset; 709*38c8a9a5SSteve French while (data_read < size) { 710*38c8a9a5SSteve French recvmsg = get_first_reassembly(st); 711*38c8a9a5SSteve French data_transfer = smb_direct_recvmsg_payload(recvmsg); 712*38c8a9a5SSteve French data_length = le32_to_cpu(data_transfer->data_length); 713*38c8a9a5SSteve French remaining_data_length = 714*38c8a9a5SSteve French le32_to_cpu(data_transfer->remaining_data_length); 715*38c8a9a5SSteve French data_offset = le32_to_cpu(data_transfer->data_offset); 716*38c8a9a5SSteve French 717*38c8a9a5SSteve French /* 718*38c8a9a5SSteve French * The upper layer expects RFC1002 length at the 719*38c8a9a5SSteve French * beginning of the payload. Return it to indicate 720*38c8a9a5SSteve French * the total length of the packet. This minimize the 721*38c8a9a5SSteve French * change to upper layer packet processing logic. This 722*38c8a9a5SSteve French * will be eventually remove when an intermediate 723*38c8a9a5SSteve French * transport layer is added 724*38c8a9a5SSteve French */ 725*38c8a9a5SSteve French if (recvmsg->first_segment && size == 4) { 726*38c8a9a5SSteve French unsigned int rfc1002_len = 727*38c8a9a5SSteve French data_length + remaining_data_length; 728*38c8a9a5SSteve French *((__be32 *)buf) = cpu_to_be32(rfc1002_len); 729*38c8a9a5SSteve French data_read = 4; 730*38c8a9a5SSteve French recvmsg->first_segment = false; 731*38c8a9a5SSteve French ksmbd_debug(RDMA, 732*38c8a9a5SSteve French "returning rfc1002 length %d\n", 733*38c8a9a5SSteve French rfc1002_len); 734*38c8a9a5SSteve French goto read_rfc1002_done; 735*38c8a9a5SSteve French } 736*38c8a9a5SSteve French 737*38c8a9a5SSteve French to_copy = min_t(int, data_length - offset, to_read); 738*38c8a9a5SSteve French memcpy(buf + data_read, (char *)data_transfer + data_offset + offset, 739*38c8a9a5SSteve French to_copy); 740*38c8a9a5SSteve French 741*38c8a9a5SSteve French /* move on to the next buffer? */ 742*38c8a9a5SSteve French if (to_copy == data_length - offset) { 743*38c8a9a5SSteve French queue_length--; 744*38c8a9a5SSteve French /* 745*38c8a9a5SSteve French * No need to lock if we are not at the 746*38c8a9a5SSteve French * end of the queue 747*38c8a9a5SSteve French */ 748*38c8a9a5SSteve French if (queue_length) { 749*38c8a9a5SSteve French list_del(&recvmsg->list); 750*38c8a9a5SSteve French } else { 751*38c8a9a5SSteve French spin_lock_irq(&st->reassembly_queue_lock); 752*38c8a9a5SSteve French list_del(&recvmsg->list); 753*38c8a9a5SSteve French spin_unlock_irq(&st->reassembly_queue_lock); 754*38c8a9a5SSteve French } 755*38c8a9a5SSteve French queue_removed++; 756*38c8a9a5SSteve French put_recvmsg(st, recvmsg); 757*38c8a9a5SSteve French offset = 0; 758*38c8a9a5SSteve French } else { 759*38c8a9a5SSteve French offset += to_copy; 760*38c8a9a5SSteve French } 761*38c8a9a5SSteve French 762*38c8a9a5SSteve French to_read -= to_copy; 763*38c8a9a5SSteve French data_read += to_copy; 764*38c8a9a5SSteve French } 765*38c8a9a5SSteve French 766*38c8a9a5SSteve French spin_lock_irq(&st->reassembly_queue_lock); 767*38c8a9a5SSteve French st->reassembly_data_length -= data_read; 768*38c8a9a5SSteve French st->reassembly_queue_length -= queue_removed; 769*38c8a9a5SSteve French spin_unlock_irq(&st->reassembly_queue_lock); 770*38c8a9a5SSteve French 771*38c8a9a5SSteve French spin_lock(&st->receive_credit_lock); 772*38c8a9a5SSteve French st->count_avail_recvmsg += queue_removed; 773*38c8a9a5SSteve French if (is_receive_credit_post_required(st->recv_credits, st->count_avail_recvmsg)) { 774*38c8a9a5SSteve French spin_unlock(&st->receive_credit_lock); 775*38c8a9a5SSteve French mod_delayed_work(smb_direct_wq, 776*38c8a9a5SSteve French &st->post_recv_credits_work, 0); 777*38c8a9a5SSteve French } else { 778*38c8a9a5SSteve French spin_unlock(&st->receive_credit_lock); 779*38c8a9a5SSteve French } 780*38c8a9a5SSteve French 781*38c8a9a5SSteve French st->first_entry_offset = offset; 782*38c8a9a5SSteve French ksmbd_debug(RDMA, 783*38c8a9a5SSteve French "returning to thread data_read=%d reassembly_data_length=%d first_entry_offset=%d\n", 784*38c8a9a5SSteve French data_read, st->reassembly_data_length, 785*38c8a9a5SSteve French st->first_entry_offset); 786*38c8a9a5SSteve French read_rfc1002_done: 787*38c8a9a5SSteve French return data_read; 788*38c8a9a5SSteve French } 789*38c8a9a5SSteve French 790*38c8a9a5SSteve French ksmbd_debug(RDMA, "wait_event on more data\n"); 791*38c8a9a5SSteve French rc = wait_event_interruptible(st->wait_reassembly_queue, 792*38c8a9a5SSteve French st->reassembly_data_length >= size || 793*38c8a9a5SSteve French st->status != SMB_DIRECT_CS_CONNECTED); 794*38c8a9a5SSteve French if (rc) 795*38c8a9a5SSteve French return -EINTR; 796*38c8a9a5SSteve French 797*38c8a9a5SSteve French goto again; 798*38c8a9a5SSteve French } 799*38c8a9a5SSteve French 800*38c8a9a5SSteve French static void smb_direct_post_recv_credits(struct work_struct *work) 801*38c8a9a5SSteve French { 802*38c8a9a5SSteve French struct smb_direct_transport *t = container_of(work, 803*38c8a9a5SSteve French struct smb_direct_transport, post_recv_credits_work.work); 804*38c8a9a5SSteve French struct smb_direct_recvmsg *recvmsg; 805*38c8a9a5SSteve French int receive_credits, credits = 0; 806*38c8a9a5SSteve French int ret; 807*38c8a9a5SSteve French int use_free = 1; 808*38c8a9a5SSteve French 809*38c8a9a5SSteve French spin_lock(&t->receive_credit_lock); 810*38c8a9a5SSteve French receive_credits = t->recv_credits; 811*38c8a9a5SSteve French spin_unlock(&t->receive_credit_lock); 812*38c8a9a5SSteve French 813*38c8a9a5SSteve French if (receive_credits < t->recv_credit_target) { 814*38c8a9a5SSteve French while (true) { 815*38c8a9a5SSteve French if (use_free) 816*38c8a9a5SSteve French recvmsg = get_free_recvmsg(t); 817*38c8a9a5SSteve French else 818*38c8a9a5SSteve French recvmsg = get_empty_recvmsg(t); 819*38c8a9a5SSteve French if (!recvmsg) { 820*38c8a9a5SSteve French if (use_free) { 821*38c8a9a5SSteve French use_free = 0; 822*38c8a9a5SSteve French continue; 823*38c8a9a5SSteve French } else { 824*38c8a9a5SSteve French break; 825*38c8a9a5SSteve French } 826*38c8a9a5SSteve French } 827*38c8a9a5SSteve French 828*38c8a9a5SSteve French recvmsg->type = SMB_DIRECT_MSG_DATA_TRANSFER; 829*38c8a9a5SSteve French recvmsg->first_segment = false; 830*38c8a9a5SSteve French 831*38c8a9a5SSteve French ret = smb_direct_post_recv(t, recvmsg); 832*38c8a9a5SSteve French if (ret) { 833*38c8a9a5SSteve French pr_err("Can't post recv: %d\n", ret); 834*38c8a9a5SSteve French put_recvmsg(t, recvmsg); 835*38c8a9a5SSteve French break; 836*38c8a9a5SSteve French } 837*38c8a9a5SSteve French credits++; 838*38c8a9a5SSteve French } 839*38c8a9a5SSteve French } 840*38c8a9a5SSteve French 841*38c8a9a5SSteve French spin_lock(&t->receive_credit_lock); 842*38c8a9a5SSteve French t->recv_credits += credits; 843*38c8a9a5SSteve French t->count_avail_recvmsg -= credits; 844*38c8a9a5SSteve French spin_unlock(&t->receive_credit_lock); 845*38c8a9a5SSteve French 846*38c8a9a5SSteve French spin_lock(&t->lock_new_recv_credits); 847*38c8a9a5SSteve French t->new_recv_credits += credits; 848*38c8a9a5SSteve French spin_unlock(&t->lock_new_recv_credits); 849*38c8a9a5SSteve French 850*38c8a9a5SSteve French if (credits) 851*38c8a9a5SSteve French queue_work(smb_direct_wq, &t->send_immediate_work); 852*38c8a9a5SSteve French } 853*38c8a9a5SSteve French 854*38c8a9a5SSteve French static void send_done(struct ib_cq *cq, struct ib_wc *wc) 855*38c8a9a5SSteve French { 856*38c8a9a5SSteve French struct smb_direct_sendmsg *sendmsg, *sibling; 857*38c8a9a5SSteve French struct smb_direct_transport *t; 858*38c8a9a5SSteve French struct list_head *pos, *prev, *end; 859*38c8a9a5SSteve French 860*38c8a9a5SSteve French sendmsg = container_of(wc->wr_cqe, struct smb_direct_sendmsg, cqe); 861*38c8a9a5SSteve French t = sendmsg->transport; 862*38c8a9a5SSteve French 863*38c8a9a5SSteve French ksmbd_debug(RDMA, "Send completed. status='%s (%d)', opcode=%d\n", 864*38c8a9a5SSteve French ib_wc_status_msg(wc->status), wc->status, 865*38c8a9a5SSteve French wc->opcode); 866*38c8a9a5SSteve French 867*38c8a9a5SSteve French if (wc->status != IB_WC_SUCCESS || wc->opcode != IB_WC_SEND) { 868*38c8a9a5SSteve French pr_err("Send error. status='%s (%d)', opcode=%d\n", 869*38c8a9a5SSteve French ib_wc_status_msg(wc->status), wc->status, 870*38c8a9a5SSteve French wc->opcode); 871*38c8a9a5SSteve French smb_direct_disconnect_rdma_connection(t); 872*38c8a9a5SSteve French } 873*38c8a9a5SSteve French 874*38c8a9a5SSteve French if (atomic_dec_and_test(&t->send_pending)) 875*38c8a9a5SSteve French wake_up(&t->wait_send_pending); 876*38c8a9a5SSteve French 877*38c8a9a5SSteve French /* iterate and free the list of messages in reverse. the list's head 878*38c8a9a5SSteve French * is invalid. 879*38c8a9a5SSteve French */ 880*38c8a9a5SSteve French for (pos = &sendmsg->list, prev = pos->prev, end = sendmsg->list.next; 881*38c8a9a5SSteve French prev != end; pos = prev, prev = prev->prev) { 882*38c8a9a5SSteve French sibling = container_of(pos, struct smb_direct_sendmsg, list); 883*38c8a9a5SSteve French smb_direct_free_sendmsg(t, sibling); 884*38c8a9a5SSteve French } 885*38c8a9a5SSteve French 886*38c8a9a5SSteve French sibling = container_of(pos, struct smb_direct_sendmsg, list); 887*38c8a9a5SSteve French smb_direct_free_sendmsg(t, sibling); 888*38c8a9a5SSteve French } 889*38c8a9a5SSteve French 890*38c8a9a5SSteve French static int manage_credits_prior_sending(struct smb_direct_transport *t) 891*38c8a9a5SSteve French { 892*38c8a9a5SSteve French int new_credits; 893*38c8a9a5SSteve French 894*38c8a9a5SSteve French spin_lock(&t->lock_new_recv_credits); 895*38c8a9a5SSteve French new_credits = t->new_recv_credits; 896*38c8a9a5SSteve French t->new_recv_credits = 0; 897*38c8a9a5SSteve French spin_unlock(&t->lock_new_recv_credits); 898*38c8a9a5SSteve French 899*38c8a9a5SSteve French return new_credits; 900*38c8a9a5SSteve French } 901*38c8a9a5SSteve French 902*38c8a9a5SSteve French static int smb_direct_post_send(struct smb_direct_transport *t, 903*38c8a9a5SSteve French struct ib_send_wr *wr) 904*38c8a9a5SSteve French { 905*38c8a9a5SSteve French int ret; 906*38c8a9a5SSteve French 907*38c8a9a5SSteve French atomic_inc(&t->send_pending); 908*38c8a9a5SSteve French ret = ib_post_send(t->qp, wr, NULL); 909*38c8a9a5SSteve French if (ret) { 910*38c8a9a5SSteve French pr_err("failed to post send: %d\n", ret); 911*38c8a9a5SSteve French if (atomic_dec_and_test(&t->send_pending)) 912*38c8a9a5SSteve French wake_up(&t->wait_send_pending); 913*38c8a9a5SSteve French smb_direct_disconnect_rdma_connection(t); 914*38c8a9a5SSteve French } 915*38c8a9a5SSteve French return ret; 916*38c8a9a5SSteve French } 917*38c8a9a5SSteve French 918*38c8a9a5SSteve French static void smb_direct_send_ctx_init(struct smb_direct_transport *t, 919*38c8a9a5SSteve French struct smb_direct_send_ctx *send_ctx, 920*38c8a9a5SSteve French bool need_invalidate_rkey, 921*38c8a9a5SSteve French unsigned int remote_key) 922*38c8a9a5SSteve French { 923*38c8a9a5SSteve French INIT_LIST_HEAD(&send_ctx->msg_list); 924*38c8a9a5SSteve French send_ctx->wr_cnt = 0; 925*38c8a9a5SSteve French send_ctx->need_invalidate_rkey = need_invalidate_rkey; 926*38c8a9a5SSteve French send_ctx->remote_key = remote_key; 927*38c8a9a5SSteve French } 928*38c8a9a5SSteve French 929*38c8a9a5SSteve French static int smb_direct_flush_send_list(struct smb_direct_transport *t, 930*38c8a9a5SSteve French struct smb_direct_send_ctx *send_ctx, 931*38c8a9a5SSteve French bool is_last) 932*38c8a9a5SSteve French { 933*38c8a9a5SSteve French struct smb_direct_sendmsg *first, *last; 934*38c8a9a5SSteve French int ret; 935*38c8a9a5SSteve French 936*38c8a9a5SSteve French if (list_empty(&send_ctx->msg_list)) 937*38c8a9a5SSteve French return 0; 938*38c8a9a5SSteve French 939*38c8a9a5SSteve French first = list_first_entry(&send_ctx->msg_list, 940*38c8a9a5SSteve French struct smb_direct_sendmsg, 941*38c8a9a5SSteve French list); 942*38c8a9a5SSteve French last = list_last_entry(&send_ctx->msg_list, 943*38c8a9a5SSteve French struct smb_direct_sendmsg, 944*38c8a9a5SSteve French list); 945*38c8a9a5SSteve French 946*38c8a9a5SSteve French last->wr.send_flags = IB_SEND_SIGNALED; 947*38c8a9a5SSteve French last->wr.wr_cqe = &last->cqe; 948*38c8a9a5SSteve French if (is_last && send_ctx->need_invalidate_rkey) { 949*38c8a9a5SSteve French last->wr.opcode = IB_WR_SEND_WITH_INV; 950*38c8a9a5SSteve French last->wr.ex.invalidate_rkey = send_ctx->remote_key; 951*38c8a9a5SSteve French } 952*38c8a9a5SSteve French 953*38c8a9a5SSteve French ret = smb_direct_post_send(t, &first->wr); 954*38c8a9a5SSteve French if (!ret) { 955*38c8a9a5SSteve French smb_direct_send_ctx_init(t, send_ctx, 956*38c8a9a5SSteve French send_ctx->need_invalidate_rkey, 957*38c8a9a5SSteve French send_ctx->remote_key); 958*38c8a9a5SSteve French } else { 959*38c8a9a5SSteve French atomic_add(send_ctx->wr_cnt, &t->send_credits); 960*38c8a9a5SSteve French wake_up(&t->wait_send_credits); 961*38c8a9a5SSteve French list_for_each_entry_safe(first, last, &send_ctx->msg_list, 962*38c8a9a5SSteve French list) { 963*38c8a9a5SSteve French smb_direct_free_sendmsg(t, first); 964*38c8a9a5SSteve French } 965*38c8a9a5SSteve French } 966*38c8a9a5SSteve French return ret; 967*38c8a9a5SSteve French } 968*38c8a9a5SSteve French 969*38c8a9a5SSteve French static int wait_for_credits(struct smb_direct_transport *t, 970*38c8a9a5SSteve French wait_queue_head_t *waitq, atomic_t *total_credits, 971*38c8a9a5SSteve French int needed) 972*38c8a9a5SSteve French { 973*38c8a9a5SSteve French int ret; 974*38c8a9a5SSteve French 975*38c8a9a5SSteve French do { 976*38c8a9a5SSteve French if (atomic_sub_return(needed, total_credits) >= 0) 977*38c8a9a5SSteve French return 0; 978*38c8a9a5SSteve French 979*38c8a9a5SSteve French atomic_add(needed, total_credits); 980*38c8a9a5SSteve French ret = wait_event_interruptible(*waitq, 981*38c8a9a5SSteve French atomic_read(total_credits) >= needed || 982*38c8a9a5SSteve French t->status != SMB_DIRECT_CS_CONNECTED); 983*38c8a9a5SSteve French 984*38c8a9a5SSteve French if (t->status != SMB_DIRECT_CS_CONNECTED) 985*38c8a9a5SSteve French return -ENOTCONN; 986*38c8a9a5SSteve French else if (ret < 0) 987*38c8a9a5SSteve French return ret; 988*38c8a9a5SSteve French } while (true); 989*38c8a9a5SSteve French } 990*38c8a9a5SSteve French 991*38c8a9a5SSteve French static int wait_for_send_credits(struct smb_direct_transport *t, 992*38c8a9a5SSteve French struct smb_direct_send_ctx *send_ctx) 993*38c8a9a5SSteve French { 994*38c8a9a5SSteve French int ret; 995*38c8a9a5SSteve French 996*38c8a9a5SSteve French if (send_ctx && 997*38c8a9a5SSteve French (send_ctx->wr_cnt >= 16 || atomic_read(&t->send_credits) <= 1)) { 998*38c8a9a5SSteve French ret = smb_direct_flush_send_list(t, send_ctx, false); 999*38c8a9a5SSteve French if (ret) 1000*38c8a9a5SSteve French return ret; 1001*38c8a9a5SSteve French } 1002*38c8a9a5SSteve French 1003*38c8a9a5SSteve French return wait_for_credits(t, &t->wait_send_credits, &t->send_credits, 1); 1004*38c8a9a5SSteve French } 1005*38c8a9a5SSteve French 1006*38c8a9a5SSteve French static int wait_for_rw_credits(struct smb_direct_transport *t, int credits) 1007*38c8a9a5SSteve French { 1008*38c8a9a5SSteve French return wait_for_credits(t, &t->wait_rw_credits, &t->rw_credits, credits); 1009*38c8a9a5SSteve French } 1010*38c8a9a5SSteve French 1011*38c8a9a5SSteve French static int calc_rw_credits(struct smb_direct_transport *t, 1012*38c8a9a5SSteve French char *buf, unsigned int len) 1013*38c8a9a5SSteve French { 1014*38c8a9a5SSteve French return DIV_ROUND_UP(get_buf_page_count(buf, len), 1015*38c8a9a5SSteve French t->pages_per_rw_credit); 1016*38c8a9a5SSteve French } 1017*38c8a9a5SSteve French 1018*38c8a9a5SSteve French static int smb_direct_create_header(struct smb_direct_transport *t, 1019*38c8a9a5SSteve French int size, int remaining_data_length, 1020*38c8a9a5SSteve French struct smb_direct_sendmsg **sendmsg_out) 1021*38c8a9a5SSteve French { 1022*38c8a9a5SSteve French struct smb_direct_sendmsg *sendmsg; 1023*38c8a9a5SSteve French struct smb_direct_data_transfer *packet; 1024*38c8a9a5SSteve French int header_length; 1025*38c8a9a5SSteve French int ret; 1026*38c8a9a5SSteve French 1027*38c8a9a5SSteve French sendmsg = smb_direct_alloc_sendmsg(t); 1028*38c8a9a5SSteve French if (IS_ERR(sendmsg)) 1029*38c8a9a5SSteve French return PTR_ERR(sendmsg); 1030*38c8a9a5SSteve French 1031*38c8a9a5SSteve French /* Fill in the packet header */ 1032*38c8a9a5SSteve French packet = (struct smb_direct_data_transfer *)sendmsg->packet; 1033*38c8a9a5SSteve French packet->credits_requested = cpu_to_le16(t->send_credit_target); 1034*38c8a9a5SSteve French packet->credits_granted = cpu_to_le16(manage_credits_prior_sending(t)); 1035*38c8a9a5SSteve French 1036*38c8a9a5SSteve French packet->flags = 0; 1037*38c8a9a5SSteve French packet->reserved = 0; 1038*38c8a9a5SSteve French if (!size) 1039*38c8a9a5SSteve French packet->data_offset = 0; 1040*38c8a9a5SSteve French else 1041*38c8a9a5SSteve French packet->data_offset = cpu_to_le32(24); 1042*38c8a9a5SSteve French packet->data_length = cpu_to_le32(size); 1043*38c8a9a5SSteve French packet->remaining_data_length = cpu_to_le32(remaining_data_length); 1044*38c8a9a5SSteve French packet->padding = 0; 1045*38c8a9a5SSteve French 1046*38c8a9a5SSteve French ksmbd_debug(RDMA, 1047*38c8a9a5SSteve French "credits_requested=%d credits_granted=%d data_offset=%d data_length=%d remaining_data_length=%d\n", 1048*38c8a9a5SSteve French le16_to_cpu(packet->credits_requested), 1049*38c8a9a5SSteve French le16_to_cpu(packet->credits_granted), 1050*38c8a9a5SSteve French le32_to_cpu(packet->data_offset), 1051*38c8a9a5SSteve French le32_to_cpu(packet->data_length), 1052*38c8a9a5SSteve French le32_to_cpu(packet->remaining_data_length)); 1053*38c8a9a5SSteve French 1054*38c8a9a5SSteve French /* Map the packet to DMA */ 1055*38c8a9a5SSteve French header_length = sizeof(struct smb_direct_data_transfer); 1056*38c8a9a5SSteve French /* If this is a packet without payload, don't send padding */ 1057*38c8a9a5SSteve French if (!size) 1058*38c8a9a5SSteve French header_length = 1059*38c8a9a5SSteve French offsetof(struct smb_direct_data_transfer, padding); 1060*38c8a9a5SSteve French 1061*38c8a9a5SSteve French sendmsg->sge[0].addr = ib_dma_map_single(t->cm_id->device, 1062*38c8a9a5SSteve French (void *)packet, 1063*38c8a9a5SSteve French header_length, 1064*38c8a9a5SSteve French DMA_TO_DEVICE); 1065*38c8a9a5SSteve French ret = ib_dma_mapping_error(t->cm_id->device, sendmsg->sge[0].addr); 1066*38c8a9a5SSteve French if (ret) { 1067*38c8a9a5SSteve French smb_direct_free_sendmsg(t, sendmsg); 1068*38c8a9a5SSteve French return ret; 1069*38c8a9a5SSteve French } 1070*38c8a9a5SSteve French 1071*38c8a9a5SSteve French sendmsg->num_sge = 1; 1072*38c8a9a5SSteve French sendmsg->sge[0].length = header_length; 1073*38c8a9a5SSteve French sendmsg->sge[0].lkey = t->pd->local_dma_lkey; 1074*38c8a9a5SSteve French 1075*38c8a9a5SSteve French *sendmsg_out = sendmsg; 1076*38c8a9a5SSteve French return 0; 1077*38c8a9a5SSteve French } 1078*38c8a9a5SSteve French 1079*38c8a9a5SSteve French static int get_sg_list(void *buf, int size, struct scatterlist *sg_list, int nentries) 1080*38c8a9a5SSteve French { 1081*38c8a9a5SSteve French bool high = is_vmalloc_addr(buf); 1082*38c8a9a5SSteve French struct page *page; 1083*38c8a9a5SSteve French int offset, len; 1084*38c8a9a5SSteve French int i = 0; 1085*38c8a9a5SSteve French 1086*38c8a9a5SSteve French if (size <= 0 || nentries < get_buf_page_count(buf, size)) 1087*38c8a9a5SSteve French return -EINVAL; 1088*38c8a9a5SSteve French 1089*38c8a9a5SSteve French offset = offset_in_page(buf); 1090*38c8a9a5SSteve French buf -= offset; 1091*38c8a9a5SSteve French while (size > 0) { 1092*38c8a9a5SSteve French len = min_t(int, PAGE_SIZE - offset, size); 1093*38c8a9a5SSteve French if (high) 1094*38c8a9a5SSteve French page = vmalloc_to_page(buf); 1095*38c8a9a5SSteve French else 1096*38c8a9a5SSteve French page = kmap_to_page(buf); 1097*38c8a9a5SSteve French 1098*38c8a9a5SSteve French if (!sg_list) 1099*38c8a9a5SSteve French return -EINVAL; 1100*38c8a9a5SSteve French sg_set_page(sg_list, page, len, offset); 1101*38c8a9a5SSteve French sg_list = sg_next(sg_list); 1102*38c8a9a5SSteve French 1103*38c8a9a5SSteve French buf += PAGE_SIZE; 1104*38c8a9a5SSteve French size -= len; 1105*38c8a9a5SSteve French offset = 0; 1106*38c8a9a5SSteve French i++; 1107*38c8a9a5SSteve French } 1108*38c8a9a5SSteve French return i; 1109*38c8a9a5SSteve French } 1110*38c8a9a5SSteve French 1111*38c8a9a5SSteve French static int get_mapped_sg_list(struct ib_device *device, void *buf, int size, 1112*38c8a9a5SSteve French struct scatterlist *sg_list, int nentries, 1113*38c8a9a5SSteve French enum dma_data_direction dir) 1114*38c8a9a5SSteve French { 1115*38c8a9a5SSteve French int npages; 1116*38c8a9a5SSteve French 1117*38c8a9a5SSteve French npages = get_sg_list(buf, size, sg_list, nentries); 1118*38c8a9a5SSteve French if (npages < 0) 1119*38c8a9a5SSteve French return -EINVAL; 1120*38c8a9a5SSteve French return ib_dma_map_sg(device, sg_list, npages, dir); 1121*38c8a9a5SSteve French } 1122*38c8a9a5SSteve French 1123*38c8a9a5SSteve French static int post_sendmsg(struct smb_direct_transport *t, 1124*38c8a9a5SSteve French struct smb_direct_send_ctx *send_ctx, 1125*38c8a9a5SSteve French struct smb_direct_sendmsg *msg) 1126*38c8a9a5SSteve French { 1127*38c8a9a5SSteve French int i; 1128*38c8a9a5SSteve French 1129*38c8a9a5SSteve French for (i = 0; i < msg->num_sge; i++) 1130*38c8a9a5SSteve French ib_dma_sync_single_for_device(t->cm_id->device, 1131*38c8a9a5SSteve French msg->sge[i].addr, msg->sge[i].length, 1132*38c8a9a5SSteve French DMA_TO_DEVICE); 1133*38c8a9a5SSteve French 1134*38c8a9a5SSteve French msg->cqe.done = send_done; 1135*38c8a9a5SSteve French msg->wr.opcode = IB_WR_SEND; 1136*38c8a9a5SSteve French msg->wr.sg_list = &msg->sge[0]; 1137*38c8a9a5SSteve French msg->wr.num_sge = msg->num_sge; 1138*38c8a9a5SSteve French msg->wr.next = NULL; 1139*38c8a9a5SSteve French 1140*38c8a9a5SSteve French if (send_ctx) { 1141*38c8a9a5SSteve French msg->wr.wr_cqe = NULL; 1142*38c8a9a5SSteve French msg->wr.send_flags = 0; 1143*38c8a9a5SSteve French if (!list_empty(&send_ctx->msg_list)) { 1144*38c8a9a5SSteve French struct smb_direct_sendmsg *last; 1145*38c8a9a5SSteve French 1146*38c8a9a5SSteve French last = list_last_entry(&send_ctx->msg_list, 1147*38c8a9a5SSteve French struct smb_direct_sendmsg, 1148*38c8a9a5SSteve French list); 1149*38c8a9a5SSteve French last->wr.next = &msg->wr; 1150*38c8a9a5SSteve French } 1151*38c8a9a5SSteve French list_add_tail(&msg->list, &send_ctx->msg_list); 1152*38c8a9a5SSteve French send_ctx->wr_cnt++; 1153*38c8a9a5SSteve French return 0; 1154*38c8a9a5SSteve French } 1155*38c8a9a5SSteve French 1156*38c8a9a5SSteve French msg->wr.wr_cqe = &msg->cqe; 1157*38c8a9a5SSteve French msg->wr.send_flags = IB_SEND_SIGNALED; 1158*38c8a9a5SSteve French return smb_direct_post_send(t, &msg->wr); 1159*38c8a9a5SSteve French } 1160*38c8a9a5SSteve French 1161*38c8a9a5SSteve French static int smb_direct_post_send_data(struct smb_direct_transport *t, 1162*38c8a9a5SSteve French struct smb_direct_send_ctx *send_ctx, 1163*38c8a9a5SSteve French struct kvec *iov, int niov, 1164*38c8a9a5SSteve French int remaining_data_length) 1165*38c8a9a5SSteve French { 1166*38c8a9a5SSteve French int i, j, ret; 1167*38c8a9a5SSteve French struct smb_direct_sendmsg *msg; 1168*38c8a9a5SSteve French int data_length; 1169*38c8a9a5SSteve French struct scatterlist sg[SMB_DIRECT_MAX_SEND_SGES - 1]; 1170*38c8a9a5SSteve French 1171*38c8a9a5SSteve French ret = wait_for_send_credits(t, send_ctx); 1172*38c8a9a5SSteve French if (ret) 1173*38c8a9a5SSteve French return ret; 1174*38c8a9a5SSteve French 1175*38c8a9a5SSteve French data_length = 0; 1176*38c8a9a5SSteve French for (i = 0; i < niov; i++) 1177*38c8a9a5SSteve French data_length += iov[i].iov_len; 1178*38c8a9a5SSteve French 1179*38c8a9a5SSteve French ret = smb_direct_create_header(t, data_length, remaining_data_length, 1180*38c8a9a5SSteve French &msg); 1181*38c8a9a5SSteve French if (ret) { 1182*38c8a9a5SSteve French atomic_inc(&t->send_credits); 1183*38c8a9a5SSteve French return ret; 1184*38c8a9a5SSteve French } 1185*38c8a9a5SSteve French 1186*38c8a9a5SSteve French for (i = 0; i < niov; i++) { 1187*38c8a9a5SSteve French struct ib_sge *sge; 1188*38c8a9a5SSteve French int sg_cnt; 1189*38c8a9a5SSteve French 1190*38c8a9a5SSteve French sg_init_table(sg, SMB_DIRECT_MAX_SEND_SGES - 1); 1191*38c8a9a5SSteve French sg_cnt = get_mapped_sg_list(t->cm_id->device, 1192*38c8a9a5SSteve French iov[i].iov_base, iov[i].iov_len, 1193*38c8a9a5SSteve French sg, SMB_DIRECT_MAX_SEND_SGES - 1, 1194*38c8a9a5SSteve French DMA_TO_DEVICE); 1195*38c8a9a5SSteve French if (sg_cnt <= 0) { 1196*38c8a9a5SSteve French pr_err("failed to map buffer\n"); 1197*38c8a9a5SSteve French ret = -ENOMEM; 1198*38c8a9a5SSteve French goto err; 1199*38c8a9a5SSteve French } else if (sg_cnt + msg->num_sge > SMB_DIRECT_MAX_SEND_SGES) { 1200*38c8a9a5SSteve French pr_err("buffer not fitted into sges\n"); 1201*38c8a9a5SSteve French ret = -E2BIG; 1202*38c8a9a5SSteve French ib_dma_unmap_sg(t->cm_id->device, sg, sg_cnt, 1203*38c8a9a5SSteve French DMA_TO_DEVICE); 1204*38c8a9a5SSteve French goto err; 1205*38c8a9a5SSteve French } 1206*38c8a9a5SSteve French 1207*38c8a9a5SSteve French for (j = 0; j < sg_cnt; j++) { 1208*38c8a9a5SSteve French sge = &msg->sge[msg->num_sge]; 1209*38c8a9a5SSteve French sge->addr = sg_dma_address(&sg[j]); 1210*38c8a9a5SSteve French sge->length = sg_dma_len(&sg[j]); 1211*38c8a9a5SSteve French sge->lkey = t->pd->local_dma_lkey; 1212*38c8a9a5SSteve French msg->num_sge++; 1213*38c8a9a5SSteve French } 1214*38c8a9a5SSteve French } 1215*38c8a9a5SSteve French 1216*38c8a9a5SSteve French ret = post_sendmsg(t, send_ctx, msg); 1217*38c8a9a5SSteve French if (ret) 1218*38c8a9a5SSteve French goto err; 1219*38c8a9a5SSteve French return 0; 1220*38c8a9a5SSteve French err: 1221*38c8a9a5SSteve French smb_direct_free_sendmsg(t, msg); 1222*38c8a9a5SSteve French atomic_inc(&t->send_credits); 1223*38c8a9a5SSteve French return ret; 1224*38c8a9a5SSteve French } 1225*38c8a9a5SSteve French 1226*38c8a9a5SSteve French static int smb_direct_writev(struct ksmbd_transport *t, 1227*38c8a9a5SSteve French struct kvec *iov, int niovs, int buflen, 1228*38c8a9a5SSteve French bool need_invalidate, unsigned int remote_key) 1229*38c8a9a5SSteve French { 1230*38c8a9a5SSteve French struct smb_direct_transport *st = smb_trans_direct_transfort(t); 1231*38c8a9a5SSteve French int remaining_data_length; 1232*38c8a9a5SSteve French int start, i, j; 1233*38c8a9a5SSteve French int max_iov_size = st->max_send_size - 1234*38c8a9a5SSteve French sizeof(struct smb_direct_data_transfer); 1235*38c8a9a5SSteve French int ret; 1236*38c8a9a5SSteve French struct kvec vec; 1237*38c8a9a5SSteve French struct smb_direct_send_ctx send_ctx; 1238*38c8a9a5SSteve French 1239*38c8a9a5SSteve French if (st->status != SMB_DIRECT_CS_CONNECTED) 1240*38c8a9a5SSteve French return -ENOTCONN; 1241*38c8a9a5SSteve French 1242*38c8a9a5SSteve French //FIXME: skip RFC1002 header.. 1243*38c8a9a5SSteve French buflen -= 4; 1244*38c8a9a5SSteve French iov[0].iov_base += 4; 1245*38c8a9a5SSteve French iov[0].iov_len -= 4; 1246*38c8a9a5SSteve French 1247*38c8a9a5SSteve French remaining_data_length = buflen; 1248*38c8a9a5SSteve French ksmbd_debug(RDMA, "Sending smb (RDMA): smb_len=%u\n", buflen); 1249*38c8a9a5SSteve French 1250*38c8a9a5SSteve French smb_direct_send_ctx_init(st, &send_ctx, need_invalidate, remote_key); 1251*38c8a9a5SSteve French start = i = 0; 1252*38c8a9a5SSteve French buflen = 0; 1253*38c8a9a5SSteve French while (true) { 1254*38c8a9a5SSteve French buflen += iov[i].iov_len; 1255*38c8a9a5SSteve French if (buflen > max_iov_size) { 1256*38c8a9a5SSteve French if (i > start) { 1257*38c8a9a5SSteve French remaining_data_length -= 1258*38c8a9a5SSteve French (buflen - iov[i].iov_len); 1259*38c8a9a5SSteve French ret = smb_direct_post_send_data(st, &send_ctx, 1260*38c8a9a5SSteve French &iov[start], i - start, 1261*38c8a9a5SSteve French remaining_data_length); 1262*38c8a9a5SSteve French if (ret) 1263*38c8a9a5SSteve French goto done; 1264*38c8a9a5SSteve French } else { 1265*38c8a9a5SSteve French /* iov[start] is too big, break it */ 1266*38c8a9a5SSteve French int nvec = (buflen + max_iov_size - 1) / 1267*38c8a9a5SSteve French max_iov_size; 1268*38c8a9a5SSteve French 1269*38c8a9a5SSteve French for (j = 0; j < nvec; j++) { 1270*38c8a9a5SSteve French vec.iov_base = 1271*38c8a9a5SSteve French (char *)iov[start].iov_base + 1272*38c8a9a5SSteve French j * max_iov_size; 1273*38c8a9a5SSteve French vec.iov_len = 1274*38c8a9a5SSteve French min_t(int, max_iov_size, 1275*38c8a9a5SSteve French buflen - max_iov_size * j); 1276*38c8a9a5SSteve French remaining_data_length -= vec.iov_len; 1277*38c8a9a5SSteve French ret = smb_direct_post_send_data(st, &send_ctx, &vec, 1, 1278*38c8a9a5SSteve French remaining_data_length); 1279*38c8a9a5SSteve French if (ret) 1280*38c8a9a5SSteve French goto done; 1281*38c8a9a5SSteve French } 1282*38c8a9a5SSteve French i++; 1283*38c8a9a5SSteve French if (i == niovs) 1284*38c8a9a5SSteve French break; 1285*38c8a9a5SSteve French } 1286*38c8a9a5SSteve French start = i; 1287*38c8a9a5SSteve French buflen = 0; 1288*38c8a9a5SSteve French } else { 1289*38c8a9a5SSteve French i++; 1290*38c8a9a5SSteve French if (i == niovs) { 1291*38c8a9a5SSteve French /* send out all remaining vecs */ 1292*38c8a9a5SSteve French remaining_data_length -= buflen; 1293*38c8a9a5SSteve French ret = smb_direct_post_send_data(st, &send_ctx, 1294*38c8a9a5SSteve French &iov[start], i - start, 1295*38c8a9a5SSteve French remaining_data_length); 1296*38c8a9a5SSteve French if (ret) 1297*38c8a9a5SSteve French goto done; 1298*38c8a9a5SSteve French break; 1299*38c8a9a5SSteve French } 1300*38c8a9a5SSteve French } 1301*38c8a9a5SSteve French } 1302*38c8a9a5SSteve French 1303*38c8a9a5SSteve French done: 1304*38c8a9a5SSteve French ret = smb_direct_flush_send_list(st, &send_ctx, true); 1305*38c8a9a5SSteve French 1306*38c8a9a5SSteve French /* 1307*38c8a9a5SSteve French * As an optimization, we don't wait for individual I/O to finish 1308*38c8a9a5SSteve French * before sending the next one. 1309*38c8a9a5SSteve French * Send them all and wait for pending send count to get to 0 1310*38c8a9a5SSteve French * that means all the I/Os have been out and we are good to return 1311*38c8a9a5SSteve French */ 1312*38c8a9a5SSteve French 1313*38c8a9a5SSteve French wait_event(st->wait_send_pending, 1314*38c8a9a5SSteve French atomic_read(&st->send_pending) == 0); 1315*38c8a9a5SSteve French return ret; 1316*38c8a9a5SSteve French } 1317*38c8a9a5SSteve French 1318*38c8a9a5SSteve French static void smb_direct_free_rdma_rw_msg(struct smb_direct_transport *t, 1319*38c8a9a5SSteve French struct smb_direct_rdma_rw_msg *msg, 1320*38c8a9a5SSteve French enum dma_data_direction dir) 1321*38c8a9a5SSteve French { 1322*38c8a9a5SSteve French rdma_rw_ctx_destroy(&msg->rw_ctx, t->qp, t->qp->port, 1323*38c8a9a5SSteve French msg->sgt.sgl, msg->sgt.nents, dir); 1324*38c8a9a5SSteve French sg_free_table_chained(&msg->sgt, SG_CHUNK_SIZE); 1325*38c8a9a5SSteve French kfree(msg); 1326*38c8a9a5SSteve French } 1327*38c8a9a5SSteve French 1328*38c8a9a5SSteve French static void read_write_done(struct ib_cq *cq, struct ib_wc *wc, 1329*38c8a9a5SSteve French enum dma_data_direction dir) 1330*38c8a9a5SSteve French { 1331*38c8a9a5SSteve French struct smb_direct_rdma_rw_msg *msg = container_of(wc->wr_cqe, 1332*38c8a9a5SSteve French struct smb_direct_rdma_rw_msg, cqe); 1333*38c8a9a5SSteve French struct smb_direct_transport *t = msg->t; 1334*38c8a9a5SSteve French 1335*38c8a9a5SSteve French if (wc->status != IB_WC_SUCCESS) { 1336*38c8a9a5SSteve French msg->status = -EIO; 1337*38c8a9a5SSteve French pr_err("read/write error. opcode = %d, status = %s(%d)\n", 1338*38c8a9a5SSteve French wc->opcode, ib_wc_status_msg(wc->status), wc->status); 1339*38c8a9a5SSteve French if (wc->status != IB_WC_WR_FLUSH_ERR) 1340*38c8a9a5SSteve French smb_direct_disconnect_rdma_connection(t); 1341*38c8a9a5SSteve French } 1342*38c8a9a5SSteve French 1343*38c8a9a5SSteve French complete(msg->completion); 1344*38c8a9a5SSteve French } 1345*38c8a9a5SSteve French 1346*38c8a9a5SSteve French static void read_done(struct ib_cq *cq, struct ib_wc *wc) 1347*38c8a9a5SSteve French { 1348*38c8a9a5SSteve French read_write_done(cq, wc, DMA_FROM_DEVICE); 1349*38c8a9a5SSteve French } 1350*38c8a9a5SSteve French 1351*38c8a9a5SSteve French static void write_done(struct ib_cq *cq, struct ib_wc *wc) 1352*38c8a9a5SSteve French { 1353*38c8a9a5SSteve French read_write_done(cq, wc, DMA_TO_DEVICE); 1354*38c8a9a5SSteve French } 1355*38c8a9a5SSteve French 1356*38c8a9a5SSteve French static int smb_direct_rdma_xmit(struct smb_direct_transport *t, 1357*38c8a9a5SSteve French void *buf, int buf_len, 1358*38c8a9a5SSteve French struct smb2_buffer_desc_v1 *desc, 1359*38c8a9a5SSteve French unsigned int desc_len, 1360*38c8a9a5SSteve French bool is_read) 1361*38c8a9a5SSteve French { 1362*38c8a9a5SSteve French struct smb_direct_rdma_rw_msg *msg, *next_msg; 1363*38c8a9a5SSteve French int i, ret; 1364*38c8a9a5SSteve French DECLARE_COMPLETION_ONSTACK(completion); 1365*38c8a9a5SSteve French struct ib_send_wr *first_wr; 1366*38c8a9a5SSteve French LIST_HEAD(msg_list); 1367*38c8a9a5SSteve French char *desc_buf; 1368*38c8a9a5SSteve French int credits_needed; 1369*38c8a9a5SSteve French unsigned int desc_buf_len; 1370*38c8a9a5SSteve French size_t total_length = 0; 1371*38c8a9a5SSteve French 1372*38c8a9a5SSteve French if (t->status != SMB_DIRECT_CS_CONNECTED) 1373*38c8a9a5SSteve French return -ENOTCONN; 1374*38c8a9a5SSteve French 1375*38c8a9a5SSteve French /* calculate needed credits */ 1376*38c8a9a5SSteve French credits_needed = 0; 1377*38c8a9a5SSteve French desc_buf = buf; 1378*38c8a9a5SSteve French for (i = 0; i < desc_len / sizeof(*desc); i++) { 1379*38c8a9a5SSteve French desc_buf_len = le32_to_cpu(desc[i].length); 1380*38c8a9a5SSteve French 1381*38c8a9a5SSteve French credits_needed += calc_rw_credits(t, desc_buf, desc_buf_len); 1382*38c8a9a5SSteve French desc_buf += desc_buf_len; 1383*38c8a9a5SSteve French total_length += desc_buf_len; 1384*38c8a9a5SSteve French if (desc_buf_len == 0 || total_length > buf_len || 1385*38c8a9a5SSteve French total_length > t->max_rdma_rw_size) 1386*38c8a9a5SSteve French return -EINVAL; 1387*38c8a9a5SSteve French } 1388*38c8a9a5SSteve French 1389*38c8a9a5SSteve French ksmbd_debug(RDMA, "RDMA %s, len %#x, needed credits %#x\n", 1390*38c8a9a5SSteve French is_read ? "read" : "write", buf_len, credits_needed); 1391*38c8a9a5SSteve French 1392*38c8a9a5SSteve French ret = wait_for_rw_credits(t, credits_needed); 1393*38c8a9a5SSteve French if (ret < 0) 1394*38c8a9a5SSteve French return ret; 1395*38c8a9a5SSteve French 1396*38c8a9a5SSteve French /* build rdma_rw_ctx for each descriptor */ 1397*38c8a9a5SSteve French desc_buf = buf; 1398*38c8a9a5SSteve French for (i = 0; i < desc_len / sizeof(*desc); i++) { 1399*38c8a9a5SSteve French msg = kzalloc(offsetof(struct smb_direct_rdma_rw_msg, sg_list) + 1400*38c8a9a5SSteve French sizeof(struct scatterlist) * SG_CHUNK_SIZE, GFP_KERNEL); 1401*38c8a9a5SSteve French if (!msg) { 1402*38c8a9a5SSteve French ret = -ENOMEM; 1403*38c8a9a5SSteve French goto out; 1404*38c8a9a5SSteve French } 1405*38c8a9a5SSteve French 1406*38c8a9a5SSteve French desc_buf_len = le32_to_cpu(desc[i].length); 1407*38c8a9a5SSteve French 1408*38c8a9a5SSteve French msg->t = t; 1409*38c8a9a5SSteve French msg->cqe.done = is_read ? read_done : write_done; 1410*38c8a9a5SSteve French msg->completion = &completion; 1411*38c8a9a5SSteve French 1412*38c8a9a5SSteve French msg->sgt.sgl = &msg->sg_list[0]; 1413*38c8a9a5SSteve French ret = sg_alloc_table_chained(&msg->sgt, 1414*38c8a9a5SSteve French get_buf_page_count(desc_buf, desc_buf_len), 1415*38c8a9a5SSteve French msg->sg_list, SG_CHUNK_SIZE); 1416*38c8a9a5SSteve French if (ret) { 1417*38c8a9a5SSteve French kfree(msg); 1418*38c8a9a5SSteve French ret = -ENOMEM; 1419*38c8a9a5SSteve French goto out; 1420*38c8a9a5SSteve French } 1421*38c8a9a5SSteve French 1422*38c8a9a5SSteve French ret = get_sg_list(desc_buf, desc_buf_len, 1423*38c8a9a5SSteve French msg->sgt.sgl, msg->sgt.orig_nents); 1424*38c8a9a5SSteve French if (ret < 0) { 1425*38c8a9a5SSteve French sg_free_table_chained(&msg->sgt, SG_CHUNK_SIZE); 1426*38c8a9a5SSteve French kfree(msg); 1427*38c8a9a5SSteve French goto out; 1428*38c8a9a5SSteve French } 1429*38c8a9a5SSteve French 1430*38c8a9a5SSteve French ret = rdma_rw_ctx_init(&msg->rw_ctx, t->qp, t->qp->port, 1431*38c8a9a5SSteve French msg->sgt.sgl, 1432*38c8a9a5SSteve French get_buf_page_count(desc_buf, desc_buf_len), 1433*38c8a9a5SSteve French 0, 1434*38c8a9a5SSteve French le64_to_cpu(desc[i].offset), 1435*38c8a9a5SSteve French le32_to_cpu(desc[i].token), 1436*38c8a9a5SSteve French is_read ? DMA_FROM_DEVICE : DMA_TO_DEVICE); 1437*38c8a9a5SSteve French if (ret < 0) { 1438*38c8a9a5SSteve French pr_err("failed to init rdma_rw_ctx: %d\n", ret); 1439*38c8a9a5SSteve French sg_free_table_chained(&msg->sgt, SG_CHUNK_SIZE); 1440*38c8a9a5SSteve French kfree(msg); 1441*38c8a9a5SSteve French goto out; 1442*38c8a9a5SSteve French } 1443*38c8a9a5SSteve French 1444*38c8a9a5SSteve French list_add_tail(&msg->list, &msg_list); 1445*38c8a9a5SSteve French desc_buf += desc_buf_len; 1446*38c8a9a5SSteve French } 1447*38c8a9a5SSteve French 1448*38c8a9a5SSteve French /* concatenate work requests of rdma_rw_ctxs */ 1449*38c8a9a5SSteve French first_wr = NULL; 1450*38c8a9a5SSteve French list_for_each_entry_reverse(msg, &msg_list, list) { 1451*38c8a9a5SSteve French first_wr = rdma_rw_ctx_wrs(&msg->rw_ctx, t->qp, t->qp->port, 1452*38c8a9a5SSteve French &msg->cqe, first_wr); 1453*38c8a9a5SSteve French } 1454*38c8a9a5SSteve French 1455*38c8a9a5SSteve French ret = ib_post_send(t->qp, first_wr, NULL); 1456*38c8a9a5SSteve French if (ret) { 1457*38c8a9a5SSteve French pr_err("failed to post send wr for RDMA R/W: %d\n", ret); 1458*38c8a9a5SSteve French goto out; 1459*38c8a9a5SSteve French } 1460*38c8a9a5SSteve French 1461*38c8a9a5SSteve French msg = list_last_entry(&msg_list, struct smb_direct_rdma_rw_msg, list); 1462*38c8a9a5SSteve French wait_for_completion(&completion); 1463*38c8a9a5SSteve French ret = msg->status; 1464*38c8a9a5SSteve French out: 1465*38c8a9a5SSteve French list_for_each_entry_safe(msg, next_msg, &msg_list, list) { 1466*38c8a9a5SSteve French list_del(&msg->list); 1467*38c8a9a5SSteve French smb_direct_free_rdma_rw_msg(t, msg, 1468*38c8a9a5SSteve French is_read ? DMA_FROM_DEVICE : DMA_TO_DEVICE); 1469*38c8a9a5SSteve French } 1470*38c8a9a5SSteve French atomic_add(credits_needed, &t->rw_credits); 1471*38c8a9a5SSteve French wake_up(&t->wait_rw_credits); 1472*38c8a9a5SSteve French return ret; 1473*38c8a9a5SSteve French } 1474*38c8a9a5SSteve French 1475*38c8a9a5SSteve French static int smb_direct_rdma_write(struct ksmbd_transport *t, 1476*38c8a9a5SSteve French void *buf, unsigned int buflen, 1477*38c8a9a5SSteve French struct smb2_buffer_desc_v1 *desc, 1478*38c8a9a5SSteve French unsigned int desc_len) 1479*38c8a9a5SSteve French { 1480*38c8a9a5SSteve French return smb_direct_rdma_xmit(smb_trans_direct_transfort(t), buf, buflen, 1481*38c8a9a5SSteve French desc, desc_len, false); 1482*38c8a9a5SSteve French } 1483*38c8a9a5SSteve French 1484*38c8a9a5SSteve French static int smb_direct_rdma_read(struct ksmbd_transport *t, 1485*38c8a9a5SSteve French void *buf, unsigned int buflen, 1486*38c8a9a5SSteve French struct smb2_buffer_desc_v1 *desc, 1487*38c8a9a5SSteve French unsigned int desc_len) 1488*38c8a9a5SSteve French { 1489*38c8a9a5SSteve French return smb_direct_rdma_xmit(smb_trans_direct_transfort(t), buf, buflen, 1490*38c8a9a5SSteve French desc, desc_len, true); 1491*38c8a9a5SSteve French } 1492*38c8a9a5SSteve French 1493*38c8a9a5SSteve French static void smb_direct_disconnect(struct ksmbd_transport *t) 1494*38c8a9a5SSteve French { 1495*38c8a9a5SSteve French struct smb_direct_transport *st = smb_trans_direct_transfort(t); 1496*38c8a9a5SSteve French 1497*38c8a9a5SSteve French ksmbd_debug(RDMA, "Disconnecting cm_id=%p\n", st->cm_id); 1498*38c8a9a5SSteve French 1499*38c8a9a5SSteve French smb_direct_disconnect_rdma_work(&st->disconnect_work); 1500*38c8a9a5SSteve French wait_event_interruptible(st->wait_status, 1501*38c8a9a5SSteve French st->status == SMB_DIRECT_CS_DISCONNECTED); 1502*38c8a9a5SSteve French free_transport(st); 1503*38c8a9a5SSteve French } 1504*38c8a9a5SSteve French 1505*38c8a9a5SSteve French static void smb_direct_shutdown(struct ksmbd_transport *t) 1506*38c8a9a5SSteve French { 1507*38c8a9a5SSteve French struct smb_direct_transport *st = smb_trans_direct_transfort(t); 1508*38c8a9a5SSteve French 1509*38c8a9a5SSteve French ksmbd_debug(RDMA, "smb-direct shutdown cm_id=%p\n", st->cm_id); 1510*38c8a9a5SSteve French 1511*38c8a9a5SSteve French smb_direct_disconnect_rdma_work(&st->disconnect_work); 1512*38c8a9a5SSteve French } 1513*38c8a9a5SSteve French 1514*38c8a9a5SSteve French static int smb_direct_cm_handler(struct rdma_cm_id *cm_id, 1515*38c8a9a5SSteve French struct rdma_cm_event *event) 1516*38c8a9a5SSteve French { 1517*38c8a9a5SSteve French struct smb_direct_transport *t = cm_id->context; 1518*38c8a9a5SSteve French 1519*38c8a9a5SSteve French ksmbd_debug(RDMA, "RDMA CM event. cm_id=%p event=%s (%d)\n", 1520*38c8a9a5SSteve French cm_id, rdma_event_msg(event->event), event->event); 1521*38c8a9a5SSteve French 1522*38c8a9a5SSteve French switch (event->event) { 1523*38c8a9a5SSteve French case RDMA_CM_EVENT_ESTABLISHED: { 1524*38c8a9a5SSteve French t->status = SMB_DIRECT_CS_CONNECTED; 1525*38c8a9a5SSteve French wake_up_interruptible(&t->wait_status); 1526*38c8a9a5SSteve French break; 1527*38c8a9a5SSteve French } 1528*38c8a9a5SSteve French case RDMA_CM_EVENT_DEVICE_REMOVAL: 1529*38c8a9a5SSteve French case RDMA_CM_EVENT_DISCONNECTED: { 1530*38c8a9a5SSteve French ib_drain_qp(t->qp); 1531*38c8a9a5SSteve French 1532*38c8a9a5SSteve French t->status = SMB_DIRECT_CS_DISCONNECTED; 1533*38c8a9a5SSteve French wake_up_interruptible(&t->wait_status); 1534*38c8a9a5SSteve French wake_up_interruptible(&t->wait_reassembly_queue); 1535*38c8a9a5SSteve French wake_up(&t->wait_send_credits); 1536*38c8a9a5SSteve French break; 1537*38c8a9a5SSteve French } 1538*38c8a9a5SSteve French case RDMA_CM_EVENT_CONNECT_ERROR: { 1539*38c8a9a5SSteve French t->status = SMB_DIRECT_CS_DISCONNECTED; 1540*38c8a9a5SSteve French wake_up_interruptible(&t->wait_status); 1541*38c8a9a5SSteve French break; 1542*38c8a9a5SSteve French } 1543*38c8a9a5SSteve French default: 1544*38c8a9a5SSteve French pr_err("Unexpected RDMA CM event. cm_id=%p, event=%s (%d)\n", 1545*38c8a9a5SSteve French cm_id, rdma_event_msg(event->event), 1546*38c8a9a5SSteve French event->event); 1547*38c8a9a5SSteve French break; 1548*38c8a9a5SSteve French } 1549*38c8a9a5SSteve French return 0; 1550*38c8a9a5SSteve French } 1551*38c8a9a5SSteve French 1552*38c8a9a5SSteve French static void smb_direct_qpair_handler(struct ib_event *event, void *context) 1553*38c8a9a5SSteve French { 1554*38c8a9a5SSteve French struct smb_direct_transport *t = context; 1555*38c8a9a5SSteve French 1556*38c8a9a5SSteve French ksmbd_debug(RDMA, "Received QP event. cm_id=%p, event=%s (%d)\n", 1557*38c8a9a5SSteve French t->cm_id, ib_event_msg(event->event), event->event); 1558*38c8a9a5SSteve French 1559*38c8a9a5SSteve French switch (event->event) { 1560*38c8a9a5SSteve French case IB_EVENT_CQ_ERR: 1561*38c8a9a5SSteve French case IB_EVENT_QP_FATAL: 1562*38c8a9a5SSteve French smb_direct_disconnect_rdma_connection(t); 1563*38c8a9a5SSteve French break; 1564*38c8a9a5SSteve French default: 1565*38c8a9a5SSteve French break; 1566*38c8a9a5SSteve French } 1567*38c8a9a5SSteve French } 1568*38c8a9a5SSteve French 1569*38c8a9a5SSteve French static int smb_direct_send_negotiate_response(struct smb_direct_transport *t, 1570*38c8a9a5SSteve French int failed) 1571*38c8a9a5SSteve French { 1572*38c8a9a5SSteve French struct smb_direct_sendmsg *sendmsg; 1573*38c8a9a5SSteve French struct smb_direct_negotiate_resp *resp; 1574*38c8a9a5SSteve French int ret; 1575*38c8a9a5SSteve French 1576*38c8a9a5SSteve French sendmsg = smb_direct_alloc_sendmsg(t); 1577*38c8a9a5SSteve French if (IS_ERR(sendmsg)) 1578*38c8a9a5SSteve French return -ENOMEM; 1579*38c8a9a5SSteve French 1580*38c8a9a5SSteve French resp = (struct smb_direct_negotiate_resp *)sendmsg->packet; 1581*38c8a9a5SSteve French if (failed) { 1582*38c8a9a5SSteve French memset(resp, 0, sizeof(*resp)); 1583*38c8a9a5SSteve French resp->min_version = cpu_to_le16(0x0100); 1584*38c8a9a5SSteve French resp->max_version = cpu_to_le16(0x0100); 1585*38c8a9a5SSteve French resp->status = STATUS_NOT_SUPPORTED; 1586*38c8a9a5SSteve French } else { 1587*38c8a9a5SSteve French resp->status = STATUS_SUCCESS; 1588*38c8a9a5SSteve French resp->min_version = SMB_DIRECT_VERSION_LE; 1589*38c8a9a5SSteve French resp->max_version = SMB_DIRECT_VERSION_LE; 1590*38c8a9a5SSteve French resp->negotiated_version = SMB_DIRECT_VERSION_LE; 1591*38c8a9a5SSteve French resp->reserved = 0; 1592*38c8a9a5SSteve French resp->credits_requested = 1593*38c8a9a5SSteve French cpu_to_le16(t->send_credit_target); 1594*38c8a9a5SSteve French resp->credits_granted = cpu_to_le16(manage_credits_prior_sending(t)); 1595*38c8a9a5SSteve French resp->max_readwrite_size = cpu_to_le32(t->max_rdma_rw_size); 1596*38c8a9a5SSteve French resp->preferred_send_size = cpu_to_le32(t->max_send_size); 1597*38c8a9a5SSteve French resp->max_receive_size = cpu_to_le32(t->max_recv_size); 1598*38c8a9a5SSteve French resp->max_fragmented_size = 1599*38c8a9a5SSteve French cpu_to_le32(t->max_fragmented_recv_size); 1600*38c8a9a5SSteve French } 1601*38c8a9a5SSteve French 1602*38c8a9a5SSteve French sendmsg->sge[0].addr = ib_dma_map_single(t->cm_id->device, 1603*38c8a9a5SSteve French (void *)resp, sizeof(*resp), 1604*38c8a9a5SSteve French DMA_TO_DEVICE); 1605*38c8a9a5SSteve French ret = ib_dma_mapping_error(t->cm_id->device, sendmsg->sge[0].addr); 1606*38c8a9a5SSteve French if (ret) { 1607*38c8a9a5SSteve French smb_direct_free_sendmsg(t, sendmsg); 1608*38c8a9a5SSteve French return ret; 1609*38c8a9a5SSteve French } 1610*38c8a9a5SSteve French 1611*38c8a9a5SSteve French sendmsg->num_sge = 1; 1612*38c8a9a5SSteve French sendmsg->sge[0].length = sizeof(*resp); 1613*38c8a9a5SSteve French sendmsg->sge[0].lkey = t->pd->local_dma_lkey; 1614*38c8a9a5SSteve French 1615*38c8a9a5SSteve French ret = post_sendmsg(t, NULL, sendmsg); 1616*38c8a9a5SSteve French if (ret) { 1617*38c8a9a5SSteve French smb_direct_free_sendmsg(t, sendmsg); 1618*38c8a9a5SSteve French return ret; 1619*38c8a9a5SSteve French } 1620*38c8a9a5SSteve French 1621*38c8a9a5SSteve French wait_event(t->wait_send_pending, 1622*38c8a9a5SSteve French atomic_read(&t->send_pending) == 0); 1623*38c8a9a5SSteve French return 0; 1624*38c8a9a5SSteve French } 1625*38c8a9a5SSteve French 1626*38c8a9a5SSteve French static int smb_direct_accept_client(struct smb_direct_transport *t) 1627*38c8a9a5SSteve French { 1628*38c8a9a5SSteve French struct rdma_conn_param conn_param; 1629*38c8a9a5SSteve French struct ib_port_immutable port_immutable; 1630*38c8a9a5SSteve French u32 ird_ord_hdr[2]; 1631*38c8a9a5SSteve French int ret; 1632*38c8a9a5SSteve French 1633*38c8a9a5SSteve French memset(&conn_param, 0, sizeof(conn_param)); 1634*38c8a9a5SSteve French conn_param.initiator_depth = min_t(u8, t->cm_id->device->attrs.max_qp_rd_atom, 1635*38c8a9a5SSteve French SMB_DIRECT_CM_INITIATOR_DEPTH); 1636*38c8a9a5SSteve French conn_param.responder_resources = 0; 1637*38c8a9a5SSteve French 1638*38c8a9a5SSteve French t->cm_id->device->ops.get_port_immutable(t->cm_id->device, 1639*38c8a9a5SSteve French t->cm_id->port_num, 1640*38c8a9a5SSteve French &port_immutable); 1641*38c8a9a5SSteve French if (port_immutable.core_cap_flags & RDMA_CORE_PORT_IWARP) { 1642*38c8a9a5SSteve French ird_ord_hdr[0] = conn_param.responder_resources; 1643*38c8a9a5SSteve French ird_ord_hdr[1] = 1; 1644*38c8a9a5SSteve French conn_param.private_data = ird_ord_hdr; 1645*38c8a9a5SSteve French conn_param.private_data_len = sizeof(ird_ord_hdr); 1646*38c8a9a5SSteve French } else { 1647*38c8a9a5SSteve French conn_param.private_data = NULL; 1648*38c8a9a5SSteve French conn_param.private_data_len = 0; 1649*38c8a9a5SSteve French } 1650*38c8a9a5SSteve French conn_param.retry_count = SMB_DIRECT_CM_RETRY; 1651*38c8a9a5SSteve French conn_param.rnr_retry_count = SMB_DIRECT_CM_RNR_RETRY; 1652*38c8a9a5SSteve French conn_param.flow_control = 0; 1653*38c8a9a5SSteve French 1654*38c8a9a5SSteve French ret = rdma_accept(t->cm_id, &conn_param); 1655*38c8a9a5SSteve French if (ret) { 1656*38c8a9a5SSteve French pr_err("error at rdma_accept: %d\n", ret); 1657*38c8a9a5SSteve French return ret; 1658*38c8a9a5SSteve French } 1659*38c8a9a5SSteve French return 0; 1660*38c8a9a5SSteve French } 1661*38c8a9a5SSteve French 1662*38c8a9a5SSteve French static int smb_direct_prepare_negotiation(struct smb_direct_transport *t) 1663*38c8a9a5SSteve French { 1664*38c8a9a5SSteve French int ret; 1665*38c8a9a5SSteve French struct smb_direct_recvmsg *recvmsg; 1666*38c8a9a5SSteve French 1667*38c8a9a5SSteve French recvmsg = get_free_recvmsg(t); 1668*38c8a9a5SSteve French if (!recvmsg) 1669*38c8a9a5SSteve French return -ENOMEM; 1670*38c8a9a5SSteve French recvmsg->type = SMB_DIRECT_MSG_NEGOTIATE_REQ; 1671*38c8a9a5SSteve French 1672*38c8a9a5SSteve French ret = smb_direct_post_recv(t, recvmsg); 1673*38c8a9a5SSteve French if (ret) { 1674*38c8a9a5SSteve French pr_err("Can't post recv: %d\n", ret); 1675*38c8a9a5SSteve French goto out_err; 1676*38c8a9a5SSteve French } 1677*38c8a9a5SSteve French 1678*38c8a9a5SSteve French t->negotiation_requested = false; 1679*38c8a9a5SSteve French ret = smb_direct_accept_client(t); 1680*38c8a9a5SSteve French if (ret) { 1681*38c8a9a5SSteve French pr_err("Can't accept client\n"); 1682*38c8a9a5SSteve French goto out_err; 1683*38c8a9a5SSteve French } 1684*38c8a9a5SSteve French 1685*38c8a9a5SSteve French smb_direct_post_recv_credits(&t->post_recv_credits_work.work); 1686*38c8a9a5SSteve French return 0; 1687*38c8a9a5SSteve French out_err: 1688*38c8a9a5SSteve French put_recvmsg(t, recvmsg); 1689*38c8a9a5SSteve French return ret; 1690*38c8a9a5SSteve French } 1691*38c8a9a5SSteve French 1692*38c8a9a5SSteve French static unsigned int smb_direct_get_max_fr_pages(struct smb_direct_transport *t) 1693*38c8a9a5SSteve French { 1694*38c8a9a5SSteve French return min_t(unsigned int, 1695*38c8a9a5SSteve French t->cm_id->device->attrs.max_fast_reg_page_list_len, 1696*38c8a9a5SSteve French 256); 1697*38c8a9a5SSteve French } 1698*38c8a9a5SSteve French 1699*38c8a9a5SSteve French static int smb_direct_init_params(struct smb_direct_transport *t, 1700*38c8a9a5SSteve French struct ib_qp_cap *cap) 1701*38c8a9a5SSteve French { 1702*38c8a9a5SSteve French struct ib_device *device = t->cm_id->device; 1703*38c8a9a5SSteve French int max_send_sges, max_rw_wrs, max_send_wrs; 1704*38c8a9a5SSteve French unsigned int max_sge_per_wr, wrs_per_credit; 1705*38c8a9a5SSteve French 1706*38c8a9a5SSteve French /* need 3 more sge. because a SMB_DIRECT header, SMB2 header, 1707*38c8a9a5SSteve French * SMB2 response could be mapped. 1708*38c8a9a5SSteve French */ 1709*38c8a9a5SSteve French t->max_send_size = smb_direct_max_send_size; 1710*38c8a9a5SSteve French max_send_sges = DIV_ROUND_UP(t->max_send_size, PAGE_SIZE) + 3; 1711*38c8a9a5SSteve French if (max_send_sges > SMB_DIRECT_MAX_SEND_SGES) { 1712*38c8a9a5SSteve French pr_err("max_send_size %d is too large\n", t->max_send_size); 1713*38c8a9a5SSteve French return -EINVAL; 1714*38c8a9a5SSteve French } 1715*38c8a9a5SSteve French 1716*38c8a9a5SSteve French /* Calculate the number of work requests for RDMA R/W. 1717*38c8a9a5SSteve French * The maximum number of pages which can be registered 1718*38c8a9a5SSteve French * with one Memory region can be transferred with one 1719*38c8a9a5SSteve French * R/W credit. And at least 4 work requests for each credit 1720*38c8a9a5SSteve French * are needed for MR registration, RDMA R/W, local & remote 1721*38c8a9a5SSteve French * MR invalidation. 1722*38c8a9a5SSteve French */ 1723*38c8a9a5SSteve French t->max_rdma_rw_size = smb_direct_max_read_write_size; 1724*38c8a9a5SSteve French t->pages_per_rw_credit = smb_direct_get_max_fr_pages(t); 1725*38c8a9a5SSteve French t->max_rw_credits = DIV_ROUND_UP(t->max_rdma_rw_size, 1726*38c8a9a5SSteve French (t->pages_per_rw_credit - 1) * 1727*38c8a9a5SSteve French PAGE_SIZE); 1728*38c8a9a5SSteve French 1729*38c8a9a5SSteve French max_sge_per_wr = min_t(unsigned int, device->attrs.max_send_sge, 1730*38c8a9a5SSteve French device->attrs.max_sge_rd); 1731*38c8a9a5SSteve French max_sge_per_wr = max_t(unsigned int, max_sge_per_wr, 1732*38c8a9a5SSteve French max_send_sges); 1733*38c8a9a5SSteve French wrs_per_credit = max_t(unsigned int, 4, 1734*38c8a9a5SSteve French DIV_ROUND_UP(t->pages_per_rw_credit, 1735*38c8a9a5SSteve French max_sge_per_wr) + 1); 1736*38c8a9a5SSteve French max_rw_wrs = t->max_rw_credits * wrs_per_credit; 1737*38c8a9a5SSteve French 1738*38c8a9a5SSteve French max_send_wrs = smb_direct_send_credit_target + max_rw_wrs; 1739*38c8a9a5SSteve French if (max_send_wrs > device->attrs.max_cqe || 1740*38c8a9a5SSteve French max_send_wrs > device->attrs.max_qp_wr) { 1741*38c8a9a5SSteve French pr_err("consider lowering send_credit_target = %d\n", 1742*38c8a9a5SSteve French smb_direct_send_credit_target); 1743*38c8a9a5SSteve French pr_err("Possible CQE overrun, device reporting max_cqe %d max_qp_wr %d\n", 1744*38c8a9a5SSteve French device->attrs.max_cqe, device->attrs.max_qp_wr); 1745*38c8a9a5SSteve French return -EINVAL; 1746*38c8a9a5SSteve French } 1747*38c8a9a5SSteve French 1748*38c8a9a5SSteve French if (smb_direct_receive_credit_max > device->attrs.max_cqe || 1749*38c8a9a5SSteve French smb_direct_receive_credit_max > device->attrs.max_qp_wr) { 1750*38c8a9a5SSteve French pr_err("consider lowering receive_credit_max = %d\n", 1751*38c8a9a5SSteve French smb_direct_receive_credit_max); 1752*38c8a9a5SSteve French pr_err("Possible CQE overrun, device reporting max_cpe %d max_qp_wr %d\n", 1753*38c8a9a5SSteve French device->attrs.max_cqe, device->attrs.max_qp_wr); 1754*38c8a9a5SSteve French return -EINVAL; 1755*38c8a9a5SSteve French } 1756*38c8a9a5SSteve French 1757*38c8a9a5SSteve French if (device->attrs.max_recv_sge < SMB_DIRECT_MAX_RECV_SGES) { 1758*38c8a9a5SSteve French pr_err("warning: device max_recv_sge = %d too small\n", 1759*38c8a9a5SSteve French device->attrs.max_recv_sge); 1760*38c8a9a5SSteve French return -EINVAL; 1761*38c8a9a5SSteve French } 1762*38c8a9a5SSteve French 1763*38c8a9a5SSteve French t->recv_credits = 0; 1764*38c8a9a5SSteve French t->count_avail_recvmsg = 0; 1765*38c8a9a5SSteve French 1766*38c8a9a5SSteve French t->recv_credit_max = smb_direct_receive_credit_max; 1767*38c8a9a5SSteve French t->recv_credit_target = 10; 1768*38c8a9a5SSteve French t->new_recv_credits = 0; 1769*38c8a9a5SSteve French 1770*38c8a9a5SSteve French t->send_credit_target = smb_direct_send_credit_target; 1771*38c8a9a5SSteve French atomic_set(&t->send_credits, 0); 1772*38c8a9a5SSteve French atomic_set(&t->rw_credits, t->max_rw_credits); 1773*38c8a9a5SSteve French 1774*38c8a9a5SSteve French t->max_send_size = smb_direct_max_send_size; 1775*38c8a9a5SSteve French t->max_recv_size = smb_direct_max_receive_size; 1776*38c8a9a5SSteve French t->max_fragmented_recv_size = smb_direct_max_fragmented_recv_size; 1777*38c8a9a5SSteve French 1778*38c8a9a5SSteve French cap->max_send_wr = max_send_wrs; 1779*38c8a9a5SSteve French cap->max_recv_wr = t->recv_credit_max; 1780*38c8a9a5SSteve French cap->max_send_sge = max_sge_per_wr; 1781*38c8a9a5SSteve French cap->max_recv_sge = SMB_DIRECT_MAX_RECV_SGES; 1782*38c8a9a5SSteve French cap->max_inline_data = 0; 1783*38c8a9a5SSteve French cap->max_rdma_ctxs = t->max_rw_credits; 1784*38c8a9a5SSteve French return 0; 1785*38c8a9a5SSteve French } 1786*38c8a9a5SSteve French 1787*38c8a9a5SSteve French static void smb_direct_destroy_pools(struct smb_direct_transport *t) 1788*38c8a9a5SSteve French { 1789*38c8a9a5SSteve French struct smb_direct_recvmsg *recvmsg; 1790*38c8a9a5SSteve French 1791*38c8a9a5SSteve French while ((recvmsg = get_free_recvmsg(t))) 1792*38c8a9a5SSteve French mempool_free(recvmsg, t->recvmsg_mempool); 1793*38c8a9a5SSteve French while ((recvmsg = get_empty_recvmsg(t))) 1794*38c8a9a5SSteve French mempool_free(recvmsg, t->recvmsg_mempool); 1795*38c8a9a5SSteve French 1796*38c8a9a5SSteve French mempool_destroy(t->recvmsg_mempool); 1797*38c8a9a5SSteve French t->recvmsg_mempool = NULL; 1798*38c8a9a5SSteve French 1799*38c8a9a5SSteve French kmem_cache_destroy(t->recvmsg_cache); 1800*38c8a9a5SSteve French t->recvmsg_cache = NULL; 1801*38c8a9a5SSteve French 1802*38c8a9a5SSteve French mempool_destroy(t->sendmsg_mempool); 1803*38c8a9a5SSteve French t->sendmsg_mempool = NULL; 1804*38c8a9a5SSteve French 1805*38c8a9a5SSteve French kmem_cache_destroy(t->sendmsg_cache); 1806*38c8a9a5SSteve French t->sendmsg_cache = NULL; 1807*38c8a9a5SSteve French } 1808*38c8a9a5SSteve French 1809*38c8a9a5SSteve French static int smb_direct_create_pools(struct smb_direct_transport *t) 1810*38c8a9a5SSteve French { 1811*38c8a9a5SSteve French char name[80]; 1812*38c8a9a5SSteve French int i; 1813*38c8a9a5SSteve French struct smb_direct_recvmsg *recvmsg; 1814*38c8a9a5SSteve French 1815*38c8a9a5SSteve French snprintf(name, sizeof(name), "smb_direct_rqst_pool_%p", t); 1816*38c8a9a5SSteve French t->sendmsg_cache = kmem_cache_create(name, 1817*38c8a9a5SSteve French sizeof(struct smb_direct_sendmsg) + 1818*38c8a9a5SSteve French sizeof(struct smb_direct_negotiate_resp), 1819*38c8a9a5SSteve French 0, SLAB_HWCACHE_ALIGN, NULL); 1820*38c8a9a5SSteve French if (!t->sendmsg_cache) 1821*38c8a9a5SSteve French return -ENOMEM; 1822*38c8a9a5SSteve French 1823*38c8a9a5SSteve French t->sendmsg_mempool = mempool_create(t->send_credit_target, 1824*38c8a9a5SSteve French mempool_alloc_slab, mempool_free_slab, 1825*38c8a9a5SSteve French t->sendmsg_cache); 1826*38c8a9a5SSteve French if (!t->sendmsg_mempool) 1827*38c8a9a5SSteve French goto err; 1828*38c8a9a5SSteve French 1829*38c8a9a5SSteve French snprintf(name, sizeof(name), "smb_direct_resp_%p", t); 1830*38c8a9a5SSteve French t->recvmsg_cache = kmem_cache_create(name, 1831*38c8a9a5SSteve French sizeof(struct smb_direct_recvmsg) + 1832*38c8a9a5SSteve French t->max_recv_size, 1833*38c8a9a5SSteve French 0, SLAB_HWCACHE_ALIGN, NULL); 1834*38c8a9a5SSteve French if (!t->recvmsg_cache) 1835*38c8a9a5SSteve French goto err; 1836*38c8a9a5SSteve French 1837*38c8a9a5SSteve French t->recvmsg_mempool = 1838*38c8a9a5SSteve French mempool_create(t->recv_credit_max, mempool_alloc_slab, 1839*38c8a9a5SSteve French mempool_free_slab, t->recvmsg_cache); 1840*38c8a9a5SSteve French if (!t->recvmsg_mempool) 1841*38c8a9a5SSteve French goto err; 1842*38c8a9a5SSteve French 1843*38c8a9a5SSteve French INIT_LIST_HEAD(&t->recvmsg_queue); 1844*38c8a9a5SSteve French 1845*38c8a9a5SSteve French for (i = 0; i < t->recv_credit_max; i++) { 1846*38c8a9a5SSteve French recvmsg = mempool_alloc(t->recvmsg_mempool, GFP_KERNEL); 1847*38c8a9a5SSteve French if (!recvmsg) 1848*38c8a9a5SSteve French goto err; 1849*38c8a9a5SSteve French recvmsg->transport = t; 1850*38c8a9a5SSteve French list_add(&recvmsg->list, &t->recvmsg_queue); 1851*38c8a9a5SSteve French } 1852*38c8a9a5SSteve French t->count_avail_recvmsg = t->recv_credit_max; 1853*38c8a9a5SSteve French 1854*38c8a9a5SSteve French return 0; 1855*38c8a9a5SSteve French err: 1856*38c8a9a5SSteve French smb_direct_destroy_pools(t); 1857*38c8a9a5SSteve French return -ENOMEM; 1858*38c8a9a5SSteve French } 1859*38c8a9a5SSteve French 1860*38c8a9a5SSteve French static int smb_direct_create_qpair(struct smb_direct_transport *t, 1861*38c8a9a5SSteve French struct ib_qp_cap *cap) 1862*38c8a9a5SSteve French { 1863*38c8a9a5SSteve French int ret; 1864*38c8a9a5SSteve French struct ib_qp_init_attr qp_attr; 1865*38c8a9a5SSteve French int pages_per_rw; 1866*38c8a9a5SSteve French 1867*38c8a9a5SSteve French t->pd = ib_alloc_pd(t->cm_id->device, 0); 1868*38c8a9a5SSteve French if (IS_ERR(t->pd)) { 1869*38c8a9a5SSteve French pr_err("Can't create RDMA PD\n"); 1870*38c8a9a5SSteve French ret = PTR_ERR(t->pd); 1871*38c8a9a5SSteve French t->pd = NULL; 1872*38c8a9a5SSteve French return ret; 1873*38c8a9a5SSteve French } 1874*38c8a9a5SSteve French 1875*38c8a9a5SSteve French t->send_cq = ib_alloc_cq(t->cm_id->device, t, 1876*38c8a9a5SSteve French smb_direct_send_credit_target + cap->max_rdma_ctxs, 1877*38c8a9a5SSteve French 0, IB_POLL_WORKQUEUE); 1878*38c8a9a5SSteve French if (IS_ERR(t->send_cq)) { 1879*38c8a9a5SSteve French pr_err("Can't create RDMA send CQ\n"); 1880*38c8a9a5SSteve French ret = PTR_ERR(t->send_cq); 1881*38c8a9a5SSteve French t->send_cq = NULL; 1882*38c8a9a5SSteve French goto err; 1883*38c8a9a5SSteve French } 1884*38c8a9a5SSteve French 1885*38c8a9a5SSteve French t->recv_cq = ib_alloc_cq(t->cm_id->device, t, 1886*38c8a9a5SSteve French t->recv_credit_max, 0, IB_POLL_WORKQUEUE); 1887*38c8a9a5SSteve French if (IS_ERR(t->recv_cq)) { 1888*38c8a9a5SSteve French pr_err("Can't create RDMA recv CQ\n"); 1889*38c8a9a5SSteve French ret = PTR_ERR(t->recv_cq); 1890*38c8a9a5SSteve French t->recv_cq = NULL; 1891*38c8a9a5SSteve French goto err; 1892*38c8a9a5SSteve French } 1893*38c8a9a5SSteve French 1894*38c8a9a5SSteve French memset(&qp_attr, 0, sizeof(qp_attr)); 1895*38c8a9a5SSteve French qp_attr.event_handler = smb_direct_qpair_handler; 1896*38c8a9a5SSteve French qp_attr.qp_context = t; 1897*38c8a9a5SSteve French qp_attr.cap = *cap; 1898*38c8a9a5SSteve French qp_attr.sq_sig_type = IB_SIGNAL_REQ_WR; 1899*38c8a9a5SSteve French qp_attr.qp_type = IB_QPT_RC; 1900*38c8a9a5SSteve French qp_attr.send_cq = t->send_cq; 1901*38c8a9a5SSteve French qp_attr.recv_cq = t->recv_cq; 1902*38c8a9a5SSteve French qp_attr.port_num = ~0; 1903*38c8a9a5SSteve French 1904*38c8a9a5SSteve French ret = rdma_create_qp(t->cm_id, t->pd, &qp_attr); 1905*38c8a9a5SSteve French if (ret) { 1906*38c8a9a5SSteve French pr_err("Can't create RDMA QP: %d\n", ret); 1907*38c8a9a5SSteve French goto err; 1908*38c8a9a5SSteve French } 1909*38c8a9a5SSteve French 1910*38c8a9a5SSteve French t->qp = t->cm_id->qp; 1911*38c8a9a5SSteve French t->cm_id->event_handler = smb_direct_cm_handler; 1912*38c8a9a5SSteve French 1913*38c8a9a5SSteve French pages_per_rw = DIV_ROUND_UP(t->max_rdma_rw_size, PAGE_SIZE) + 1; 1914*38c8a9a5SSteve French if (pages_per_rw > t->cm_id->device->attrs.max_sgl_rd) { 1915*38c8a9a5SSteve French ret = ib_mr_pool_init(t->qp, &t->qp->rdma_mrs, 1916*38c8a9a5SSteve French t->max_rw_credits, IB_MR_TYPE_MEM_REG, 1917*38c8a9a5SSteve French t->pages_per_rw_credit, 0); 1918*38c8a9a5SSteve French if (ret) { 1919*38c8a9a5SSteve French pr_err("failed to init mr pool count %d pages %d\n", 1920*38c8a9a5SSteve French t->max_rw_credits, t->pages_per_rw_credit); 1921*38c8a9a5SSteve French goto err; 1922*38c8a9a5SSteve French } 1923*38c8a9a5SSteve French } 1924*38c8a9a5SSteve French 1925*38c8a9a5SSteve French return 0; 1926*38c8a9a5SSteve French err: 1927*38c8a9a5SSteve French if (t->qp) { 1928*38c8a9a5SSteve French ib_destroy_qp(t->qp); 1929*38c8a9a5SSteve French t->qp = NULL; 1930*38c8a9a5SSteve French } 1931*38c8a9a5SSteve French if (t->recv_cq) { 1932*38c8a9a5SSteve French ib_destroy_cq(t->recv_cq); 1933*38c8a9a5SSteve French t->recv_cq = NULL; 1934*38c8a9a5SSteve French } 1935*38c8a9a5SSteve French if (t->send_cq) { 1936*38c8a9a5SSteve French ib_destroy_cq(t->send_cq); 1937*38c8a9a5SSteve French t->send_cq = NULL; 1938*38c8a9a5SSteve French } 1939*38c8a9a5SSteve French if (t->pd) { 1940*38c8a9a5SSteve French ib_dealloc_pd(t->pd); 1941*38c8a9a5SSteve French t->pd = NULL; 1942*38c8a9a5SSteve French } 1943*38c8a9a5SSteve French return ret; 1944*38c8a9a5SSteve French } 1945*38c8a9a5SSteve French 1946*38c8a9a5SSteve French static int smb_direct_prepare(struct ksmbd_transport *t) 1947*38c8a9a5SSteve French { 1948*38c8a9a5SSteve French struct smb_direct_transport *st = smb_trans_direct_transfort(t); 1949*38c8a9a5SSteve French struct smb_direct_recvmsg *recvmsg; 1950*38c8a9a5SSteve French struct smb_direct_negotiate_req *req; 1951*38c8a9a5SSteve French int ret; 1952*38c8a9a5SSteve French 1953*38c8a9a5SSteve French ksmbd_debug(RDMA, "Waiting for SMB_DIRECT negotiate request\n"); 1954*38c8a9a5SSteve French ret = wait_event_interruptible_timeout(st->wait_status, 1955*38c8a9a5SSteve French st->negotiation_requested || 1956*38c8a9a5SSteve French st->status == SMB_DIRECT_CS_DISCONNECTED, 1957*38c8a9a5SSteve French SMB_DIRECT_NEGOTIATE_TIMEOUT * HZ); 1958*38c8a9a5SSteve French if (ret <= 0 || st->status == SMB_DIRECT_CS_DISCONNECTED) 1959*38c8a9a5SSteve French return ret < 0 ? ret : -ETIMEDOUT; 1960*38c8a9a5SSteve French 1961*38c8a9a5SSteve French recvmsg = get_first_reassembly(st); 1962*38c8a9a5SSteve French if (!recvmsg) 1963*38c8a9a5SSteve French return -ECONNABORTED; 1964*38c8a9a5SSteve French 1965*38c8a9a5SSteve French ret = smb_direct_check_recvmsg(recvmsg); 1966*38c8a9a5SSteve French if (ret == -ECONNABORTED) 1967*38c8a9a5SSteve French goto out; 1968*38c8a9a5SSteve French 1969*38c8a9a5SSteve French req = (struct smb_direct_negotiate_req *)recvmsg->packet; 1970*38c8a9a5SSteve French st->max_recv_size = min_t(int, st->max_recv_size, 1971*38c8a9a5SSteve French le32_to_cpu(req->preferred_send_size)); 1972*38c8a9a5SSteve French st->max_send_size = min_t(int, st->max_send_size, 1973*38c8a9a5SSteve French le32_to_cpu(req->max_receive_size)); 1974*38c8a9a5SSteve French st->max_fragmented_send_size = 1975*38c8a9a5SSteve French le32_to_cpu(req->max_fragmented_size); 1976*38c8a9a5SSteve French st->max_fragmented_recv_size = 1977*38c8a9a5SSteve French (st->recv_credit_max * st->max_recv_size) / 2; 1978*38c8a9a5SSteve French 1979*38c8a9a5SSteve French ret = smb_direct_send_negotiate_response(st, ret); 1980*38c8a9a5SSteve French out: 1981*38c8a9a5SSteve French spin_lock_irq(&st->reassembly_queue_lock); 1982*38c8a9a5SSteve French st->reassembly_queue_length--; 1983*38c8a9a5SSteve French list_del(&recvmsg->list); 1984*38c8a9a5SSteve French spin_unlock_irq(&st->reassembly_queue_lock); 1985*38c8a9a5SSteve French put_recvmsg(st, recvmsg); 1986*38c8a9a5SSteve French 1987*38c8a9a5SSteve French return ret; 1988*38c8a9a5SSteve French } 1989*38c8a9a5SSteve French 1990*38c8a9a5SSteve French static int smb_direct_connect(struct smb_direct_transport *st) 1991*38c8a9a5SSteve French { 1992*38c8a9a5SSteve French int ret; 1993*38c8a9a5SSteve French struct ib_qp_cap qp_cap; 1994*38c8a9a5SSteve French 1995*38c8a9a5SSteve French ret = smb_direct_init_params(st, &qp_cap); 1996*38c8a9a5SSteve French if (ret) { 1997*38c8a9a5SSteve French pr_err("Can't configure RDMA parameters\n"); 1998*38c8a9a5SSteve French return ret; 1999*38c8a9a5SSteve French } 2000*38c8a9a5SSteve French 2001*38c8a9a5SSteve French ret = smb_direct_create_pools(st); 2002*38c8a9a5SSteve French if (ret) { 2003*38c8a9a5SSteve French pr_err("Can't init RDMA pool: %d\n", ret); 2004*38c8a9a5SSteve French return ret; 2005*38c8a9a5SSteve French } 2006*38c8a9a5SSteve French 2007*38c8a9a5SSteve French ret = smb_direct_create_qpair(st, &qp_cap); 2008*38c8a9a5SSteve French if (ret) { 2009*38c8a9a5SSteve French pr_err("Can't accept RDMA client: %d\n", ret); 2010*38c8a9a5SSteve French return ret; 2011*38c8a9a5SSteve French } 2012*38c8a9a5SSteve French 2013*38c8a9a5SSteve French ret = smb_direct_prepare_negotiation(st); 2014*38c8a9a5SSteve French if (ret) { 2015*38c8a9a5SSteve French pr_err("Can't negotiate: %d\n", ret); 2016*38c8a9a5SSteve French return ret; 2017*38c8a9a5SSteve French } 2018*38c8a9a5SSteve French return 0; 2019*38c8a9a5SSteve French } 2020*38c8a9a5SSteve French 2021*38c8a9a5SSteve French static bool rdma_frwr_is_supported(struct ib_device_attr *attrs) 2022*38c8a9a5SSteve French { 2023*38c8a9a5SSteve French if (!(attrs->device_cap_flags & IB_DEVICE_MEM_MGT_EXTENSIONS)) 2024*38c8a9a5SSteve French return false; 2025*38c8a9a5SSteve French if (attrs->max_fast_reg_page_list_len == 0) 2026*38c8a9a5SSteve French return false; 2027*38c8a9a5SSteve French return true; 2028*38c8a9a5SSteve French } 2029*38c8a9a5SSteve French 2030*38c8a9a5SSteve French static int smb_direct_handle_connect_request(struct rdma_cm_id *new_cm_id) 2031*38c8a9a5SSteve French { 2032*38c8a9a5SSteve French struct smb_direct_transport *t; 2033*38c8a9a5SSteve French int ret; 2034*38c8a9a5SSteve French 2035*38c8a9a5SSteve French if (!rdma_frwr_is_supported(&new_cm_id->device->attrs)) { 2036*38c8a9a5SSteve French ksmbd_debug(RDMA, 2037*38c8a9a5SSteve French "Fast Registration Work Requests is not supported. device capabilities=%llx\n", 2038*38c8a9a5SSteve French new_cm_id->device->attrs.device_cap_flags); 2039*38c8a9a5SSteve French return -EPROTONOSUPPORT; 2040*38c8a9a5SSteve French } 2041*38c8a9a5SSteve French 2042*38c8a9a5SSteve French t = alloc_transport(new_cm_id); 2043*38c8a9a5SSteve French if (!t) 2044*38c8a9a5SSteve French return -ENOMEM; 2045*38c8a9a5SSteve French 2046*38c8a9a5SSteve French ret = smb_direct_connect(t); 2047*38c8a9a5SSteve French if (ret) 2048*38c8a9a5SSteve French goto out_err; 2049*38c8a9a5SSteve French 2050*38c8a9a5SSteve French KSMBD_TRANS(t)->handler = kthread_run(ksmbd_conn_handler_loop, 2051*38c8a9a5SSteve French KSMBD_TRANS(t)->conn, "ksmbd:r%u", 2052*38c8a9a5SSteve French smb_direct_port); 2053*38c8a9a5SSteve French if (IS_ERR(KSMBD_TRANS(t)->handler)) { 2054*38c8a9a5SSteve French ret = PTR_ERR(KSMBD_TRANS(t)->handler); 2055*38c8a9a5SSteve French pr_err("Can't start thread\n"); 2056*38c8a9a5SSteve French goto out_err; 2057*38c8a9a5SSteve French } 2058*38c8a9a5SSteve French 2059*38c8a9a5SSteve French return 0; 2060*38c8a9a5SSteve French out_err: 2061*38c8a9a5SSteve French free_transport(t); 2062*38c8a9a5SSteve French return ret; 2063*38c8a9a5SSteve French } 2064*38c8a9a5SSteve French 2065*38c8a9a5SSteve French static int smb_direct_listen_handler(struct rdma_cm_id *cm_id, 2066*38c8a9a5SSteve French struct rdma_cm_event *event) 2067*38c8a9a5SSteve French { 2068*38c8a9a5SSteve French switch (event->event) { 2069*38c8a9a5SSteve French case RDMA_CM_EVENT_CONNECT_REQUEST: { 2070*38c8a9a5SSteve French int ret = smb_direct_handle_connect_request(cm_id); 2071*38c8a9a5SSteve French 2072*38c8a9a5SSteve French if (ret) { 2073*38c8a9a5SSteve French pr_err("Can't create transport: %d\n", ret); 2074*38c8a9a5SSteve French return ret; 2075*38c8a9a5SSteve French } 2076*38c8a9a5SSteve French 2077*38c8a9a5SSteve French ksmbd_debug(RDMA, "Received connection request. cm_id=%p\n", 2078*38c8a9a5SSteve French cm_id); 2079*38c8a9a5SSteve French break; 2080*38c8a9a5SSteve French } 2081*38c8a9a5SSteve French default: 2082*38c8a9a5SSteve French pr_err("Unexpected listen event. cm_id=%p, event=%s (%d)\n", 2083*38c8a9a5SSteve French cm_id, rdma_event_msg(event->event), event->event); 2084*38c8a9a5SSteve French break; 2085*38c8a9a5SSteve French } 2086*38c8a9a5SSteve French return 0; 2087*38c8a9a5SSteve French } 2088*38c8a9a5SSteve French 2089*38c8a9a5SSteve French static int smb_direct_listen(int port) 2090*38c8a9a5SSteve French { 2091*38c8a9a5SSteve French int ret; 2092*38c8a9a5SSteve French struct rdma_cm_id *cm_id; 2093*38c8a9a5SSteve French struct sockaddr_in sin = { 2094*38c8a9a5SSteve French .sin_family = AF_INET, 2095*38c8a9a5SSteve French .sin_addr.s_addr = htonl(INADDR_ANY), 2096*38c8a9a5SSteve French .sin_port = htons(port), 2097*38c8a9a5SSteve French }; 2098*38c8a9a5SSteve French 2099*38c8a9a5SSteve French cm_id = rdma_create_id(&init_net, smb_direct_listen_handler, 2100*38c8a9a5SSteve French &smb_direct_listener, RDMA_PS_TCP, IB_QPT_RC); 2101*38c8a9a5SSteve French if (IS_ERR(cm_id)) { 2102*38c8a9a5SSteve French pr_err("Can't create cm id: %ld\n", PTR_ERR(cm_id)); 2103*38c8a9a5SSteve French return PTR_ERR(cm_id); 2104*38c8a9a5SSteve French } 2105*38c8a9a5SSteve French 2106*38c8a9a5SSteve French ret = rdma_bind_addr(cm_id, (struct sockaddr *)&sin); 2107*38c8a9a5SSteve French if (ret) { 2108*38c8a9a5SSteve French pr_err("Can't bind: %d\n", ret); 2109*38c8a9a5SSteve French goto err; 2110*38c8a9a5SSteve French } 2111*38c8a9a5SSteve French 2112*38c8a9a5SSteve French smb_direct_listener.cm_id = cm_id; 2113*38c8a9a5SSteve French 2114*38c8a9a5SSteve French ret = rdma_listen(cm_id, 10); 2115*38c8a9a5SSteve French if (ret) { 2116*38c8a9a5SSteve French pr_err("Can't listen: %d\n", ret); 2117*38c8a9a5SSteve French goto err; 2118*38c8a9a5SSteve French } 2119*38c8a9a5SSteve French return 0; 2120*38c8a9a5SSteve French err: 2121*38c8a9a5SSteve French smb_direct_listener.cm_id = NULL; 2122*38c8a9a5SSteve French rdma_destroy_id(cm_id); 2123*38c8a9a5SSteve French return ret; 2124*38c8a9a5SSteve French } 2125*38c8a9a5SSteve French 2126*38c8a9a5SSteve French static int smb_direct_ib_client_add(struct ib_device *ib_dev) 2127*38c8a9a5SSteve French { 2128*38c8a9a5SSteve French struct smb_direct_device *smb_dev; 2129*38c8a9a5SSteve French 2130*38c8a9a5SSteve French /* Set 5445 port if device type is iWARP(No IB) */ 2131*38c8a9a5SSteve French if (ib_dev->node_type != RDMA_NODE_IB_CA) 2132*38c8a9a5SSteve French smb_direct_port = SMB_DIRECT_PORT_IWARP; 2133*38c8a9a5SSteve French 2134*38c8a9a5SSteve French if (!ib_dev->ops.get_netdev || 2135*38c8a9a5SSteve French !rdma_frwr_is_supported(&ib_dev->attrs)) 2136*38c8a9a5SSteve French return 0; 2137*38c8a9a5SSteve French 2138*38c8a9a5SSteve French smb_dev = kzalloc(sizeof(*smb_dev), GFP_KERNEL); 2139*38c8a9a5SSteve French if (!smb_dev) 2140*38c8a9a5SSteve French return -ENOMEM; 2141*38c8a9a5SSteve French smb_dev->ib_dev = ib_dev; 2142*38c8a9a5SSteve French 2143*38c8a9a5SSteve French write_lock(&smb_direct_device_lock); 2144*38c8a9a5SSteve French list_add(&smb_dev->list, &smb_direct_device_list); 2145*38c8a9a5SSteve French write_unlock(&smb_direct_device_lock); 2146*38c8a9a5SSteve French 2147*38c8a9a5SSteve French ksmbd_debug(RDMA, "ib device added: name %s\n", ib_dev->name); 2148*38c8a9a5SSteve French return 0; 2149*38c8a9a5SSteve French } 2150*38c8a9a5SSteve French 2151*38c8a9a5SSteve French static void smb_direct_ib_client_remove(struct ib_device *ib_dev, 2152*38c8a9a5SSteve French void *client_data) 2153*38c8a9a5SSteve French { 2154*38c8a9a5SSteve French struct smb_direct_device *smb_dev, *tmp; 2155*38c8a9a5SSteve French 2156*38c8a9a5SSteve French write_lock(&smb_direct_device_lock); 2157*38c8a9a5SSteve French list_for_each_entry_safe(smb_dev, tmp, &smb_direct_device_list, list) { 2158*38c8a9a5SSteve French if (smb_dev->ib_dev == ib_dev) { 2159*38c8a9a5SSteve French list_del(&smb_dev->list); 2160*38c8a9a5SSteve French kfree(smb_dev); 2161*38c8a9a5SSteve French break; 2162*38c8a9a5SSteve French } 2163*38c8a9a5SSteve French } 2164*38c8a9a5SSteve French write_unlock(&smb_direct_device_lock); 2165*38c8a9a5SSteve French } 2166*38c8a9a5SSteve French 2167*38c8a9a5SSteve French static struct ib_client smb_direct_ib_client = { 2168*38c8a9a5SSteve French .name = "ksmbd_smb_direct_ib", 2169*38c8a9a5SSteve French .add = smb_direct_ib_client_add, 2170*38c8a9a5SSteve French .remove = smb_direct_ib_client_remove, 2171*38c8a9a5SSteve French }; 2172*38c8a9a5SSteve French 2173*38c8a9a5SSteve French int ksmbd_rdma_init(void) 2174*38c8a9a5SSteve French { 2175*38c8a9a5SSteve French int ret; 2176*38c8a9a5SSteve French 2177*38c8a9a5SSteve French smb_direct_listener.cm_id = NULL; 2178*38c8a9a5SSteve French 2179*38c8a9a5SSteve French ret = ib_register_client(&smb_direct_ib_client); 2180*38c8a9a5SSteve French if (ret) { 2181*38c8a9a5SSteve French pr_err("failed to ib_register_client\n"); 2182*38c8a9a5SSteve French return ret; 2183*38c8a9a5SSteve French } 2184*38c8a9a5SSteve French 2185*38c8a9a5SSteve French /* When a client is running out of send credits, the credits are 2186*38c8a9a5SSteve French * granted by the server's sending a packet using this queue. 2187*38c8a9a5SSteve French * This avoids the situation that a clients cannot send packets 2188*38c8a9a5SSteve French * for lack of credits 2189*38c8a9a5SSteve French */ 2190*38c8a9a5SSteve French smb_direct_wq = alloc_workqueue("ksmbd-smb_direct-wq", 2191*38c8a9a5SSteve French WQ_HIGHPRI | WQ_MEM_RECLAIM, 0); 2192*38c8a9a5SSteve French if (!smb_direct_wq) 2193*38c8a9a5SSteve French return -ENOMEM; 2194*38c8a9a5SSteve French 2195*38c8a9a5SSteve French ret = smb_direct_listen(smb_direct_port); 2196*38c8a9a5SSteve French if (ret) { 2197*38c8a9a5SSteve French destroy_workqueue(smb_direct_wq); 2198*38c8a9a5SSteve French smb_direct_wq = NULL; 2199*38c8a9a5SSteve French pr_err("Can't listen: %d\n", ret); 2200*38c8a9a5SSteve French return ret; 2201*38c8a9a5SSteve French } 2202*38c8a9a5SSteve French 2203*38c8a9a5SSteve French ksmbd_debug(RDMA, "init RDMA listener. cm_id=%p\n", 2204*38c8a9a5SSteve French smb_direct_listener.cm_id); 2205*38c8a9a5SSteve French return 0; 2206*38c8a9a5SSteve French } 2207*38c8a9a5SSteve French 2208*38c8a9a5SSteve French void ksmbd_rdma_destroy(void) 2209*38c8a9a5SSteve French { 2210*38c8a9a5SSteve French if (!smb_direct_listener.cm_id) 2211*38c8a9a5SSteve French return; 2212*38c8a9a5SSteve French 2213*38c8a9a5SSteve French ib_unregister_client(&smb_direct_ib_client); 2214*38c8a9a5SSteve French rdma_destroy_id(smb_direct_listener.cm_id); 2215*38c8a9a5SSteve French 2216*38c8a9a5SSteve French smb_direct_listener.cm_id = NULL; 2217*38c8a9a5SSteve French 2218*38c8a9a5SSteve French if (smb_direct_wq) { 2219*38c8a9a5SSteve French destroy_workqueue(smb_direct_wq); 2220*38c8a9a5SSteve French smb_direct_wq = NULL; 2221*38c8a9a5SSteve French } 2222*38c8a9a5SSteve French } 2223*38c8a9a5SSteve French 2224*38c8a9a5SSteve French bool ksmbd_rdma_capable_netdev(struct net_device *netdev) 2225*38c8a9a5SSteve French { 2226*38c8a9a5SSteve French struct smb_direct_device *smb_dev; 2227*38c8a9a5SSteve French int i; 2228*38c8a9a5SSteve French bool rdma_capable = false; 2229*38c8a9a5SSteve French 2230*38c8a9a5SSteve French read_lock(&smb_direct_device_lock); 2231*38c8a9a5SSteve French list_for_each_entry(smb_dev, &smb_direct_device_list, list) { 2232*38c8a9a5SSteve French for (i = 0; i < smb_dev->ib_dev->phys_port_cnt; i++) { 2233*38c8a9a5SSteve French struct net_device *ndev; 2234*38c8a9a5SSteve French 2235*38c8a9a5SSteve French ndev = smb_dev->ib_dev->ops.get_netdev(smb_dev->ib_dev, 2236*38c8a9a5SSteve French i + 1); 2237*38c8a9a5SSteve French if (!ndev) 2238*38c8a9a5SSteve French continue; 2239*38c8a9a5SSteve French 2240*38c8a9a5SSteve French if (ndev == netdev) { 2241*38c8a9a5SSteve French dev_put(ndev); 2242*38c8a9a5SSteve French rdma_capable = true; 2243*38c8a9a5SSteve French goto out; 2244*38c8a9a5SSteve French } 2245*38c8a9a5SSteve French dev_put(ndev); 2246*38c8a9a5SSteve French } 2247*38c8a9a5SSteve French } 2248*38c8a9a5SSteve French out: 2249*38c8a9a5SSteve French read_unlock(&smb_direct_device_lock); 2250*38c8a9a5SSteve French 2251*38c8a9a5SSteve French if (rdma_capable == false) { 2252*38c8a9a5SSteve French struct ib_device *ibdev; 2253*38c8a9a5SSteve French 2254*38c8a9a5SSteve French ibdev = ib_device_get_by_netdev(netdev, RDMA_DRIVER_UNKNOWN); 2255*38c8a9a5SSteve French if (ibdev) { 2256*38c8a9a5SSteve French if (rdma_frwr_is_supported(&ibdev->attrs)) 2257*38c8a9a5SSteve French rdma_capable = true; 2258*38c8a9a5SSteve French ib_device_put(ibdev); 2259*38c8a9a5SSteve French } 2260*38c8a9a5SSteve French } 2261*38c8a9a5SSteve French 2262*38c8a9a5SSteve French return rdma_capable; 2263*38c8a9a5SSteve French } 2264*38c8a9a5SSteve French 2265*38c8a9a5SSteve French static struct ksmbd_transport_ops ksmbd_smb_direct_transport_ops = { 2266*38c8a9a5SSteve French .prepare = smb_direct_prepare, 2267*38c8a9a5SSteve French .disconnect = smb_direct_disconnect, 2268*38c8a9a5SSteve French .shutdown = smb_direct_shutdown, 2269*38c8a9a5SSteve French .writev = smb_direct_writev, 2270*38c8a9a5SSteve French .read = smb_direct_read, 2271*38c8a9a5SSteve French .rdma_read = smb_direct_rdma_read, 2272*38c8a9a5SSteve French .rdma_write = smb_direct_rdma_write, 2273*38c8a9a5SSteve French }; 2274