1*1249c01aSStefan Metzmacher // SPDX-License-Identifier: GPL-2.0-or-later 2*1249c01aSStefan Metzmacher /* 3*1249c01aSStefan Metzmacher * Copyright (C) 2017, Microsoft Corporation. 4*1249c01aSStefan Metzmacher * Copyright (c) 2025, Stefan Metzmacher 5*1249c01aSStefan Metzmacher */ 6*1249c01aSStefan Metzmacher 7*1249c01aSStefan Metzmacher #include "internal.h" 8*1249c01aSStefan Metzmacher #include <linux/folio_queue.h> 9*1249c01aSStefan Metzmacher 10*1249c01aSStefan Metzmacher struct smbdirect_map_sges { 11*1249c01aSStefan Metzmacher struct ib_sge *sge; 12*1249c01aSStefan Metzmacher size_t num_sge; 13*1249c01aSStefan Metzmacher size_t max_sge; 14*1249c01aSStefan Metzmacher struct ib_device *device; 15*1249c01aSStefan Metzmacher u32 local_dma_lkey; 16*1249c01aSStefan Metzmacher enum dma_data_direction direction; 17*1249c01aSStefan Metzmacher }; 18*1249c01aSStefan Metzmacher 19*1249c01aSStefan Metzmacher static ssize_t smbdirect_map_sges_from_iter(struct iov_iter *iter, size_t len, 20*1249c01aSStefan Metzmacher struct smbdirect_map_sges *state); 21*1249c01aSStefan Metzmacher 22*1249c01aSStefan Metzmacher static void smbdirect_connection_recv_io_refill_work(struct work_struct *work); 23*1249c01aSStefan Metzmacher static void smbdirect_connection_send_immediate_work(struct work_struct *work); 24*1249c01aSStefan Metzmacher 25*1249c01aSStefan Metzmacher static void smbdirect_connection_qp_event_handler(struct ib_event *event, void *context) 26*1249c01aSStefan Metzmacher { 27*1249c01aSStefan Metzmacher struct smbdirect_socket *sc = context; 28*1249c01aSStefan Metzmacher 29*1249c01aSStefan Metzmacher smbdirect_log_rdma_event(sc, SMBDIRECT_LOG_ERR, 30*1249c01aSStefan Metzmacher "%s on device %.*s socket %p (cm_id=%p) status %s first_error %1pe\n", 31*1249c01aSStefan Metzmacher ib_event_msg(event->event), 32*1249c01aSStefan Metzmacher IB_DEVICE_NAME_MAX, 33*1249c01aSStefan Metzmacher event->device->name, 34*1249c01aSStefan Metzmacher sc, sc->rdma.cm_id, 35*1249c01aSStefan Metzmacher smbdirect_socket_status_string(sc->status), 36*1249c01aSStefan Metzmacher SMBDIRECT_DEBUG_ERR_PTR(sc->first_error)); 37*1249c01aSStefan Metzmacher 38*1249c01aSStefan Metzmacher switch (event->event) { 39*1249c01aSStefan Metzmacher case IB_EVENT_CQ_ERR: 40*1249c01aSStefan Metzmacher case IB_EVENT_QP_FATAL: 41*1249c01aSStefan Metzmacher smbdirect_socket_schedule_cleanup(sc, -ECONNABORTED); 42*1249c01aSStefan Metzmacher break; 43*1249c01aSStefan Metzmacher 44*1249c01aSStefan Metzmacher default: 45*1249c01aSStefan Metzmacher break; 46*1249c01aSStefan Metzmacher } 47*1249c01aSStefan Metzmacher } 48*1249c01aSStefan Metzmacher 49*1249c01aSStefan Metzmacher static int smbdirect_connection_rdma_event_handler(struct rdma_cm_id *id, 50*1249c01aSStefan Metzmacher struct rdma_cm_event *event) 51*1249c01aSStefan Metzmacher { 52*1249c01aSStefan Metzmacher struct smbdirect_socket *sc = id->context; 53*1249c01aSStefan Metzmacher int ret = -ECONNRESET; 54*1249c01aSStefan Metzmacher 55*1249c01aSStefan Metzmacher if (event->event == RDMA_CM_EVENT_DEVICE_REMOVAL) 56*1249c01aSStefan Metzmacher ret = -ENETDOWN; 57*1249c01aSStefan Metzmacher if (IS_ERR(SMBDIRECT_DEBUG_ERR_PTR(event->status))) 58*1249c01aSStefan Metzmacher ret = event->status; 59*1249c01aSStefan Metzmacher 60*1249c01aSStefan Metzmacher /* 61*1249c01aSStefan Metzmacher * cma_cm_event_handler() has 62*1249c01aSStefan Metzmacher * lockdep_assert_held(&id_priv->handler_mutex); 63*1249c01aSStefan Metzmacher * 64*1249c01aSStefan Metzmacher * Mutexes are not allowed in interrupts, 65*1249c01aSStefan Metzmacher * and we rely on not being in an interrupt here. 66*1249c01aSStefan Metzmacher */ 67*1249c01aSStefan Metzmacher WARN_ON_ONCE(in_interrupt()); 68*1249c01aSStefan Metzmacher 69*1249c01aSStefan Metzmacher if (event->event != sc->rdma.expected_event) { 70*1249c01aSStefan Metzmacher smbdirect_log_rdma_event(sc, SMBDIRECT_LOG_ERR, 71*1249c01aSStefan Metzmacher "%s (first_error=%1pe, expected=%s) => event=%s status=%d => ret=%1pe\n", 72*1249c01aSStefan Metzmacher smbdirect_socket_status_string(sc->status), 73*1249c01aSStefan Metzmacher SMBDIRECT_DEBUG_ERR_PTR(sc->first_error), 74*1249c01aSStefan Metzmacher rdma_event_msg(sc->rdma.expected_event), 75*1249c01aSStefan Metzmacher rdma_event_msg(event->event), 76*1249c01aSStefan Metzmacher event->status, 77*1249c01aSStefan Metzmacher SMBDIRECT_DEBUG_ERR_PTR(ret)); 78*1249c01aSStefan Metzmacher 79*1249c01aSStefan Metzmacher /* 80*1249c01aSStefan Metzmacher * If we get RDMA_CM_EVENT_DEVICE_REMOVAL, 81*1249c01aSStefan Metzmacher * we should change to SMBDIRECT_SOCKET_DISCONNECTED, 82*1249c01aSStefan Metzmacher * so that rdma_disconnect() is avoided later via 83*1249c01aSStefan Metzmacher * smbdirect_socket_schedule_cleanup[_status]() => 84*1249c01aSStefan Metzmacher * smbdirect_socket_cleanup_work(). 85*1249c01aSStefan Metzmacher * 86*1249c01aSStefan Metzmacher * As otherwise we'd set SMBDIRECT_SOCKET_DISCONNECTING, 87*1249c01aSStefan Metzmacher * but never ever get RDMA_CM_EVENT_DISCONNECTED and 88*1249c01aSStefan Metzmacher * never reach SMBDIRECT_SOCKET_DISCONNECTED. 89*1249c01aSStefan Metzmacher */ 90*1249c01aSStefan Metzmacher if (event->event == RDMA_CM_EVENT_DEVICE_REMOVAL) 91*1249c01aSStefan Metzmacher smbdirect_socket_schedule_cleanup_status(sc, 92*1249c01aSStefan Metzmacher SMBDIRECT_LOG_ERR, 93*1249c01aSStefan Metzmacher ret, 94*1249c01aSStefan Metzmacher SMBDIRECT_SOCKET_DISCONNECTED); 95*1249c01aSStefan Metzmacher else 96*1249c01aSStefan Metzmacher smbdirect_socket_schedule_cleanup(sc, ret); 97*1249c01aSStefan Metzmacher if (sc->ib.qp) 98*1249c01aSStefan Metzmacher ib_drain_qp(sc->ib.qp); 99*1249c01aSStefan Metzmacher return 0; 100*1249c01aSStefan Metzmacher } 101*1249c01aSStefan Metzmacher 102*1249c01aSStefan Metzmacher smbdirect_log_rdma_event(sc, SMBDIRECT_LOG_INFO, 103*1249c01aSStefan Metzmacher "%s (first_error=%1pe) event=%s\n", 104*1249c01aSStefan Metzmacher smbdirect_socket_status_string(sc->status), 105*1249c01aSStefan Metzmacher SMBDIRECT_DEBUG_ERR_PTR(sc->first_error), 106*1249c01aSStefan Metzmacher rdma_event_msg(event->event)); 107*1249c01aSStefan Metzmacher 108*1249c01aSStefan Metzmacher switch (event->event) { 109*1249c01aSStefan Metzmacher case RDMA_CM_EVENT_DISCONNECTED: 110*1249c01aSStefan Metzmacher /* 111*1249c01aSStefan Metzmacher * We need to change to SMBDIRECT_SOCKET_DISCONNECTED, 112*1249c01aSStefan Metzmacher * so that rdma_disconnect() is avoided later via 113*1249c01aSStefan Metzmacher * smbdirect_socket_schedule_cleanup_status() => 114*1249c01aSStefan Metzmacher * smbdirect_socket_cleanup_work(). 115*1249c01aSStefan Metzmacher * 116*1249c01aSStefan Metzmacher * As otherwise we'd set SMBDIRECT_SOCKET_DISCONNECTING, 117*1249c01aSStefan Metzmacher * but never ever get RDMA_CM_EVENT_DISCONNECTED and 118*1249c01aSStefan Metzmacher * never reach SMBDIRECT_SOCKET_DISCONNECTED. 119*1249c01aSStefan Metzmacher * 120*1249c01aSStefan Metzmacher * This is also a normal disconnect so 121*1249c01aSStefan Metzmacher * SMBDIRECT_LOG_INFO should be good enough 122*1249c01aSStefan Metzmacher * and avoids spamming the default logs. 123*1249c01aSStefan Metzmacher */ 124*1249c01aSStefan Metzmacher smbdirect_socket_schedule_cleanup_status(sc, 125*1249c01aSStefan Metzmacher SMBDIRECT_LOG_INFO, 126*1249c01aSStefan Metzmacher ret, 127*1249c01aSStefan Metzmacher SMBDIRECT_SOCKET_DISCONNECTED); 128*1249c01aSStefan Metzmacher if (sc->ib.qp) 129*1249c01aSStefan Metzmacher ib_drain_qp(sc->ib.qp); 130*1249c01aSStefan Metzmacher return 0; 131*1249c01aSStefan Metzmacher 132*1249c01aSStefan Metzmacher default: 133*1249c01aSStefan Metzmacher break; 134*1249c01aSStefan Metzmacher } 135*1249c01aSStefan Metzmacher 136*1249c01aSStefan Metzmacher /* 137*1249c01aSStefan Metzmacher * This is an internal error, should be handled above via 138*1249c01aSStefan Metzmacher * event->event != sc->rdma.expected_event already. 139*1249c01aSStefan Metzmacher */ 140*1249c01aSStefan Metzmacher WARN_ON_ONCE(sc->rdma.expected_event != RDMA_CM_EVENT_DISCONNECTED); 141*1249c01aSStefan Metzmacher smbdirect_socket_schedule_cleanup(sc, -ECONNABORTED); 142*1249c01aSStefan Metzmacher return 0; 143*1249c01aSStefan Metzmacher } 144*1249c01aSStefan Metzmacher 145*1249c01aSStefan Metzmacher void smbdirect_connection_rdma_established(struct smbdirect_socket *sc) 146*1249c01aSStefan Metzmacher { 147*1249c01aSStefan Metzmacher smbdirect_log_rdma_event(sc, SMBDIRECT_LOG_INFO, 148*1249c01aSStefan Metzmacher "rdma established: device: %.*s local: %pISpsfc remote: %pISpsfc\n", 149*1249c01aSStefan Metzmacher IB_DEVICE_NAME_MAX, 150*1249c01aSStefan Metzmacher sc->ib.dev->name, 151*1249c01aSStefan Metzmacher &sc->rdma.cm_id->route.addr.src_addr, 152*1249c01aSStefan Metzmacher &sc->rdma.cm_id->route.addr.dst_addr); 153*1249c01aSStefan Metzmacher 154*1249c01aSStefan Metzmacher sc->rdma.cm_id->event_handler = smbdirect_connection_rdma_event_handler; 155*1249c01aSStefan Metzmacher sc->rdma.expected_event = RDMA_CM_EVENT_DISCONNECTED; 156*1249c01aSStefan Metzmacher } 157*1249c01aSStefan Metzmacher 158*1249c01aSStefan Metzmacher void smbdirect_connection_negotiation_done(struct smbdirect_socket *sc) 159*1249c01aSStefan Metzmacher { 160*1249c01aSStefan Metzmacher if (unlikely(sc->first_error)) 161*1249c01aSStefan Metzmacher return; 162*1249c01aSStefan Metzmacher 163*1249c01aSStefan Metzmacher if (sc->status == SMBDIRECT_SOCKET_CONNECTED) 164*1249c01aSStefan Metzmacher /* 165*1249c01aSStefan Metzmacher * This is the accept case where 166*1249c01aSStefan Metzmacher * smbdirect_socket_accept() already sets 167*1249c01aSStefan Metzmacher * SMBDIRECT_SOCKET_CONNECTED 168*1249c01aSStefan Metzmacher */ 169*1249c01aSStefan Metzmacher goto done; 170*1249c01aSStefan Metzmacher 171*1249c01aSStefan Metzmacher if (sc->status != SMBDIRECT_SOCKET_NEGOTIATE_RUNNING) { 172*1249c01aSStefan Metzmacher /* 173*1249c01aSStefan Metzmacher * Something went wrong... 174*1249c01aSStefan Metzmacher */ 175*1249c01aSStefan Metzmacher smbdirect_log_rdma_event(sc, SMBDIRECT_LOG_ERR, 176*1249c01aSStefan Metzmacher "status=%s first_error=%1pe local: %pISpsfc remote: %pISpsfc\n", 177*1249c01aSStefan Metzmacher smbdirect_socket_status_string(sc->status), 178*1249c01aSStefan Metzmacher SMBDIRECT_DEBUG_ERR_PTR(sc->first_error), 179*1249c01aSStefan Metzmacher &sc->rdma.cm_id->route.addr.src_addr, 180*1249c01aSStefan Metzmacher &sc->rdma.cm_id->route.addr.dst_addr); 181*1249c01aSStefan Metzmacher return; 182*1249c01aSStefan Metzmacher } 183*1249c01aSStefan Metzmacher 184*1249c01aSStefan Metzmacher /* 185*1249c01aSStefan Metzmacher * We are done, so we can wake up the waiter. 186*1249c01aSStefan Metzmacher */ 187*1249c01aSStefan Metzmacher WARN_ONCE(sc->status == SMBDIRECT_SOCKET_CONNECTED, 188*1249c01aSStefan Metzmacher "status=%s first_error=%1pe", 189*1249c01aSStefan Metzmacher smbdirect_socket_status_string(sc->status), 190*1249c01aSStefan Metzmacher SMBDIRECT_DEBUG_ERR_PTR(sc->first_error)); 191*1249c01aSStefan Metzmacher sc->status = SMBDIRECT_SOCKET_CONNECTED; 192*1249c01aSStefan Metzmacher 193*1249c01aSStefan Metzmacher /* 194*1249c01aSStefan Metzmacher * We need to setup the refill and send immediate work 195*1249c01aSStefan Metzmacher * in order to get a working connection. 196*1249c01aSStefan Metzmacher */ 197*1249c01aSStefan Metzmacher done: 198*1249c01aSStefan Metzmacher INIT_WORK(&sc->recv_io.posted.refill_work, smbdirect_connection_recv_io_refill_work); 199*1249c01aSStefan Metzmacher INIT_WORK(&sc->idle.immediate_work, smbdirect_connection_send_immediate_work); 200*1249c01aSStefan Metzmacher 201*1249c01aSStefan Metzmacher smbdirect_log_rdma_event(sc, SMBDIRECT_LOG_INFO, 202*1249c01aSStefan Metzmacher "negotiated: local: %pISpsfc remote: %pISpsfc\n", 203*1249c01aSStefan Metzmacher &sc->rdma.cm_id->route.addr.src_addr, 204*1249c01aSStefan Metzmacher &sc->rdma.cm_id->route.addr.dst_addr); 205*1249c01aSStefan Metzmacher 206*1249c01aSStefan Metzmacher wake_up(&sc->status_wait); 207*1249c01aSStefan Metzmacher } 208*1249c01aSStefan Metzmacher 209*1249c01aSStefan Metzmacher static u32 smbdirect_rdma_rw_send_wrs(struct ib_device *dev, 210*1249c01aSStefan Metzmacher const struct ib_qp_init_attr *attr) 211*1249c01aSStefan Metzmacher { 212*1249c01aSStefan Metzmacher /* 213*1249c01aSStefan Metzmacher * This could be split out of rdma_rw_init_qp() 214*1249c01aSStefan Metzmacher * and be a helper function next to rdma_rw_mr_factor() 215*1249c01aSStefan Metzmacher * 216*1249c01aSStefan Metzmacher * We can't check unlikely(rdma_rw_force_mr) here, 217*1249c01aSStefan Metzmacher * but that is most likely 0 anyway. 218*1249c01aSStefan Metzmacher */ 219*1249c01aSStefan Metzmacher u32 factor; 220*1249c01aSStefan Metzmacher 221*1249c01aSStefan Metzmacher WARN_ON_ONCE(attr->port_num == 0); 222*1249c01aSStefan Metzmacher 223*1249c01aSStefan Metzmacher /* 224*1249c01aSStefan Metzmacher * Each context needs at least one RDMA READ or WRITE WR. 225*1249c01aSStefan Metzmacher * 226*1249c01aSStefan Metzmacher * For some hardware we might need more, eventually we should ask the 227*1249c01aSStefan Metzmacher * HCA driver for a multiplier here. 228*1249c01aSStefan Metzmacher */ 229*1249c01aSStefan Metzmacher factor = 1; 230*1249c01aSStefan Metzmacher 231*1249c01aSStefan Metzmacher /* 232*1249c01aSStefan Metzmacher * If the device needs MRs to perform RDMA READ or WRITE operations, 233*1249c01aSStefan Metzmacher * we'll need two additional MRs for the registrations and the 234*1249c01aSStefan Metzmacher * invalidation. 235*1249c01aSStefan Metzmacher */ 236*1249c01aSStefan Metzmacher if (rdma_protocol_iwarp(dev, attr->port_num) || dev->attrs.max_sgl_rd) 237*1249c01aSStefan Metzmacher factor += 2; /* inv + reg */ 238*1249c01aSStefan Metzmacher 239*1249c01aSStefan Metzmacher return factor * attr->cap.max_rdma_ctxs; 240*1249c01aSStefan Metzmacher } 241*1249c01aSStefan Metzmacher 242*1249c01aSStefan Metzmacher int smbdirect_connection_create_qp(struct smbdirect_socket *sc) 243*1249c01aSStefan Metzmacher { 244*1249c01aSStefan Metzmacher const struct smbdirect_socket_parameters *sp = &sc->parameters; 245*1249c01aSStefan Metzmacher struct ib_qp_init_attr qp_attr; 246*1249c01aSStefan Metzmacher struct ib_qp_cap qp_cap; 247*1249c01aSStefan Metzmacher u32 rdma_send_wr; 248*1249c01aSStefan Metzmacher u32 max_send_wr; 249*1249c01aSStefan Metzmacher int ret; 250*1249c01aSStefan Metzmacher 251*1249c01aSStefan Metzmacher /* 252*1249c01aSStefan Metzmacher * Note that {rdma,ib}_create_qp() will call 253*1249c01aSStefan Metzmacher * rdma_rw_init_qp() if max_rdma_ctxs is not 0. 254*1249c01aSStefan Metzmacher * It will adjust max_send_wr to the required 255*1249c01aSStefan Metzmacher * number of additional WRs for the RDMA RW operations. 256*1249c01aSStefan Metzmacher * It will cap max_send_wr to the device limit. 257*1249c01aSStefan Metzmacher * 258*1249c01aSStefan Metzmacher * We use allocate sp->responder_resources * 2 MRs 259*1249c01aSStefan Metzmacher * and each MR needs WRs for REG and INV, so 260*1249c01aSStefan Metzmacher * we use '* 4'. 261*1249c01aSStefan Metzmacher * 262*1249c01aSStefan Metzmacher * +1 for ib_drain_qp() 263*1249c01aSStefan Metzmacher */ 264*1249c01aSStefan Metzmacher memset(&qp_cap, 0, sizeof(qp_cap)); 265*1249c01aSStefan Metzmacher qp_cap.max_send_wr = sp->send_credit_target + sp->responder_resources * 4 + 1; 266*1249c01aSStefan Metzmacher qp_cap.max_recv_wr = sp->recv_credit_max + 1; 267*1249c01aSStefan Metzmacher qp_cap.max_send_sge = SMBDIRECT_SEND_IO_MAX_SGE; 268*1249c01aSStefan Metzmacher qp_cap.max_recv_sge = SMBDIRECT_RECV_IO_MAX_SGE; 269*1249c01aSStefan Metzmacher qp_cap.max_inline_data = 0; 270*1249c01aSStefan Metzmacher qp_cap.max_rdma_ctxs = sc->rw_io.credits.max; 271*1249c01aSStefan Metzmacher 272*1249c01aSStefan Metzmacher /* 273*1249c01aSStefan Metzmacher * Find out the number of max_send_wr 274*1249c01aSStefan Metzmacher * after rdma_rw_init_qp() adjusted it. 275*1249c01aSStefan Metzmacher * 276*1249c01aSStefan Metzmacher * We only do it on a temporary variable, 277*1249c01aSStefan Metzmacher * as rdma_create_qp() will trigger 278*1249c01aSStefan Metzmacher * rdma_rw_init_qp() again. 279*1249c01aSStefan Metzmacher */ 280*1249c01aSStefan Metzmacher memset(&qp_attr, 0, sizeof(qp_attr)); 281*1249c01aSStefan Metzmacher qp_attr.cap = qp_cap; 282*1249c01aSStefan Metzmacher qp_attr.port_num = sc->rdma.cm_id->port_num; 283*1249c01aSStefan Metzmacher rdma_send_wr = smbdirect_rdma_rw_send_wrs(sc->ib.dev, &qp_attr); 284*1249c01aSStefan Metzmacher max_send_wr = qp_cap.max_send_wr + rdma_send_wr; 285*1249c01aSStefan Metzmacher 286*1249c01aSStefan Metzmacher if (qp_cap.max_send_wr > sc->ib.dev->attrs.max_cqe || 287*1249c01aSStefan Metzmacher qp_cap.max_send_wr > sc->ib.dev->attrs.max_qp_wr) { 288*1249c01aSStefan Metzmacher pr_err("Possible CQE overrun: max_send_wr %d\n", 289*1249c01aSStefan Metzmacher qp_cap.max_send_wr); 290*1249c01aSStefan Metzmacher pr_err("device %.*s reporting max_cqe %d max_qp_wr %d\n", 291*1249c01aSStefan Metzmacher IB_DEVICE_NAME_MAX, 292*1249c01aSStefan Metzmacher sc->ib.dev->name, 293*1249c01aSStefan Metzmacher sc->ib.dev->attrs.max_cqe, 294*1249c01aSStefan Metzmacher sc->ib.dev->attrs.max_qp_wr); 295*1249c01aSStefan Metzmacher pr_err("consider lowering send_credit_target = %d\n", 296*1249c01aSStefan Metzmacher sp->send_credit_target); 297*1249c01aSStefan Metzmacher return -EINVAL; 298*1249c01aSStefan Metzmacher } 299*1249c01aSStefan Metzmacher 300*1249c01aSStefan Metzmacher if (qp_cap.max_rdma_ctxs && 301*1249c01aSStefan Metzmacher (max_send_wr >= sc->ib.dev->attrs.max_cqe || 302*1249c01aSStefan Metzmacher max_send_wr >= sc->ib.dev->attrs.max_qp_wr)) { 303*1249c01aSStefan Metzmacher pr_err("Possible CQE overrun: rdma_send_wr %d + max_send_wr %d = %d\n", 304*1249c01aSStefan Metzmacher rdma_send_wr, qp_cap.max_send_wr, max_send_wr); 305*1249c01aSStefan Metzmacher pr_err("device %.*s reporting max_cqe %d max_qp_wr %d\n", 306*1249c01aSStefan Metzmacher IB_DEVICE_NAME_MAX, 307*1249c01aSStefan Metzmacher sc->ib.dev->name, 308*1249c01aSStefan Metzmacher sc->ib.dev->attrs.max_cqe, 309*1249c01aSStefan Metzmacher sc->ib.dev->attrs.max_qp_wr); 310*1249c01aSStefan Metzmacher pr_err("consider lowering send_credit_target = %d, max_rdma_ctxs = %d\n", 311*1249c01aSStefan Metzmacher sp->send_credit_target, qp_cap.max_rdma_ctxs); 312*1249c01aSStefan Metzmacher return -EINVAL; 313*1249c01aSStefan Metzmacher } 314*1249c01aSStefan Metzmacher 315*1249c01aSStefan Metzmacher if (qp_cap.max_recv_wr > sc->ib.dev->attrs.max_cqe || 316*1249c01aSStefan Metzmacher qp_cap.max_recv_wr > sc->ib.dev->attrs.max_qp_wr) { 317*1249c01aSStefan Metzmacher pr_err("Possible CQE overrun: max_recv_wr %d\n", 318*1249c01aSStefan Metzmacher qp_cap.max_recv_wr); 319*1249c01aSStefan Metzmacher pr_err("device %.*s reporting max_cqe %d max_qp_wr %d\n", 320*1249c01aSStefan Metzmacher IB_DEVICE_NAME_MAX, 321*1249c01aSStefan Metzmacher sc->ib.dev->name, 322*1249c01aSStefan Metzmacher sc->ib.dev->attrs.max_cqe, 323*1249c01aSStefan Metzmacher sc->ib.dev->attrs.max_qp_wr); 324*1249c01aSStefan Metzmacher pr_err("consider lowering receive_credit_max = %d\n", 325*1249c01aSStefan Metzmacher sp->recv_credit_max); 326*1249c01aSStefan Metzmacher return -EINVAL; 327*1249c01aSStefan Metzmacher } 328*1249c01aSStefan Metzmacher 329*1249c01aSStefan Metzmacher if (qp_cap.max_send_sge > sc->ib.dev->attrs.max_send_sge || 330*1249c01aSStefan Metzmacher qp_cap.max_recv_sge > sc->ib.dev->attrs.max_recv_sge) { 331*1249c01aSStefan Metzmacher pr_err("device %.*s max_send_sge/max_recv_sge = %d/%d too small\n", 332*1249c01aSStefan Metzmacher IB_DEVICE_NAME_MAX, 333*1249c01aSStefan Metzmacher sc->ib.dev->name, 334*1249c01aSStefan Metzmacher sc->ib.dev->attrs.max_send_sge, 335*1249c01aSStefan Metzmacher sc->ib.dev->attrs.max_recv_sge); 336*1249c01aSStefan Metzmacher return -EINVAL; 337*1249c01aSStefan Metzmacher } 338*1249c01aSStefan Metzmacher 339*1249c01aSStefan Metzmacher sc->ib.pd = ib_alloc_pd(sc->ib.dev, 0); 340*1249c01aSStefan Metzmacher if (IS_ERR(sc->ib.pd)) { 341*1249c01aSStefan Metzmacher pr_err("Can't create RDMA PD: %1pe\n", sc->ib.pd); 342*1249c01aSStefan Metzmacher ret = PTR_ERR(sc->ib.pd); 343*1249c01aSStefan Metzmacher sc->ib.pd = NULL; 344*1249c01aSStefan Metzmacher return ret; 345*1249c01aSStefan Metzmacher } 346*1249c01aSStefan Metzmacher 347*1249c01aSStefan Metzmacher sc->ib.send_cq = ib_alloc_cq_any(sc->ib.dev, sc, 348*1249c01aSStefan Metzmacher max_send_wr, 349*1249c01aSStefan Metzmacher sc->ib.poll_ctx); 350*1249c01aSStefan Metzmacher if (IS_ERR(sc->ib.send_cq)) { 351*1249c01aSStefan Metzmacher pr_err("Can't create RDMA send CQ: %1pe\n", sc->ib.send_cq); 352*1249c01aSStefan Metzmacher ret = PTR_ERR(sc->ib.send_cq); 353*1249c01aSStefan Metzmacher sc->ib.send_cq = NULL; 354*1249c01aSStefan Metzmacher goto err; 355*1249c01aSStefan Metzmacher } 356*1249c01aSStefan Metzmacher 357*1249c01aSStefan Metzmacher sc->ib.recv_cq = ib_alloc_cq_any(sc->ib.dev, sc, 358*1249c01aSStefan Metzmacher qp_cap.max_recv_wr, 359*1249c01aSStefan Metzmacher sc->ib.poll_ctx); 360*1249c01aSStefan Metzmacher if (IS_ERR(sc->ib.recv_cq)) { 361*1249c01aSStefan Metzmacher pr_err("Can't create RDMA recv CQ: %1pe\n", sc->ib.recv_cq); 362*1249c01aSStefan Metzmacher ret = PTR_ERR(sc->ib.recv_cq); 363*1249c01aSStefan Metzmacher sc->ib.recv_cq = NULL; 364*1249c01aSStefan Metzmacher goto err; 365*1249c01aSStefan Metzmacher } 366*1249c01aSStefan Metzmacher 367*1249c01aSStefan Metzmacher /* 368*1249c01aSStefan Metzmacher * We reset completely here! 369*1249c01aSStefan Metzmacher * As the above use was just temporary 370*1249c01aSStefan Metzmacher * to calc max_send_wr and rdma_send_wr. 371*1249c01aSStefan Metzmacher * 372*1249c01aSStefan Metzmacher * rdma_create_qp() will trigger rdma_rw_init_qp() 373*1249c01aSStefan Metzmacher * again if max_rdma_ctxs is not 0. 374*1249c01aSStefan Metzmacher */ 375*1249c01aSStefan Metzmacher memset(&qp_attr, 0, sizeof(qp_attr)); 376*1249c01aSStefan Metzmacher qp_attr.event_handler = smbdirect_connection_qp_event_handler; 377*1249c01aSStefan Metzmacher qp_attr.qp_context = sc; 378*1249c01aSStefan Metzmacher qp_attr.cap = qp_cap; 379*1249c01aSStefan Metzmacher qp_attr.sq_sig_type = IB_SIGNAL_REQ_WR; 380*1249c01aSStefan Metzmacher qp_attr.qp_type = IB_QPT_RC; 381*1249c01aSStefan Metzmacher qp_attr.send_cq = sc->ib.send_cq; 382*1249c01aSStefan Metzmacher qp_attr.recv_cq = sc->ib.recv_cq; 383*1249c01aSStefan Metzmacher qp_attr.port_num = ~0; 384*1249c01aSStefan Metzmacher 385*1249c01aSStefan Metzmacher ret = rdma_create_qp(sc->rdma.cm_id, sc->ib.pd, &qp_attr); 386*1249c01aSStefan Metzmacher if (ret) { 387*1249c01aSStefan Metzmacher pr_err("Can't create RDMA QP: %1pe\n", 388*1249c01aSStefan Metzmacher SMBDIRECT_DEBUG_ERR_PTR(ret)); 389*1249c01aSStefan Metzmacher goto err; 390*1249c01aSStefan Metzmacher } 391*1249c01aSStefan Metzmacher sc->ib.qp = sc->rdma.cm_id->qp; 392*1249c01aSStefan Metzmacher 393*1249c01aSStefan Metzmacher return 0; 394*1249c01aSStefan Metzmacher err: 395*1249c01aSStefan Metzmacher smbdirect_connection_destroy_qp(sc); 396*1249c01aSStefan Metzmacher return ret; 397*1249c01aSStefan Metzmacher } 398*1249c01aSStefan Metzmacher 399*1249c01aSStefan Metzmacher void smbdirect_connection_destroy_qp(struct smbdirect_socket *sc) 400*1249c01aSStefan Metzmacher { 401*1249c01aSStefan Metzmacher if (sc->ib.qp) { 402*1249c01aSStefan Metzmacher ib_drain_qp(sc->ib.qp); 403*1249c01aSStefan Metzmacher sc->ib.qp = NULL; 404*1249c01aSStefan Metzmacher rdma_destroy_qp(sc->rdma.cm_id); 405*1249c01aSStefan Metzmacher } 406*1249c01aSStefan Metzmacher if (sc->ib.recv_cq) { 407*1249c01aSStefan Metzmacher ib_destroy_cq(sc->ib.recv_cq); 408*1249c01aSStefan Metzmacher sc->ib.recv_cq = NULL; 409*1249c01aSStefan Metzmacher } 410*1249c01aSStefan Metzmacher if (sc->ib.send_cq) { 411*1249c01aSStefan Metzmacher ib_destroy_cq(sc->ib.send_cq); 412*1249c01aSStefan Metzmacher sc->ib.send_cq = NULL; 413*1249c01aSStefan Metzmacher } 414*1249c01aSStefan Metzmacher if (sc->ib.pd) { 415*1249c01aSStefan Metzmacher ib_dealloc_pd(sc->ib.pd); 416*1249c01aSStefan Metzmacher sc->ib.pd = NULL; 417*1249c01aSStefan Metzmacher } 418*1249c01aSStefan Metzmacher } 419*1249c01aSStefan Metzmacher 420*1249c01aSStefan Metzmacher int smbdirect_connection_create_mem_pools(struct smbdirect_socket *sc) 421*1249c01aSStefan Metzmacher { 422*1249c01aSStefan Metzmacher const struct smbdirect_socket_parameters *sp = &sc->parameters; 423*1249c01aSStefan Metzmacher char name[80]; 424*1249c01aSStefan Metzmacher size_t i; 425*1249c01aSStefan Metzmacher 426*1249c01aSStefan Metzmacher /* 427*1249c01aSStefan Metzmacher * We use sizeof(struct smbdirect_negotiate_resp) for the 428*1249c01aSStefan Metzmacher * payload size as it is larger as 429*1249c01aSStefan Metzmacher * sizeof(struct smbdirect_data_transfer). 430*1249c01aSStefan Metzmacher * 431*1249c01aSStefan Metzmacher * This will fit client and server usage for now. 432*1249c01aSStefan Metzmacher */ 433*1249c01aSStefan Metzmacher snprintf(name, sizeof(name), "smbdirect_send_io_cache_%p", sc); 434*1249c01aSStefan Metzmacher struct kmem_cache_args send_io_args = { 435*1249c01aSStefan Metzmacher .align = __alignof__(struct smbdirect_send_io), 436*1249c01aSStefan Metzmacher }; 437*1249c01aSStefan Metzmacher sc->send_io.mem.cache = kmem_cache_create(name, 438*1249c01aSStefan Metzmacher sizeof(struct smbdirect_send_io) + 439*1249c01aSStefan Metzmacher sizeof(struct smbdirect_negotiate_resp), 440*1249c01aSStefan Metzmacher &send_io_args, 441*1249c01aSStefan Metzmacher SLAB_HWCACHE_ALIGN); 442*1249c01aSStefan Metzmacher if (!sc->send_io.mem.cache) 443*1249c01aSStefan Metzmacher goto err; 444*1249c01aSStefan Metzmacher 445*1249c01aSStefan Metzmacher sc->send_io.mem.pool = mempool_create_slab_pool(sp->send_credit_target, 446*1249c01aSStefan Metzmacher sc->send_io.mem.cache); 447*1249c01aSStefan Metzmacher if (!sc->send_io.mem.pool) 448*1249c01aSStefan Metzmacher goto err; 449*1249c01aSStefan Metzmacher 450*1249c01aSStefan Metzmacher /* 451*1249c01aSStefan Metzmacher * A payload size of sp->max_recv_size should fit 452*1249c01aSStefan Metzmacher * any message. 453*1249c01aSStefan Metzmacher * 454*1249c01aSStefan Metzmacher * For smbdirect_data_transfer messages the whole 455*1249c01aSStefan Metzmacher * buffer might be exposed to userspace 456*1249c01aSStefan Metzmacher * (currently on the client side...) 457*1249c01aSStefan Metzmacher * The documentation says data_offset = 0 would be 458*1249c01aSStefan Metzmacher * strange but valid. 459*1249c01aSStefan Metzmacher */ 460*1249c01aSStefan Metzmacher snprintf(name, sizeof(name), "smbdirect_recv_io_cache_%p", sc); 461*1249c01aSStefan Metzmacher struct kmem_cache_args recv_io_args = { 462*1249c01aSStefan Metzmacher .align = __alignof__(struct smbdirect_recv_io), 463*1249c01aSStefan Metzmacher .useroffset = sizeof(struct smbdirect_recv_io), 464*1249c01aSStefan Metzmacher .usersize = sp->max_recv_size, 465*1249c01aSStefan Metzmacher }; 466*1249c01aSStefan Metzmacher sc->recv_io.mem.cache = kmem_cache_create(name, 467*1249c01aSStefan Metzmacher sizeof(struct smbdirect_recv_io) + 468*1249c01aSStefan Metzmacher sp->max_recv_size, 469*1249c01aSStefan Metzmacher &recv_io_args, 470*1249c01aSStefan Metzmacher SLAB_HWCACHE_ALIGN); 471*1249c01aSStefan Metzmacher if (!sc->recv_io.mem.cache) 472*1249c01aSStefan Metzmacher goto err; 473*1249c01aSStefan Metzmacher 474*1249c01aSStefan Metzmacher sc->recv_io.mem.pool = mempool_create_slab_pool(sp->recv_credit_max, 475*1249c01aSStefan Metzmacher sc->recv_io.mem.cache); 476*1249c01aSStefan Metzmacher if (!sc->recv_io.mem.pool) 477*1249c01aSStefan Metzmacher goto err; 478*1249c01aSStefan Metzmacher 479*1249c01aSStefan Metzmacher for (i = 0; i < sp->recv_credit_max; i++) { 480*1249c01aSStefan Metzmacher struct smbdirect_recv_io *recv_io; 481*1249c01aSStefan Metzmacher 482*1249c01aSStefan Metzmacher recv_io = mempool_alloc(sc->recv_io.mem.pool, 483*1249c01aSStefan Metzmacher sc->recv_io.mem.gfp_mask); 484*1249c01aSStefan Metzmacher if (!recv_io) 485*1249c01aSStefan Metzmacher goto err; 486*1249c01aSStefan Metzmacher recv_io->socket = sc; 487*1249c01aSStefan Metzmacher recv_io->sge.length = 0; 488*1249c01aSStefan Metzmacher list_add_tail(&recv_io->list, &sc->recv_io.free.list); 489*1249c01aSStefan Metzmacher } 490*1249c01aSStefan Metzmacher 491*1249c01aSStefan Metzmacher return 0; 492*1249c01aSStefan Metzmacher err: 493*1249c01aSStefan Metzmacher smbdirect_connection_destroy_mem_pools(sc); 494*1249c01aSStefan Metzmacher return -ENOMEM; 495*1249c01aSStefan Metzmacher } 496*1249c01aSStefan Metzmacher 497*1249c01aSStefan Metzmacher void smbdirect_connection_destroy_mem_pools(struct smbdirect_socket *sc) 498*1249c01aSStefan Metzmacher { 499*1249c01aSStefan Metzmacher struct smbdirect_recv_io *recv_io, *next_io; 500*1249c01aSStefan Metzmacher 501*1249c01aSStefan Metzmacher list_for_each_entry_safe(recv_io, next_io, &sc->recv_io.free.list, list) { 502*1249c01aSStefan Metzmacher list_del(&recv_io->list); 503*1249c01aSStefan Metzmacher mempool_free(recv_io, sc->recv_io.mem.pool); 504*1249c01aSStefan Metzmacher } 505*1249c01aSStefan Metzmacher 506*1249c01aSStefan Metzmacher /* 507*1249c01aSStefan Metzmacher * Note mempool_destroy() and kmem_cache_destroy() 508*1249c01aSStefan Metzmacher * work fine with a NULL pointer 509*1249c01aSStefan Metzmacher */ 510*1249c01aSStefan Metzmacher 511*1249c01aSStefan Metzmacher mempool_destroy(sc->recv_io.mem.pool); 512*1249c01aSStefan Metzmacher sc->recv_io.mem.pool = NULL; 513*1249c01aSStefan Metzmacher 514*1249c01aSStefan Metzmacher kmem_cache_destroy(sc->recv_io.mem.cache); 515*1249c01aSStefan Metzmacher sc->recv_io.mem.cache = NULL; 516*1249c01aSStefan Metzmacher 517*1249c01aSStefan Metzmacher mempool_destroy(sc->send_io.mem.pool); 518*1249c01aSStefan Metzmacher sc->send_io.mem.pool = NULL; 519*1249c01aSStefan Metzmacher 520*1249c01aSStefan Metzmacher kmem_cache_destroy(sc->send_io.mem.cache); 521*1249c01aSStefan Metzmacher sc->send_io.mem.cache = NULL; 522*1249c01aSStefan Metzmacher } 523*1249c01aSStefan Metzmacher 524*1249c01aSStefan Metzmacher struct smbdirect_send_io *smbdirect_connection_alloc_send_io(struct smbdirect_socket *sc) 525*1249c01aSStefan Metzmacher { 526*1249c01aSStefan Metzmacher struct smbdirect_send_io *msg; 527*1249c01aSStefan Metzmacher 528*1249c01aSStefan Metzmacher msg = mempool_alloc(sc->send_io.mem.pool, sc->send_io.mem.gfp_mask); 529*1249c01aSStefan Metzmacher if (!msg) 530*1249c01aSStefan Metzmacher return ERR_PTR(-ENOMEM); 531*1249c01aSStefan Metzmacher msg->socket = sc; 532*1249c01aSStefan Metzmacher INIT_LIST_HEAD(&msg->sibling_list); 533*1249c01aSStefan Metzmacher msg->num_sge = 0; 534*1249c01aSStefan Metzmacher 535*1249c01aSStefan Metzmacher return msg; 536*1249c01aSStefan Metzmacher } 537*1249c01aSStefan Metzmacher 538*1249c01aSStefan Metzmacher void smbdirect_connection_free_send_io(struct smbdirect_send_io *msg) 539*1249c01aSStefan Metzmacher { 540*1249c01aSStefan Metzmacher struct smbdirect_socket *sc = msg->socket; 541*1249c01aSStefan Metzmacher size_t i; 542*1249c01aSStefan Metzmacher 543*1249c01aSStefan Metzmacher /* 544*1249c01aSStefan Metzmacher * The list needs to be empty! 545*1249c01aSStefan Metzmacher * The caller should take care of it. 546*1249c01aSStefan Metzmacher */ 547*1249c01aSStefan Metzmacher WARN_ON_ONCE(!list_empty(&msg->sibling_list)); 548*1249c01aSStefan Metzmacher 549*1249c01aSStefan Metzmacher /* 550*1249c01aSStefan Metzmacher * Note we call ib_dma_unmap_page(), even if some sges are mapped using 551*1249c01aSStefan Metzmacher * ib_dma_map_single(). 552*1249c01aSStefan Metzmacher * 553*1249c01aSStefan Metzmacher * The difference between _single() and _page() only matters for the 554*1249c01aSStefan Metzmacher * ib_dma_map_*() case. 555*1249c01aSStefan Metzmacher * 556*1249c01aSStefan Metzmacher * For the ib_dma_unmap_*() case it does not matter as both take the 557*1249c01aSStefan Metzmacher * dma_addr_t and dma_unmap_single_attrs() is just an alias to 558*1249c01aSStefan Metzmacher * dma_unmap_page_attrs(). 559*1249c01aSStefan Metzmacher */ 560*1249c01aSStefan Metzmacher for (i = 0; i < msg->num_sge; i++) 561*1249c01aSStefan Metzmacher ib_dma_unmap_page(sc->ib.dev, 562*1249c01aSStefan Metzmacher msg->sge[i].addr, 563*1249c01aSStefan Metzmacher msg->sge[i].length, 564*1249c01aSStefan Metzmacher DMA_TO_DEVICE); 565*1249c01aSStefan Metzmacher 566*1249c01aSStefan Metzmacher mempool_free(msg, sc->send_io.mem.pool); 567*1249c01aSStefan Metzmacher } 568*1249c01aSStefan Metzmacher 569*1249c01aSStefan Metzmacher struct smbdirect_recv_io *smbdirect_connection_get_recv_io(struct smbdirect_socket *sc) 570*1249c01aSStefan Metzmacher { 571*1249c01aSStefan Metzmacher struct smbdirect_recv_io *msg = NULL; 572*1249c01aSStefan Metzmacher unsigned long flags; 573*1249c01aSStefan Metzmacher 574*1249c01aSStefan Metzmacher spin_lock_irqsave(&sc->recv_io.free.lock, flags); 575*1249c01aSStefan Metzmacher if (likely(!sc->first_error)) 576*1249c01aSStefan Metzmacher msg = list_first_entry_or_null(&sc->recv_io.free.list, 577*1249c01aSStefan Metzmacher struct smbdirect_recv_io, 578*1249c01aSStefan Metzmacher list); 579*1249c01aSStefan Metzmacher if (likely(msg)) { 580*1249c01aSStefan Metzmacher list_del(&msg->list); 581*1249c01aSStefan Metzmacher sc->statistics.get_receive_buffer++; 582*1249c01aSStefan Metzmacher } 583*1249c01aSStefan Metzmacher spin_unlock_irqrestore(&sc->recv_io.free.lock, flags); 584*1249c01aSStefan Metzmacher 585*1249c01aSStefan Metzmacher return msg; 586*1249c01aSStefan Metzmacher } 587*1249c01aSStefan Metzmacher 588*1249c01aSStefan Metzmacher void smbdirect_connection_put_recv_io(struct smbdirect_recv_io *msg) 589*1249c01aSStefan Metzmacher { 590*1249c01aSStefan Metzmacher struct smbdirect_socket *sc = msg->socket; 591*1249c01aSStefan Metzmacher unsigned long flags; 592*1249c01aSStefan Metzmacher 593*1249c01aSStefan Metzmacher if (likely(msg->sge.length != 0)) { 594*1249c01aSStefan Metzmacher ib_dma_unmap_single(sc->ib.dev, 595*1249c01aSStefan Metzmacher msg->sge.addr, 596*1249c01aSStefan Metzmacher msg->sge.length, 597*1249c01aSStefan Metzmacher DMA_FROM_DEVICE); 598*1249c01aSStefan Metzmacher msg->sge.length = 0; 599*1249c01aSStefan Metzmacher } 600*1249c01aSStefan Metzmacher 601*1249c01aSStefan Metzmacher spin_lock_irqsave(&sc->recv_io.free.lock, flags); 602*1249c01aSStefan Metzmacher list_add_tail(&msg->list, &sc->recv_io.free.list); 603*1249c01aSStefan Metzmacher sc->statistics.put_receive_buffer++; 604*1249c01aSStefan Metzmacher spin_unlock_irqrestore(&sc->recv_io.free.lock, flags); 605*1249c01aSStefan Metzmacher 606*1249c01aSStefan Metzmacher queue_work(sc->workqueues.refill, &sc->recv_io.posted.refill_work); 607*1249c01aSStefan Metzmacher } 608*1249c01aSStefan Metzmacher 609*1249c01aSStefan Metzmacher void smbdirect_connection_reassembly_append_recv_io(struct smbdirect_socket *sc, 610*1249c01aSStefan Metzmacher struct smbdirect_recv_io *msg, 611*1249c01aSStefan Metzmacher u32 data_length) 612*1249c01aSStefan Metzmacher { 613*1249c01aSStefan Metzmacher unsigned long flags; 614*1249c01aSStefan Metzmacher 615*1249c01aSStefan Metzmacher spin_lock_irqsave(&sc->recv_io.reassembly.lock, flags); 616*1249c01aSStefan Metzmacher list_add_tail(&msg->list, &sc->recv_io.reassembly.list); 617*1249c01aSStefan Metzmacher sc->recv_io.reassembly.queue_length++; 618*1249c01aSStefan Metzmacher /* 619*1249c01aSStefan Metzmacher * Make sure reassembly_data_length is updated after list and 620*1249c01aSStefan Metzmacher * reassembly_queue_length are updated. On the dequeue side 621*1249c01aSStefan Metzmacher * reassembly_data_length is checked without a lock to determine 622*1249c01aSStefan Metzmacher * if reassembly_queue_length and list is up to date 623*1249c01aSStefan Metzmacher */ 624*1249c01aSStefan Metzmacher virt_wmb(); 625*1249c01aSStefan Metzmacher sc->recv_io.reassembly.data_length += data_length; 626*1249c01aSStefan Metzmacher spin_unlock_irqrestore(&sc->recv_io.reassembly.lock, flags); 627*1249c01aSStefan Metzmacher sc->statistics.enqueue_reassembly_queue++; 628*1249c01aSStefan Metzmacher } 629*1249c01aSStefan Metzmacher 630*1249c01aSStefan Metzmacher struct smbdirect_recv_io * 631*1249c01aSStefan Metzmacher smbdirect_connection_reassembly_first_recv_io(struct smbdirect_socket *sc) 632*1249c01aSStefan Metzmacher { 633*1249c01aSStefan Metzmacher struct smbdirect_recv_io *msg; 634*1249c01aSStefan Metzmacher 635*1249c01aSStefan Metzmacher msg = list_first_entry_or_null(&sc->recv_io.reassembly.list, 636*1249c01aSStefan Metzmacher struct smbdirect_recv_io, 637*1249c01aSStefan Metzmacher list); 638*1249c01aSStefan Metzmacher 639*1249c01aSStefan Metzmacher return msg; 640*1249c01aSStefan Metzmacher } 641*1249c01aSStefan Metzmacher 642*1249c01aSStefan Metzmacher void smbdirect_connection_negotiate_rdma_resources(struct smbdirect_socket *sc, 643*1249c01aSStefan Metzmacher u8 peer_initiator_depth, 644*1249c01aSStefan Metzmacher u8 peer_responder_resources, 645*1249c01aSStefan Metzmacher const struct rdma_conn_param *param) 646*1249c01aSStefan Metzmacher { 647*1249c01aSStefan Metzmacher struct smbdirect_socket_parameters *sp = &sc->parameters; 648*1249c01aSStefan Metzmacher 649*1249c01aSStefan Metzmacher if (rdma_protocol_iwarp(sc->ib.dev, sc->rdma.cm_id->port_num) && 650*1249c01aSStefan Metzmacher param->private_data_len == 8) { 651*1249c01aSStefan Metzmacher /* 652*1249c01aSStefan Metzmacher * Legacy clients with only iWarp MPA v1 support 653*1249c01aSStefan Metzmacher * need a private blob in order to negotiate 654*1249c01aSStefan Metzmacher * the IRD/ORD values. 655*1249c01aSStefan Metzmacher */ 656*1249c01aSStefan Metzmacher const __be32 *ird_ord_hdr = param->private_data; 657*1249c01aSStefan Metzmacher u32 ird32 = be32_to_cpu(ird_ord_hdr[0]); 658*1249c01aSStefan Metzmacher u32 ord32 = be32_to_cpu(ird_ord_hdr[1]); 659*1249c01aSStefan Metzmacher 660*1249c01aSStefan Metzmacher /* 661*1249c01aSStefan Metzmacher * cifs.ko sends the legacy IRD/ORD negotiation 662*1249c01aSStefan Metzmacher * event if iWarp MPA v2 was used. 663*1249c01aSStefan Metzmacher * 664*1249c01aSStefan Metzmacher * Here we check that the values match and only 665*1249c01aSStefan Metzmacher * mark the client as legacy if they don't match. 666*1249c01aSStefan Metzmacher */ 667*1249c01aSStefan Metzmacher if ((u32)param->initiator_depth != ird32 || 668*1249c01aSStefan Metzmacher (u32)param->responder_resources != ord32) { 669*1249c01aSStefan Metzmacher /* 670*1249c01aSStefan Metzmacher * There are broken clients (old cifs.ko) 671*1249c01aSStefan Metzmacher * using little endian and also 672*1249c01aSStefan Metzmacher * struct rdma_conn_param only uses u8 673*1249c01aSStefan Metzmacher * for initiator_depth and responder_resources, 674*1249c01aSStefan Metzmacher * so we truncate the value to U8_MAX. 675*1249c01aSStefan Metzmacher * 676*1249c01aSStefan Metzmacher * smb_direct_accept_client() will then 677*1249c01aSStefan Metzmacher * do the real negotiation in order to 678*1249c01aSStefan Metzmacher * select the minimum between client and 679*1249c01aSStefan Metzmacher * server. 680*1249c01aSStefan Metzmacher */ 681*1249c01aSStefan Metzmacher ird32 = min_t(u32, ird32, U8_MAX); 682*1249c01aSStefan Metzmacher ord32 = min_t(u32, ord32, U8_MAX); 683*1249c01aSStefan Metzmacher 684*1249c01aSStefan Metzmacher sc->rdma.legacy_iwarp = true; 685*1249c01aSStefan Metzmacher peer_initiator_depth = (u8)ird32; 686*1249c01aSStefan Metzmacher peer_responder_resources = (u8)ord32; 687*1249c01aSStefan Metzmacher } 688*1249c01aSStefan Metzmacher } 689*1249c01aSStefan Metzmacher 690*1249c01aSStefan Metzmacher /* 691*1249c01aSStefan Metzmacher * negotiate the value by using the minimum 692*1249c01aSStefan Metzmacher * between client and server if the client provided 693*1249c01aSStefan Metzmacher * non 0 values. 694*1249c01aSStefan Metzmacher */ 695*1249c01aSStefan Metzmacher if (peer_initiator_depth != 0) 696*1249c01aSStefan Metzmacher sp->initiator_depth = min_t(u8, sp->initiator_depth, 697*1249c01aSStefan Metzmacher peer_initiator_depth); 698*1249c01aSStefan Metzmacher if (peer_responder_resources != 0) 699*1249c01aSStefan Metzmacher sp->responder_resources = min_t(u8, sp->responder_resources, 700*1249c01aSStefan Metzmacher peer_responder_resources); 701*1249c01aSStefan Metzmacher } 702*1249c01aSStefan Metzmacher 703*1249c01aSStefan Metzmacher bool smbdirect_connection_is_connected(struct smbdirect_socket *sc) 704*1249c01aSStefan Metzmacher { 705*1249c01aSStefan Metzmacher if (unlikely(!sc || sc->first_error || sc->status != SMBDIRECT_SOCKET_CONNECTED)) 706*1249c01aSStefan Metzmacher return false; 707*1249c01aSStefan Metzmacher return true; 708*1249c01aSStefan Metzmacher } 709*1249c01aSStefan Metzmacher __SMBDIRECT_EXPORT_SYMBOL__(smbdirect_connection_is_connected); 710*1249c01aSStefan Metzmacher 711*1249c01aSStefan Metzmacher int smbdirect_connection_wait_for_connected(struct smbdirect_socket *sc) 712*1249c01aSStefan Metzmacher { 713*1249c01aSStefan Metzmacher const struct smbdirect_socket_parameters *sp = &sc->parameters; 714*1249c01aSStefan Metzmacher union { 715*1249c01aSStefan Metzmacher struct sockaddr sa; 716*1249c01aSStefan Metzmacher struct sockaddr_storage ss; 717*1249c01aSStefan Metzmacher } src_addr, dst_addr; 718*1249c01aSStefan Metzmacher const struct sockaddr *src = NULL; 719*1249c01aSStefan Metzmacher const struct sockaddr *dst = NULL; 720*1249c01aSStefan Metzmacher char _devname[IB_DEVICE_NAME_MAX] = { 0, }; 721*1249c01aSStefan Metzmacher const char *devname = NULL; 722*1249c01aSStefan Metzmacher int ret; 723*1249c01aSStefan Metzmacher 724*1249c01aSStefan Metzmacher if (sc->rdma.cm_id) { 725*1249c01aSStefan Metzmacher src_addr.ss = sc->rdma.cm_id->route.addr.src_addr; 726*1249c01aSStefan Metzmacher if (src_addr.sa.sa_family != AF_UNSPEC) 727*1249c01aSStefan Metzmacher src = &src_addr.sa; 728*1249c01aSStefan Metzmacher dst_addr.ss = sc->rdma.cm_id->route.addr.dst_addr; 729*1249c01aSStefan Metzmacher if (dst_addr.sa.sa_family != AF_UNSPEC) 730*1249c01aSStefan Metzmacher dst = &dst_addr.sa; 731*1249c01aSStefan Metzmacher 732*1249c01aSStefan Metzmacher if (sc->ib.dev) { 733*1249c01aSStefan Metzmacher memcpy(_devname, sc->ib.dev->name, IB_DEVICE_NAME_MAX); 734*1249c01aSStefan Metzmacher devname = _devname; 735*1249c01aSStefan Metzmacher } 736*1249c01aSStefan Metzmacher } 737*1249c01aSStefan Metzmacher 738*1249c01aSStefan Metzmacher smbdirect_log_rdma_event(sc, SMBDIRECT_LOG_INFO, 739*1249c01aSStefan Metzmacher "waiting for connection: device: %.*s local: %pISpsfc remote: %pISpsfc\n", 740*1249c01aSStefan Metzmacher IB_DEVICE_NAME_MAX, devname, src, dst); 741*1249c01aSStefan Metzmacher 742*1249c01aSStefan Metzmacher ret = wait_event_interruptible_timeout(sc->status_wait, 743*1249c01aSStefan Metzmacher sc->status == SMBDIRECT_SOCKET_CONNECTED || 744*1249c01aSStefan Metzmacher sc->first_error, 745*1249c01aSStefan Metzmacher msecs_to_jiffies(sp->negotiate_timeout_msec)); 746*1249c01aSStefan Metzmacher if (sc->rdma.cm_id) { 747*1249c01aSStefan Metzmacher /* 748*1249c01aSStefan Metzmacher * Maybe src and dev are updated in the meantime. 749*1249c01aSStefan Metzmacher */ 750*1249c01aSStefan Metzmacher src_addr.ss = sc->rdma.cm_id->route.addr.src_addr; 751*1249c01aSStefan Metzmacher if (src_addr.sa.sa_family != AF_UNSPEC) 752*1249c01aSStefan Metzmacher src = &src_addr.sa; 753*1249c01aSStefan Metzmacher dst_addr.ss = sc->rdma.cm_id->route.addr.dst_addr; 754*1249c01aSStefan Metzmacher if (dst_addr.sa.sa_family != AF_UNSPEC) 755*1249c01aSStefan Metzmacher dst = &dst_addr.sa; 756*1249c01aSStefan Metzmacher 757*1249c01aSStefan Metzmacher if (sc->ib.dev) { 758*1249c01aSStefan Metzmacher memcpy(_devname, sc->ib.dev->name, IB_DEVICE_NAME_MAX); 759*1249c01aSStefan Metzmacher devname = _devname; 760*1249c01aSStefan Metzmacher } 761*1249c01aSStefan Metzmacher } 762*1249c01aSStefan Metzmacher if (ret == 0) 763*1249c01aSStefan Metzmacher ret = -ETIMEDOUT; 764*1249c01aSStefan Metzmacher if (ret < 0) 765*1249c01aSStefan Metzmacher smbdirect_socket_schedule_cleanup(sc, ret); 766*1249c01aSStefan Metzmacher if (sc->first_error) { 767*1249c01aSStefan Metzmacher int lvl = SMBDIRECT_LOG_ERR; 768*1249c01aSStefan Metzmacher 769*1249c01aSStefan Metzmacher ret = sc->first_error; 770*1249c01aSStefan Metzmacher if (ret == -ENODEV) 771*1249c01aSStefan Metzmacher lvl = SMBDIRECT_LOG_INFO; 772*1249c01aSStefan Metzmacher 773*1249c01aSStefan Metzmacher smbdirect_log_rdma_event(sc, lvl, 774*1249c01aSStefan Metzmacher "connection failed %1pe device: %.*s local: %pISpsfc remote: %pISpsfc\n", 775*1249c01aSStefan Metzmacher SMBDIRECT_DEBUG_ERR_PTR(ret), 776*1249c01aSStefan Metzmacher IB_DEVICE_NAME_MAX, devname, src, dst); 777*1249c01aSStefan Metzmacher return ret; 778*1249c01aSStefan Metzmacher } 779*1249c01aSStefan Metzmacher 780*1249c01aSStefan Metzmacher return 0; 781*1249c01aSStefan Metzmacher } 782*1249c01aSStefan Metzmacher __SMBDIRECT_EXPORT_SYMBOL__(smbdirect_connection_wait_for_connected); 783*1249c01aSStefan Metzmacher 784*1249c01aSStefan Metzmacher void smbdirect_connection_idle_timer_work(struct work_struct *work) 785*1249c01aSStefan Metzmacher { 786*1249c01aSStefan Metzmacher struct smbdirect_socket *sc = 787*1249c01aSStefan Metzmacher container_of(work, struct smbdirect_socket, idle.timer_work.work); 788*1249c01aSStefan Metzmacher const struct smbdirect_socket_parameters *sp = &sc->parameters; 789*1249c01aSStefan Metzmacher 790*1249c01aSStefan Metzmacher if (sc->idle.keepalive != SMBDIRECT_KEEPALIVE_NONE) { 791*1249c01aSStefan Metzmacher smbdirect_log_keep_alive(sc, SMBDIRECT_LOG_ERR, 792*1249c01aSStefan Metzmacher "%s => timeout sc->idle.keepalive=%s\n", 793*1249c01aSStefan Metzmacher smbdirect_socket_status_string(sc->status), 794*1249c01aSStefan Metzmacher sc->idle.keepalive == SMBDIRECT_KEEPALIVE_SENT ? 795*1249c01aSStefan Metzmacher "SENT" : "PENDING"); 796*1249c01aSStefan Metzmacher smbdirect_socket_schedule_cleanup(sc, -ETIMEDOUT); 797*1249c01aSStefan Metzmacher return; 798*1249c01aSStefan Metzmacher } 799*1249c01aSStefan Metzmacher 800*1249c01aSStefan Metzmacher if (sc->status != SMBDIRECT_SOCKET_CONNECTED) 801*1249c01aSStefan Metzmacher return; 802*1249c01aSStefan Metzmacher 803*1249c01aSStefan Metzmacher /* 804*1249c01aSStefan Metzmacher * Now use the keepalive timeout (instead of keepalive interval) 805*1249c01aSStefan Metzmacher * in order to wait for a response 806*1249c01aSStefan Metzmacher */ 807*1249c01aSStefan Metzmacher sc->idle.keepalive = SMBDIRECT_KEEPALIVE_PENDING; 808*1249c01aSStefan Metzmacher mod_delayed_work(sc->workqueues.idle, &sc->idle.timer_work, 809*1249c01aSStefan Metzmacher msecs_to_jiffies(sp->keepalive_timeout_msec)); 810*1249c01aSStefan Metzmacher smbdirect_log_keep_alive(sc, SMBDIRECT_LOG_INFO, 811*1249c01aSStefan Metzmacher "schedule send of empty idle message\n"); 812*1249c01aSStefan Metzmacher queue_work(sc->workqueues.immediate, &sc->idle.immediate_work); 813*1249c01aSStefan Metzmacher } 814*1249c01aSStefan Metzmacher 815*1249c01aSStefan Metzmacher u16 smbdirect_connection_grant_recv_credits(struct smbdirect_socket *sc) 816*1249c01aSStefan Metzmacher { 817*1249c01aSStefan Metzmacher int missing; 818*1249c01aSStefan Metzmacher int available; 819*1249c01aSStefan Metzmacher int new_credits; 820*1249c01aSStefan Metzmacher 821*1249c01aSStefan Metzmacher if (atomic_read(&sc->recv_io.credits.count) >= sc->recv_io.credits.target) 822*1249c01aSStefan Metzmacher return 0; 823*1249c01aSStefan Metzmacher 824*1249c01aSStefan Metzmacher missing = (int)sc->recv_io.credits.target - atomic_read(&sc->recv_io.credits.count); 825*1249c01aSStefan Metzmacher available = atomic_xchg(&sc->recv_io.credits.available, 0); 826*1249c01aSStefan Metzmacher new_credits = min3((int)U16_MAX, missing, available); 827*1249c01aSStefan Metzmacher if (new_credits <= 0) { 828*1249c01aSStefan Metzmacher /* 829*1249c01aSStefan Metzmacher * If credits are available, but not granted 830*1249c01aSStefan Metzmacher * we need to re-add them again. 831*1249c01aSStefan Metzmacher */ 832*1249c01aSStefan Metzmacher if (available) 833*1249c01aSStefan Metzmacher atomic_add(available, &sc->recv_io.credits.available); 834*1249c01aSStefan Metzmacher return 0; 835*1249c01aSStefan Metzmacher } 836*1249c01aSStefan Metzmacher 837*1249c01aSStefan Metzmacher if (new_credits < available) { 838*1249c01aSStefan Metzmacher /* 839*1249c01aSStefan Metzmacher * Readd the remaining available again. 840*1249c01aSStefan Metzmacher */ 841*1249c01aSStefan Metzmacher available -= new_credits; 842*1249c01aSStefan Metzmacher atomic_add(available, &sc->recv_io.credits.available); 843*1249c01aSStefan Metzmacher } 844*1249c01aSStefan Metzmacher 845*1249c01aSStefan Metzmacher /* 846*1249c01aSStefan Metzmacher * Remember we granted the credits 847*1249c01aSStefan Metzmacher */ 848*1249c01aSStefan Metzmacher atomic_add(new_credits, &sc->recv_io.credits.count); 849*1249c01aSStefan Metzmacher return new_credits; 850*1249c01aSStefan Metzmacher } 851*1249c01aSStefan Metzmacher 852*1249c01aSStefan Metzmacher static bool smbdirect_connection_request_keep_alive(struct smbdirect_socket *sc) 853*1249c01aSStefan Metzmacher { 854*1249c01aSStefan Metzmacher const struct smbdirect_socket_parameters *sp = &sc->parameters; 855*1249c01aSStefan Metzmacher 856*1249c01aSStefan Metzmacher if (sc->idle.keepalive == SMBDIRECT_KEEPALIVE_PENDING) { 857*1249c01aSStefan Metzmacher sc->idle.keepalive = SMBDIRECT_KEEPALIVE_SENT; 858*1249c01aSStefan Metzmacher /* 859*1249c01aSStefan Metzmacher * Now use the keepalive timeout (instead of keepalive interval) 860*1249c01aSStefan Metzmacher * in order to wait for a response 861*1249c01aSStefan Metzmacher */ 862*1249c01aSStefan Metzmacher mod_delayed_work(sc->workqueues.idle, &sc->idle.timer_work, 863*1249c01aSStefan Metzmacher msecs_to_jiffies(sp->keepalive_timeout_msec)); 864*1249c01aSStefan Metzmacher return true; 865*1249c01aSStefan Metzmacher } 866*1249c01aSStefan Metzmacher 867*1249c01aSStefan Metzmacher return false; 868*1249c01aSStefan Metzmacher } 869*1249c01aSStefan Metzmacher 870*1249c01aSStefan Metzmacher int smbdirect_connection_post_send_wr(struct smbdirect_socket *sc, 871*1249c01aSStefan Metzmacher struct ib_send_wr *wr) 872*1249c01aSStefan Metzmacher { 873*1249c01aSStefan Metzmacher int ret; 874*1249c01aSStefan Metzmacher 875*1249c01aSStefan Metzmacher if (unlikely(sc->first_error)) 876*1249c01aSStefan Metzmacher return sc->first_error; 877*1249c01aSStefan Metzmacher 878*1249c01aSStefan Metzmacher atomic_inc(&sc->send_io.pending.count); 879*1249c01aSStefan Metzmacher ret = ib_post_send(sc->ib.qp, wr, NULL); 880*1249c01aSStefan Metzmacher if (ret) { 881*1249c01aSStefan Metzmacher atomic_dec(&sc->send_io.pending.count); 882*1249c01aSStefan Metzmacher smbdirect_log_rdma_send(sc, SMBDIRECT_LOG_ERR, 883*1249c01aSStefan Metzmacher "ib_post_send() failed %1pe\n", 884*1249c01aSStefan Metzmacher SMBDIRECT_DEBUG_ERR_PTR(ret)); 885*1249c01aSStefan Metzmacher smbdirect_socket_schedule_cleanup(sc, ret); 886*1249c01aSStefan Metzmacher } 887*1249c01aSStefan Metzmacher 888*1249c01aSStefan Metzmacher return ret; 889*1249c01aSStefan Metzmacher } 890*1249c01aSStefan Metzmacher 891*1249c01aSStefan Metzmacher static void smbdirect_connection_send_batch_init(struct smbdirect_send_batch *batch, 892*1249c01aSStefan Metzmacher bool need_invalidate_rkey, 893*1249c01aSStefan Metzmacher unsigned int remote_key) 894*1249c01aSStefan Metzmacher { 895*1249c01aSStefan Metzmacher INIT_LIST_HEAD(&batch->msg_list); 896*1249c01aSStefan Metzmacher batch->wr_cnt = 0; 897*1249c01aSStefan Metzmacher batch->need_invalidate_rkey = need_invalidate_rkey; 898*1249c01aSStefan Metzmacher batch->remote_key = remote_key; 899*1249c01aSStefan Metzmacher batch->credit = 0; 900*1249c01aSStefan Metzmacher } 901*1249c01aSStefan Metzmacher 902*1249c01aSStefan Metzmacher int smbdirect_connection_send_batch_flush(struct smbdirect_socket *sc, 903*1249c01aSStefan Metzmacher struct smbdirect_send_batch *batch, 904*1249c01aSStefan Metzmacher bool is_last) 905*1249c01aSStefan Metzmacher { 906*1249c01aSStefan Metzmacher struct smbdirect_send_io *first, *last; 907*1249c01aSStefan Metzmacher int ret = 0; 908*1249c01aSStefan Metzmacher 909*1249c01aSStefan Metzmacher if (list_empty(&batch->msg_list)) 910*1249c01aSStefan Metzmacher goto release_credit; 911*1249c01aSStefan Metzmacher 912*1249c01aSStefan Metzmacher first = list_first_entry(&batch->msg_list, 913*1249c01aSStefan Metzmacher struct smbdirect_send_io, 914*1249c01aSStefan Metzmacher sibling_list); 915*1249c01aSStefan Metzmacher last = list_last_entry(&batch->msg_list, 916*1249c01aSStefan Metzmacher struct smbdirect_send_io, 917*1249c01aSStefan Metzmacher sibling_list); 918*1249c01aSStefan Metzmacher 919*1249c01aSStefan Metzmacher if (batch->need_invalidate_rkey) { 920*1249c01aSStefan Metzmacher first->wr.opcode = IB_WR_SEND_WITH_INV; 921*1249c01aSStefan Metzmacher first->wr.ex.invalidate_rkey = batch->remote_key; 922*1249c01aSStefan Metzmacher batch->need_invalidate_rkey = false; 923*1249c01aSStefan Metzmacher batch->remote_key = 0; 924*1249c01aSStefan Metzmacher } 925*1249c01aSStefan Metzmacher 926*1249c01aSStefan Metzmacher last->wr.send_flags = IB_SEND_SIGNALED; 927*1249c01aSStefan Metzmacher last->wr.wr_cqe = &last->cqe; 928*1249c01aSStefan Metzmacher 929*1249c01aSStefan Metzmacher /* 930*1249c01aSStefan Metzmacher * Remove last from send_ctx->msg_list 931*1249c01aSStefan Metzmacher * and splice the rest of send_ctx->msg_list 932*1249c01aSStefan Metzmacher * to last->sibling_list. 933*1249c01aSStefan Metzmacher * 934*1249c01aSStefan Metzmacher * send_ctx->msg_list is a valid empty list 935*1249c01aSStefan Metzmacher * at the end. 936*1249c01aSStefan Metzmacher */ 937*1249c01aSStefan Metzmacher list_del_init(&last->sibling_list); 938*1249c01aSStefan Metzmacher list_splice_tail_init(&batch->msg_list, &last->sibling_list); 939*1249c01aSStefan Metzmacher batch->wr_cnt = 0; 940*1249c01aSStefan Metzmacher 941*1249c01aSStefan Metzmacher ret = smbdirect_connection_post_send_wr(sc, &first->wr); 942*1249c01aSStefan Metzmacher if (ret) { 943*1249c01aSStefan Metzmacher struct smbdirect_send_io *sibling, *next; 944*1249c01aSStefan Metzmacher 945*1249c01aSStefan Metzmacher list_for_each_entry_safe(sibling, next, &last->sibling_list, sibling_list) { 946*1249c01aSStefan Metzmacher list_del_init(&sibling->sibling_list); 947*1249c01aSStefan Metzmacher smbdirect_connection_free_send_io(sibling); 948*1249c01aSStefan Metzmacher } 949*1249c01aSStefan Metzmacher smbdirect_connection_free_send_io(last); 950*1249c01aSStefan Metzmacher } 951*1249c01aSStefan Metzmacher 952*1249c01aSStefan Metzmacher release_credit: 953*1249c01aSStefan Metzmacher if (is_last && !ret && batch->credit) { 954*1249c01aSStefan Metzmacher atomic_add(batch->credit, &sc->send_io.bcredits.count); 955*1249c01aSStefan Metzmacher batch->credit = 0; 956*1249c01aSStefan Metzmacher wake_up(&sc->send_io.bcredits.wait_queue); 957*1249c01aSStefan Metzmacher } 958*1249c01aSStefan Metzmacher 959*1249c01aSStefan Metzmacher return ret; 960*1249c01aSStefan Metzmacher } 961*1249c01aSStefan Metzmacher __SMBDIRECT_EXPORT_SYMBOL__(smbdirect_connection_send_batch_flush); 962*1249c01aSStefan Metzmacher 963*1249c01aSStefan Metzmacher struct smbdirect_send_batch * 964*1249c01aSStefan Metzmacher smbdirect_init_send_batch_storage(struct smbdirect_send_batch_storage *storage, 965*1249c01aSStefan Metzmacher bool need_invalidate_rkey, 966*1249c01aSStefan Metzmacher unsigned int remote_key) 967*1249c01aSStefan Metzmacher { 968*1249c01aSStefan Metzmacher struct smbdirect_send_batch *batch = (struct smbdirect_send_batch *)storage; 969*1249c01aSStefan Metzmacher 970*1249c01aSStefan Metzmacher memset(storage, 0, sizeof(*storage)); 971*1249c01aSStefan Metzmacher BUILD_BUG_ON(sizeof(*batch) > sizeof(*storage)); 972*1249c01aSStefan Metzmacher 973*1249c01aSStefan Metzmacher smbdirect_connection_send_batch_init(batch, 974*1249c01aSStefan Metzmacher need_invalidate_rkey, 975*1249c01aSStefan Metzmacher remote_key); 976*1249c01aSStefan Metzmacher 977*1249c01aSStefan Metzmacher return batch; 978*1249c01aSStefan Metzmacher } 979*1249c01aSStefan Metzmacher __SMBDIRECT_EXPORT_SYMBOL__(smbdirect_init_send_batch_storage); 980*1249c01aSStefan Metzmacher 981*1249c01aSStefan Metzmacher static int smbdirect_connection_wait_for_send_bcredit(struct smbdirect_socket *sc, 982*1249c01aSStefan Metzmacher struct smbdirect_send_batch *batch) 983*1249c01aSStefan Metzmacher { 984*1249c01aSStefan Metzmacher int ret; 985*1249c01aSStefan Metzmacher 986*1249c01aSStefan Metzmacher if (batch->credit) 987*1249c01aSStefan Metzmacher return 0; 988*1249c01aSStefan Metzmacher 989*1249c01aSStefan Metzmacher ret = smbdirect_socket_wait_for_credits(sc, 990*1249c01aSStefan Metzmacher SMBDIRECT_SOCKET_CONNECTED, 991*1249c01aSStefan Metzmacher -ENOTCONN, 992*1249c01aSStefan Metzmacher &sc->send_io.bcredits.wait_queue, 993*1249c01aSStefan Metzmacher &sc->send_io.bcredits.count, 994*1249c01aSStefan Metzmacher 1); 995*1249c01aSStefan Metzmacher if (ret) 996*1249c01aSStefan Metzmacher return ret; 997*1249c01aSStefan Metzmacher 998*1249c01aSStefan Metzmacher batch->credit = 1; 999*1249c01aSStefan Metzmacher return 0; 1000*1249c01aSStefan Metzmacher } 1001*1249c01aSStefan Metzmacher 1002*1249c01aSStefan Metzmacher static int smbdirect_connection_wait_for_send_lcredit(struct smbdirect_socket *sc, 1003*1249c01aSStefan Metzmacher struct smbdirect_send_batch *batch) 1004*1249c01aSStefan Metzmacher { 1005*1249c01aSStefan Metzmacher if (batch && atomic_read(&sc->send_io.lcredits.count) <= 1) { 1006*1249c01aSStefan Metzmacher int ret; 1007*1249c01aSStefan Metzmacher 1008*1249c01aSStefan Metzmacher ret = smbdirect_connection_send_batch_flush(sc, batch, false); 1009*1249c01aSStefan Metzmacher if (ret) 1010*1249c01aSStefan Metzmacher return ret; 1011*1249c01aSStefan Metzmacher } 1012*1249c01aSStefan Metzmacher 1013*1249c01aSStefan Metzmacher return smbdirect_socket_wait_for_credits(sc, 1014*1249c01aSStefan Metzmacher SMBDIRECT_SOCKET_CONNECTED, 1015*1249c01aSStefan Metzmacher -ENOTCONN, 1016*1249c01aSStefan Metzmacher &sc->send_io.lcredits.wait_queue, 1017*1249c01aSStefan Metzmacher &sc->send_io.lcredits.count, 1018*1249c01aSStefan Metzmacher 1); 1019*1249c01aSStefan Metzmacher } 1020*1249c01aSStefan Metzmacher 1021*1249c01aSStefan Metzmacher static int smbdirect_connection_wait_for_send_credits(struct smbdirect_socket *sc, 1022*1249c01aSStefan Metzmacher struct smbdirect_send_batch *batch) 1023*1249c01aSStefan Metzmacher { 1024*1249c01aSStefan Metzmacher if (batch && (batch->wr_cnt >= 16 || atomic_read(&sc->send_io.credits.count) <= 1)) { 1025*1249c01aSStefan Metzmacher int ret; 1026*1249c01aSStefan Metzmacher 1027*1249c01aSStefan Metzmacher ret = smbdirect_connection_send_batch_flush(sc, batch, false); 1028*1249c01aSStefan Metzmacher if (ret) 1029*1249c01aSStefan Metzmacher return ret; 1030*1249c01aSStefan Metzmacher } 1031*1249c01aSStefan Metzmacher 1032*1249c01aSStefan Metzmacher return smbdirect_socket_wait_for_credits(sc, 1033*1249c01aSStefan Metzmacher SMBDIRECT_SOCKET_CONNECTED, 1034*1249c01aSStefan Metzmacher -ENOTCONN, 1035*1249c01aSStefan Metzmacher &sc->send_io.credits.wait_queue, 1036*1249c01aSStefan Metzmacher &sc->send_io.credits.count, 1037*1249c01aSStefan Metzmacher 1); 1038*1249c01aSStefan Metzmacher } 1039*1249c01aSStefan Metzmacher 1040*1249c01aSStefan Metzmacher static void smbdirect_connection_send_io_done(struct ib_cq *cq, struct ib_wc *wc); 1041*1249c01aSStefan Metzmacher 1042*1249c01aSStefan Metzmacher static int smbdirect_connection_post_send_io(struct smbdirect_socket *sc, 1043*1249c01aSStefan Metzmacher struct smbdirect_send_batch *batch, 1044*1249c01aSStefan Metzmacher struct smbdirect_send_io *msg) 1045*1249c01aSStefan Metzmacher { 1046*1249c01aSStefan Metzmacher int i; 1047*1249c01aSStefan Metzmacher 1048*1249c01aSStefan Metzmacher for (i = 0; i < msg->num_sge; i++) 1049*1249c01aSStefan Metzmacher ib_dma_sync_single_for_device(sc->ib.dev, 1050*1249c01aSStefan Metzmacher msg->sge[i].addr, msg->sge[i].length, 1051*1249c01aSStefan Metzmacher DMA_TO_DEVICE); 1052*1249c01aSStefan Metzmacher 1053*1249c01aSStefan Metzmacher msg->cqe.done = smbdirect_connection_send_io_done; 1054*1249c01aSStefan Metzmacher msg->wr.wr_cqe = &msg->cqe; 1055*1249c01aSStefan Metzmacher msg->wr.opcode = IB_WR_SEND; 1056*1249c01aSStefan Metzmacher msg->wr.sg_list = &msg->sge[0]; 1057*1249c01aSStefan Metzmacher msg->wr.num_sge = msg->num_sge; 1058*1249c01aSStefan Metzmacher msg->wr.next = NULL; 1059*1249c01aSStefan Metzmacher 1060*1249c01aSStefan Metzmacher if (batch) { 1061*1249c01aSStefan Metzmacher msg->wr.send_flags = 0; 1062*1249c01aSStefan Metzmacher if (!list_empty(&batch->msg_list)) { 1063*1249c01aSStefan Metzmacher struct smbdirect_send_io *last; 1064*1249c01aSStefan Metzmacher 1065*1249c01aSStefan Metzmacher last = list_last_entry(&batch->msg_list, 1066*1249c01aSStefan Metzmacher struct smbdirect_send_io, 1067*1249c01aSStefan Metzmacher sibling_list); 1068*1249c01aSStefan Metzmacher last->wr.next = &msg->wr; 1069*1249c01aSStefan Metzmacher } 1070*1249c01aSStefan Metzmacher list_add_tail(&msg->sibling_list, &batch->msg_list); 1071*1249c01aSStefan Metzmacher batch->wr_cnt++; 1072*1249c01aSStefan Metzmacher return 0; 1073*1249c01aSStefan Metzmacher } 1074*1249c01aSStefan Metzmacher 1075*1249c01aSStefan Metzmacher msg->wr.send_flags = IB_SEND_SIGNALED; 1076*1249c01aSStefan Metzmacher return smbdirect_connection_post_send_wr(sc, &msg->wr); 1077*1249c01aSStefan Metzmacher } 1078*1249c01aSStefan Metzmacher 1079*1249c01aSStefan Metzmacher int smbdirect_connection_send_single_iter(struct smbdirect_socket *sc, 1080*1249c01aSStefan Metzmacher struct smbdirect_send_batch *batch, 1081*1249c01aSStefan Metzmacher struct iov_iter *iter, 1082*1249c01aSStefan Metzmacher unsigned int flags, 1083*1249c01aSStefan Metzmacher u32 remaining_data_length) 1084*1249c01aSStefan Metzmacher { 1085*1249c01aSStefan Metzmacher const struct smbdirect_socket_parameters *sp = &sc->parameters; 1086*1249c01aSStefan Metzmacher struct smbdirect_send_batch _batch; 1087*1249c01aSStefan Metzmacher struct smbdirect_send_io *msg; 1088*1249c01aSStefan Metzmacher struct smbdirect_data_transfer *packet; 1089*1249c01aSStefan Metzmacher size_t header_length; 1090*1249c01aSStefan Metzmacher u16 new_credits = 0; 1091*1249c01aSStefan Metzmacher u32 data_length = 0; 1092*1249c01aSStefan Metzmacher int ret; 1093*1249c01aSStefan Metzmacher 1094*1249c01aSStefan Metzmacher if (WARN_ON_ONCE(flags)) 1095*1249c01aSStefan Metzmacher return -EINVAL; /* no flags support for now */ 1096*1249c01aSStefan Metzmacher 1097*1249c01aSStefan Metzmacher if (iter) { 1098*1249c01aSStefan Metzmacher if (WARN_ON_ONCE(iov_iter_rw(iter) != ITER_SOURCE)) 1099*1249c01aSStefan Metzmacher return -EINVAL; /* It's a bug in upper layer to get there */ 1100*1249c01aSStefan Metzmacher 1101*1249c01aSStefan Metzmacher header_length = sizeof(struct smbdirect_data_transfer); 1102*1249c01aSStefan Metzmacher if (WARN_ON_ONCE(remaining_data_length == 0 || 1103*1249c01aSStefan Metzmacher iov_iter_count(iter) > remaining_data_length)) 1104*1249c01aSStefan Metzmacher return -EINVAL; 1105*1249c01aSStefan Metzmacher } else { 1106*1249c01aSStefan Metzmacher /* If this is a packet without payload, don't send padding */ 1107*1249c01aSStefan Metzmacher header_length = offsetof(struct smbdirect_data_transfer, padding); 1108*1249c01aSStefan Metzmacher if (WARN_ON_ONCE(remaining_data_length)) 1109*1249c01aSStefan Metzmacher return -EINVAL; 1110*1249c01aSStefan Metzmacher } 1111*1249c01aSStefan Metzmacher 1112*1249c01aSStefan Metzmacher if (sc->status != SMBDIRECT_SOCKET_CONNECTED) { 1113*1249c01aSStefan Metzmacher smbdirect_log_write(sc, SMBDIRECT_LOG_ERR, 1114*1249c01aSStefan Metzmacher "status=%s first_error=%1pe => %1pe\n", 1115*1249c01aSStefan Metzmacher smbdirect_socket_status_string(sc->status), 1116*1249c01aSStefan Metzmacher SMBDIRECT_DEBUG_ERR_PTR(sc->first_error), 1117*1249c01aSStefan Metzmacher SMBDIRECT_DEBUG_ERR_PTR(-ENOTCONN)); 1118*1249c01aSStefan Metzmacher return -ENOTCONN; 1119*1249c01aSStefan Metzmacher } 1120*1249c01aSStefan Metzmacher 1121*1249c01aSStefan Metzmacher if (!batch) { 1122*1249c01aSStefan Metzmacher smbdirect_connection_send_batch_init(&_batch, false, 0); 1123*1249c01aSStefan Metzmacher batch = &_batch; 1124*1249c01aSStefan Metzmacher } 1125*1249c01aSStefan Metzmacher 1126*1249c01aSStefan Metzmacher ret = smbdirect_connection_wait_for_send_bcredit(sc, batch); 1127*1249c01aSStefan Metzmacher if (ret) 1128*1249c01aSStefan Metzmacher goto bcredit_failed; 1129*1249c01aSStefan Metzmacher 1130*1249c01aSStefan Metzmacher ret = smbdirect_connection_wait_for_send_lcredit(sc, batch); 1131*1249c01aSStefan Metzmacher if (ret) 1132*1249c01aSStefan Metzmacher goto lcredit_failed; 1133*1249c01aSStefan Metzmacher 1134*1249c01aSStefan Metzmacher ret = smbdirect_connection_wait_for_send_credits(sc, batch); 1135*1249c01aSStefan Metzmacher if (ret) 1136*1249c01aSStefan Metzmacher goto credit_failed; 1137*1249c01aSStefan Metzmacher 1138*1249c01aSStefan Metzmacher new_credits = smbdirect_connection_grant_recv_credits(sc); 1139*1249c01aSStefan Metzmacher if (new_credits == 0 && 1140*1249c01aSStefan Metzmacher atomic_read(&sc->send_io.credits.count) == 0 && 1141*1249c01aSStefan Metzmacher atomic_read(&sc->recv_io.credits.count) == 0) { 1142*1249c01aSStefan Metzmacher /* 1143*1249c01aSStefan Metzmacher * queue the refill work in order to 1144*1249c01aSStefan Metzmacher * get some new recv credits we can grant to 1145*1249c01aSStefan Metzmacher * the peer. 1146*1249c01aSStefan Metzmacher */ 1147*1249c01aSStefan Metzmacher queue_work(sc->workqueues.refill, &sc->recv_io.posted.refill_work); 1148*1249c01aSStefan Metzmacher 1149*1249c01aSStefan Metzmacher /* 1150*1249c01aSStefan Metzmacher * wait until either the refill work or the peer 1151*1249c01aSStefan Metzmacher * granted new credits 1152*1249c01aSStefan Metzmacher */ 1153*1249c01aSStefan Metzmacher ret = wait_event_interruptible(sc->send_io.credits.wait_queue, 1154*1249c01aSStefan Metzmacher atomic_read(&sc->send_io.credits.count) >= 1 || 1155*1249c01aSStefan Metzmacher atomic_read(&sc->recv_io.credits.available) >= 1 || 1156*1249c01aSStefan Metzmacher sc->status != SMBDIRECT_SOCKET_CONNECTED); 1157*1249c01aSStefan Metzmacher if (sc->status != SMBDIRECT_SOCKET_CONNECTED) 1158*1249c01aSStefan Metzmacher ret = -ENOTCONN; 1159*1249c01aSStefan Metzmacher if (ret < 0) 1160*1249c01aSStefan Metzmacher goto credit_failed; 1161*1249c01aSStefan Metzmacher 1162*1249c01aSStefan Metzmacher new_credits = smbdirect_connection_grant_recv_credits(sc); 1163*1249c01aSStefan Metzmacher } 1164*1249c01aSStefan Metzmacher 1165*1249c01aSStefan Metzmacher msg = smbdirect_connection_alloc_send_io(sc); 1166*1249c01aSStefan Metzmacher if (IS_ERR(msg)) { 1167*1249c01aSStefan Metzmacher ret = PTR_ERR(msg); 1168*1249c01aSStefan Metzmacher goto alloc_failed; 1169*1249c01aSStefan Metzmacher } 1170*1249c01aSStefan Metzmacher 1171*1249c01aSStefan Metzmacher /* Map the packet to DMA */ 1172*1249c01aSStefan Metzmacher msg->sge[0].addr = ib_dma_map_single(sc->ib.dev, 1173*1249c01aSStefan Metzmacher msg->packet, 1174*1249c01aSStefan Metzmacher header_length, 1175*1249c01aSStefan Metzmacher DMA_TO_DEVICE); 1176*1249c01aSStefan Metzmacher ret = ib_dma_mapping_error(sc->ib.dev, msg->sge[0].addr); 1177*1249c01aSStefan Metzmacher if (ret) 1178*1249c01aSStefan Metzmacher goto err; 1179*1249c01aSStefan Metzmacher 1180*1249c01aSStefan Metzmacher msg->sge[0].length = header_length; 1181*1249c01aSStefan Metzmacher msg->sge[0].lkey = sc->ib.pd->local_dma_lkey; 1182*1249c01aSStefan Metzmacher msg->num_sge = 1; 1183*1249c01aSStefan Metzmacher 1184*1249c01aSStefan Metzmacher if (iter) { 1185*1249c01aSStefan Metzmacher struct smbdirect_map_sges extract = { 1186*1249c01aSStefan Metzmacher .num_sge = msg->num_sge, 1187*1249c01aSStefan Metzmacher .max_sge = ARRAY_SIZE(msg->sge), 1188*1249c01aSStefan Metzmacher .sge = msg->sge, 1189*1249c01aSStefan Metzmacher .device = sc->ib.dev, 1190*1249c01aSStefan Metzmacher .local_dma_lkey = sc->ib.pd->local_dma_lkey, 1191*1249c01aSStefan Metzmacher .direction = DMA_TO_DEVICE, 1192*1249c01aSStefan Metzmacher }; 1193*1249c01aSStefan Metzmacher size_t payload_len = umin(iov_iter_count(iter), 1194*1249c01aSStefan Metzmacher sp->max_send_size - sizeof(*packet)); 1195*1249c01aSStefan Metzmacher 1196*1249c01aSStefan Metzmacher ret = smbdirect_map_sges_from_iter(iter, payload_len, &extract); 1197*1249c01aSStefan Metzmacher if (ret < 0) 1198*1249c01aSStefan Metzmacher goto err; 1199*1249c01aSStefan Metzmacher data_length = ret; 1200*1249c01aSStefan Metzmacher remaining_data_length -= data_length; 1201*1249c01aSStefan Metzmacher msg->num_sge = extract.num_sge; 1202*1249c01aSStefan Metzmacher } 1203*1249c01aSStefan Metzmacher 1204*1249c01aSStefan Metzmacher /* Fill in the packet header */ 1205*1249c01aSStefan Metzmacher packet = (struct smbdirect_data_transfer *)msg->packet; 1206*1249c01aSStefan Metzmacher packet->credits_requested = cpu_to_le16(sp->send_credit_target); 1207*1249c01aSStefan Metzmacher packet->credits_granted = cpu_to_le16(new_credits); 1208*1249c01aSStefan Metzmacher 1209*1249c01aSStefan Metzmacher packet->flags = 0; 1210*1249c01aSStefan Metzmacher if (smbdirect_connection_request_keep_alive(sc)) 1211*1249c01aSStefan Metzmacher packet->flags |= cpu_to_le16(SMBDIRECT_FLAG_RESPONSE_REQUESTED); 1212*1249c01aSStefan Metzmacher 1213*1249c01aSStefan Metzmacher packet->reserved = 0; 1214*1249c01aSStefan Metzmacher if (!data_length) 1215*1249c01aSStefan Metzmacher packet->data_offset = 0; 1216*1249c01aSStefan Metzmacher else 1217*1249c01aSStefan Metzmacher packet->data_offset = cpu_to_le32(24); 1218*1249c01aSStefan Metzmacher packet->data_length = cpu_to_le32(data_length); 1219*1249c01aSStefan Metzmacher packet->remaining_data_length = cpu_to_le32(remaining_data_length); 1220*1249c01aSStefan Metzmacher packet->padding = 0; 1221*1249c01aSStefan Metzmacher 1222*1249c01aSStefan Metzmacher smbdirect_log_outgoing(sc, SMBDIRECT_LOG_INFO, 1223*1249c01aSStefan Metzmacher "DataOut: %s=%u, %s=%u, %s=0x%x, %s=%u, %s=%u, %s=%u\n", 1224*1249c01aSStefan Metzmacher "CreditsRequested", 1225*1249c01aSStefan Metzmacher le16_to_cpu(packet->credits_requested), 1226*1249c01aSStefan Metzmacher "CreditsGranted", 1227*1249c01aSStefan Metzmacher le16_to_cpu(packet->credits_granted), 1228*1249c01aSStefan Metzmacher "Flags", 1229*1249c01aSStefan Metzmacher le16_to_cpu(packet->flags), 1230*1249c01aSStefan Metzmacher "RemainingDataLength", 1231*1249c01aSStefan Metzmacher le32_to_cpu(packet->remaining_data_length), 1232*1249c01aSStefan Metzmacher "DataOffset", 1233*1249c01aSStefan Metzmacher le32_to_cpu(packet->data_offset), 1234*1249c01aSStefan Metzmacher "DataLength", 1235*1249c01aSStefan Metzmacher le32_to_cpu(packet->data_length)); 1236*1249c01aSStefan Metzmacher 1237*1249c01aSStefan Metzmacher ret = smbdirect_connection_post_send_io(sc, batch, msg); 1238*1249c01aSStefan Metzmacher if (ret) 1239*1249c01aSStefan Metzmacher goto err; 1240*1249c01aSStefan Metzmacher 1241*1249c01aSStefan Metzmacher /* 1242*1249c01aSStefan Metzmacher * From here msg is moved to send_ctx 1243*1249c01aSStefan Metzmacher * and we should not free it explicitly. 1244*1249c01aSStefan Metzmacher */ 1245*1249c01aSStefan Metzmacher 1246*1249c01aSStefan Metzmacher if (batch == &_batch) { 1247*1249c01aSStefan Metzmacher ret = smbdirect_connection_send_batch_flush(sc, batch, true); 1248*1249c01aSStefan Metzmacher if (ret) 1249*1249c01aSStefan Metzmacher goto flush_failed; 1250*1249c01aSStefan Metzmacher } 1251*1249c01aSStefan Metzmacher 1252*1249c01aSStefan Metzmacher return data_length; 1253*1249c01aSStefan Metzmacher err: 1254*1249c01aSStefan Metzmacher smbdirect_connection_free_send_io(msg); 1255*1249c01aSStefan Metzmacher flush_failed: 1256*1249c01aSStefan Metzmacher alloc_failed: 1257*1249c01aSStefan Metzmacher atomic_inc(&sc->send_io.credits.count); 1258*1249c01aSStefan Metzmacher credit_failed: 1259*1249c01aSStefan Metzmacher atomic_inc(&sc->send_io.lcredits.count); 1260*1249c01aSStefan Metzmacher lcredit_failed: 1261*1249c01aSStefan Metzmacher atomic_add(batch->credit, &sc->send_io.bcredits.count); 1262*1249c01aSStefan Metzmacher batch->credit = 0; 1263*1249c01aSStefan Metzmacher bcredit_failed: 1264*1249c01aSStefan Metzmacher return ret; 1265*1249c01aSStefan Metzmacher } 1266*1249c01aSStefan Metzmacher __SMBDIRECT_EXPORT_SYMBOL__(smbdirect_connection_send_single_iter); 1267*1249c01aSStefan Metzmacher 1268*1249c01aSStefan Metzmacher int smbdirect_connection_send_wait_zero_pending(struct smbdirect_socket *sc) 1269*1249c01aSStefan Metzmacher { 1270*1249c01aSStefan Metzmacher /* 1271*1249c01aSStefan Metzmacher * As an optimization, we don't wait for individual I/O to finish 1272*1249c01aSStefan Metzmacher * before sending the next one. 1273*1249c01aSStefan Metzmacher * Send them all and wait for pending send count to get to 0 1274*1249c01aSStefan Metzmacher * that means all the I/Os have been out and we are good to return 1275*1249c01aSStefan Metzmacher */ 1276*1249c01aSStefan Metzmacher 1277*1249c01aSStefan Metzmacher wait_event(sc->send_io.pending.zero_wait_queue, 1278*1249c01aSStefan Metzmacher atomic_read(&sc->send_io.pending.count) == 0 || 1279*1249c01aSStefan Metzmacher sc->status != SMBDIRECT_SOCKET_CONNECTED); 1280*1249c01aSStefan Metzmacher if (sc->status != SMBDIRECT_SOCKET_CONNECTED) { 1281*1249c01aSStefan Metzmacher smbdirect_log_write(sc, SMBDIRECT_LOG_ERR, 1282*1249c01aSStefan Metzmacher "status=%s first_error=%1pe => %1pe\n", 1283*1249c01aSStefan Metzmacher smbdirect_socket_status_string(sc->status), 1284*1249c01aSStefan Metzmacher SMBDIRECT_DEBUG_ERR_PTR(sc->first_error), 1285*1249c01aSStefan Metzmacher SMBDIRECT_DEBUG_ERR_PTR(-ENOTCONN)); 1286*1249c01aSStefan Metzmacher return -ENOTCONN; 1287*1249c01aSStefan Metzmacher } 1288*1249c01aSStefan Metzmacher 1289*1249c01aSStefan Metzmacher return 0; 1290*1249c01aSStefan Metzmacher } 1291*1249c01aSStefan Metzmacher __SMBDIRECT_EXPORT_SYMBOL__(smbdirect_connection_send_wait_zero_pending); 1292*1249c01aSStefan Metzmacher 1293*1249c01aSStefan Metzmacher int smbdirect_connection_send_iter(struct smbdirect_socket *sc, 1294*1249c01aSStefan Metzmacher struct iov_iter *iter, 1295*1249c01aSStefan Metzmacher unsigned int flags, 1296*1249c01aSStefan Metzmacher bool need_invalidate, 1297*1249c01aSStefan Metzmacher unsigned int remote_key) 1298*1249c01aSStefan Metzmacher { 1299*1249c01aSStefan Metzmacher const struct smbdirect_socket_parameters *sp = &sc->parameters; 1300*1249c01aSStefan Metzmacher struct smbdirect_send_batch batch; 1301*1249c01aSStefan Metzmacher int total_count = iov_iter_count(iter); 1302*1249c01aSStefan Metzmacher int ret; 1303*1249c01aSStefan Metzmacher int error = 0; 1304*1249c01aSStefan Metzmacher __be32 hdr; 1305*1249c01aSStefan Metzmacher 1306*1249c01aSStefan Metzmacher if (WARN_ONCE(flags, "unexpected flags=0x%x\n", flags)) 1307*1249c01aSStefan Metzmacher return -EINVAL; /* no flags support for now */ 1308*1249c01aSStefan Metzmacher 1309*1249c01aSStefan Metzmacher if (WARN_ON_ONCE(iov_iter_rw(iter) != ITER_SOURCE)) 1310*1249c01aSStefan Metzmacher return -EINVAL; /* It's a bug in upper layer to get there */ 1311*1249c01aSStefan Metzmacher 1312*1249c01aSStefan Metzmacher if (sc->status != SMBDIRECT_SOCKET_CONNECTED) { 1313*1249c01aSStefan Metzmacher smbdirect_log_write(sc, SMBDIRECT_LOG_INFO, 1314*1249c01aSStefan Metzmacher "status=%s first_error=%1pe => %1pe\n", 1315*1249c01aSStefan Metzmacher smbdirect_socket_status_string(sc->status), 1316*1249c01aSStefan Metzmacher SMBDIRECT_DEBUG_ERR_PTR(sc->first_error), 1317*1249c01aSStefan Metzmacher SMBDIRECT_DEBUG_ERR_PTR(-ENOTCONN)); 1318*1249c01aSStefan Metzmacher return -ENOTCONN; 1319*1249c01aSStefan Metzmacher } 1320*1249c01aSStefan Metzmacher 1321*1249c01aSStefan Metzmacher /* 1322*1249c01aSStefan Metzmacher * For now we expect the iter to have the full 1323*1249c01aSStefan Metzmacher * message, including a 4 byte length header. 1324*1249c01aSStefan Metzmacher */ 1325*1249c01aSStefan Metzmacher if (iov_iter_count(iter) <= 4) 1326*1249c01aSStefan Metzmacher return -EINVAL; 1327*1249c01aSStefan Metzmacher if (!copy_from_iter_full(&hdr, sizeof(hdr), iter)) 1328*1249c01aSStefan Metzmacher return -EFAULT; 1329*1249c01aSStefan Metzmacher if (iov_iter_count(iter) != be32_to_cpu(hdr)) 1330*1249c01aSStefan Metzmacher return -EINVAL; 1331*1249c01aSStefan Metzmacher 1332*1249c01aSStefan Metzmacher /* 1333*1249c01aSStefan Metzmacher * The size must fit into the negotiated 1334*1249c01aSStefan Metzmacher * fragmented send size. 1335*1249c01aSStefan Metzmacher */ 1336*1249c01aSStefan Metzmacher if (iov_iter_count(iter) > sp->max_fragmented_send_size) 1337*1249c01aSStefan Metzmacher return -EMSGSIZE; 1338*1249c01aSStefan Metzmacher 1339*1249c01aSStefan Metzmacher smbdirect_log_write(sc, SMBDIRECT_LOG_INFO, 1340*1249c01aSStefan Metzmacher "Sending (RDMA): length=%zu\n", 1341*1249c01aSStefan Metzmacher iov_iter_count(iter)); 1342*1249c01aSStefan Metzmacher 1343*1249c01aSStefan Metzmacher smbdirect_connection_send_batch_init(&batch, need_invalidate, remote_key); 1344*1249c01aSStefan Metzmacher while (iov_iter_count(iter)) { 1345*1249c01aSStefan Metzmacher ret = smbdirect_connection_send_single_iter(sc, 1346*1249c01aSStefan Metzmacher &batch, 1347*1249c01aSStefan Metzmacher iter, 1348*1249c01aSStefan Metzmacher flags, 1349*1249c01aSStefan Metzmacher iov_iter_count(iter)); 1350*1249c01aSStefan Metzmacher if (unlikely(ret < 0)) { 1351*1249c01aSStefan Metzmacher error = ret; 1352*1249c01aSStefan Metzmacher break; 1353*1249c01aSStefan Metzmacher } 1354*1249c01aSStefan Metzmacher } 1355*1249c01aSStefan Metzmacher 1356*1249c01aSStefan Metzmacher ret = smbdirect_connection_send_batch_flush(sc, &batch, true); 1357*1249c01aSStefan Metzmacher if (unlikely(ret && !error)) 1358*1249c01aSStefan Metzmacher error = ret; 1359*1249c01aSStefan Metzmacher 1360*1249c01aSStefan Metzmacher /* 1361*1249c01aSStefan Metzmacher * As an optimization, we don't wait for individual I/O to finish 1362*1249c01aSStefan Metzmacher * before sending the next one. 1363*1249c01aSStefan Metzmacher * Send them all and wait for pending send count to get to 0 1364*1249c01aSStefan Metzmacher * that means all the I/Os have been out and we are good to return 1365*1249c01aSStefan Metzmacher */ 1366*1249c01aSStefan Metzmacher 1367*1249c01aSStefan Metzmacher ret = smbdirect_connection_send_wait_zero_pending(sc); 1368*1249c01aSStefan Metzmacher if (unlikely(ret && !error)) 1369*1249c01aSStefan Metzmacher error = ret; 1370*1249c01aSStefan Metzmacher 1371*1249c01aSStefan Metzmacher if (unlikely(error)) 1372*1249c01aSStefan Metzmacher return error; 1373*1249c01aSStefan Metzmacher 1374*1249c01aSStefan Metzmacher return total_count; 1375*1249c01aSStefan Metzmacher } 1376*1249c01aSStefan Metzmacher __SMBDIRECT_EXPORT_SYMBOL__(smbdirect_connection_send_iter); 1377*1249c01aSStefan Metzmacher 1378*1249c01aSStefan Metzmacher static void smbdirect_connection_send_io_done(struct ib_cq *cq, struct ib_wc *wc) 1379*1249c01aSStefan Metzmacher { 1380*1249c01aSStefan Metzmacher struct smbdirect_send_io *msg = 1381*1249c01aSStefan Metzmacher container_of(wc->wr_cqe, struct smbdirect_send_io, cqe); 1382*1249c01aSStefan Metzmacher struct smbdirect_socket *sc = msg->socket; 1383*1249c01aSStefan Metzmacher struct smbdirect_send_io *sibling, *next; 1384*1249c01aSStefan Metzmacher int lcredits = 0; 1385*1249c01aSStefan Metzmacher 1386*1249c01aSStefan Metzmacher smbdirect_log_rdma_send(sc, SMBDIRECT_LOG_INFO, 1387*1249c01aSStefan Metzmacher "smbdirect_send_io completed. status='%s (%d)', opcode=%d\n", 1388*1249c01aSStefan Metzmacher ib_wc_status_msg(wc->status), wc->status, wc->opcode); 1389*1249c01aSStefan Metzmacher 1390*1249c01aSStefan Metzmacher if (unlikely(!(msg->wr.send_flags & IB_SEND_SIGNALED))) { 1391*1249c01aSStefan Metzmacher /* 1392*1249c01aSStefan Metzmacher * This happens when smbdirect_send_io is a sibling 1393*1249c01aSStefan Metzmacher * before the final message, it is signaled on 1394*1249c01aSStefan Metzmacher * error anyway, so we need to skip 1395*1249c01aSStefan Metzmacher * smbdirect_connection_free_send_io here, 1396*1249c01aSStefan Metzmacher * otherwise is will destroy the memory 1397*1249c01aSStefan Metzmacher * of the siblings too, which will cause 1398*1249c01aSStefan Metzmacher * use after free problems for the others 1399*1249c01aSStefan Metzmacher * triggered from ib_drain_qp(). 1400*1249c01aSStefan Metzmacher */ 1401*1249c01aSStefan Metzmacher if (wc->status != IB_WC_SUCCESS) 1402*1249c01aSStefan Metzmacher goto skip_free; 1403*1249c01aSStefan Metzmacher 1404*1249c01aSStefan Metzmacher /* 1405*1249c01aSStefan Metzmacher * This should not happen! 1406*1249c01aSStefan Metzmacher * But we better just close the 1407*1249c01aSStefan Metzmacher * connection... 1408*1249c01aSStefan Metzmacher */ 1409*1249c01aSStefan Metzmacher smbdirect_log_rdma_send(sc, SMBDIRECT_LOG_ERR, 1410*1249c01aSStefan Metzmacher "unexpected send completion wc->status=%s (%d) wc->opcode=%d\n", 1411*1249c01aSStefan Metzmacher ib_wc_status_msg(wc->status), wc->status, wc->opcode); 1412*1249c01aSStefan Metzmacher smbdirect_socket_schedule_cleanup(sc, -ECONNABORTED); 1413*1249c01aSStefan Metzmacher return; 1414*1249c01aSStefan Metzmacher } 1415*1249c01aSStefan Metzmacher 1416*1249c01aSStefan Metzmacher /* 1417*1249c01aSStefan Metzmacher * Free possible siblings and then the main send_io 1418*1249c01aSStefan Metzmacher */ 1419*1249c01aSStefan Metzmacher list_for_each_entry_safe(sibling, next, &msg->sibling_list, sibling_list) { 1420*1249c01aSStefan Metzmacher list_del_init(&sibling->sibling_list); 1421*1249c01aSStefan Metzmacher smbdirect_connection_free_send_io(sibling); 1422*1249c01aSStefan Metzmacher lcredits += 1; 1423*1249c01aSStefan Metzmacher } 1424*1249c01aSStefan Metzmacher /* Note this frees wc->wr_cqe, but not wc */ 1425*1249c01aSStefan Metzmacher smbdirect_connection_free_send_io(msg); 1426*1249c01aSStefan Metzmacher lcredits += 1; 1427*1249c01aSStefan Metzmacher 1428*1249c01aSStefan Metzmacher if (unlikely(wc->status != IB_WC_SUCCESS || WARN_ON_ONCE(wc->opcode != IB_WC_SEND))) { 1429*1249c01aSStefan Metzmacher skip_free: 1430*1249c01aSStefan Metzmacher if (wc->status != IB_WC_WR_FLUSH_ERR) 1431*1249c01aSStefan Metzmacher smbdirect_log_rdma_send(sc, SMBDIRECT_LOG_ERR, 1432*1249c01aSStefan Metzmacher "wc->status=%s (%d) wc->opcode=%d\n", 1433*1249c01aSStefan Metzmacher ib_wc_status_msg(wc->status), wc->status, wc->opcode); 1434*1249c01aSStefan Metzmacher smbdirect_socket_schedule_cleanup(sc, -ECONNABORTED); 1435*1249c01aSStefan Metzmacher return; 1436*1249c01aSStefan Metzmacher } 1437*1249c01aSStefan Metzmacher 1438*1249c01aSStefan Metzmacher atomic_add(lcredits, &sc->send_io.lcredits.count); 1439*1249c01aSStefan Metzmacher wake_up(&sc->send_io.lcredits.wait_queue); 1440*1249c01aSStefan Metzmacher 1441*1249c01aSStefan Metzmacher if (atomic_dec_and_test(&sc->send_io.pending.count)) 1442*1249c01aSStefan Metzmacher wake_up(&sc->send_io.pending.zero_wait_queue); 1443*1249c01aSStefan Metzmacher } 1444*1249c01aSStefan Metzmacher 1445*1249c01aSStefan Metzmacher static void smbdirect_connection_send_immediate_work(struct work_struct *work) 1446*1249c01aSStefan Metzmacher { 1447*1249c01aSStefan Metzmacher struct smbdirect_socket *sc = 1448*1249c01aSStefan Metzmacher container_of(work, struct smbdirect_socket, idle.immediate_work); 1449*1249c01aSStefan Metzmacher int ret; 1450*1249c01aSStefan Metzmacher 1451*1249c01aSStefan Metzmacher if (sc->status != SMBDIRECT_SOCKET_CONNECTED) 1452*1249c01aSStefan Metzmacher return; 1453*1249c01aSStefan Metzmacher 1454*1249c01aSStefan Metzmacher smbdirect_log_keep_alive(sc, SMBDIRECT_LOG_INFO, 1455*1249c01aSStefan Metzmacher "send an empty message\n"); 1456*1249c01aSStefan Metzmacher sc->statistics.send_empty++; 1457*1249c01aSStefan Metzmacher ret = smbdirect_connection_send_single_iter(sc, NULL, NULL, 0, 0); 1458*1249c01aSStefan Metzmacher if (ret < 0) { 1459*1249c01aSStefan Metzmacher smbdirect_log_write(sc, SMBDIRECT_LOG_ERR, 1460*1249c01aSStefan Metzmacher "smbdirect_connection_send_single_iter ret=%1pe\n", 1461*1249c01aSStefan Metzmacher SMBDIRECT_DEBUG_ERR_PTR(ret)); 1462*1249c01aSStefan Metzmacher smbdirect_socket_schedule_cleanup(sc, ret); 1463*1249c01aSStefan Metzmacher } 1464*1249c01aSStefan Metzmacher } 1465*1249c01aSStefan Metzmacher 1466*1249c01aSStefan Metzmacher int smbdirect_connection_post_recv_io(struct smbdirect_recv_io *msg) 1467*1249c01aSStefan Metzmacher { 1468*1249c01aSStefan Metzmacher struct smbdirect_socket *sc = msg->socket; 1469*1249c01aSStefan Metzmacher const struct smbdirect_socket_parameters *sp = &sc->parameters; 1470*1249c01aSStefan Metzmacher struct ib_recv_wr recv_wr = { 1471*1249c01aSStefan Metzmacher .wr_cqe = &msg->cqe, 1472*1249c01aSStefan Metzmacher .sg_list = &msg->sge, 1473*1249c01aSStefan Metzmacher .num_sge = 1, 1474*1249c01aSStefan Metzmacher }; 1475*1249c01aSStefan Metzmacher int ret; 1476*1249c01aSStefan Metzmacher 1477*1249c01aSStefan Metzmacher if (unlikely(sc->first_error)) 1478*1249c01aSStefan Metzmacher return sc->first_error; 1479*1249c01aSStefan Metzmacher 1480*1249c01aSStefan Metzmacher msg->sge.addr = ib_dma_map_single(sc->ib.dev, 1481*1249c01aSStefan Metzmacher msg->packet, 1482*1249c01aSStefan Metzmacher sp->max_recv_size, 1483*1249c01aSStefan Metzmacher DMA_FROM_DEVICE); 1484*1249c01aSStefan Metzmacher ret = ib_dma_mapping_error(sc->ib.dev, msg->sge.addr); 1485*1249c01aSStefan Metzmacher if (ret) 1486*1249c01aSStefan Metzmacher return ret; 1487*1249c01aSStefan Metzmacher 1488*1249c01aSStefan Metzmacher msg->sge.length = sp->max_recv_size; 1489*1249c01aSStefan Metzmacher msg->sge.lkey = sc->ib.pd->local_dma_lkey; 1490*1249c01aSStefan Metzmacher 1491*1249c01aSStefan Metzmacher ret = ib_post_recv(sc->ib.qp, &recv_wr, NULL); 1492*1249c01aSStefan Metzmacher if (ret) { 1493*1249c01aSStefan Metzmacher smbdirect_log_rdma_recv(sc, SMBDIRECT_LOG_ERR, 1494*1249c01aSStefan Metzmacher "ib_post_recv failed ret=%d (%1pe)\n", 1495*1249c01aSStefan Metzmacher ret, SMBDIRECT_DEBUG_ERR_PTR(ret)); 1496*1249c01aSStefan Metzmacher ib_dma_unmap_single(sc->ib.dev, 1497*1249c01aSStefan Metzmacher msg->sge.addr, 1498*1249c01aSStefan Metzmacher msg->sge.length, 1499*1249c01aSStefan Metzmacher DMA_FROM_DEVICE); 1500*1249c01aSStefan Metzmacher msg->sge.length = 0; 1501*1249c01aSStefan Metzmacher smbdirect_socket_schedule_cleanup(sc, ret); 1502*1249c01aSStefan Metzmacher } 1503*1249c01aSStefan Metzmacher 1504*1249c01aSStefan Metzmacher return ret; 1505*1249c01aSStefan Metzmacher } 1506*1249c01aSStefan Metzmacher 1507*1249c01aSStefan Metzmacher void smbdirect_connection_recv_io_done(struct ib_cq *cq, struct ib_wc *wc) 1508*1249c01aSStefan Metzmacher { 1509*1249c01aSStefan Metzmacher struct smbdirect_recv_io *recv_io = 1510*1249c01aSStefan Metzmacher container_of(wc->wr_cqe, struct smbdirect_recv_io, cqe); 1511*1249c01aSStefan Metzmacher struct smbdirect_socket *sc = recv_io->socket; 1512*1249c01aSStefan Metzmacher const struct smbdirect_socket_parameters *sp = &sc->parameters; 1513*1249c01aSStefan Metzmacher struct smbdirect_data_transfer *data_transfer; 1514*1249c01aSStefan Metzmacher int current_recv_credits; 1515*1249c01aSStefan Metzmacher u16 old_recv_credit_target; 1516*1249c01aSStefan Metzmacher u16 credits_requested; 1517*1249c01aSStefan Metzmacher u16 credits_granted; 1518*1249c01aSStefan Metzmacher u16 flags; 1519*1249c01aSStefan Metzmacher u32 data_offset; 1520*1249c01aSStefan Metzmacher u32 data_length; 1521*1249c01aSStefan Metzmacher u32 remaining_data_length; 1522*1249c01aSStefan Metzmacher 1523*1249c01aSStefan Metzmacher if (unlikely(wc->status != IB_WC_SUCCESS || WARN_ON_ONCE(wc->opcode != IB_WC_RECV))) { 1524*1249c01aSStefan Metzmacher if (wc->status != IB_WC_WR_FLUSH_ERR) 1525*1249c01aSStefan Metzmacher smbdirect_log_rdma_recv(sc, SMBDIRECT_LOG_ERR, 1526*1249c01aSStefan Metzmacher "wc->status=%s (%d) wc->opcode=%d\n", 1527*1249c01aSStefan Metzmacher ib_wc_status_msg(wc->status), wc->status, wc->opcode); 1528*1249c01aSStefan Metzmacher goto error; 1529*1249c01aSStefan Metzmacher } 1530*1249c01aSStefan Metzmacher 1531*1249c01aSStefan Metzmacher smbdirect_log_rdma_recv(sc, SMBDIRECT_LOG_INFO, 1532*1249c01aSStefan Metzmacher "recv_io=0x%p type=%d wc status=%s wc opcode %d byte_len=%d pkey_index=%u\n", 1533*1249c01aSStefan Metzmacher recv_io, sc->recv_io.expected, 1534*1249c01aSStefan Metzmacher ib_wc_status_msg(wc->status), wc->opcode, 1535*1249c01aSStefan Metzmacher wc->byte_len, wc->pkey_index); 1536*1249c01aSStefan Metzmacher 1537*1249c01aSStefan Metzmacher /* 1538*1249c01aSStefan Metzmacher * Reset timer to the keepalive interval in 1539*1249c01aSStefan Metzmacher * order to trigger our next keepalive message. 1540*1249c01aSStefan Metzmacher */ 1541*1249c01aSStefan Metzmacher sc->idle.keepalive = SMBDIRECT_KEEPALIVE_NONE; 1542*1249c01aSStefan Metzmacher mod_delayed_work(sc->workqueues.idle, &sc->idle.timer_work, 1543*1249c01aSStefan Metzmacher msecs_to_jiffies(sp->keepalive_interval_msec)); 1544*1249c01aSStefan Metzmacher 1545*1249c01aSStefan Metzmacher ib_dma_sync_single_for_cpu(sc->ib.dev, 1546*1249c01aSStefan Metzmacher recv_io->sge.addr, 1547*1249c01aSStefan Metzmacher recv_io->sge.length, 1548*1249c01aSStefan Metzmacher DMA_FROM_DEVICE); 1549*1249c01aSStefan Metzmacher 1550*1249c01aSStefan Metzmacher if (unlikely(wc->byte_len < 1551*1249c01aSStefan Metzmacher offsetof(struct smbdirect_data_transfer, padding))) { 1552*1249c01aSStefan Metzmacher smbdirect_log_rdma_event(sc, SMBDIRECT_LOG_ERR, 1553*1249c01aSStefan Metzmacher "wc->byte_len=%u < %zu\n", 1554*1249c01aSStefan Metzmacher wc->byte_len, 1555*1249c01aSStefan Metzmacher offsetof(struct smbdirect_data_transfer, padding)); 1556*1249c01aSStefan Metzmacher goto error; 1557*1249c01aSStefan Metzmacher } 1558*1249c01aSStefan Metzmacher 1559*1249c01aSStefan Metzmacher data_transfer = (struct smbdirect_data_transfer *)recv_io->packet; 1560*1249c01aSStefan Metzmacher credits_requested = le16_to_cpu(data_transfer->credits_requested); 1561*1249c01aSStefan Metzmacher credits_granted = le16_to_cpu(data_transfer->credits_granted); 1562*1249c01aSStefan Metzmacher flags = le16_to_cpu(data_transfer->flags); 1563*1249c01aSStefan Metzmacher remaining_data_length = le32_to_cpu(data_transfer->remaining_data_length); 1564*1249c01aSStefan Metzmacher data_offset = le32_to_cpu(data_transfer->data_offset); 1565*1249c01aSStefan Metzmacher data_length = le32_to_cpu(data_transfer->data_length); 1566*1249c01aSStefan Metzmacher 1567*1249c01aSStefan Metzmacher smbdirect_log_incoming(sc, SMBDIRECT_LOG_INFO, 1568*1249c01aSStefan Metzmacher "DataIn: %s=%u, %s=%u, %s=0x%x, %s=%u, %s=%u, %s=%u\n", 1569*1249c01aSStefan Metzmacher "CreditsRequested", 1570*1249c01aSStefan Metzmacher credits_requested, 1571*1249c01aSStefan Metzmacher "CreditsGranted", 1572*1249c01aSStefan Metzmacher credits_granted, 1573*1249c01aSStefan Metzmacher "Flags", 1574*1249c01aSStefan Metzmacher flags, 1575*1249c01aSStefan Metzmacher "RemainingDataLength", 1576*1249c01aSStefan Metzmacher remaining_data_length, 1577*1249c01aSStefan Metzmacher "DataOffset", 1578*1249c01aSStefan Metzmacher data_offset, 1579*1249c01aSStefan Metzmacher "DataLength", 1580*1249c01aSStefan Metzmacher data_length); 1581*1249c01aSStefan Metzmacher 1582*1249c01aSStefan Metzmacher if (unlikely(credits_requested == 0)) { 1583*1249c01aSStefan Metzmacher smbdirect_log_rdma_event(sc, SMBDIRECT_LOG_ERR, 1584*1249c01aSStefan Metzmacher "invalid: credits_requested == 0\n"); 1585*1249c01aSStefan Metzmacher goto error; 1586*1249c01aSStefan Metzmacher } 1587*1249c01aSStefan Metzmacher 1588*1249c01aSStefan Metzmacher if (unlikely(data_offset % 8 != 0)) { 1589*1249c01aSStefan Metzmacher smbdirect_log_rdma_event(sc, SMBDIRECT_LOG_ERR, 1590*1249c01aSStefan Metzmacher "invalid: data_offset=%u (0x%x) not aligned to 8\n", 1591*1249c01aSStefan Metzmacher data_offset, data_offset); 1592*1249c01aSStefan Metzmacher goto error; 1593*1249c01aSStefan Metzmacher } 1594*1249c01aSStefan Metzmacher 1595*1249c01aSStefan Metzmacher if (unlikely(wc->byte_len < data_offset || 1596*1249c01aSStefan Metzmacher (u64)wc->byte_len < (u64)data_offset + data_length)) { 1597*1249c01aSStefan Metzmacher smbdirect_log_rdma_event(sc, SMBDIRECT_LOG_ERR, 1598*1249c01aSStefan Metzmacher "wc->byte_len=%u < date_offset=%u + data_length=%u\n", 1599*1249c01aSStefan Metzmacher wc->byte_len, data_offset, data_length); 1600*1249c01aSStefan Metzmacher goto error; 1601*1249c01aSStefan Metzmacher } 1602*1249c01aSStefan Metzmacher 1603*1249c01aSStefan Metzmacher if (unlikely(remaining_data_length > sp->max_fragmented_recv_size || 1604*1249c01aSStefan Metzmacher data_length > sp->max_fragmented_recv_size || 1605*1249c01aSStefan Metzmacher (u64)remaining_data_length + (u64)data_length > (u64)sp->max_fragmented_recv_size)) { 1606*1249c01aSStefan Metzmacher smbdirect_log_rdma_event(sc, SMBDIRECT_LOG_ERR, 1607*1249c01aSStefan Metzmacher "remaining_data_length=%u + data_length=%u > max_fragmented=%u\n", 1608*1249c01aSStefan Metzmacher remaining_data_length, data_length, sp->max_fragmented_recv_size); 1609*1249c01aSStefan Metzmacher goto error; 1610*1249c01aSStefan Metzmacher } 1611*1249c01aSStefan Metzmacher 1612*1249c01aSStefan Metzmacher if (data_length) { 1613*1249c01aSStefan Metzmacher if (sc->recv_io.reassembly.full_packet_received) 1614*1249c01aSStefan Metzmacher recv_io->first_segment = true; 1615*1249c01aSStefan Metzmacher 1616*1249c01aSStefan Metzmacher if (remaining_data_length) 1617*1249c01aSStefan Metzmacher sc->recv_io.reassembly.full_packet_received = false; 1618*1249c01aSStefan Metzmacher else 1619*1249c01aSStefan Metzmacher sc->recv_io.reassembly.full_packet_received = true; 1620*1249c01aSStefan Metzmacher } 1621*1249c01aSStefan Metzmacher 1622*1249c01aSStefan Metzmacher atomic_dec(&sc->recv_io.posted.count); 1623*1249c01aSStefan Metzmacher current_recv_credits = atomic_dec_return(&sc->recv_io.credits.count); 1624*1249c01aSStefan Metzmacher 1625*1249c01aSStefan Metzmacher /* 1626*1249c01aSStefan Metzmacher * We take the value from the peer, which is checked to be higher than 0, 1627*1249c01aSStefan Metzmacher * but we limit it to the max value we support in order to have 1628*1249c01aSStefan Metzmacher * the main logic simpler. 1629*1249c01aSStefan Metzmacher */ 1630*1249c01aSStefan Metzmacher old_recv_credit_target = sc->recv_io.credits.target; 1631*1249c01aSStefan Metzmacher sc->recv_io.credits.target = credits_requested; 1632*1249c01aSStefan Metzmacher sc->recv_io.credits.target = min_t(u16, sc->recv_io.credits.target, 1633*1249c01aSStefan Metzmacher sp->recv_credit_max); 1634*1249c01aSStefan Metzmacher if (credits_granted) { 1635*1249c01aSStefan Metzmacher atomic_add(credits_granted, &sc->send_io.credits.count); 1636*1249c01aSStefan Metzmacher /* 1637*1249c01aSStefan Metzmacher * We have new send credits granted from remote peer 1638*1249c01aSStefan Metzmacher * If any sender is waiting for credits, unblock it 1639*1249c01aSStefan Metzmacher */ 1640*1249c01aSStefan Metzmacher wake_up(&sc->send_io.credits.wait_queue); 1641*1249c01aSStefan Metzmacher } 1642*1249c01aSStefan Metzmacher 1643*1249c01aSStefan Metzmacher /* Send an immediate response right away if requested */ 1644*1249c01aSStefan Metzmacher if (flags & SMBDIRECT_FLAG_RESPONSE_REQUESTED) { 1645*1249c01aSStefan Metzmacher smbdirect_log_keep_alive(sc, SMBDIRECT_LOG_INFO, 1646*1249c01aSStefan Metzmacher "schedule send of immediate response\n"); 1647*1249c01aSStefan Metzmacher queue_work(sc->workqueues.immediate, &sc->idle.immediate_work); 1648*1249c01aSStefan Metzmacher } 1649*1249c01aSStefan Metzmacher 1650*1249c01aSStefan Metzmacher /* 1651*1249c01aSStefan Metzmacher * If this is a packet with data playload place the data in 1652*1249c01aSStefan Metzmacher * reassembly queue and wake up the reading thread 1653*1249c01aSStefan Metzmacher */ 1654*1249c01aSStefan Metzmacher if (data_length) { 1655*1249c01aSStefan Metzmacher if (current_recv_credits <= (sc->recv_io.credits.target / 4) || 1656*1249c01aSStefan Metzmacher sc->recv_io.credits.target > old_recv_credit_target) 1657*1249c01aSStefan Metzmacher queue_work(sc->workqueues.refill, &sc->recv_io.posted.refill_work); 1658*1249c01aSStefan Metzmacher 1659*1249c01aSStefan Metzmacher smbdirect_connection_reassembly_append_recv_io(sc, recv_io, data_length); 1660*1249c01aSStefan Metzmacher wake_up(&sc->recv_io.reassembly.wait_queue); 1661*1249c01aSStefan Metzmacher } else 1662*1249c01aSStefan Metzmacher smbdirect_connection_put_recv_io(recv_io); 1663*1249c01aSStefan Metzmacher 1664*1249c01aSStefan Metzmacher return; 1665*1249c01aSStefan Metzmacher 1666*1249c01aSStefan Metzmacher error: 1667*1249c01aSStefan Metzmacher /* 1668*1249c01aSStefan Metzmacher * Make sure smbdirect_connection_put_recv_io() does not 1669*1249c01aSStefan Metzmacher * start recv_io.posted.refill_work. 1670*1249c01aSStefan Metzmacher */ 1671*1249c01aSStefan Metzmacher disable_work(&sc->recv_io.posted.refill_work); 1672*1249c01aSStefan Metzmacher smbdirect_connection_put_recv_io(recv_io); 1673*1249c01aSStefan Metzmacher smbdirect_socket_schedule_cleanup(sc, -ECONNABORTED); 1674*1249c01aSStefan Metzmacher } 1675*1249c01aSStefan Metzmacher 1676*1249c01aSStefan Metzmacher int smbdirect_connection_recv_io_refill(struct smbdirect_socket *sc) 1677*1249c01aSStefan Metzmacher { 1678*1249c01aSStefan Metzmacher int missing; 1679*1249c01aSStefan Metzmacher int posted = 0; 1680*1249c01aSStefan Metzmacher 1681*1249c01aSStefan Metzmacher if (unlikely(sc->first_error)) 1682*1249c01aSStefan Metzmacher return sc->first_error; 1683*1249c01aSStefan Metzmacher 1684*1249c01aSStefan Metzmacher /* 1685*1249c01aSStefan Metzmacher * Find out how much smbdirect_recv_io buffers we should post. 1686*1249c01aSStefan Metzmacher * 1687*1249c01aSStefan Metzmacher * Note that sc->recv_io.credits.target is the value 1688*1249c01aSStefan Metzmacher * from the peer and it can in theory change over time, 1689*1249c01aSStefan Metzmacher * but it is forced to be at least 1 and at max 1690*1249c01aSStefan Metzmacher * sp->recv_credit_max. 1691*1249c01aSStefan Metzmacher * 1692*1249c01aSStefan Metzmacher * So it can happen that missing will be lower than 0, 1693*1249c01aSStefan Metzmacher * which means the peer has recently lowered its desired 1694*1249c01aSStefan Metzmacher * target, while be already granted a higher number of credits. 1695*1249c01aSStefan Metzmacher * 1696*1249c01aSStefan Metzmacher * Note 'posted' is the number of smbdirect_recv_io buffers 1697*1249c01aSStefan Metzmacher * posted within this function, while sc->recv_io.posted.count 1698*1249c01aSStefan Metzmacher * is the overall value of posted smbdirect_recv_io buffers. 1699*1249c01aSStefan Metzmacher * 1700*1249c01aSStefan Metzmacher * We try to post as much buffers as missing, but 1701*1249c01aSStefan Metzmacher * this is limited if a lot of smbdirect_recv_io buffers 1702*1249c01aSStefan Metzmacher * are still in the sc->recv_io.reassembly.list instead of 1703*1249c01aSStefan Metzmacher * the sc->recv_io.free.list. 1704*1249c01aSStefan Metzmacher * 1705*1249c01aSStefan Metzmacher */ 1706*1249c01aSStefan Metzmacher missing = (int)sc->recv_io.credits.target - atomic_read(&sc->recv_io.posted.count); 1707*1249c01aSStefan Metzmacher while (posted < missing) { 1708*1249c01aSStefan Metzmacher struct smbdirect_recv_io *recv_io; 1709*1249c01aSStefan Metzmacher int ret; 1710*1249c01aSStefan Metzmacher 1711*1249c01aSStefan Metzmacher /* 1712*1249c01aSStefan Metzmacher * It's ok if smbdirect_connection_get_recv_io() 1713*1249c01aSStefan Metzmacher * returns NULL, it means smbdirect_recv_io structures 1714*1249c01aSStefan Metzmacher * are still be in the reassembly.list. 1715*1249c01aSStefan Metzmacher */ 1716*1249c01aSStefan Metzmacher recv_io = smbdirect_connection_get_recv_io(sc); 1717*1249c01aSStefan Metzmacher if (!recv_io) 1718*1249c01aSStefan Metzmacher break; 1719*1249c01aSStefan Metzmacher 1720*1249c01aSStefan Metzmacher recv_io->first_segment = false; 1721*1249c01aSStefan Metzmacher 1722*1249c01aSStefan Metzmacher ret = smbdirect_connection_post_recv_io(recv_io); 1723*1249c01aSStefan Metzmacher if (ret) { 1724*1249c01aSStefan Metzmacher smbdirect_log_rdma_recv(sc, SMBDIRECT_LOG_ERR, 1725*1249c01aSStefan Metzmacher "smbdirect_connection_post_recv_io failed rc=%d (%1pe)\n", 1726*1249c01aSStefan Metzmacher ret, SMBDIRECT_DEBUG_ERR_PTR(ret)); 1727*1249c01aSStefan Metzmacher smbdirect_connection_put_recv_io(recv_io); 1728*1249c01aSStefan Metzmacher return ret; 1729*1249c01aSStefan Metzmacher } 1730*1249c01aSStefan Metzmacher 1731*1249c01aSStefan Metzmacher atomic_inc(&sc->recv_io.posted.count); 1732*1249c01aSStefan Metzmacher posted += 1; 1733*1249c01aSStefan Metzmacher } 1734*1249c01aSStefan Metzmacher 1735*1249c01aSStefan Metzmacher /* If nothing was posted we're done */ 1736*1249c01aSStefan Metzmacher if (posted == 0) 1737*1249c01aSStefan Metzmacher return 0; 1738*1249c01aSStefan Metzmacher 1739*1249c01aSStefan Metzmacher atomic_add(posted, &sc->recv_io.credits.available); 1740*1249c01aSStefan Metzmacher 1741*1249c01aSStefan Metzmacher /* 1742*1249c01aSStefan Metzmacher * If the last send credit is waiting for credits 1743*1249c01aSStefan Metzmacher * it can grant we need to wake it up 1744*1249c01aSStefan Metzmacher */ 1745*1249c01aSStefan Metzmacher if (atomic_read(&sc->send_io.bcredits.count) == 0 && 1746*1249c01aSStefan Metzmacher atomic_read(&sc->send_io.credits.count) == 0) 1747*1249c01aSStefan Metzmacher wake_up(&sc->send_io.credits.wait_queue); 1748*1249c01aSStefan Metzmacher 1749*1249c01aSStefan Metzmacher /* 1750*1249c01aSStefan Metzmacher * If we posted at least one smbdirect_recv_io buffer, 1751*1249c01aSStefan Metzmacher * we need to inform the peer about it and grant 1752*1249c01aSStefan Metzmacher * additional credits. 1753*1249c01aSStefan Metzmacher * 1754*1249c01aSStefan Metzmacher * However there is one case where we don't want to 1755*1249c01aSStefan Metzmacher * do that. 1756*1249c01aSStefan Metzmacher * 1757*1249c01aSStefan Metzmacher * If only a single credit was missing before 1758*1249c01aSStefan Metzmacher * reaching the requested target, we should not 1759*1249c01aSStefan Metzmacher * post an immediate send, as that would cause 1760*1249c01aSStefan Metzmacher * endless ping pong once a keep alive exchange 1761*1249c01aSStefan Metzmacher * is started. 1762*1249c01aSStefan Metzmacher * 1763*1249c01aSStefan Metzmacher * However if sc->recv_io.credits.target is only 1, 1764*1249c01aSStefan Metzmacher * the peer has no credit left and we need to 1765*1249c01aSStefan Metzmacher * grant the credit anyway. 1766*1249c01aSStefan Metzmacher */ 1767*1249c01aSStefan Metzmacher if (missing == 1 && sc->recv_io.credits.target != 1) 1768*1249c01aSStefan Metzmacher return 0; 1769*1249c01aSStefan Metzmacher 1770*1249c01aSStefan Metzmacher return posted; 1771*1249c01aSStefan Metzmacher } 1772*1249c01aSStefan Metzmacher 1773*1249c01aSStefan Metzmacher static void smbdirect_connection_recv_io_refill_work(struct work_struct *work) 1774*1249c01aSStefan Metzmacher { 1775*1249c01aSStefan Metzmacher struct smbdirect_socket *sc = 1776*1249c01aSStefan Metzmacher container_of(work, struct smbdirect_socket, recv_io.posted.refill_work); 1777*1249c01aSStefan Metzmacher int posted; 1778*1249c01aSStefan Metzmacher 1779*1249c01aSStefan Metzmacher posted = smbdirect_connection_recv_io_refill(sc); 1780*1249c01aSStefan Metzmacher if (unlikely(posted < 0)) { 1781*1249c01aSStefan Metzmacher smbdirect_socket_schedule_cleanup(sc, posted); 1782*1249c01aSStefan Metzmacher return; 1783*1249c01aSStefan Metzmacher } 1784*1249c01aSStefan Metzmacher if (posted > 0) { 1785*1249c01aSStefan Metzmacher smbdirect_log_keep_alive(sc, SMBDIRECT_LOG_INFO, 1786*1249c01aSStefan Metzmacher "schedule send of an empty message\n"); 1787*1249c01aSStefan Metzmacher queue_work(sc->workqueues.immediate, &sc->idle.immediate_work); 1788*1249c01aSStefan Metzmacher } 1789*1249c01aSStefan Metzmacher } 1790*1249c01aSStefan Metzmacher 1791*1249c01aSStefan Metzmacher int smbdirect_connection_recvmsg(struct smbdirect_socket *sc, 1792*1249c01aSStefan Metzmacher struct msghdr *msg, 1793*1249c01aSStefan Metzmacher unsigned int flags) 1794*1249c01aSStefan Metzmacher { 1795*1249c01aSStefan Metzmacher struct smbdirect_recv_io *response; 1796*1249c01aSStefan Metzmacher struct smbdirect_data_transfer *data_transfer; 1797*1249c01aSStefan Metzmacher size_t size = iov_iter_count(&msg->msg_iter); 1798*1249c01aSStefan Metzmacher int to_copy, to_read, data_read, offset; 1799*1249c01aSStefan Metzmacher u32 data_length, remaining_data_length, data_offset; 1800*1249c01aSStefan Metzmacher int ret; 1801*1249c01aSStefan Metzmacher 1802*1249c01aSStefan Metzmacher if (WARN_ONCE(flags, "unexpected flags=0x%x\n", flags)) 1803*1249c01aSStefan Metzmacher return -EINVAL; /* no flags support for now */ 1804*1249c01aSStefan Metzmacher 1805*1249c01aSStefan Metzmacher if (WARN_ON_ONCE(iov_iter_rw(&msg->msg_iter) != ITER_DEST)) 1806*1249c01aSStefan Metzmacher return -EINVAL; /* It's a bug in upper layer to get there */ 1807*1249c01aSStefan Metzmacher 1808*1249c01aSStefan Metzmacher again: 1809*1249c01aSStefan Metzmacher if (sc->status != SMBDIRECT_SOCKET_CONNECTED) { 1810*1249c01aSStefan Metzmacher smbdirect_log_read(sc, SMBDIRECT_LOG_INFO, 1811*1249c01aSStefan Metzmacher "status=%s first_error=%1pe => %1pe\n", 1812*1249c01aSStefan Metzmacher smbdirect_socket_status_string(sc->status), 1813*1249c01aSStefan Metzmacher SMBDIRECT_DEBUG_ERR_PTR(sc->first_error), 1814*1249c01aSStefan Metzmacher SMBDIRECT_DEBUG_ERR_PTR(-ENOTCONN)); 1815*1249c01aSStefan Metzmacher return -ENOTCONN; 1816*1249c01aSStefan Metzmacher } 1817*1249c01aSStefan Metzmacher 1818*1249c01aSStefan Metzmacher /* 1819*1249c01aSStefan Metzmacher * No need to hold the reassembly queue lock all the time as we are 1820*1249c01aSStefan Metzmacher * the only one reading from the front of the queue. The transport 1821*1249c01aSStefan Metzmacher * may add more entries to the back of the queue at the same time 1822*1249c01aSStefan Metzmacher */ 1823*1249c01aSStefan Metzmacher smbdirect_log_read(sc, SMBDIRECT_LOG_INFO, 1824*1249c01aSStefan Metzmacher "size=%zd sc->recv_io.reassembly.data_length=%d\n", 1825*1249c01aSStefan Metzmacher size, sc->recv_io.reassembly.data_length); 1826*1249c01aSStefan Metzmacher if (sc->recv_io.reassembly.data_length >= size) { 1827*1249c01aSStefan Metzmacher int queue_length; 1828*1249c01aSStefan Metzmacher int queue_removed = 0; 1829*1249c01aSStefan Metzmacher unsigned long flags; 1830*1249c01aSStefan Metzmacher 1831*1249c01aSStefan Metzmacher /* 1832*1249c01aSStefan Metzmacher * Need to make sure reassembly_data_length is read before 1833*1249c01aSStefan Metzmacher * reading reassembly_queue_length and calling 1834*1249c01aSStefan Metzmacher * smbdirect_connection_reassembly_first_recv_io. This call is lock free 1835*1249c01aSStefan Metzmacher * as we never read at the end of the queue which are being 1836*1249c01aSStefan Metzmacher * updated in SOFTIRQ as more data is received 1837*1249c01aSStefan Metzmacher */ 1838*1249c01aSStefan Metzmacher virt_rmb(); 1839*1249c01aSStefan Metzmacher queue_length = sc->recv_io.reassembly.queue_length; 1840*1249c01aSStefan Metzmacher data_read = 0; 1841*1249c01aSStefan Metzmacher to_read = size; 1842*1249c01aSStefan Metzmacher offset = sc->recv_io.reassembly.first_entry_offset; 1843*1249c01aSStefan Metzmacher while (data_read < size) { 1844*1249c01aSStefan Metzmacher response = smbdirect_connection_reassembly_first_recv_io(sc); 1845*1249c01aSStefan Metzmacher data_transfer = (void *)response->packet; 1846*1249c01aSStefan Metzmacher data_length = le32_to_cpu(data_transfer->data_length); 1847*1249c01aSStefan Metzmacher remaining_data_length = 1848*1249c01aSStefan Metzmacher le32_to_cpu( 1849*1249c01aSStefan Metzmacher data_transfer->remaining_data_length); 1850*1249c01aSStefan Metzmacher data_offset = le32_to_cpu(data_transfer->data_offset); 1851*1249c01aSStefan Metzmacher 1852*1249c01aSStefan Metzmacher /* 1853*1249c01aSStefan Metzmacher * The upper layer expects RFC1002 length at the 1854*1249c01aSStefan Metzmacher * beginning of the payload. Return it to indicate 1855*1249c01aSStefan Metzmacher * the total length of the packet. This minimize the 1856*1249c01aSStefan Metzmacher * change to upper layer packet processing logic. This 1857*1249c01aSStefan Metzmacher * will be eventually remove when an intermediate 1858*1249c01aSStefan Metzmacher * transport layer is added 1859*1249c01aSStefan Metzmacher */ 1860*1249c01aSStefan Metzmacher if (response->first_segment && size == 4) { 1861*1249c01aSStefan Metzmacher unsigned int rfc1002_len = 1862*1249c01aSStefan Metzmacher data_length + remaining_data_length; 1863*1249c01aSStefan Metzmacher __be32 rfc1002_hdr = cpu_to_be32(rfc1002_len); 1864*1249c01aSStefan Metzmacher 1865*1249c01aSStefan Metzmacher if (copy_to_iter(&rfc1002_hdr, sizeof(rfc1002_hdr), 1866*1249c01aSStefan Metzmacher &msg->msg_iter) != sizeof(rfc1002_hdr)) 1867*1249c01aSStefan Metzmacher return -EFAULT; 1868*1249c01aSStefan Metzmacher data_read = 4; 1869*1249c01aSStefan Metzmacher response->first_segment = false; 1870*1249c01aSStefan Metzmacher smbdirect_log_read(sc, SMBDIRECT_LOG_INFO, 1871*1249c01aSStefan Metzmacher "returning rfc1002 length %d\n", 1872*1249c01aSStefan Metzmacher rfc1002_len); 1873*1249c01aSStefan Metzmacher goto read_rfc1002_done; 1874*1249c01aSStefan Metzmacher } 1875*1249c01aSStefan Metzmacher 1876*1249c01aSStefan Metzmacher to_copy = min_t(int, data_length - offset, to_read); 1877*1249c01aSStefan Metzmacher if (copy_to_iter((u8 *)data_transfer + data_offset + offset, 1878*1249c01aSStefan Metzmacher to_copy, &msg->msg_iter) != to_copy) 1879*1249c01aSStefan Metzmacher return -EFAULT; 1880*1249c01aSStefan Metzmacher 1881*1249c01aSStefan Metzmacher /* move on to the next buffer? */ 1882*1249c01aSStefan Metzmacher if (to_copy == data_length - offset) { 1883*1249c01aSStefan Metzmacher queue_length--; 1884*1249c01aSStefan Metzmacher /* 1885*1249c01aSStefan Metzmacher * No need to lock if we are not at the 1886*1249c01aSStefan Metzmacher * end of the queue 1887*1249c01aSStefan Metzmacher */ 1888*1249c01aSStefan Metzmacher if (queue_length) 1889*1249c01aSStefan Metzmacher list_del(&response->list); 1890*1249c01aSStefan Metzmacher else { 1891*1249c01aSStefan Metzmacher spin_lock_irqsave( 1892*1249c01aSStefan Metzmacher &sc->recv_io.reassembly.lock, flags); 1893*1249c01aSStefan Metzmacher list_del(&response->list); 1894*1249c01aSStefan Metzmacher spin_unlock_irqrestore( 1895*1249c01aSStefan Metzmacher &sc->recv_io.reassembly.lock, flags); 1896*1249c01aSStefan Metzmacher } 1897*1249c01aSStefan Metzmacher queue_removed++; 1898*1249c01aSStefan Metzmacher sc->statistics.dequeue_reassembly_queue++; 1899*1249c01aSStefan Metzmacher smbdirect_connection_put_recv_io(response); 1900*1249c01aSStefan Metzmacher offset = 0; 1901*1249c01aSStefan Metzmacher smbdirect_log_read(sc, SMBDIRECT_LOG_INFO, 1902*1249c01aSStefan Metzmacher "smbdirect_connection_put_recv_io offset=0\n"); 1903*1249c01aSStefan Metzmacher } else 1904*1249c01aSStefan Metzmacher offset += to_copy; 1905*1249c01aSStefan Metzmacher 1906*1249c01aSStefan Metzmacher to_read -= to_copy; 1907*1249c01aSStefan Metzmacher data_read += to_copy; 1908*1249c01aSStefan Metzmacher 1909*1249c01aSStefan Metzmacher smbdirect_log_read(sc, SMBDIRECT_LOG_INFO, 1910*1249c01aSStefan Metzmacher "memcpy %d bytes len-ofs=%u => todo=%u done=%u ofs=%u\n", 1911*1249c01aSStefan Metzmacher to_copy, data_length - offset, 1912*1249c01aSStefan Metzmacher to_read, data_read, offset); 1913*1249c01aSStefan Metzmacher } 1914*1249c01aSStefan Metzmacher 1915*1249c01aSStefan Metzmacher spin_lock_irqsave(&sc->recv_io.reassembly.lock, flags); 1916*1249c01aSStefan Metzmacher sc->recv_io.reassembly.data_length -= data_read; 1917*1249c01aSStefan Metzmacher sc->recv_io.reassembly.queue_length -= queue_removed; 1918*1249c01aSStefan Metzmacher spin_unlock_irqrestore(&sc->recv_io.reassembly.lock, flags); 1919*1249c01aSStefan Metzmacher 1920*1249c01aSStefan Metzmacher sc->recv_io.reassembly.first_entry_offset = offset; 1921*1249c01aSStefan Metzmacher smbdirect_log_read(sc, SMBDIRECT_LOG_INFO, 1922*1249c01aSStefan Metzmacher "returning data_read=%d reassembly_length=%d first_ofs=%u\n", 1923*1249c01aSStefan Metzmacher data_read, sc->recv_io.reassembly.data_length, 1924*1249c01aSStefan Metzmacher sc->recv_io.reassembly.first_entry_offset); 1925*1249c01aSStefan Metzmacher read_rfc1002_done: 1926*1249c01aSStefan Metzmacher return data_read; 1927*1249c01aSStefan Metzmacher } 1928*1249c01aSStefan Metzmacher 1929*1249c01aSStefan Metzmacher smbdirect_log_read(sc, SMBDIRECT_LOG_INFO, 1930*1249c01aSStefan Metzmacher "wait_event on more data\n"); 1931*1249c01aSStefan Metzmacher ret = wait_event_interruptible(sc->recv_io.reassembly.wait_queue, 1932*1249c01aSStefan Metzmacher sc->recv_io.reassembly.data_length >= size || 1933*1249c01aSStefan Metzmacher sc->status != SMBDIRECT_SOCKET_CONNECTED); 1934*1249c01aSStefan Metzmacher /* Don't return any data if interrupted */ 1935*1249c01aSStefan Metzmacher if (ret) 1936*1249c01aSStefan Metzmacher return ret; 1937*1249c01aSStefan Metzmacher 1938*1249c01aSStefan Metzmacher goto again; 1939*1249c01aSStefan Metzmacher } 1940*1249c01aSStefan Metzmacher __SMBDIRECT_EXPORT_SYMBOL__(smbdirect_connection_recvmsg); 1941*1249c01aSStefan Metzmacher 1942*1249c01aSStefan Metzmacher static bool smbdirect_map_sges_single_page(struct smbdirect_map_sges *state, 1943*1249c01aSStefan Metzmacher struct page *page, size_t off, size_t len) 1944*1249c01aSStefan Metzmacher { 1945*1249c01aSStefan Metzmacher struct ib_sge *sge; 1946*1249c01aSStefan Metzmacher u64 addr; 1947*1249c01aSStefan Metzmacher 1948*1249c01aSStefan Metzmacher if (state->num_sge >= state->max_sge) 1949*1249c01aSStefan Metzmacher return false; 1950*1249c01aSStefan Metzmacher 1951*1249c01aSStefan Metzmacher addr = ib_dma_map_page(state->device, page, 1952*1249c01aSStefan Metzmacher off, len, state->direction); 1953*1249c01aSStefan Metzmacher if (ib_dma_mapping_error(state->device, addr)) 1954*1249c01aSStefan Metzmacher return false; 1955*1249c01aSStefan Metzmacher 1956*1249c01aSStefan Metzmacher sge = &state->sge[state->num_sge++]; 1957*1249c01aSStefan Metzmacher sge->addr = addr; 1958*1249c01aSStefan Metzmacher sge->length = len; 1959*1249c01aSStefan Metzmacher sge->lkey = state->local_dma_lkey; 1960*1249c01aSStefan Metzmacher 1961*1249c01aSStefan Metzmacher return true; 1962*1249c01aSStefan Metzmacher } 1963*1249c01aSStefan Metzmacher 1964*1249c01aSStefan Metzmacher /* 1965*1249c01aSStefan Metzmacher * Extract page fragments from a BVEC-class iterator and add them to an ib_sge 1966*1249c01aSStefan Metzmacher * list. The pages are not pinned. 1967*1249c01aSStefan Metzmacher */ 1968*1249c01aSStefan Metzmacher static ssize_t smbdirect_map_sges_from_bvec(struct iov_iter *iter, 1969*1249c01aSStefan Metzmacher struct smbdirect_map_sges *state, 1970*1249c01aSStefan Metzmacher ssize_t maxsize) 1971*1249c01aSStefan Metzmacher { 1972*1249c01aSStefan Metzmacher const struct bio_vec *bv = iter->bvec; 1973*1249c01aSStefan Metzmacher unsigned long start = iter->iov_offset; 1974*1249c01aSStefan Metzmacher unsigned int i; 1975*1249c01aSStefan Metzmacher ssize_t ret = 0; 1976*1249c01aSStefan Metzmacher 1977*1249c01aSStefan Metzmacher for (i = 0; i < iter->nr_segs; i++) { 1978*1249c01aSStefan Metzmacher size_t off, len; 1979*1249c01aSStefan Metzmacher bool ok; 1980*1249c01aSStefan Metzmacher 1981*1249c01aSStefan Metzmacher len = bv[i].bv_len; 1982*1249c01aSStefan Metzmacher if (start >= len) { 1983*1249c01aSStefan Metzmacher start -= len; 1984*1249c01aSStefan Metzmacher continue; 1985*1249c01aSStefan Metzmacher } 1986*1249c01aSStefan Metzmacher 1987*1249c01aSStefan Metzmacher len = min_t(size_t, maxsize, len - start); 1988*1249c01aSStefan Metzmacher off = bv[i].bv_offset + start; 1989*1249c01aSStefan Metzmacher 1990*1249c01aSStefan Metzmacher ok = smbdirect_map_sges_single_page(state, 1991*1249c01aSStefan Metzmacher bv[i].bv_page, 1992*1249c01aSStefan Metzmacher off, 1993*1249c01aSStefan Metzmacher len); 1994*1249c01aSStefan Metzmacher if (!ok) 1995*1249c01aSStefan Metzmacher return -EIO; 1996*1249c01aSStefan Metzmacher 1997*1249c01aSStefan Metzmacher ret += len; 1998*1249c01aSStefan Metzmacher maxsize -= len; 1999*1249c01aSStefan Metzmacher if (state->num_sge >= state->max_sge || maxsize <= 0) 2000*1249c01aSStefan Metzmacher break; 2001*1249c01aSStefan Metzmacher start = 0; 2002*1249c01aSStefan Metzmacher } 2003*1249c01aSStefan Metzmacher 2004*1249c01aSStefan Metzmacher if (ret > 0) 2005*1249c01aSStefan Metzmacher iov_iter_advance(iter, ret); 2006*1249c01aSStefan Metzmacher return ret; 2007*1249c01aSStefan Metzmacher } 2008*1249c01aSStefan Metzmacher 2009*1249c01aSStefan Metzmacher /* 2010*1249c01aSStefan Metzmacher * Extract fragments from a KVEC-class iterator and add them to an ib_sge list. 2011*1249c01aSStefan Metzmacher * This can deal with vmalloc'd buffers as well as kmalloc'd or static buffers. 2012*1249c01aSStefan Metzmacher * The pages are not pinned. 2013*1249c01aSStefan Metzmacher */ 2014*1249c01aSStefan Metzmacher static ssize_t smbdirect_map_sges_from_kvec(struct iov_iter *iter, 2015*1249c01aSStefan Metzmacher struct smbdirect_map_sges *state, 2016*1249c01aSStefan Metzmacher ssize_t maxsize) 2017*1249c01aSStefan Metzmacher { 2018*1249c01aSStefan Metzmacher const struct kvec *kv = iter->kvec; 2019*1249c01aSStefan Metzmacher unsigned long start = iter->iov_offset; 2020*1249c01aSStefan Metzmacher unsigned int i; 2021*1249c01aSStefan Metzmacher ssize_t ret = 0; 2022*1249c01aSStefan Metzmacher 2023*1249c01aSStefan Metzmacher for (i = 0; i < iter->nr_segs; i++) { 2024*1249c01aSStefan Metzmacher struct page *page; 2025*1249c01aSStefan Metzmacher unsigned long kaddr; 2026*1249c01aSStefan Metzmacher size_t off, len, seg; 2027*1249c01aSStefan Metzmacher 2028*1249c01aSStefan Metzmacher len = kv[i].iov_len; 2029*1249c01aSStefan Metzmacher if (start >= len) { 2030*1249c01aSStefan Metzmacher start -= len; 2031*1249c01aSStefan Metzmacher continue; 2032*1249c01aSStefan Metzmacher } 2033*1249c01aSStefan Metzmacher 2034*1249c01aSStefan Metzmacher kaddr = (unsigned long)kv[i].iov_base + start; 2035*1249c01aSStefan Metzmacher off = kaddr & ~PAGE_MASK; 2036*1249c01aSStefan Metzmacher len = min_t(size_t, maxsize, len - start); 2037*1249c01aSStefan Metzmacher kaddr &= PAGE_MASK; 2038*1249c01aSStefan Metzmacher 2039*1249c01aSStefan Metzmacher maxsize -= len; 2040*1249c01aSStefan Metzmacher do { 2041*1249c01aSStefan Metzmacher bool ok; 2042*1249c01aSStefan Metzmacher 2043*1249c01aSStefan Metzmacher seg = min_t(size_t, len, PAGE_SIZE - off); 2044*1249c01aSStefan Metzmacher 2045*1249c01aSStefan Metzmacher if (is_vmalloc_or_module_addr((void *)kaddr)) 2046*1249c01aSStefan Metzmacher page = vmalloc_to_page((void *)kaddr); 2047*1249c01aSStefan Metzmacher else 2048*1249c01aSStefan Metzmacher page = virt_to_page((void *)kaddr); 2049*1249c01aSStefan Metzmacher 2050*1249c01aSStefan Metzmacher ok = smbdirect_map_sges_single_page(state, page, off, seg); 2051*1249c01aSStefan Metzmacher if (!ok) 2052*1249c01aSStefan Metzmacher return -EIO; 2053*1249c01aSStefan Metzmacher 2054*1249c01aSStefan Metzmacher ret += seg; 2055*1249c01aSStefan Metzmacher len -= seg; 2056*1249c01aSStefan Metzmacher kaddr += PAGE_SIZE; 2057*1249c01aSStefan Metzmacher off = 0; 2058*1249c01aSStefan Metzmacher } while (len > 0 && state->num_sge < state->max_sge); 2059*1249c01aSStefan Metzmacher 2060*1249c01aSStefan Metzmacher if (state->num_sge >= state->max_sge || maxsize <= 0) 2061*1249c01aSStefan Metzmacher break; 2062*1249c01aSStefan Metzmacher start = 0; 2063*1249c01aSStefan Metzmacher } 2064*1249c01aSStefan Metzmacher 2065*1249c01aSStefan Metzmacher if (ret > 0) 2066*1249c01aSStefan Metzmacher iov_iter_advance(iter, ret); 2067*1249c01aSStefan Metzmacher return ret; 2068*1249c01aSStefan Metzmacher } 2069*1249c01aSStefan Metzmacher 2070*1249c01aSStefan Metzmacher /* 2071*1249c01aSStefan Metzmacher * Extract folio fragments from a FOLIOQ-class iterator and add them to an 2072*1249c01aSStefan Metzmacher * ib_sge list. The folios are not pinned. 2073*1249c01aSStefan Metzmacher */ 2074*1249c01aSStefan Metzmacher static ssize_t smbdirect_map_sges_from_folioq(struct iov_iter *iter, 2075*1249c01aSStefan Metzmacher struct smbdirect_map_sges *state, 2076*1249c01aSStefan Metzmacher ssize_t maxsize) 2077*1249c01aSStefan Metzmacher { 2078*1249c01aSStefan Metzmacher const struct folio_queue *folioq = iter->folioq; 2079*1249c01aSStefan Metzmacher unsigned int slot = iter->folioq_slot; 2080*1249c01aSStefan Metzmacher ssize_t ret = 0; 2081*1249c01aSStefan Metzmacher size_t offset = iter->iov_offset; 2082*1249c01aSStefan Metzmacher 2083*1249c01aSStefan Metzmacher if (WARN_ON_ONCE(!folioq)) 2084*1249c01aSStefan Metzmacher return -EIO; 2085*1249c01aSStefan Metzmacher 2086*1249c01aSStefan Metzmacher if (slot >= folioq_nr_slots(folioq)) { 2087*1249c01aSStefan Metzmacher folioq = folioq->next; 2088*1249c01aSStefan Metzmacher if (WARN_ON_ONCE(!folioq)) 2089*1249c01aSStefan Metzmacher return -EIO; 2090*1249c01aSStefan Metzmacher slot = 0; 2091*1249c01aSStefan Metzmacher } 2092*1249c01aSStefan Metzmacher 2093*1249c01aSStefan Metzmacher do { 2094*1249c01aSStefan Metzmacher struct folio *folio = folioq_folio(folioq, slot); 2095*1249c01aSStefan Metzmacher size_t fsize = folioq_folio_size(folioq, slot); 2096*1249c01aSStefan Metzmacher 2097*1249c01aSStefan Metzmacher if (offset < fsize) { 2098*1249c01aSStefan Metzmacher size_t part = umin(maxsize, fsize - offset); 2099*1249c01aSStefan Metzmacher bool ok; 2100*1249c01aSStefan Metzmacher 2101*1249c01aSStefan Metzmacher ok = smbdirect_map_sges_single_page(state, 2102*1249c01aSStefan Metzmacher folio_page(folio, 0), 2103*1249c01aSStefan Metzmacher offset, 2104*1249c01aSStefan Metzmacher part); 2105*1249c01aSStefan Metzmacher if (!ok) 2106*1249c01aSStefan Metzmacher return -EIO; 2107*1249c01aSStefan Metzmacher 2108*1249c01aSStefan Metzmacher offset += part; 2109*1249c01aSStefan Metzmacher ret += part; 2110*1249c01aSStefan Metzmacher maxsize -= part; 2111*1249c01aSStefan Metzmacher } 2112*1249c01aSStefan Metzmacher 2113*1249c01aSStefan Metzmacher if (offset >= fsize) { 2114*1249c01aSStefan Metzmacher offset = 0; 2115*1249c01aSStefan Metzmacher slot++; 2116*1249c01aSStefan Metzmacher if (slot >= folioq_nr_slots(folioq)) { 2117*1249c01aSStefan Metzmacher if (!folioq->next) { 2118*1249c01aSStefan Metzmacher WARN_ON_ONCE(ret < iter->count); 2119*1249c01aSStefan Metzmacher break; 2120*1249c01aSStefan Metzmacher } 2121*1249c01aSStefan Metzmacher folioq = folioq->next; 2122*1249c01aSStefan Metzmacher slot = 0; 2123*1249c01aSStefan Metzmacher } 2124*1249c01aSStefan Metzmacher } 2125*1249c01aSStefan Metzmacher } while (state->num_sge < state->max_sge && maxsize > 0); 2126*1249c01aSStefan Metzmacher 2127*1249c01aSStefan Metzmacher iter->folioq = folioq; 2128*1249c01aSStefan Metzmacher iter->folioq_slot = slot; 2129*1249c01aSStefan Metzmacher iter->iov_offset = offset; 2130*1249c01aSStefan Metzmacher iter->count -= ret; 2131*1249c01aSStefan Metzmacher return ret; 2132*1249c01aSStefan Metzmacher } 2133*1249c01aSStefan Metzmacher 2134*1249c01aSStefan Metzmacher /* 2135*1249c01aSStefan Metzmacher * Extract page fragments from up to the given amount of the source iterator 2136*1249c01aSStefan Metzmacher * and build up an ib_sge list that refers to all of those bits. The ib_sge list 2137*1249c01aSStefan Metzmacher * is appended to, up to the maximum number of elements set in the parameter 2138*1249c01aSStefan Metzmacher * block. 2139*1249c01aSStefan Metzmacher * 2140*1249c01aSStefan Metzmacher * The extracted page fragments are not pinned or ref'd in any way; if an 2141*1249c01aSStefan Metzmacher * IOVEC/UBUF-type iterator is to be used, it should be converted to a 2142*1249c01aSStefan Metzmacher * BVEC-type iterator and the pages pinned, ref'd or otherwise held in some 2143*1249c01aSStefan Metzmacher * way. 2144*1249c01aSStefan Metzmacher */ 2145*1249c01aSStefan Metzmacher static ssize_t smbdirect_map_sges_from_iter(struct iov_iter *iter, size_t len, 2146*1249c01aSStefan Metzmacher struct smbdirect_map_sges *state) 2147*1249c01aSStefan Metzmacher { 2148*1249c01aSStefan Metzmacher ssize_t ret; 2149*1249c01aSStefan Metzmacher size_t before = state->num_sge; 2150*1249c01aSStefan Metzmacher 2151*1249c01aSStefan Metzmacher if (WARN_ON_ONCE(iov_iter_rw(iter) != ITER_SOURCE)) 2152*1249c01aSStefan Metzmacher return -EIO; 2153*1249c01aSStefan Metzmacher 2154*1249c01aSStefan Metzmacher switch (iov_iter_type(iter)) { 2155*1249c01aSStefan Metzmacher case ITER_BVEC: 2156*1249c01aSStefan Metzmacher ret = smbdirect_map_sges_from_bvec(iter, state, len); 2157*1249c01aSStefan Metzmacher break; 2158*1249c01aSStefan Metzmacher case ITER_KVEC: 2159*1249c01aSStefan Metzmacher ret = smbdirect_map_sges_from_kvec(iter, state, len); 2160*1249c01aSStefan Metzmacher break; 2161*1249c01aSStefan Metzmacher case ITER_FOLIOQ: 2162*1249c01aSStefan Metzmacher ret = smbdirect_map_sges_from_folioq(iter, state, len); 2163*1249c01aSStefan Metzmacher break; 2164*1249c01aSStefan Metzmacher default: 2165*1249c01aSStefan Metzmacher WARN_ONCE(1, "iov_iter_type[%u]\n", iov_iter_type(iter)); 2166*1249c01aSStefan Metzmacher return -EIO; 2167*1249c01aSStefan Metzmacher } 2168*1249c01aSStefan Metzmacher 2169*1249c01aSStefan Metzmacher if (ret < 0) { 2170*1249c01aSStefan Metzmacher while (state->num_sge > before) { 2171*1249c01aSStefan Metzmacher struct ib_sge *sge = &state->sge[state->num_sge--]; 2172*1249c01aSStefan Metzmacher 2173*1249c01aSStefan Metzmacher ib_dma_unmap_page(state->device, 2174*1249c01aSStefan Metzmacher sge->addr, 2175*1249c01aSStefan Metzmacher sge->length, 2176*1249c01aSStefan Metzmacher state->direction); 2177*1249c01aSStefan Metzmacher } 2178*1249c01aSStefan Metzmacher } 2179*1249c01aSStefan Metzmacher 2180*1249c01aSStefan Metzmacher return ret; 2181*1249c01aSStefan Metzmacher } 2182