int isert_rx_pdu_done(struct isert_cmnd *pdu) { int err; struct isert_connection *isert_conn = (struct isert_connection *)pdu->iscsi.conn; TRACE_ENTRY(); err = isert_reinit_rx_pdu(pdu); if (unlikely(err)) goto out; spin_lock(&isert_conn->post_recv_lock); if (unlikely(isert_conn->to_post_recv == 0)) isert_conn->post_recv_first = &pdu->wr[0]; else isert_link_recv_wrs(isert_conn->post_recv_curr, &pdu->wr[0]); isert_conn->post_recv_curr = &pdu->wr[0]; if (++isert_conn->to_post_recv > isert_conn->repost_threshold) { err = isert_post_recv(isert_conn, isert_conn->post_recv_first, isert_conn->to_post_recv); isert_conn->to_post_recv = 0; } spin_unlock(&isert_conn->post_recv_lock); out: TRACE_EXIT_RES(err); return err; }
/* if last transition into FF (Fully Featured) state */ int isert_login_rsp_tx(struct iscsi_cmnd *login_rsp, int last, int discovery) { struct isert_connection *isert_conn = container_of(login_rsp->conn, struct isert_connection, iscsi); int err; if (last && !discovery) { err = isert_alloc_conn_resources(isert_conn); if (unlikely(err)) { pr_err("Failed to init conn resources\n"); return err; } isert_pdu_free(isert_conn->login_req_pdu); isert_conn->login_req_pdu = NULL; } else { err = isert_post_recv(isert_conn, &isert_conn->login_req_pdu->wr[0], 1); if (unlikely(err)) { pr_err("Failed to post recv login req rx buf, err:%d\n", err); return err; } } return isert_pdu_tx(login_rsp); }
int isert_alloc_conn_resources(struct isert_connection *isert_conn) { struct isert_cmnd *pdu, *prev_pdu = NULL, *first_pdu = NULL; int t_datasz = 512; /* RFC states that minimum receive data size is 512 */ int i_datasz = ISER_HDRS_SZ + SCST_SENSE_BUFFERSIZE; int i, err = 0; int to_alloc; TRACE_ENTRY(); isert_conn->repost_threshold = 32; to_alloc = isert_conn->queue_depth * 2 + isert_conn->repost_threshold; if (unlikely(to_alloc > ISER_MAX_WCE)) { pr_err("QueuedCommands larger than %d not supported\n", (ISER_MAX_WCE - isert_conn->repost_threshold) / 2); err = -EINVAL; goto out; } for (i = 0; i < to_alloc; i++) { pdu = isert_rx_pdu_alloc(isert_conn, t_datasz); if (unlikely(!pdu)) { err = -ENOMEM; goto clean_pdus; } if (unlikely(first_pdu == NULL)) first_pdu = pdu; else isert_link_recv_pdu_wrs(prev_pdu, pdu); prev_pdu = pdu; pdu = isert_tx_pdu_alloc(isert_conn, i_datasz); if (unlikely(!pdu)) { err = -ENOMEM; goto clean_pdus; } } err = isert_post_recv(isert_conn, &first_pdu->wr[0], to_alloc); if (unlikely(err)) { pr_err("Failed to post recv err:%d\n", err); goto clean_pdus; } out: TRACE_EXIT_RES(err); return err; clean_pdus: isert_free_conn_resources(isert_conn); goto out; }
static struct isert_connection *isert_conn_create(struct rdma_cm_id *cm_id, struct isert_device *isert_dev) { struct isert_connection *isert_conn; int err; struct isert_cq *cq; TRACE_ENTRY(); isert_conn = isert_conn_alloc(); if (unlikely(!isert_conn)) { pr_err("Unable to allocate iser conn, cm_id:%p\n", cm_id); err = -ENOMEM; goto fail_alloc; } isert_conn->state = ISER_CONN_INIT; isert_conn->cm_id = cm_id; isert_conn->isert_dev = isert_dev; /* * A quote from the OFED 1.5.3.1 release notes * (docs/release_notes/mthca_release_notes.txt), section "Known Issues": * In mem-free devices, RC QPs can be created with a maximum of * (max_sge - 1) entries only; UD QPs can be created with a maximum of * (max_sge - 3) entries. * A quote from the OFED 1.2.5 release notes * (docs/mthca_release_notes.txt), section "Known Issues": * In mem-free devices, RC QPs can be created with a maximum of * (max_sge - 3) entries only. */ isert_conn->max_sge = isert_dev->device_attr.max_sge - 3; WARN_ON(isert_conn->max_sge < 1); INIT_LIST_HEAD(&isert_conn->rx_buf_list); INIT_LIST_HEAD(&isert_conn->tx_free_list); INIT_LIST_HEAD(&isert_conn->tx_busy_list); spin_lock_init(&isert_conn->tx_lock); spin_lock_init(&isert_conn->post_recv_lock); isert_conn->login_req_pdu = isert_rx_pdu_alloc(isert_conn, ISER_MAX_LOGIN_RDSL); if (unlikely(!isert_conn->login_req_pdu)) { pr_err("Failed to init login req rx pdu\n"); err = -ENOMEM; goto fail_login_req_pdu; } isert_conn->login_rsp_pdu = isert_tx_pdu_alloc(isert_conn, ISER_MAX_LOGIN_RDSL); if (unlikely(!isert_conn->login_rsp_pdu)) { pr_err("Failed to init login rsp tx pdu\n"); err = -ENOMEM; goto fail_login_rsp_pdu; } err = isert_conn_qp_create(isert_conn); if (unlikely(err)) goto fail_qp; err = isert_post_recv(isert_conn, &isert_conn->login_req_pdu->wr[0], 1); if (unlikely(err)) { pr_err("Failed to post recv login req rx buf, err:%d\n", err); goto fail_post_recv; } kref_init(&isert_conn->kref); TRACE_EXIT(); return isert_conn; fail_post_recv: cq = isert_conn->qp->recv_cq->cq_context; mutex_lock(&dev_list_mutex); isert_dev->cq_qps[cq->idx]--; mutex_unlock(&dev_list_mutex); isert_conn_qp_destroy(isert_conn); fail_qp: isert_pdu_free(isert_conn->login_rsp_pdu); fail_login_rsp_pdu: isert_pdu_free(isert_conn->login_req_pdu); fail_login_req_pdu: isert_conn_kfree(isert_conn); fail_alloc: module_put(THIS_MODULE); TRACE_EXIT_RES(err); return ERR_PTR(err); }
static struct isert_connection *isert_conn_create(struct rdma_cm_id *cm_id, struct isert_device *isert_dev) { struct isert_connection *isert_conn; int err; struct isert_cq *cq; TRACE_ENTRY(); isert_conn = isert_conn_alloc(); if (unlikely(!isert_conn)) { pr_err("Unable to allocate iser conn, cm_id:%p\n", cm_id); err = -ENOMEM; goto fail_alloc; } isert_conn->state = ISER_CONN_INIT; isert_conn->cm_id = cm_id; isert_conn->isert_dev = isert_dev; INIT_LIST_HEAD(&isert_conn->rx_buf_list); INIT_LIST_HEAD(&isert_conn->tx_free_list); INIT_LIST_HEAD(&isert_conn->tx_busy_list); spin_lock_init(&isert_conn->tx_lock); spin_lock_init(&isert_conn->post_recv_lock); isert_conn->login_req_pdu = isert_rx_pdu_alloc(isert_conn, ISER_MAX_LOGIN_RDSL); if (unlikely(!isert_conn->login_req_pdu)) { pr_err("Failed to init login req rx pdu\n"); err = -ENOMEM; goto fail_login_req_pdu; } isert_conn->login_rsp_pdu = isert_tx_pdu_alloc(isert_conn, ISER_MAX_LOGIN_RDSL); if (unlikely(!isert_conn->login_rsp_pdu)) { pr_err("Failed to init login rsp tx pdu\n"); err = -ENOMEM; goto fail_login_rsp_pdu; } err = isert_conn_qp_create(isert_conn); if (unlikely(err)) goto fail_qp; err = isert_post_recv(isert_conn, &isert_conn->login_req_pdu->wr[0], 1); if (unlikely(err)) { pr_err("Failed to post recv login req rx buf, err:%d\n", err); goto fail_post_recv; } kref_init(&isert_conn->kref); TRACE_EXIT(); return isert_conn; fail_post_recv: cq = isert_conn->qp->recv_cq->cq_context; mutex_lock(&dev_list_mutex); isert_dev->cq_qps[cq->idx]--; mutex_unlock(&dev_list_mutex); isert_conn_qp_destroy(isert_conn); fail_qp: isert_pdu_free(isert_conn->login_rsp_pdu); fail_login_rsp_pdu: isert_pdu_free(isert_conn->login_req_pdu); fail_login_req_pdu: isert_conn_kfree(isert_conn); fail_alloc: module_put(THIS_MODULE); TRACE_EXIT_RES(err); return ERR_PTR(err); }