IB/iser: Initialize T10-PI resources
During connection establishment we also initialize T10-PI resources (QP, PI contexts) in order to support SCSI's protection operations. Signed-off-by: Alex Tabachnik <alext@mellanox.com> Signed-off-by: Sagi Grimberg <sagig@mellanox.com> Signed-off-by: Roland Dreier <roland@purestorage.com>
This commit is contained in:
parent
7f73384752
commit
6b5a8fb0d2
|
@ -134,6 +134,15 @@
|
||||||
ISER_MAX_TX_MISC_PDUS + \
|
ISER_MAX_TX_MISC_PDUS + \
|
||||||
ISER_MAX_RX_MISC_PDUS)
|
ISER_MAX_RX_MISC_PDUS)
|
||||||
|
|
||||||
|
/* Max registration work requests per command */
|
||||||
|
#define ISER_MAX_REG_WR_PER_CMD 5
|
||||||
|
|
||||||
|
/* For Signature we don't support DATAOUTs so no need to make room for them */
|
||||||
|
#define ISER_QP_SIG_MAX_REQ_DTOS (ISER_DEF_XMIT_CMDS_MAX * \
|
||||||
|
(1 + ISER_MAX_REG_WR_PER_CMD) + \
|
||||||
|
ISER_MAX_TX_MISC_PDUS + \
|
||||||
|
ISER_MAX_RX_MISC_PDUS)
|
||||||
|
|
||||||
#define ISER_VER 0x10
|
#define ISER_VER 0x10
|
||||||
#define ISER_WSV 0x08
|
#define ISER_WSV 0x08
|
||||||
#define ISER_RSV 0x04
|
#define ISER_RSV 0x04
|
||||||
|
@ -281,7 +290,16 @@ struct iser_device {
|
||||||
};
|
};
|
||||||
|
|
||||||
enum iser_reg_indicator {
|
enum iser_reg_indicator {
|
||||||
ISER_DATA_KEY_VALID = 1 << 0,
|
ISER_DATA_KEY_VALID = 1 << 0,
|
||||||
|
ISER_PROT_KEY_VALID = 1 << 1,
|
||||||
|
ISER_SIG_KEY_VALID = 1 << 2,
|
||||||
|
ISER_FASTREG_PROTECTED = 1 << 3,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct iser_pi_context {
|
||||||
|
struct ib_mr *prot_mr;
|
||||||
|
struct ib_fast_reg_page_list *prot_frpl;
|
||||||
|
struct ib_mr *sig_mr;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct fast_reg_descriptor {
|
struct fast_reg_descriptor {
|
||||||
|
@ -289,6 +307,7 @@ struct fast_reg_descriptor {
|
||||||
/* For fast registration - FRWR */
|
/* For fast registration - FRWR */
|
||||||
struct ib_mr *data_mr;
|
struct ib_mr *data_mr;
|
||||||
struct ib_fast_reg_page_list *data_frpl;
|
struct ib_fast_reg_page_list *data_frpl;
|
||||||
|
struct iser_pi_context *pi_ctx;
|
||||||
/* registration indicators container */
|
/* registration indicators container */
|
||||||
u8 reg_indicators;
|
u8 reg_indicators;
|
||||||
};
|
};
|
||||||
|
|
|
@ -275,7 +275,7 @@ void iser_free_fmr_pool(struct iser_conn *ib_conn)
|
||||||
|
|
||||||
static int
|
static int
|
||||||
iser_create_fastreg_desc(struct ib_device *ib_device, struct ib_pd *pd,
|
iser_create_fastreg_desc(struct ib_device *ib_device, struct ib_pd *pd,
|
||||||
struct fast_reg_descriptor *desc)
|
bool pi_enable, struct fast_reg_descriptor *desc)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
@ -294,12 +294,64 @@ iser_create_fastreg_desc(struct ib_device *ib_device, struct ib_pd *pd,
|
||||||
iser_err("Failed to allocate ib_fast_reg_mr err=%d\n", ret);
|
iser_err("Failed to allocate ib_fast_reg_mr err=%d\n", ret);
|
||||||
goto fast_reg_mr_failure;
|
goto fast_reg_mr_failure;
|
||||||
}
|
}
|
||||||
iser_info("Create fr_desc %p page_list %p\n",
|
|
||||||
desc, desc->data_frpl->page_list);
|
|
||||||
desc->reg_indicators |= ISER_DATA_KEY_VALID;
|
desc->reg_indicators |= ISER_DATA_KEY_VALID;
|
||||||
|
|
||||||
return 0;
|
if (pi_enable) {
|
||||||
|
struct ib_mr_init_attr mr_init_attr = {0};
|
||||||
|
struct iser_pi_context *pi_ctx = NULL;
|
||||||
|
|
||||||
|
desc->pi_ctx = kzalloc(sizeof(*desc->pi_ctx), GFP_KERNEL);
|
||||||
|
if (!desc->pi_ctx) {
|
||||||
|
iser_err("Failed to allocate pi context\n");
|
||||||
|
ret = -ENOMEM;
|
||||||
|
goto pi_ctx_alloc_failure;
|
||||||
|
}
|
||||||
|
pi_ctx = desc->pi_ctx;
|
||||||
|
|
||||||
|
pi_ctx->prot_frpl = ib_alloc_fast_reg_page_list(ib_device,
|
||||||
|
ISCSI_ISER_SG_TABLESIZE);
|
||||||
|
if (IS_ERR(pi_ctx->prot_frpl)) {
|
||||||
|
ret = PTR_ERR(pi_ctx->prot_frpl);
|
||||||
|
iser_err("Failed to allocate prot frpl ret=%d\n",
|
||||||
|
ret);
|
||||||
|
goto prot_frpl_failure;
|
||||||
|
}
|
||||||
|
|
||||||
|
pi_ctx->prot_mr = ib_alloc_fast_reg_mr(pd,
|
||||||
|
ISCSI_ISER_SG_TABLESIZE + 1);
|
||||||
|
if (IS_ERR(pi_ctx->prot_mr)) {
|
||||||
|
ret = PTR_ERR(pi_ctx->prot_mr);
|
||||||
|
iser_err("Failed to allocate prot frmr ret=%d\n",
|
||||||
|
ret);
|
||||||
|
goto prot_mr_failure;
|
||||||
|
}
|
||||||
|
desc->reg_indicators |= ISER_PROT_KEY_VALID;
|
||||||
|
|
||||||
|
mr_init_attr.max_reg_descriptors = 2;
|
||||||
|
mr_init_attr.flags |= IB_MR_SIGNATURE_EN;
|
||||||
|
pi_ctx->sig_mr = ib_create_mr(pd, &mr_init_attr);
|
||||||
|
if (IS_ERR(pi_ctx->sig_mr)) {
|
||||||
|
ret = PTR_ERR(pi_ctx->sig_mr);
|
||||||
|
iser_err("Failed to allocate signature enabled mr err=%d\n",
|
||||||
|
ret);
|
||||||
|
goto sig_mr_failure;
|
||||||
|
}
|
||||||
|
desc->reg_indicators |= ISER_SIG_KEY_VALID;
|
||||||
|
}
|
||||||
|
desc->reg_indicators &= ~ISER_FASTREG_PROTECTED;
|
||||||
|
|
||||||
|
iser_info("Create fr_desc %p page_list %p\n",
|
||||||
|
desc, desc->data_frpl->page_list);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
sig_mr_failure:
|
||||||
|
ib_dereg_mr(desc->pi_ctx->prot_mr);
|
||||||
|
prot_mr_failure:
|
||||||
|
ib_free_fast_reg_page_list(desc->pi_ctx->prot_frpl);
|
||||||
|
prot_frpl_failure:
|
||||||
|
kfree(desc->pi_ctx);
|
||||||
|
pi_ctx_alloc_failure:
|
||||||
|
ib_dereg_mr(desc->data_mr);
|
||||||
fast_reg_mr_failure:
|
fast_reg_mr_failure:
|
||||||
ib_free_fast_reg_page_list(desc->data_frpl);
|
ib_free_fast_reg_page_list(desc->data_frpl);
|
||||||
|
|
||||||
|
@ -320,15 +372,15 @@ int iser_create_fastreg_pool(struct iser_conn *ib_conn, unsigned cmds_max)
|
||||||
INIT_LIST_HEAD(&ib_conn->fastreg.pool);
|
INIT_LIST_HEAD(&ib_conn->fastreg.pool);
|
||||||
ib_conn->fastreg.pool_size = 0;
|
ib_conn->fastreg.pool_size = 0;
|
||||||
for (i = 0; i < cmds_max; i++) {
|
for (i = 0; i < cmds_max; i++) {
|
||||||
desc = kmalloc(sizeof(*desc), GFP_KERNEL);
|
desc = kzalloc(sizeof(*desc), GFP_KERNEL);
|
||||||
if (!desc) {
|
if (!desc) {
|
||||||
iser_err("Failed to allocate a new fast_reg descriptor\n");
|
iser_err("Failed to allocate a new fast_reg descriptor\n");
|
||||||
ret = -ENOMEM;
|
ret = -ENOMEM;
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = iser_create_fastreg_desc(device->ib_device,
|
ret = iser_create_fastreg_desc(device->ib_device, device->pd,
|
||||||
device->pd, desc);
|
ib_conn->pi_support, desc);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
iser_err("Failed to create fastreg descriptor err=%d\n",
|
iser_err("Failed to create fastreg descriptor err=%d\n",
|
||||||
ret);
|
ret);
|
||||||
|
@ -364,6 +416,12 @@ void iser_free_fastreg_pool(struct iser_conn *ib_conn)
|
||||||
list_del(&desc->list);
|
list_del(&desc->list);
|
||||||
ib_free_fast_reg_page_list(desc->data_frpl);
|
ib_free_fast_reg_page_list(desc->data_frpl);
|
||||||
ib_dereg_mr(desc->data_mr);
|
ib_dereg_mr(desc->data_mr);
|
||||||
|
if (desc->pi_ctx) {
|
||||||
|
ib_free_fast_reg_page_list(desc->pi_ctx->prot_frpl);
|
||||||
|
ib_dereg_mr(desc->pi_ctx->prot_mr);
|
||||||
|
ib_destroy_mr(desc->pi_ctx->sig_mr);
|
||||||
|
kfree(desc->pi_ctx);
|
||||||
|
}
|
||||||
kfree(desc);
|
kfree(desc);
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
|
@ -405,12 +463,17 @@ static int iser_create_ib_conn_res(struct iser_conn *ib_conn)
|
||||||
init_attr.qp_context = (void *)ib_conn;
|
init_attr.qp_context = (void *)ib_conn;
|
||||||
init_attr.send_cq = device->tx_cq[min_index];
|
init_attr.send_cq = device->tx_cq[min_index];
|
||||||
init_attr.recv_cq = device->rx_cq[min_index];
|
init_attr.recv_cq = device->rx_cq[min_index];
|
||||||
init_attr.cap.max_send_wr = ISER_QP_MAX_REQ_DTOS;
|
|
||||||
init_attr.cap.max_recv_wr = ISER_QP_MAX_RECV_DTOS;
|
init_attr.cap.max_recv_wr = ISER_QP_MAX_RECV_DTOS;
|
||||||
init_attr.cap.max_send_sge = 2;
|
init_attr.cap.max_send_sge = 2;
|
||||||
init_attr.cap.max_recv_sge = 1;
|
init_attr.cap.max_recv_sge = 1;
|
||||||
init_attr.sq_sig_type = IB_SIGNAL_REQ_WR;
|
init_attr.sq_sig_type = IB_SIGNAL_REQ_WR;
|
||||||
init_attr.qp_type = IB_QPT_RC;
|
init_attr.qp_type = IB_QPT_RC;
|
||||||
|
if (ib_conn->pi_support) {
|
||||||
|
init_attr.cap.max_send_wr = ISER_QP_SIG_MAX_REQ_DTOS;
|
||||||
|
init_attr.create_flags |= IB_QP_CREATE_SIGNATURE_EN;
|
||||||
|
} else {
|
||||||
|
init_attr.cap.max_send_wr = ISER_QP_MAX_REQ_DTOS;
|
||||||
|
}
|
||||||
|
|
||||||
ret = rdma_create_qp(ib_conn->cma_id, device->pd, &init_attr);
|
ret = rdma_create_qp(ib_conn->cma_id, device->pd, &init_attr);
|
||||||
if (ret)
|
if (ret)
|
||||||
|
|
Loading…
Reference in New Issue