Exemple #1
0
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;
}
Exemple #2
0
/* 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);
}
Exemple #3
0
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;
}
Exemple #4
0
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);
}
Exemple #5
0
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);
}