1*1249c01aSStefan Metzmacher /* SPDX-License-Identifier: GPL-2.0-or-later */ 2*1249c01aSStefan Metzmacher /* 3*1249c01aSStefan Metzmacher * Copyright (c) 2025 Stefan Metzmacher 4*1249c01aSStefan Metzmacher */ 5*1249c01aSStefan Metzmacher 6*1249c01aSStefan Metzmacher #ifndef __FS_SMB_COMMON_SMBDIRECT_SMBDIRECT_SOCKET_H__ 7*1249c01aSStefan Metzmacher #define __FS_SMB_COMMON_SMBDIRECT_SMBDIRECT_SOCKET_H__ 8*1249c01aSStefan Metzmacher 9*1249c01aSStefan Metzmacher #include <linux/wait.h> 10*1249c01aSStefan Metzmacher #include <linux/workqueue.h> 11*1249c01aSStefan Metzmacher #include <linux/kref.h> 12*1249c01aSStefan Metzmacher #include <linux/mempool.h> 13*1249c01aSStefan Metzmacher #include <linux/spinlock.h> 14*1249c01aSStefan Metzmacher #include <linux/mutex.h> 15*1249c01aSStefan Metzmacher #include <linux/completion.h> 16*1249c01aSStefan Metzmacher #include <rdma/rw.h> 17*1249c01aSStefan Metzmacher 18*1249c01aSStefan Metzmacher enum smbdirect_socket_status { 19*1249c01aSStefan Metzmacher SMBDIRECT_SOCKET_CREATED, 20*1249c01aSStefan Metzmacher SMBDIRECT_SOCKET_LISTENING, 21*1249c01aSStefan Metzmacher SMBDIRECT_SOCKET_RESOLVE_ADDR_NEEDED, 22*1249c01aSStefan Metzmacher SMBDIRECT_SOCKET_RESOLVE_ADDR_RUNNING, 23*1249c01aSStefan Metzmacher SMBDIRECT_SOCKET_RESOLVE_ADDR_FAILED, 24*1249c01aSStefan Metzmacher SMBDIRECT_SOCKET_RESOLVE_ROUTE_NEEDED, 25*1249c01aSStefan Metzmacher SMBDIRECT_SOCKET_RESOLVE_ROUTE_RUNNING, 26*1249c01aSStefan Metzmacher SMBDIRECT_SOCKET_RESOLVE_ROUTE_FAILED, 27*1249c01aSStefan Metzmacher SMBDIRECT_SOCKET_RDMA_CONNECT_NEEDED, 28*1249c01aSStefan Metzmacher SMBDIRECT_SOCKET_RDMA_CONNECT_RUNNING, 29*1249c01aSStefan Metzmacher SMBDIRECT_SOCKET_RDMA_CONNECT_FAILED, 30*1249c01aSStefan Metzmacher SMBDIRECT_SOCKET_NEGOTIATE_NEEDED, 31*1249c01aSStefan Metzmacher SMBDIRECT_SOCKET_NEGOTIATE_RUNNING, 32*1249c01aSStefan Metzmacher SMBDIRECT_SOCKET_NEGOTIATE_FAILED, 33*1249c01aSStefan Metzmacher SMBDIRECT_SOCKET_CONNECTED, 34*1249c01aSStefan Metzmacher SMBDIRECT_SOCKET_ERROR, 35*1249c01aSStefan Metzmacher SMBDIRECT_SOCKET_DISCONNECTING, 36*1249c01aSStefan Metzmacher SMBDIRECT_SOCKET_DISCONNECTED, 37*1249c01aSStefan Metzmacher SMBDIRECT_SOCKET_DESTROYED 38*1249c01aSStefan Metzmacher }; 39*1249c01aSStefan Metzmacher 40*1249c01aSStefan Metzmacher static __always_inline 41*1249c01aSStefan Metzmacher const char *smbdirect_socket_status_string(enum smbdirect_socket_status status) 42*1249c01aSStefan Metzmacher { 43*1249c01aSStefan Metzmacher switch (status) { 44*1249c01aSStefan Metzmacher case SMBDIRECT_SOCKET_CREATED: 45*1249c01aSStefan Metzmacher return "CREATED"; 46*1249c01aSStefan Metzmacher case SMBDIRECT_SOCKET_LISTENING: 47*1249c01aSStefan Metzmacher return "LISTENING"; 48*1249c01aSStefan Metzmacher case SMBDIRECT_SOCKET_RESOLVE_ADDR_NEEDED: 49*1249c01aSStefan Metzmacher return "RESOLVE_ADDR_NEEDED"; 50*1249c01aSStefan Metzmacher case SMBDIRECT_SOCKET_RESOLVE_ADDR_RUNNING: 51*1249c01aSStefan Metzmacher return "RESOLVE_ADDR_RUNNING"; 52*1249c01aSStefan Metzmacher case SMBDIRECT_SOCKET_RESOLVE_ADDR_FAILED: 53*1249c01aSStefan Metzmacher return "RESOLVE_ADDR_FAILED"; 54*1249c01aSStefan Metzmacher case SMBDIRECT_SOCKET_RESOLVE_ROUTE_NEEDED: 55*1249c01aSStefan Metzmacher return "RESOLVE_ROUTE_NEEDED"; 56*1249c01aSStefan Metzmacher case SMBDIRECT_SOCKET_RESOLVE_ROUTE_RUNNING: 57*1249c01aSStefan Metzmacher return "RESOLVE_ROUTE_RUNNING"; 58*1249c01aSStefan Metzmacher case SMBDIRECT_SOCKET_RESOLVE_ROUTE_FAILED: 59*1249c01aSStefan Metzmacher return "RESOLVE_ROUTE_FAILED"; 60*1249c01aSStefan Metzmacher case SMBDIRECT_SOCKET_RDMA_CONNECT_NEEDED: 61*1249c01aSStefan Metzmacher return "RDMA_CONNECT_NEEDED"; 62*1249c01aSStefan Metzmacher case SMBDIRECT_SOCKET_RDMA_CONNECT_RUNNING: 63*1249c01aSStefan Metzmacher return "RDMA_CONNECT_RUNNING"; 64*1249c01aSStefan Metzmacher case SMBDIRECT_SOCKET_RDMA_CONNECT_FAILED: 65*1249c01aSStefan Metzmacher return "RDMA_CONNECT_FAILED"; 66*1249c01aSStefan Metzmacher case SMBDIRECT_SOCKET_NEGOTIATE_NEEDED: 67*1249c01aSStefan Metzmacher return "NEGOTIATE_NEEDED"; 68*1249c01aSStefan Metzmacher case SMBDIRECT_SOCKET_NEGOTIATE_RUNNING: 69*1249c01aSStefan Metzmacher return "NEGOTIATE_RUNNING"; 70*1249c01aSStefan Metzmacher case SMBDIRECT_SOCKET_NEGOTIATE_FAILED: 71*1249c01aSStefan Metzmacher return "NEGOTIATE_FAILED"; 72*1249c01aSStefan Metzmacher case SMBDIRECT_SOCKET_CONNECTED: 73*1249c01aSStefan Metzmacher return "CONNECTED"; 74*1249c01aSStefan Metzmacher case SMBDIRECT_SOCKET_ERROR: 75*1249c01aSStefan Metzmacher return "ERROR"; 76*1249c01aSStefan Metzmacher case SMBDIRECT_SOCKET_DISCONNECTING: 77*1249c01aSStefan Metzmacher return "DISCONNECTING"; 78*1249c01aSStefan Metzmacher case SMBDIRECT_SOCKET_DISCONNECTED: 79*1249c01aSStefan Metzmacher return "DISCONNECTED"; 80*1249c01aSStefan Metzmacher case SMBDIRECT_SOCKET_DESTROYED: 81*1249c01aSStefan Metzmacher return "DESTROYED"; 82*1249c01aSStefan Metzmacher } 83*1249c01aSStefan Metzmacher 84*1249c01aSStefan Metzmacher return "<unknown>"; 85*1249c01aSStefan Metzmacher } 86*1249c01aSStefan Metzmacher 87*1249c01aSStefan Metzmacher /* 88*1249c01aSStefan Metzmacher * This can be used with %1pe to print errors as strings or '0' 89*1249c01aSStefan Metzmacher * And it avoids warnings like: warn: passing zero to 'ERR_PTR' 90*1249c01aSStefan Metzmacher * from smatch -p=kernel --pedantic 91*1249c01aSStefan Metzmacher */ 92*1249c01aSStefan Metzmacher static __always_inline 93*1249c01aSStefan Metzmacher const void * __must_check SMBDIRECT_DEBUG_ERR_PTR(long error) 94*1249c01aSStefan Metzmacher { 95*1249c01aSStefan Metzmacher if (error == 0) 96*1249c01aSStefan Metzmacher return NULL; 97*1249c01aSStefan Metzmacher return ERR_PTR(error); 98*1249c01aSStefan Metzmacher } 99*1249c01aSStefan Metzmacher 100*1249c01aSStefan Metzmacher enum smbdirect_keepalive_status { 101*1249c01aSStefan Metzmacher SMBDIRECT_KEEPALIVE_NONE, 102*1249c01aSStefan Metzmacher SMBDIRECT_KEEPALIVE_PENDING, 103*1249c01aSStefan Metzmacher SMBDIRECT_KEEPALIVE_SENT 104*1249c01aSStefan Metzmacher }; 105*1249c01aSStefan Metzmacher 106*1249c01aSStefan Metzmacher struct smbdirect_socket { 107*1249c01aSStefan Metzmacher enum smbdirect_socket_status status; 108*1249c01aSStefan Metzmacher wait_queue_head_t status_wait; 109*1249c01aSStefan Metzmacher int first_error; 110*1249c01aSStefan Metzmacher 111*1249c01aSStefan Metzmacher /* 112*1249c01aSStefan Metzmacher * This points to the workqueues to 113*1249c01aSStefan Metzmacher * be used for this socket. 114*1249c01aSStefan Metzmacher */ 115*1249c01aSStefan Metzmacher struct { 116*1249c01aSStefan Metzmacher struct workqueue_struct *accept; 117*1249c01aSStefan Metzmacher struct workqueue_struct *connect; 118*1249c01aSStefan Metzmacher struct workqueue_struct *idle; 119*1249c01aSStefan Metzmacher struct workqueue_struct *refill; 120*1249c01aSStefan Metzmacher struct workqueue_struct *immediate; 121*1249c01aSStefan Metzmacher struct workqueue_struct *cleanup; 122*1249c01aSStefan Metzmacher } workqueues; 123*1249c01aSStefan Metzmacher 124*1249c01aSStefan Metzmacher struct work_struct disconnect_work; 125*1249c01aSStefan Metzmacher 126*1249c01aSStefan Metzmacher /* 127*1249c01aSStefan Metzmacher * The reference counts. 128*1249c01aSStefan Metzmacher */ 129*1249c01aSStefan Metzmacher struct { 130*1249c01aSStefan Metzmacher /* 131*1249c01aSStefan Metzmacher * This holds the references by the 132*1249c01aSStefan Metzmacher * frontend, typically the smb layer. 133*1249c01aSStefan Metzmacher * 134*1249c01aSStefan Metzmacher * It is typically 1 and a disconnect 135*1249c01aSStefan Metzmacher * will happen if it reaches 0. 136*1249c01aSStefan Metzmacher */ 137*1249c01aSStefan Metzmacher struct kref disconnect; 138*1249c01aSStefan Metzmacher 139*1249c01aSStefan Metzmacher /* 140*1249c01aSStefan Metzmacher * This holds the reference by the 141*1249c01aSStefan Metzmacher * backend, the code that manages 142*1249c01aSStefan Metzmacher * the lifetime of the whole 143*1249c01aSStefan Metzmacher * struct smbdirect_socket, 144*1249c01aSStefan Metzmacher * if this reaches 0 it can will 145*1249c01aSStefan Metzmacher * be freed. 146*1249c01aSStefan Metzmacher * 147*1249c01aSStefan Metzmacher * Can be REFCOUNT_MAX is part 148*1249c01aSStefan Metzmacher * of another structure. 149*1249c01aSStefan Metzmacher * 150*1249c01aSStefan Metzmacher * This is equal or higher than 151*1249c01aSStefan Metzmacher * the disconnect refcount. 152*1249c01aSStefan Metzmacher */ 153*1249c01aSStefan Metzmacher struct kref destroy; 154*1249c01aSStefan Metzmacher } refs; 155*1249c01aSStefan Metzmacher 156*1249c01aSStefan Metzmacher /* RDMA related */ 157*1249c01aSStefan Metzmacher struct { 158*1249c01aSStefan Metzmacher struct rdma_cm_id *cm_id; 159*1249c01aSStefan Metzmacher /* 160*1249c01aSStefan Metzmacher * The expected event in our current 161*1249c01aSStefan Metzmacher * cm_id->event_handler, all other events 162*1249c01aSStefan Metzmacher * are treated as an error. 163*1249c01aSStefan Metzmacher */ 164*1249c01aSStefan Metzmacher enum rdma_cm_event_type expected_event; 165*1249c01aSStefan Metzmacher /* 166*1249c01aSStefan Metzmacher * This is for iWarp MPA v1 167*1249c01aSStefan Metzmacher */ 168*1249c01aSStefan Metzmacher bool legacy_iwarp; 169*1249c01aSStefan Metzmacher } rdma; 170*1249c01aSStefan Metzmacher 171*1249c01aSStefan Metzmacher /* IB verbs related */ 172*1249c01aSStefan Metzmacher struct { 173*1249c01aSStefan Metzmacher struct ib_pd *pd; 174*1249c01aSStefan Metzmacher enum ib_poll_context poll_ctx; 175*1249c01aSStefan Metzmacher struct ib_cq *send_cq; 176*1249c01aSStefan Metzmacher struct ib_cq *recv_cq; 177*1249c01aSStefan Metzmacher 178*1249c01aSStefan Metzmacher /* 179*1249c01aSStefan Metzmacher * shortcuts for rdma.cm_id->{qp,device}; 180*1249c01aSStefan Metzmacher */ 181*1249c01aSStefan Metzmacher struct ib_qp *qp; 182*1249c01aSStefan Metzmacher struct ib_device *dev; 183*1249c01aSStefan Metzmacher } ib; 184*1249c01aSStefan Metzmacher 185*1249c01aSStefan Metzmacher struct smbdirect_socket_parameters parameters; 186*1249c01aSStefan Metzmacher 187*1249c01aSStefan Metzmacher /* 188*1249c01aSStefan Metzmacher * The state for connect/negotiation 189*1249c01aSStefan Metzmacher */ 190*1249c01aSStefan Metzmacher struct { 191*1249c01aSStefan Metzmacher spinlock_t lock; 192*1249c01aSStefan Metzmacher struct work_struct work; 193*1249c01aSStefan Metzmacher } connect; 194*1249c01aSStefan Metzmacher 195*1249c01aSStefan Metzmacher /* 196*1249c01aSStefan Metzmacher * The state for keepalive and timeout handling 197*1249c01aSStefan Metzmacher */ 198*1249c01aSStefan Metzmacher struct { 199*1249c01aSStefan Metzmacher enum smbdirect_keepalive_status keepalive; 200*1249c01aSStefan Metzmacher struct work_struct immediate_work; 201*1249c01aSStefan Metzmacher struct delayed_work timer_work; 202*1249c01aSStefan Metzmacher } idle; 203*1249c01aSStefan Metzmacher 204*1249c01aSStefan Metzmacher /* 205*1249c01aSStefan Metzmacher * The state for listen sockets 206*1249c01aSStefan Metzmacher */ 207*1249c01aSStefan Metzmacher struct { 208*1249c01aSStefan Metzmacher spinlock_t lock; 209*1249c01aSStefan Metzmacher struct list_head pending; 210*1249c01aSStefan Metzmacher struct list_head ready; 211*1249c01aSStefan Metzmacher wait_queue_head_t wait_queue; 212*1249c01aSStefan Metzmacher /* 213*1249c01aSStefan Metzmacher * This starts as -1 and a value != -1 214*1249c01aSStefan Metzmacher * means this socket was in LISTENING state 215*1249c01aSStefan Metzmacher * before. Note the valid backlog can 216*1249c01aSStefan Metzmacher * only be > 0. 217*1249c01aSStefan Metzmacher */ 218*1249c01aSStefan Metzmacher int backlog; 219*1249c01aSStefan Metzmacher } listen; 220*1249c01aSStefan Metzmacher 221*1249c01aSStefan Metzmacher /* 222*1249c01aSStefan Metzmacher * The state for sockets waiting 223*1249c01aSStefan Metzmacher * for accept, either still waiting 224*1249c01aSStefan Metzmacher * for the negotiation to finish 225*1249c01aSStefan Metzmacher * or already ready with a usable 226*1249c01aSStefan Metzmacher * connection. 227*1249c01aSStefan Metzmacher */ 228*1249c01aSStefan Metzmacher struct { 229*1249c01aSStefan Metzmacher struct smbdirect_socket *listener; 230*1249c01aSStefan Metzmacher struct list_head list; 231*1249c01aSStefan Metzmacher } accept; 232*1249c01aSStefan Metzmacher 233*1249c01aSStefan Metzmacher /* 234*1249c01aSStefan Metzmacher * The state for posted send buffers 235*1249c01aSStefan Metzmacher */ 236*1249c01aSStefan Metzmacher struct { 237*1249c01aSStefan Metzmacher /* 238*1249c01aSStefan Metzmacher * Memory pools for preallocating 239*1249c01aSStefan Metzmacher * smbdirect_send_io buffers 240*1249c01aSStefan Metzmacher */ 241*1249c01aSStefan Metzmacher struct { 242*1249c01aSStefan Metzmacher struct kmem_cache *cache; 243*1249c01aSStefan Metzmacher mempool_t *pool; 244*1249c01aSStefan Metzmacher gfp_t gfp_mask; 245*1249c01aSStefan Metzmacher } mem; 246*1249c01aSStefan Metzmacher 247*1249c01aSStefan Metzmacher /* 248*1249c01aSStefan Metzmacher * This is a coordination for smbdirect_send_batch. 249*1249c01aSStefan Metzmacher * 250*1249c01aSStefan Metzmacher * There's only one possible credit, which means 251*1249c01aSStefan Metzmacher * only one instance is running at a time. 252*1249c01aSStefan Metzmacher */ 253*1249c01aSStefan Metzmacher struct { 254*1249c01aSStefan Metzmacher atomic_t count; 255*1249c01aSStefan Metzmacher wait_queue_head_t wait_queue; 256*1249c01aSStefan Metzmacher } bcredits; 257*1249c01aSStefan Metzmacher 258*1249c01aSStefan Metzmacher /* 259*1249c01aSStefan Metzmacher * The local credit state for ib_post_send() 260*1249c01aSStefan Metzmacher */ 261*1249c01aSStefan Metzmacher struct { 262*1249c01aSStefan Metzmacher atomic_t count; 263*1249c01aSStefan Metzmacher wait_queue_head_t wait_queue; 264*1249c01aSStefan Metzmacher } lcredits; 265*1249c01aSStefan Metzmacher 266*1249c01aSStefan Metzmacher /* 267*1249c01aSStefan Metzmacher * The remote credit state for the send side 268*1249c01aSStefan Metzmacher */ 269*1249c01aSStefan Metzmacher struct { 270*1249c01aSStefan Metzmacher atomic_t count; 271*1249c01aSStefan Metzmacher wait_queue_head_t wait_queue; 272*1249c01aSStefan Metzmacher } credits; 273*1249c01aSStefan Metzmacher 274*1249c01aSStefan Metzmacher /* 275*1249c01aSStefan Metzmacher * The state about posted/pending sends 276*1249c01aSStefan Metzmacher */ 277*1249c01aSStefan Metzmacher struct { 278*1249c01aSStefan Metzmacher atomic_t count; 279*1249c01aSStefan Metzmacher /* 280*1249c01aSStefan Metzmacher * woken when count reached zero 281*1249c01aSStefan Metzmacher */ 282*1249c01aSStefan Metzmacher wait_queue_head_t zero_wait_queue; 283*1249c01aSStefan Metzmacher } pending; 284*1249c01aSStefan Metzmacher } send_io; 285*1249c01aSStefan Metzmacher 286*1249c01aSStefan Metzmacher /* 287*1249c01aSStefan Metzmacher * The state for posted receive buffers 288*1249c01aSStefan Metzmacher */ 289*1249c01aSStefan Metzmacher struct { 290*1249c01aSStefan Metzmacher /* 291*1249c01aSStefan Metzmacher * The type of PDU we are expecting 292*1249c01aSStefan Metzmacher */ 293*1249c01aSStefan Metzmacher enum { 294*1249c01aSStefan Metzmacher SMBDIRECT_EXPECT_NEGOTIATE_REQ = 1, 295*1249c01aSStefan Metzmacher SMBDIRECT_EXPECT_NEGOTIATE_REP = 2, 296*1249c01aSStefan Metzmacher SMBDIRECT_EXPECT_DATA_TRANSFER = 3, 297*1249c01aSStefan Metzmacher } expected; 298*1249c01aSStefan Metzmacher 299*1249c01aSStefan Metzmacher /* 300*1249c01aSStefan Metzmacher * Memory pools for preallocating 301*1249c01aSStefan Metzmacher * smbdirect_recv_io buffers 302*1249c01aSStefan Metzmacher */ 303*1249c01aSStefan Metzmacher struct { 304*1249c01aSStefan Metzmacher struct kmem_cache *cache; 305*1249c01aSStefan Metzmacher mempool_t *pool; 306*1249c01aSStefan Metzmacher gfp_t gfp_mask; 307*1249c01aSStefan Metzmacher } mem; 308*1249c01aSStefan Metzmacher 309*1249c01aSStefan Metzmacher /* 310*1249c01aSStefan Metzmacher * The list of free smbdirect_recv_io 311*1249c01aSStefan Metzmacher * structures 312*1249c01aSStefan Metzmacher */ 313*1249c01aSStefan Metzmacher struct { 314*1249c01aSStefan Metzmacher struct list_head list; 315*1249c01aSStefan Metzmacher spinlock_t lock; 316*1249c01aSStefan Metzmacher } free; 317*1249c01aSStefan Metzmacher 318*1249c01aSStefan Metzmacher /* 319*1249c01aSStefan Metzmacher * The state for posted recv_io messages 320*1249c01aSStefan Metzmacher * and the refill work struct. 321*1249c01aSStefan Metzmacher */ 322*1249c01aSStefan Metzmacher struct { 323*1249c01aSStefan Metzmacher atomic_t count; 324*1249c01aSStefan Metzmacher struct work_struct refill_work; 325*1249c01aSStefan Metzmacher } posted; 326*1249c01aSStefan Metzmacher 327*1249c01aSStefan Metzmacher /* 328*1249c01aSStefan Metzmacher * The credit state for the recv side 329*1249c01aSStefan Metzmacher */ 330*1249c01aSStefan Metzmacher struct { 331*1249c01aSStefan Metzmacher u16 target; 332*1249c01aSStefan Metzmacher atomic_t available; 333*1249c01aSStefan Metzmacher atomic_t count; 334*1249c01aSStefan Metzmacher } credits; 335*1249c01aSStefan Metzmacher 336*1249c01aSStefan Metzmacher /* 337*1249c01aSStefan Metzmacher * The list of arrived non-empty smbdirect_recv_io 338*1249c01aSStefan Metzmacher * structures 339*1249c01aSStefan Metzmacher * 340*1249c01aSStefan Metzmacher * This represents the reassembly queue. 341*1249c01aSStefan Metzmacher */ 342*1249c01aSStefan Metzmacher struct { 343*1249c01aSStefan Metzmacher struct list_head list; 344*1249c01aSStefan Metzmacher spinlock_t lock; 345*1249c01aSStefan Metzmacher wait_queue_head_t wait_queue; 346*1249c01aSStefan Metzmacher /* total data length of reassembly queue */ 347*1249c01aSStefan Metzmacher int data_length; 348*1249c01aSStefan Metzmacher int queue_length; 349*1249c01aSStefan Metzmacher /* the offset to first buffer in reassembly queue */ 350*1249c01aSStefan Metzmacher int first_entry_offset; 351*1249c01aSStefan Metzmacher /* 352*1249c01aSStefan Metzmacher * Indicate if we have received a full packet on the 353*1249c01aSStefan Metzmacher * connection This is used to identify the first SMBD 354*1249c01aSStefan Metzmacher * packet of a assembled payload (SMB packet) in 355*1249c01aSStefan Metzmacher * reassembly queue so we can return a RFC1002 length to 356*1249c01aSStefan Metzmacher * upper layer to indicate the length of the SMB packet 357*1249c01aSStefan Metzmacher * received 358*1249c01aSStefan Metzmacher */ 359*1249c01aSStefan Metzmacher bool full_packet_received; 360*1249c01aSStefan Metzmacher } reassembly; 361*1249c01aSStefan Metzmacher } recv_io; 362*1249c01aSStefan Metzmacher 363*1249c01aSStefan Metzmacher /* 364*1249c01aSStefan Metzmacher * The state for Memory registrations on the client 365*1249c01aSStefan Metzmacher */ 366*1249c01aSStefan Metzmacher struct { 367*1249c01aSStefan Metzmacher enum ib_mr_type type; 368*1249c01aSStefan Metzmacher 369*1249c01aSStefan Metzmacher /* 370*1249c01aSStefan Metzmacher * The list of free smbdirect_mr_io 371*1249c01aSStefan Metzmacher * structures 372*1249c01aSStefan Metzmacher */ 373*1249c01aSStefan Metzmacher struct { 374*1249c01aSStefan Metzmacher struct list_head list; 375*1249c01aSStefan Metzmacher spinlock_t lock; 376*1249c01aSStefan Metzmacher } all; 377*1249c01aSStefan Metzmacher 378*1249c01aSStefan Metzmacher /* 379*1249c01aSStefan Metzmacher * The number of available MRs ready for memory registration 380*1249c01aSStefan Metzmacher */ 381*1249c01aSStefan Metzmacher struct { 382*1249c01aSStefan Metzmacher atomic_t count; 383*1249c01aSStefan Metzmacher wait_queue_head_t wait_queue; 384*1249c01aSStefan Metzmacher } ready; 385*1249c01aSStefan Metzmacher 386*1249c01aSStefan Metzmacher /* 387*1249c01aSStefan Metzmacher * The number of used MRs 388*1249c01aSStefan Metzmacher */ 389*1249c01aSStefan Metzmacher struct { 390*1249c01aSStefan Metzmacher atomic_t count; 391*1249c01aSStefan Metzmacher } used; 392*1249c01aSStefan Metzmacher } mr_io; 393*1249c01aSStefan Metzmacher 394*1249c01aSStefan Metzmacher /* 395*1249c01aSStefan Metzmacher * The state for RDMA read/write requests on the server 396*1249c01aSStefan Metzmacher */ 397*1249c01aSStefan Metzmacher struct { 398*1249c01aSStefan Metzmacher /* 399*1249c01aSStefan Metzmacher * Memory hints for 400*1249c01aSStefan Metzmacher * smbdirect_rw_io structs 401*1249c01aSStefan Metzmacher */ 402*1249c01aSStefan Metzmacher struct { 403*1249c01aSStefan Metzmacher gfp_t gfp_mask; 404*1249c01aSStefan Metzmacher } mem; 405*1249c01aSStefan Metzmacher 406*1249c01aSStefan Metzmacher /* 407*1249c01aSStefan Metzmacher * The credit state for the send side 408*1249c01aSStefan Metzmacher */ 409*1249c01aSStefan Metzmacher struct { 410*1249c01aSStefan Metzmacher /* 411*1249c01aSStefan Metzmacher * The maximum number of rw credits 412*1249c01aSStefan Metzmacher */ 413*1249c01aSStefan Metzmacher size_t max; 414*1249c01aSStefan Metzmacher /* 415*1249c01aSStefan Metzmacher * The number of pages per credit 416*1249c01aSStefan Metzmacher */ 417*1249c01aSStefan Metzmacher size_t num_pages; 418*1249c01aSStefan Metzmacher atomic_t count; 419*1249c01aSStefan Metzmacher wait_queue_head_t wait_queue; 420*1249c01aSStefan Metzmacher } credits; 421*1249c01aSStefan Metzmacher } rw_io; 422*1249c01aSStefan Metzmacher 423*1249c01aSStefan Metzmacher /* 424*1249c01aSStefan Metzmacher * For debug purposes 425*1249c01aSStefan Metzmacher */ 426*1249c01aSStefan Metzmacher struct { 427*1249c01aSStefan Metzmacher u64 get_receive_buffer; 428*1249c01aSStefan Metzmacher u64 put_receive_buffer; 429*1249c01aSStefan Metzmacher u64 enqueue_reassembly_queue; 430*1249c01aSStefan Metzmacher u64 dequeue_reassembly_queue; 431*1249c01aSStefan Metzmacher u64 send_empty; 432*1249c01aSStefan Metzmacher } statistics; 433*1249c01aSStefan Metzmacher 434*1249c01aSStefan Metzmacher struct { 435*1249c01aSStefan Metzmacher void *private_ptr; 436*1249c01aSStefan Metzmacher bool (*needed)(struct smbdirect_socket *sc, 437*1249c01aSStefan Metzmacher void *private_ptr, 438*1249c01aSStefan Metzmacher unsigned int lvl, 439*1249c01aSStefan Metzmacher unsigned int cls); 440*1249c01aSStefan Metzmacher void (*vaprintf)(struct smbdirect_socket *sc, 441*1249c01aSStefan Metzmacher const char *func, 442*1249c01aSStefan Metzmacher unsigned int line, 443*1249c01aSStefan Metzmacher void *private_ptr, 444*1249c01aSStefan Metzmacher unsigned int lvl, 445*1249c01aSStefan Metzmacher unsigned int cls, 446*1249c01aSStefan Metzmacher struct va_format *vaf); 447*1249c01aSStefan Metzmacher } logging; 448*1249c01aSStefan Metzmacher }; 449*1249c01aSStefan Metzmacher 450*1249c01aSStefan Metzmacher static void __smbdirect_socket_disabled_work(struct work_struct *work) 451*1249c01aSStefan Metzmacher { 452*1249c01aSStefan Metzmacher /* 453*1249c01aSStefan Metzmacher * Should never be called as disable_[delayed_]work_sync() was used. 454*1249c01aSStefan Metzmacher */ 455*1249c01aSStefan Metzmacher WARN_ON_ONCE(1); 456*1249c01aSStefan Metzmacher } 457*1249c01aSStefan Metzmacher 458*1249c01aSStefan Metzmacher static bool __smbdirect_log_needed(struct smbdirect_socket *sc, 459*1249c01aSStefan Metzmacher void *private_ptr, 460*1249c01aSStefan Metzmacher unsigned int lvl, 461*1249c01aSStefan Metzmacher unsigned int cls) 462*1249c01aSStefan Metzmacher { 463*1249c01aSStefan Metzmacher /* 464*1249c01aSStefan Metzmacher * Should never be called, the caller should 465*1249c01aSStefan Metzmacher * set it's own functions. 466*1249c01aSStefan Metzmacher */ 467*1249c01aSStefan Metzmacher WARN_ON_ONCE(1); 468*1249c01aSStefan Metzmacher return false; 469*1249c01aSStefan Metzmacher } 470*1249c01aSStefan Metzmacher 471*1249c01aSStefan Metzmacher static void __smbdirect_log_vaprintf(struct smbdirect_socket *sc, 472*1249c01aSStefan Metzmacher const char *func, 473*1249c01aSStefan Metzmacher unsigned int line, 474*1249c01aSStefan Metzmacher void *private_ptr, 475*1249c01aSStefan Metzmacher unsigned int lvl, 476*1249c01aSStefan Metzmacher unsigned int cls, 477*1249c01aSStefan Metzmacher struct va_format *vaf) 478*1249c01aSStefan Metzmacher { 479*1249c01aSStefan Metzmacher /* 480*1249c01aSStefan Metzmacher * Should never be called, the caller should 481*1249c01aSStefan Metzmacher * set it's own functions. 482*1249c01aSStefan Metzmacher */ 483*1249c01aSStefan Metzmacher WARN_ON_ONCE(1); 484*1249c01aSStefan Metzmacher } 485*1249c01aSStefan Metzmacher 486*1249c01aSStefan Metzmacher __printf(6, 7) 487*1249c01aSStefan Metzmacher static void __smbdirect_log_printf(struct smbdirect_socket *sc, 488*1249c01aSStefan Metzmacher const char *func, 489*1249c01aSStefan Metzmacher unsigned int line, 490*1249c01aSStefan Metzmacher unsigned int lvl, 491*1249c01aSStefan Metzmacher unsigned int cls, 492*1249c01aSStefan Metzmacher const char *fmt, 493*1249c01aSStefan Metzmacher ...); 494*1249c01aSStefan Metzmacher __maybe_unused 495*1249c01aSStefan Metzmacher static void __smbdirect_log_printf(struct smbdirect_socket *sc, 496*1249c01aSStefan Metzmacher const char *func, 497*1249c01aSStefan Metzmacher unsigned int line, 498*1249c01aSStefan Metzmacher unsigned int lvl, 499*1249c01aSStefan Metzmacher unsigned int cls, 500*1249c01aSStefan Metzmacher const char *fmt, 501*1249c01aSStefan Metzmacher ...) 502*1249c01aSStefan Metzmacher { 503*1249c01aSStefan Metzmacher struct va_format vaf; 504*1249c01aSStefan Metzmacher va_list args; 505*1249c01aSStefan Metzmacher 506*1249c01aSStefan Metzmacher va_start(args, fmt); 507*1249c01aSStefan Metzmacher 508*1249c01aSStefan Metzmacher vaf.fmt = fmt; 509*1249c01aSStefan Metzmacher vaf.va = &args; 510*1249c01aSStefan Metzmacher 511*1249c01aSStefan Metzmacher sc->logging.vaprintf(sc, 512*1249c01aSStefan Metzmacher func, 513*1249c01aSStefan Metzmacher line, 514*1249c01aSStefan Metzmacher sc->logging.private_ptr, 515*1249c01aSStefan Metzmacher lvl, 516*1249c01aSStefan Metzmacher cls, 517*1249c01aSStefan Metzmacher &vaf); 518*1249c01aSStefan Metzmacher va_end(args); 519*1249c01aSStefan Metzmacher } 520*1249c01aSStefan Metzmacher 521*1249c01aSStefan Metzmacher #define ___smbdirect_log_generic(sc, func, line, lvl, cls, fmt, args...) do { \ 522*1249c01aSStefan Metzmacher if (sc->logging.needed(sc, sc->logging.private_ptr, lvl, cls)) { \ 523*1249c01aSStefan Metzmacher __smbdirect_log_printf(sc, func, line, lvl, cls, fmt, ##args); \ 524*1249c01aSStefan Metzmacher } \ 525*1249c01aSStefan Metzmacher } while (0) 526*1249c01aSStefan Metzmacher #define __smbdirect_log_generic(sc, lvl, cls, fmt, args...) \ 527*1249c01aSStefan Metzmacher ___smbdirect_log_generic(sc, __func__, __LINE__, lvl, cls, fmt, ##args) 528*1249c01aSStefan Metzmacher 529*1249c01aSStefan Metzmacher #define smbdirect_log_outgoing(sc, lvl, fmt, args...) \ 530*1249c01aSStefan Metzmacher __smbdirect_log_generic(sc, lvl, SMBDIRECT_LOG_OUTGOING, fmt, ##args) 531*1249c01aSStefan Metzmacher #define smbdirect_log_incoming(sc, lvl, fmt, args...) \ 532*1249c01aSStefan Metzmacher __smbdirect_log_generic(sc, lvl, SMBDIRECT_LOG_INCOMING, fmt, ##args) 533*1249c01aSStefan Metzmacher #define smbdirect_log_read(sc, lvl, fmt, args...) \ 534*1249c01aSStefan Metzmacher __smbdirect_log_generic(sc, lvl, SMBDIRECT_LOG_READ, fmt, ##args) 535*1249c01aSStefan Metzmacher #define smbdirect_log_write(sc, lvl, fmt, args...) \ 536*1249c01aSStefan Metzmacher __smbdirect_log_generic(sc, lvl, SMBDIRECT_LOG_WRITE, fmt, ##args) 537*1249c01aSStefan Metzmacher #define smbdirect_log_rdma_send(sc, lvl, fmt, args...) \ 538*1249c01aSStefan Metzmacher __smbdirect_log_generic(sc, lvl, SMBDIRECT_LOG_RDMA_SEND, fmt, ##args) 539*1249c01aSStefan Metzmacher #define smbdirect_log_rdma_recv(sc, lvl, fmt, args...) \ 540*1249c01aSStefan Metzmacher __smbdirect_log_generic(sc, lvl, SMBDIRECT_LOG_RDMA_RECV, fmt, ##args) 541*1249c01aSStefan Metzmacher #define smbdirect_log_keep_alive(sc, lvl, fmt, args...) \ 542*1249c01aSStefan Metzmacher __smbdirect_log_generic(sc, lvl, SMBDIRECT_LOG_KEEP_ALIVE, fmt, ##args) 543*1249c01aSStefan Metzmacher #define smbdirect_log_rdma_event(sc, lvl, fmt, args...) \ 544*1249c01aSStefan Metzmacher __smbdirect_log_generic(sc, lvl, SMBDIRECT_LOG_RDMA_EVENT, fmt, ##args) 545*1249c01aSStefan Metzmacher #define smbdirect_log_rdma_mr(sc, lvl, fmt, args...) \ 546*1249c01aSStefan Metzmacher __smbdirect_log_generic(sc, lvl, SMBDIRECT_LOG_RDMA_MR, fmt, ##args) 547*1249c01aSStefan Metzmacher #define smbdirect_log_rdma_rw(sc, lvl, fmt, args...) \ 548*1249c01aSStefan Metzmacher __smbdirect_log_generic(sc, lvl, SMBDIRECT_LOG_RDMA_RW, fmt, ##args) 549*1249c01aSStefan Metzmacher #define smbdirect_log_negotiate(sc, lvl, fmt, args...) \ 550*1249c01aSStefan Metzmacher __smbdirect_log_generic(sc, lvl, SMBDIRECT_LOG_NEGOTIATE, fmt, ##args) 551*1249c01aSStefan Metzmacher 552*1249c01aSStefan Metzmacher static __always_inline void smbdirect_socket_init(struct smbdirect_socket *sc) 553*1249c01aSStefan Metzmacher { 554*1249c01aSStefan Metzmacher /* 555*1249c01aSStefan Metzmacher * This also sets status = SMBDIRECT_SOCKET_CREATED 556*1249c01aSStefan Metzmacher */ 557*1249c01aSStefan Metzmacher BUILD_BUG_ON(SMBDIRECT_SOCKET_CREATED != 0); 558*1249c01aSStefan Metzmacher memset(sc, 0, sizeof(*sc)); 559*1249c01aSStefan Metzmacher 560*1249c01aSStefan Metzmacher init_waitqueue_head(&sc->status_wait); 561*1249c01aSStefan Metzmacher 562*1249c01aSStefan Metzmacher sc->workqueues.accept = smbdirect_globals.workqueues.accept; 563*1249c01aSStefan Metzmacher sc->workqueues.connect = smbdirect_globals.workqueues.connect; 564*1249c01aSStefan Metzmacher sc->workqueues.idle = smbdirect_globals.workqueues.idle; 565*1249c01aSStefan Metzmacher sc->workqueues.refill = smbdirect_globals.workqueues.refill; 566*1249c01aSStefan Metzmacher sc->workqueues.immediate = smbdirect_globals.workqueues.immediate; 567*1249c01aSStefan Metzmacher sc->workqueues.cleanup = smbdirect_globals.workqueues.cleanup; 568*1249c01aSStefan Metzmacher 569*1249c01aSStefan Metzmacher INIT_WORK(&sc->disconnect_work, __smbdirect_socket_disabled_work); 570*1249c01aSStefan Metzmacher disable_work_sync(&sc->disconnect_work); 571*1249c01aSStefan Metzmacher 572*1249c01aSStefan Metzmacher kref_init(&sc->refs.disconnect); 573*1249c01aSStefan Metzmacher sc->refs.destroy = (struct kref) KREF_INIT(REFCOUNT_MAX); 574*1249c01aSStefan Metzmacher 575*1249c01aSStefan Metzmacher sc->rdma.expected_event = RDMA_CM_EVENT_INTERNAL; 576*1249c01aSStefan Metzmacher 577*1249c01aSStefan Metzmacher sc->ib.poll_ctx = IB_POLL_UNBOUND_WORKQUEUE; 578*1249c01aSStefan Metzmacher 579*1249c01aSStefan Metzmacher spin_lock_init(&sc->connect.lock); 580*1249c01aSStefan Metzmacher INIT_WORK(&sc->connect.work, __smbdirect_socket_disabled_work); 581*1249c01aSStefan Metzmacher disable_work_sync(&sc->connect.work); 582*1249c01aSStefan Metzmacher 583*1249c01aSStefan Metzmacher INIT_WORK(&sc->idle.immediate_work, __smbdirect_socket_disabled_work); 584*1249c01aSStefan Metzmacher disable_work_sync(&sc->idle.immediate_work); 585*1249c01aSStefan Metzmacher INIT_DELAYED_WORK(&sc->idle.timer_work, __smbdirect_socket_disabled_work); 586*1249c01aSStefan Metzmacher disable_delayed_work_sync(&sc->idle.timer_work); 587*1249c01aSStefan Metzmacher 588*1249c01aSStefan Metzmacher spin_lock_init(&sc->listen.lock); 589*1249c01aSStefan Metzmacher INIT_LIST_HEAD(&sc->listen.pending); 590*1249c01aSStefan Metzmacher INIT_LIST_HEAD(&sc->listen.ready); 591*1249c01aSStefan Metzmacher sc->listen.backlog = -1; /* not a listener */ 592*1249c01aSStefan Metzmacher init_waitqueue_head(&sc->listen.wait_queue); 593*1249c01aSStefan Metzmacher 594*1249c01aSStefan Metzmacher INIT_LIST_HEAD(&sc->accept.list); 595*1249c01aSStefan Metzmacher 596*1249c01aSStefan Metzmacher sc->send_io.mem.gfp_mask = GFP_KERNEL; 597*1249c01aSStefan Metzmacher 598*1249c01aSStefan Metzmacher atomic_set(&sc->send_io.bcredits.count, 0); 599*1249c01aSStefan Metzmacher init_waitqueue_head(&sc->send_io.bcredits.wait_queue); 600*1249c01aSStefan Metzmacher 601*1249c01aSStefan Metzmacher atomic_set(&sc->send_io.lcredits.count, 0); 602*1249c01aSStefan Metzmacher init_waitqueue_head(&sc->send_io.lcredits.wait_queue); 603*1249c01aSStefan Metzmacher 604*1249c01aSStefan Metzmacher atomic_set(&sc->send_io.credits.count, 0); 605*1249c01aSStefan Metzmacher init_waitqueue_head(&sc->send_io.credits.wait_queue); 606*1249c01aSStefan Metzmacher 607*1249c01aSStefan Metzmacher atomic_set(&sc->send_io.pending.count, 0); 608*1249c01aSStefan Metzmacher init_waitqueue_head(&sc->send_io.pending.zero_wait_queue); 609*1249c01aSStefan Metzmacher 610*1249c01aSStefan Metzmacher sc->recv_io.mem.gfp_mask = GFP_KERNEL; 611*1249c01aSStefan Metzmacher 612*1249c01aSStefan Metzmacher INIT_LIST_HEAD(&sc->recv_io.free.list); 613*1249c01aSStefan Metzmacher spin_lock_init(&sc->recv_io.free.lock); 614*1249c01aSStefan Metzmacher 615*1249c01aSStefan Metzmacher atomic_set(&sc->recv_io.posted.count, 0); 616*1249c01aSStefan Metzmacher INIT_WORK(&sc->recv_io.posted.refill_work, __smbdirect_socket_disabled_work); 617*1249c01aSStefan Metzmacher disable_work_sync(&sc->recv_io.posted.refill_work); 618*1249c01aSStefan Metzmacher 619*1249c01aSStefan Metzmacher atomic_set(&sc->recv_io.credits.available, 0); 620*1249c01aSStefan Metzmacher atomic_set(&sc->recv_io.credits.count, 0); 621*1249c01aSStefan Metzmacher 622*1249c01aSStefan Metzmacher INIT_LIST_HEAD(&sc->recv_io.reassembly.list); 623*1249c01aSStefan Metzmacher spin_lock_init(&sc->recv_io.reassembly.lock); 624*1249c01aSStefan Metzmacher init_waitqueue_head(&sc->recv_io.reassembly.wait_queue); 625*1249c01aSStefan Metzmacher 626*1249c01aSStefan Metzmacher sc->rw_io.mem.gfp_mask = GFP_KERNEL; 627*1249c01aSStefan Metzmacher atomic_set(&sc->rw_io.credits.count, 0); 628*1249c01aSStefan Metzmacher init_waitqueue_head(&sc->rw_io.credits.wait_queue); 629*1249c01aSStefan Metzmacher 630*1249c01aSStefan Metzmacher spin_lock_init(&sc->mr_io.all.lock); 631*1249c01aSStefan Metzmacher INIT_LIST_HEAD(&sc->mr_io.all.list); 632*1249c01aSStefan Metzmacher atomic_set(&sc->mr_io.ready.count, 0); 633*1249c01aSStefan Metzmacher init_waitqueue_head(&sc->mr_io.ready.wait_queue); 634*1249c01aSStefan Metzmacher atomic_set(&sc->mr_io.used.count, 0); 635*1249c01aSStefan Metzmacher 636*1249c01aSStefan Metzmacher sc->logging.private_ptr = NULL; 637*1249c01aSStefan Metzmacher sc->logging.needed = __smbdirect_log_needed; 638*1249c01aSStefan Metzmacher sc->logging.vaprintf = __smbdirect_log_vaprintf; 639*1249c01aSStefan Metzmacher } 640*1249c01aSStefan Metzmacher 641*1249c01aSStefan Metzmacher #define __SMBDIRECT_CHECK_STATUS_FAILED(__sc, __expected_status, __error_cmd, __unexpected_cmd) ({ \ 642*1249c01aSStefan Metzmacher bool __failed = false; \ 643*1249c01aSStefan Metzmacher if (unlikely((__sc)->first_error)) { \ 644*1249c01aSStefan Metzmacher __failed = true; \ 645*1249c01aSStefan Metzmacher __error_cmd \ 646*1249c01aSStefan Metzmacher } else if (unlikely((__sc)->status != (__expected_status))) { \ 647*1249c01aSStefan Metzmacher __failed = true; \ 648*1249c01aSStefan Metzmacher __unexpected_cmd \ 649*1249c01aSStefan Metzmacher } \ 650*1249c01aSStefan Metzmacher __failed; \ 651*1249c01aSStefan Metzmacher }) 652*1249c01aSStefan Metzmacher 653*1249c01aSStefan Metzmacher #define __SMBDIRECT_CHECK_STATUS_WARN(__sc, __expected_status, __unexpected_cmd) \ 654*1249c01aSStefan Metzmacher __SMBDIRECT_CHECK_STATUS_FAILED(__sc, __expected_status, \ 655*1249c01aSStefan Metzmacher { \ 656*1249c01aSStefan Metzmacher const struct sockaddr_storage *__src = NULL; \ 657*1249c01aSStefan Metzmacher const struct sockaddr_storage *__dst = NULL; \ 658*1249c01aSStefan Metzmacher if ((__sc)->rdma.cm_id) { \ 659*1249c01aSStefan Metzmacher __src = &(__sc)->rdma.cm_id->route.addr.src_addr; \ 660*1249c01aSStefan Metzmacher __dst = &(__sc)->rdma.cm_id->route.addr.dst_addr; \ 661*1249c01aSStefan Metzmacher } \ 662*1249c01aSStefan Metzmacher smbdirect_log_rdma_event(sc, SMBDIRECT_LOG_INFO, \ 663*1249c01aSStefan Metzmacher "expected[%s] != %s first_error=%1pe local=%pISpsfc remote=%pISpsfc\n", \ 664*1249c01aSStefan Metzmacher smbdirect_socket_status_string(__expected_status), \ 665*1249c01aSStefan Metzmacher smbdirect_socket_status_string((__sc)->status), \ 666*1249c01aSStefan Metzmacher SMBDIRECT_DEBUG_ERR_PTR((__sc)->first_error), \ 667*1249c01aSStefan Metzmacher __src, __dst); \ 668*1249c01aSStefan Metzmacher }, \ 669*1249c01aSStefan Metzmacher { \ 670*1249c01aSStefan Metzmacher const struct sockaddr_storage *__src = NULL; \ 671*1249c01aSStefan Metzmacher const struct sockaddr_storage *__dst = NULL; \ 672*1249c01aSStefan Metzmacher if ((__sc)->rdma.cm_id) { \ 673*1249c01aSStefan Metzmacher __src = &(__sc)->rdma.cm_id->route.addr.src_addr; \ 674*1249c01aSStefan Metzmacher __dst = &(__sc)->rdma.cm_id->route.addr.dst_addr; \ 675*1249c01aSStefan Metzmacher } \ 676*1249c01aSStefan Metzmacher smbdirect_log_rdma_event(sc, SMBDIRECT_LOG_ERR, \ 677*1249c01aSStefan Metzmacher "expected[%s] != %s first_error=%1pe local=%pISpsfc remote=%pISpsfc\n", \ 678*1249c01aSStefan Metzmacher smbdirect_socket_status_string(__expected_status), \ 679*1249c01aSStefan Metzmacher smbdirect_socket_status_string((__sc)->status), \ 680*1249c01aSStefan Metzmacher SMBDIRECT_DEBUG_ERR_PTR((__sc)->first_error), \ 681*1249c01aSStefan Metzmacher __src, __dst); \ 682*1249c01aSStefan Metzmacher WARN_ONCE(1, \ 683*1249c01aSStefan Metzmacher "expected[%s] != %s first_error=%1pe local=%pISpsfc remote=%pISpsfc\n", \ 684*1249c01aSStefan Metzmacher smbdirect_socket_status_string(__expected_status), \ 685*1249c01aSStefan Metzmacher smbdirect_socket_status_string((__sc)->status), \ 686*1249c01aSStefan Metzmacher SMBDIRECT_DEBUG_ERR_PTR((__sc)->first_error), \ 687*1249c01aSStefan Metzmacher __src, __dst); \ 688*1249c01aSStefan Metzmacher __unexpected_cmd \ 689*1249c01aSStefan Metzmacher }) 690*1249c01aSStefan Metzmacher 691*1249c01aSStefan Metzmacher #define SMBDIRECT_CHECK_STATUS_WARN(__sc, __expected_status) \ 692*1249c01aSStefan Metzmacher __SMBDIRECT_CHECK_STATUS_WARN(__sc, __expected_status, /* nothing */) 693*1249c01aSStefan Metzmacher 694*1249c01aSStefan Metzmacher #ifndef __SMBDIRECT_SOCKET_DISCONNECT 695*1249c01aSStefan Metzmacher #define __SMBDIRECT_SOCKET_DISCONNECT(__sc) \ 696*1249c01aSStefan Metzmacher smbdirect_socket_schedule_cleanup(__sc, -ECONNABORTED) 697*1249c01aSStefan Metzmacher #endif /* ! __SMBDIRECT_SOCKET_DISCONNECT */ 698*1249c01aSStefan Metzmacher 699*1249c01aSStefan Metzmacher #define SMBDIRECT_CHECK_STATUS_DISCONNECT(__sc, __expected_status) \ 700*1249c01aSStefan Metzmacher __SMBDIRECT_CHECK_STATUS_WARN(__sc, __expected_status, \ 701*1249c01aSStefan Metzmacher __SMBDIRECT_SOCKET_DISCONNECT(__sc);) 702*1249c01aSStefan Metzmacher 703*1249c01aSStefan Metzmacher struct smbdirect_send_io { 704*1249c01aSStefan Metzmacher struct smbdirect_socket *socket; 705*1249c01aSStefan Metzmacher struct ib_cqe cqe; 706*1249c01aSStefan Metzmacher 707*1249c01aSStefan Metzmacher /* 708*1249c01aSStefan Metzmacher * The SGE entries for this work request 709*1249c01aSStefan Metzmacher * 710*1249c01aSStefan Metzmacher * The first points to the packet header 711*1249c01aSStefan Metzmacher */ 712*1249c01aSStefan Metzmacher #define SMBDIRECT_SEND_IO_MAX_SGE 6 713*1249c01aSStefan Metzmacher size_t num_sge; 714*1249c01aSStefan Metzmacher struct ib_sge sge[SMBDIRECT_SEND_IO_MAX_SGE]; 715*1249c01aSStefan Metzmacher 716*1249c01aSStefan Metzmacher /* 717*1249c01aSStefan Metzmacher * Link to the list of sibling smbdirect_send_io 718*1249c01aSStefan Metzmacher * messages. 719*1249c01aSStefan Metzmacher */ 720*1249c01aSStefan Metzmacher struct list_head sibling_list; 721*1249c01aSStefan Metzmacher struct ib_send_wr wr; 722*1249c01aSStefan Metzmacher 723*1249c01aSStefan Metzmacher /* SMBD packet header follows this structure */ 724*1249c01aSStefan Metzmacher u8 packet[]; 725*1249c01aSStefan Metzmacher }; 726*1249c01aSStefan Metzmacher 727*1249c01aSStefan Metzmacher struct smbdirect_send_batch { 728*1249c01aSStefan Metzmacher /* 729*1249c01aSStefan Metzmacher * List of smbdirect_send_io messages 730*1249c01aSStefan Metzmacher */ 731*1249c01aSStefan Metzmacher struct list_head msg_list; 732*1249c01aSStefan Metzmacher /* 733*1249c01aSStefan Metzmacher * Number of list entries 734*1249c01aSStefan Metzmacher */ 735*1249c01aSStefan Metzmacher size_t wr_cnt; 736*1249c01aSStefan Metzmacher 737*1249c01aSStefan Metzmacher /* 738*1249c01aSStefan Metzmacher * Possible remote key invalidation state 739*1249c01aSStefan Metzmacher */ 740*1249c01aSStefan Metzmacher bool need_invalidate_rkey; 741*1249c01aSStefan Metzmacher u32 remote_key; 742*1249c01aSStefan Metzmacher 743*1249c01aSStefan Metzmacher int credit; 744*1249c01aSStefan Metzmacher }; 745*1249c01aSStefan Metzmacher 746*1249c01aSStefan Metzmacher struct smbdirect_recv_io { 747*1249c01aSStefan Metzmacher struct smbdirect_socket *socket; 748*1249c01aSStefan Metzmacher struct ib_cqe cqe; 749*1249c01aSStefan Metzmacher 750*1249c01aSStefan Metzmacher /* 751*1249c01aSStefan Metzmacher * For now we only use a single SGE 752*1249c01aSStefan Metzmacher * as we have just one large buffer 753*1249c01aSStefan Metzmacher * per posted recv. 754*1249c01aSStefan Metzmacher */ 755*1249c01aSStefan Metzmacher #define SMBDIRECT_RECV_IO_MAX_SGE 1 756*1249c01aSStefan Metzmacher struct ib_sge sge; 757*1249c01aSStefan Metzmacher 758*1249c01aSStefan Metzmacher /* Link to free or reassembly list */ 759*1249c01aSStefan Metzmacher struct list_head list; 760*1249c01aSStefan Metzmacher 761*1249c01aSStefan Metzmacher /* Indicate if this is the 1st packet of a payload */ 762*1249c01aSStefan Metzmacher bool first_segment; 763*1249c01aSStefan Metzmacher 764*1249c01aSStefan Metzmacher /* SMBD packet header and payload follows this structure */ 765*1249c01aSStefan Metzmacher u8 packet[]; 766*1249c01aSStefan Metzmacher }; 767*1249c01aSStefan Metzmacher 768*1249c01aSStefan Metzmacher enum smbdirect_mr_state { 769*1249c01aSStefan Metzmacher SMBDIRECT_MR_READY, 770*1249c01aSStefan Metzmacher SMBDIRECT_MR_REGISTERED, 771*1249c01aSStefan Metzmacher SMBDIRECT_MR_INVALIDATED, 772*1249c01aSStefan Metzmacher SMBDIRECT_MR_ERROR, 773*1249c01aSStefan Metzmacher SMBDIRECT_MR_DISABLED 774*1249c01aSStefan Metzmacher }; 775*1249c01aSStefan Metzmacher 776*1249c01aSStefan Metzmacher struct smbdirect_mr_io { 777*1249c01aSStefan Metzmacher struct smbdirect_socket *socket; 778*1249c01aSStefan Metzmacher struct ib_cqe cqe; 779*1249c01aSStefan Metzmacher 780*1249c01aSStefan Metzmacher /* 781*1249c01aSStefan Metzmacher * We can have up to two references: 782*1249c01aSStefan Metzmacher * 1. by the connection 783*1249c01aSStefan Metzmacher * 2. by the registration 784*1249c01aSStefan Metzmacher */ 785*1249c01aSStefan Metzmacher struct kref kref; 786*1249c01aSStefan Metzmacher struct mutex mutex; 787*1249c01aSStefan Metzmacher 788*1249c01aSStefan Metzmacher struct list_head list; 789*1249c01aSStefan Metzmacher 790*1249c01aSStefan Metzmacher enum smbdirect_mr_state state; 791*1249c01aSStefan Metzmacher struct ib_mr *mr; 792*1249c01aSStefan Metzmacher struct sg_table sgt; 793*1249c01aSStefan Metzmacher enum dma_data_direction dir; 794*1249c01aSStefan Metzmacher union { 795*1249c01aSStefan Metzmacher struct ib_reg_wr wr; 796*1249c01aSStefan Metzmacher struct ib_send_wr inv_wr; 797*1249c01aSStefan Metzmacher }; 798*1249c01aSStefan Metzmacher 799*1249c01aSStefan Metzmacher bool need_invalidate; 800*1249c01aSStefan Metzmacher struct completion invalidate_done; 801*1249c01aSStefan Metzmacher }; 802*1249c01aSStefan Metzmacher 803*1249c01aSStefan Metzmacher struct smbdirect_rw_io { 804*1249c01aSStefan Metzmacher struct smbdirect_socket *socket; 805*1249c01aSStefan Metzmacher struct ib_cqe cqe; 806*1249c01aSStefan Metzmacher 807*1249c01aSStefan Metzmacher struct list_head list; 808*1249c01aSStefan Metzmacher 809*1249c01aSStefan Metzmacher int error; 810*1249c01aSStefan Metzmacher struct completion *completion; 811*1249c01aSStefan Metzmacher 812*1249c01aSStefan Metzmacher struct rdma_rw_ctx rdma_ctx; 813*1249c01aSStefan Metzmacher struct sg_table sgt; 814*1249c01aSStefan Metzmacher struct scatterlist sg_list[]; 815*1249c01aSStefan Metzmacher }; 816*1249c01aSStefan Metzmacher 817*1249c01aSStefan Metzmacher static inline size_t smbdirect_get_buf_page_count(const void *buf, size_t size) 818*1249c01aSStefan Metzmacher { 819*1249c01aSStefan Metzmacher return DIV_ROUND_UP((uintptr_t)buf + size, PAGE_SIZE) - 820*1249c01aSStefan Metzmacher (uintptr_t)buf / PAGE_SIZE; 821*1249c01aSStefan Metzmacher } 822*1249c01aSStefan Metzmacher 823*1249c01aSStefan Metzmacher /* 824*1249c01aSStefan Metzmacher * Maximum number of retries on data transfer operations 825*1249c01aSStefan Metzmacher */ 826*1249c01aSStefan Metzmacher #define SMBDIRECT_RDMA_CM_RETRY 6 827*1249c01aSStefan Metzmacher /* 828*1249c01aSStefan Metzmacher * No need to retry on Receiver Not Ready since SMB_DIRECT manages credits 829*1249c01aSStefan Metzmacher */ 830*1249c01aSStefan Metzmacher #define SMBDIRECT_RDMA_CM_RNR_RETRY 0 831*1249c01aSStefan Metzmacher 832*1249c01aSStefan Metzmacher #endif /* __FS_SMB_COMMON_SMBDIRECT_SMBDIRECT_SOCKET_H__ */ 833