Discussion:
[PATCH 0/7] Signature feature update
Sagi Grimberg
2014-08-13 16:54:28 UTC
Permalink
Lately MKP posted some block data integrity updates over Linux-scsi (see https://lwn.net/Articles/606820/).
These changes follow DIX draft 1.1 (see see https://oss.oracle.com/~mkp/docs/dix-1.1.pdf).
The draft updates the execution parameters passed from SCSI midlayer
to the LLDs with respect to data integrity feature.

This set updates signature feature accordingly.

Once Martin's patches will land mainline I'll also modify iSER
to take relevant parameters from the scsi command structure.

This set consists of:
- Patches #1, #2, #3 are minor fixes
- Patch #4 is a preparation patch
- Patches #5, #6 are code centralization
- Patch #7 is an API update (modifies ib_core, mlx5, iser, isert)

Roland, there are some patches in iser-target code, but I'm pretty
sure that they can go from your tree. Right Nic?

Sagi Grimberg (7):
IB/mlx5: Use enumerations for PI copy mask
IB/iser: Remove redundant assignment
IB/iser: Set IP_CSUM as default guard type
IB/mlx5: Use extended internal signature layout
IB/iser: Centralize ib_sig_domain settings
Target/iser: Centralize ib_sig_domain setting
IB/mlx5, iser, isert: Add Signature API additions

drivers/infiniband/hw/mlx5/qp.c | 134 ++++++++++++-----------------
drivers/infiniband/ulp/iser/iscsi_iser.c | 4 +-
drivers/infiniband/ulp/iser/iser_memory.c | 79 ++++++++---------
drivers/infiniband/ulp/isert/ib_isert.c | 65 ++++++---------
include/linux/mlx5/qp.h | 35 ++++++--
include/rdma/ib_verbs.h | 32 +++----
6 files changed, 164 insertions(+), 185 deletions(-)

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-***@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Sagi Grimberg
2014-08-13 16:54:29 UTC
Permalink
In case input and output space parameters match, we can
use a copy mask from input and output space. Use enums
for those.

Signed-off-by: Sagi Grimberg <***@mellanox.com>
---
drivers/infiniband/hw/mlx5/qp.c | 6 +++---
include/linux/mlx5/qp.h | 3 +++
2 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c
index e847ecf..af3b7fa 100644
--- a/drivers/infiniband/hw/mlx5/qp.c
+++ b/drivers/infiniband/hw/mlx5/qp.c
@@ -2095,11 +2095,11 @@ static int mlx5_set_bsf(struct ib_mr *sig_mr,
/* Same block structure */
basic->bsf_size_sbs = 1 << 4;
if (mem->sig.dif.bg_type == wire->sig.dif.bg_type)
- basic->wire.copy_byte_mask |= 0xc0;
+ basic->wire.copy_byte_mask |= MLX5_CPY_GRD_MASK;
if (mem->sig.dif.app_tag == wire->sig.dif.app_tag)
- basic->wire.copy_byte_mask |= 0x30;
+ basic->wire.copy_byte_mask |= MLX5_CPY_APP_MASK;
if (mem->sig.dif.ref_tag == wire->sig.dif.ref_tag)
- basic->wire.copy_byte_mask |= 0x0f;
+ basic->wire.copy_byte_mask |= MLX5_CPY_REF_MASK;
} else
basic->wire.bs_selector = bs_selector(wire->sig.dif.pi_interval);

diff --git a/include/linux/mlx5/qp.h b/include/linux/mlx5/qp.h
index 9709b30..4aa5634 100644
--- a/include/linux/mlx5/qp.h
+++ b/include/linux/mlx5/qp.h
@@ -40,6 +40,9 @@
#define MLX5_SIG_WQE_SIZE (MLX5_SEND_WQE_BB * 5)
#define MLX5_DIF_SIZE 8
#define MLX5_STRIDE_BLOCK_OP 0x400
+#define MLX5_CPY_GRD_MASK 0xc0
+#define MLX5_CPY_APP_MASK 0x30
+#define MLX5_CPY_REF_MASK 0x0f

enum mlx5_qp_optpar {
MLX5_QP_OPTPAR_ALT_ADDR_PATH = 1 << 0,
--
1.7.1
Sagi Grimberg
2014-08-13 16:54:30 UTC
Permalink
We clear the struct before - no need to do 0 assignment.

Signed-off-by: Sagi Grimberg <***@mellanox.com>
---
drivers/infiniband/ulp/iser/iser_memory.c | 1 -
1 files changed, 0 insertions(+), 1 deletions(-)

diff --git a/drivers/infiniband/ulp/iser/iser_memory.c b/drivers/infiniband/ulp/iser/iser_memory.c
index 47acd3a..bf0d1cc 100644
--- a/drivers/infiniband/ulp/iser/iser_memory.c
+++ b/drivers/infiniband/ulp/iser/iser_memory.c
@@ -510,7 +510,6 @@ iser_set_prot_checks(struct scsi_cmnd *sc, u8 *mask)
{
switch (scsi_get_prot_type(sc)) {
case SCSI_PROT_DIF_TYPE0:
- *mask = 0x0;
break;
case SCSI_PROT_DIF_TYPE1:
case SCSI_PROT_DIF_TYPE2:
--
1.7.1
Sagi Grimberg
2014-08-13 16:54:31 UTC
Permalink
In the future this will be a per-command parameter so we
can lose it, but in the mean time IP_CSUM is a lot lighter
for SW layers to compute, set it as default.

Signed-off-by: Sagi Grimberg <***@mellanox.com>
---
drivers/infiniband/ulp/iser/iscsi_iser.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c
index eb79739..d42658f 100644
--- a/drivers/infiniband/ulp/iser/iscsi_iser.c
+++ b/drivers/infiniband/ulp/iser/iscsi_iser.c
@@ -83,7 +83,7 @@ module_param_named(max_lun, iscsi_max_lun, uint, S_IRUGO);

int iser_debug_level = 0;
bool iser_pi_enable = false;
-int iser_pi_guard = 0;
+int iser_pi_guard = 1;

MODULE_DESCRIPTION("iSER (iSCSI Extensions for RDMA) Datamover");
MODULE_LICENSE("Dual BSD/GPL");
@@ -97,7 +97,7 @@ module_param_named(pi_enable, iser_pi_enable, bool, 0644);
MODULE_PARM_DESC(pi_enable, "Enable T10-PI offload support (default:disabled)");

module_param_named(pi_guard, iser_pi_guard, int, 0644);
-MODULE_PARM_DESC(pi_guard, "T10-PI guard_type, 0:CRC|1:IP_CSUM (default:CRC)");
+MODULE_PARM_DESC(pi_guard, "T10-PI guard_type, 0:CRC|1:IP_CSUM (default:IP_CSUM)");

static struct workqueue_struct *release_wq;
struct iser_global ig;
--
1.7.1
Sagi Grimberg
2014-08-13 16:54:35 UTC
Permalink
Expose more signature setting parameters. We modify the signature
API to allow usage of some new execution parameters relevant to
data integrity feature.

This patch modifies ib_sig_domain structure by:
- Deprecate DIF type in signature API (operation will
be determined by the parameters alone, no DIF type awareness)
- Add APPTAG check bitmask (for input domain)
- Add REFTAG remap (increment) flag for each domain
- Add APPTAG/REFTAG escape options for each domain

The mlx5 driver is modified to follow the new parameters in
HW signature setup.

At the moment the callers (iser/isert) hard-code new parameters
(by DIF type). In the future, callers will retrieve them from the
scsi command structure.

Signed-off-by: Sagi Grimberg <sagig-VPRAkNaXOzVWk0Htik3J/***@public.gmane.org>
---
drivers/infiniband/hw/mlx5/qp.c | 104 ++++++++++++----------------
drivers/infiniband/ulp/iser/iser_memory.c | 50 +++++++-------
drivers/infiniband/ulp/isert/ib_isert.c | 40 ++++-------
include/rdma/ib_verbs.h | 32 ++++-----
4 files changed, 97 insertions(+), 129 deletions(-)

diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c
index 8377816..b71c2bc 100644
--- a/drivers/infiniband/hw/mlx5/qp.c
+++ b/drivers/infiniband/hw/mlx5/qp.c
@@ -2020,50 +2020,31 @@ static u8 bs_selector(int block_size)
}
}

-static int mlx5_fill_inl_bsf(struct ib_sig_domain *domain,
- struct mlx5_bsf_inl *inl)
+static void mlx5_fill_inl_bsf(struct ib_sig_domain *domain,
+ struct mlx5_bsf_inl *inl)
{
/* Valid inline section and allow BSF refresh */
inl->vld_refresh = cpu_to_be16(MLX5_BSF_INL_VALID |
MLX5_BSF_REFRESH_DIF);
inl->dif_apptag = cpu_to_be16(domain->sig.dif.app_tag);
inl->dif_reftag = cpu_to_be32(domain->sig.dif.ref_tag);
+ /* repeating block */
+ inl->rp_inv_seed = MLX5_BSF_REPEAT_BLOCK;
+ inl->sig_type = domain->sig.dif.bg_type == IB_T10DIF_CRC ?
+ MLX5_DIF_CRC : MLX5_DIF_IPCS;

- switch (domain->sig.dif.type) {
- case IB_T10DIF_NONE:
- /* No DIF */
- break;
- case IB_T10DIF_TYPE1: /* Fall through */
- case IB_T10DIF_TYPE2:
- inl->sig_type = domain->sig.dif.bg_type == IB_T10DIF_CRC ?
- MLX5_DIF_CRC : MLX5_DIF_IPCS;
- /*
- * increment reftag and don't check if
- * apptag=0xffff and reftag=0xffffffff
- */
- inl->dif_inc_ref_guard_check = MLX5_BSF_INC_REFTAG |
- MLX5_BSF_APPREF_ESCAPE;
- inl->dif_app_bitmask_check = 0xffff;
- /* repeating block */
- inl->rp_inv_seed = MLX5_BSF_REPEAT_BLOCK;
- break;
- case IB_T10DIF_TYPE3:
- inl->sig_type = domain->sig.dif.bg_type == IB_T10DIF_CRC ?
- MLX5_DIF_CRC : MLX5_DIF_IPCS;
- /*
- * Don't inc reftag and don't check if
- * apptag=0xffff and reftag=0xffffffff
- */
- inl->dif_inc_ref_guard_check = MLX5_BSF_APPREF_ESCAPE;
- inl->dif_app_bitmask_check = 0xffff;
- /* Repeating block */
- inl->rp_inv_seed = MLX5_BSF_REPEAT_BLOCK;
- break;
- default:
- return -EINVAL;
+ if (domain->sig.dif.ref_remap)
+ inl->dif_inc_ref_guard_check |= MLX5_BSF_INC_REFTAG;
+
+ if (domain->sig.dif.app_escape) {
+ if (domain->sig.dif.ref_escape)
+ inl->dif_inc_ref_guard_check |= MLX5_BSF_APPREF_ESCAPE;
+ else
+ inl->dif_inc_ref_guard_check |= MLX5_BSF_APPTAG_ESCAPE;
}

- return 0;
+ inl->dif_app_bitmask_check =
+ cpu_to_be16(domain->sig.dif.apptag_check_mask);
}

static int mlx5_set_bsf(struct ib_mr *sig_mr,
@@ -2074,20 +2055,35 @@ static int mlx5_set_bsf(struct ib_mr *sig_mr,
struct mlx5_bsf_basic *basic = &bsf->basic;
struct ib_sig_domain *mem = &sig_attrs->mem;
struct ib_sig_domain *wire = &sig_attrs->wire;
- int ret;

memset(bsf, 0, sizeof(*bsf));
+
+ /* Basic + Extended + Inline */
+ basic->bsf_size_sbs = 1 << 7;
+ /* Input domain check byte mask */
+ basic->check_byte_mask = sig_attrs->check_mask;
+ basic->raw_data_size = cpu_to_be32(data_size);
+
+ /* Memory domain */
switch (sig_attrs->mem.sig_type) {
+ case IB_SIG_TYPE_NONE:
+ break;
case IB_SIG_TYPE_T10_DIF:
- if (sig_attrs->wire.sig_type != IB_SIG_TYPE_T10_DIF)
- return -EINVAL;
+ basic->mem.bs_selector = bs_selector(mem->sig.dif.pi_interval);
+ basic->m_bfs_psv = cpu_to_be32(msig->psv_memory.psv_idx);
+ mlx5_fill_inl_bsf(mem, &bsf->m_inl);
+ break;
+ default:
+ return -EINVAL;
+ }

- /* Basic + Extended + Inline */
- basic->bsf_size_sbs = 1 << 7;
- /* Input domain check byte mask */
- basic->check_byte_mask = sig_attrs->check_mask;
+ /* Wire domain */
+ switch (sig_attrs->wire.sig_type) {
+ case IB_SIG_TYPE_NONE:
+ break;
+ case IB_SIG_TYPE_T10_DIF:
if (mem->sig.dif.pi_interval == wire->sig.dif.pi_interval &&
- mem->sig.dif.type == wire->sig.dif.type) {
+ mem->sig_type == wire->sig_type) {
/* Same block structure */
basic->bsf_size_sbs |= 1 << 4;
if (mem->sig.dif.bg_type == wire->sig.dif.bg_type)
@@ -2099,20 +2095,9 @@ static int mlx5_set_bsf(struct ib_mr *sig_mr,
} else
basic->wire.bs_selector = bs_selector(wire->sig.dif.pi_interval);

- basic->mem.bs_selector = bs_selector(mem->sig.dif.pi_interval);
- basic->raw_data_size = cpu_to_be32(data_size);
- basic->m_bfs_psv = cpu_to_be32(msig->psv_memory.psv_idx);
basic->w_bfs_psv = cpu_to_be32(msig->psv_wire.psv_idx);
-
- ret = mlx5_fill_inl_bsf(wire, &bsf->w_inl);
- if (ret)
- return -EINVAL;
-
- ret = mlx5_fill_inl_bsf(mem, &bsf->m_inl);
- if (ret)
- return -EINVAL;
+ mlx5_fill_inl_bsf(wire, &bsf->w_inl);
break;
-
default:
return -EINVAL;
}
@@ -2311,20 +2296,21 @@ static int set_psv_wr(struct ib_sig_domain *domain,
memset(psv_seg, 0, sizeof(*psv_seg));
psv_seg->psv_num = cpu_to_be32(psv_idx);
switch (domain->sig_type) {
+ case IB_SIG_TYPE_NONE:
+ break;
case IB_SIG_TYPE_T10_DIF:
psv_seg->transient_sig = cpu_to_be32(domain->sig.dif.bg << 16 |
domain->sig.dif.app_tag);
psv_seg->ref_tag = cpu_to_be32(domain->sig.dif.ref_tag);
-
- *seg += sizeof(*psv_seg);
- *size += sizeof(*psv_seg) / 16;
break;
-
default:
pr_err("Bad signature type given.\n");
return 1;
}

+ *seg += sizeof(*psv_seg);
+ *size += sizeof(*psv_seg) / 16;
+
return 0;
}

diff --git a/drivers/infiniband/ulp/iser/iser_memory.c b/drivers/infiniband/ulp/iser/iser_memory.c
index 5842d50..df65309 100644
--- a/drivers/infiniband/ulp/iser/iser_memory.c
+++ b/drivers/infiniband/ulp/iser/iser_memory.c
@@ -440,51 +440,44 @@ int iser_reg_rdma_mem_fmr(struct iscsi_iser_task *iser_task,
return 0;
}

-static inline enum ib_t10_dif_type
-scsi2ib_prot_type(unsigned char prot_type)
-{
- switch (prot_type) {
- case SCSI_PROT_DIF_TYPE0:
- return IB_T10DIF_NONE;
- case SCSI_PROT_DIF_TYPE1:
- return IB_T10DIF_TYPE1;
- case SCSI_PROT_DIF_TYPE2:
- return IB_T10DIF_TYPE2;
- case SCSI_PROT_DIF_TYPE3:
- return IB_T10DIF_TYPE3;
- default:
- return IB_T10DIF_NONE;
- }
-}
-
static inline void
iser_set_dif_domain(struct scsi_cmnd *sc, struct ib_sig_attrs *sig_attrs,
struct ib_sig_domain *domain)
{
- unsigned char scsi_ptype = scsi_get_prot_type(sc);
-
- domain->sig.dif.type = scsi2ib_prot_type(scsi_ptype);
+ domain->sig_type = IB_SIG_TYPE_T10_DIF;
domain->sig.dif.pi_interval = sc->device->sector_size;
domain->sig.dif.ref_tag = scsi_get_lba(sc) & 0xffffffff;
+ /*
+ * At the moment we hard code those, but in the future
+ * we will take them from sc.
+ */
+ domain->sig.dif.apptag_check_mask = 0xffff;
+ domain->sig.dif.app_escape = true;
+ domain->sig.dif.ref_escape = true;
+ if (scsi_get_prot_type(sc) == SCSI_PROT_DIF_TYPE1 ||
+ scsi_get_prot_type(sc) == SCSI_PROT_DIF_TYPE2)
+ domain->sig.dif.ref_remap = true;
};

static int
iser_set_sig_attrs(struct scsi_cmnd *sc, struct ib_sig_attrs *sig_attrs)
{
- sig_attrs->mem.sig_type = IB_SIG_TYPE_T10_DIF;
- sig_attrs->wire.sig_type = IB_SIG_TYPE_T10_DIF;
-
switch (scsi_get_prot_op(sc)) {
case SCSI_PROT_WRITE_INSERT:
case SCSI_PROT_READ_STRIP:
- sig_attrs->mem.sig.dif.type = IB_T10DIF_NONE;
+ sig_attrs->mem.sig_type = IB_SIG_TYPE_NONE;
iser_set_dif_domain(sc, sig_attrs, &sig_attrs->wire);
sig_attrs->wire.sig.dif.bg_type = IB_T10DIF_CRC;
break;
case SCSI_PROT_READ_INSERT:
case SCSI_PROT_WRITE_STRIP:
- sig_attrs->wire.sig.dif.type = IB_T10DIF_NONE;
+ sig_attrs->wire.sig_type = IB_SIG_TYPE_NONE;
iser_set_dif_domain(sc, sig_attrs, &sig_attrs->mem);
+ /*
+ * At the moment we use this modparam to tell what is
+ * the memory bg_type, in the future we will take it
+ * from sc.
+ */
sig_attrs->mem.sig.dif.bg_type = iser_pi_guard ? IB_T10DIF_CSUM :
IB_T10DIF_CRC;
break;
@@ -493,6 +486,11 @@ iser_set_sig_attrs(struct scsi_cmnd *sc, struct ib_sig_attrs *sig_attrs)
iser_set_dif_domain(sc, sig_attrs, &sig_attrs->wire);
sig_attrs->wire.sig.dif.bg_type = IB_T10DIF_CRC;
iser_set_dif_domain(sc, sig_attrs, &sig_attrs->mem);
+ /*
+ * At the moment we use this modparam to tell what is
+ * the memory bg_type, in the future we will take it
+ * from sc.
+ */
sig_attrs->mem.sig.dif.bg_type = iser_pi_guard ? IB_T10DIF_CSUM :
IB_T10DIF_CRC;
break;
@@ -501,10 +499,10 @@ iser_set_sig_attrs(struct scsi_cmnd *sc, struct ib_sig_attrs *sig_attrs)
scsi_get_prot_op(sc));
return -EINVAL;
}
+
return 0;
}

-
static int
iser_set_prot_checks(struct scsi_cmnd *sc, u8 *mask)
{
diff --git a/drivers/infiniband/ulp/isert/ib_isert.c b/drivers/infiniband/ulp/isert/ib_isert.c
index 7309275..0bea577 100644
--- a/drivers/infiniband/ulp/isert/ib_isert.c
+++ b/drivers/infiniband/ulp/isert/ib_isert.c
@@ -2609,51 +2609,39 @@ isert_fast_reg_mr(struct isert_conn *isert_conn,
return ret;
}

-static inline enum ib_t10_dif_type
-se2ib_prot_type(enum target_prot_type prot_type)
-{
- switch (prot_type) {
- case TARGET_DIF_TYPE0_PROT:
- return IB_T10DIF_NONE;
- case TARGET_DIF_TYPE1_PROT:
- return IB_T10DIF_TYPE1;
- case TARGET_DIF_TYPE2_PROT:
- return IB_T10DIF_TYPE2;
- case TARGET_DIF_TYPE3_PROT:
- return IB_T10DIF_TYPE3;
- default:
- return IB_T10DIF_NONE;
- }
-}
-
static inline void
isert_set_dif_domain(struct se_cmd *se_cmd, struct ib_sig_attrs *sig_attrs,
struct ib_sig_domain *domain)
{
- enum ib_t10_dif_type ib_prot_type = se2ib_prot_type(se_cmd->prot_type);
-
- domain->sig.dif.type = ib_prot_type;
+ domain->sig_type = IB_SIG_TYPE_T10_DIF;
domain->sig.dif.bg_type = IB_T10DIF_CRC;
domain->sig.dif.pi_interval = se_cmd->se_dev->dev_attrib.block_size;
domain->sig.dif.ref_tag = se_cmd->reftag_seed;
+ /*
+ * At the moment we hard code those, but if in the future
+ * the target core would like to use it, we will take it
+ * from se_cmd.
+ */
+ domain->sig.dif.apptag_check_mask = 0xffff;
+ domain->sig.dif.app_escape = true;
+ domain->sig.dif.ref_escape = true;
+ if (se_cmd->prot_type == TARGET_DIF_TYPE1_PROT ||
+ se_cmd->prot_type == TARGET_DIF_TYPE2_PROT)
+ domain->sig.dif.ref_remap = true;
};

static int
isert_set_sig_attrs(struct se_cmd *se_cmd, struct ib_sig_attrs *sig_attrs)
{
-
- sig_attrs->mem.sig_type = IB_SIG_TYPE_T10_DIF;
- sig_attrs->wire.sig_type = IB_SIG_TYPE_T10_DIF;
-
switch (se_cmd->prot_op) {
case TARGET_PROT_DIN_INSERT:
case TARGET_PROT_DOUT_STRIP:
- sig_attrs->mem.sig.dif.type = IB_T10DIF_NONE;
+ sig_attrs->mem.sig_type = IB_SIG_TYPE_NONE;
isert_set_dif_domain(se_cmd, sig_attrs, &sig_attrs->wire);
break;
case TARGET_PROT_DOUT_INSERT:
case TARGET_PROT_DIN_STRIP:
- sig_attrs->wire.sig.dif.type = IB_T10DIF_NONE;
+ sig_attrs->wire.sig_type = IB_SIG_TYPE_NONE;
isert_set_dif_domain(se_cmd, sig_attrs, &sig_attrs->mem);
break;
case TARGET_PROT_DIN_PASS:
diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h
index 7ccef34..d3e2462 100644
--- a/include/rdma/ib_verbs.h
+++ b/include/rdma/ib_verbs.h
@@ -491,20 +491,14 @@ struct ib_mr_init_attr {
u32 flags;
};

-enum ib_signature_type {
- IB_SIG_TYPE_T10_DIF,
-};
-
/**
- * T10-DIF Signature types
- * T10-DIF types are defined by SCSI
- * specifications.
+ * Signature types
+ * IB_SIG_TYPE_NONE: Unprotected.
+ * IB_SIG_TYPE_T10_DIF: Type T10-DIF
*/
-enum ib_t10_dif_type {
- IB_T10DIF_NONE,
- IB_T10DIF_TYPE1,
- IB_T10DIF_TYPE2,
- IB_T10DIF_TYPE3
+enum ib_signature_type {
+ IB_SIG_TYPE_NONE,
+ IB_SIG_TYPE_T10_DIF,
};

/**
@@ -520,24 +514,26 @@ enum ib_t10_dif_bg_type {
/**
* struct ib_t10_dif_domain - Parameters specific for T10-DIF
* domain.
- * @type: T10-DIF type (0|1|2|3)
* @bg_type: T10-DIF block guard type (CRC|CSUM)
* @pi_interval: protection information interval.
* @bg: seed of guard computation.
* @app_tag: application tag of guard block
* @ref_tag: initial guard block reference tag.
- * @type3_inc_reftag: T10-DIF type 3 does not state
- * about the reference tag, it is the user
- * choice to increment it or not.
+ * @ref_remap: Indicate wethear the reftag increments each block
+ * @app_escape: Indicate to skip block check if apptag=0xffff
+ * @ref_escape: Indicate to skip block check if reftag=0xffffffff
+ * @apptag_check_mask: check bitmask of application tag.
*/
struct ib_t10_dif_domain {
- enum ib_t10_dif_type type;
enum ib_t10_dif_bg_type bg_type;
u16 pi_interval;
u16 bg;
u16 app_tag;
u32 ref_tag;
- bool type3_inc_reftag;
+ bool ref_remap;
+ bool app_escape;
+ bool ref_escape;
+ u16 apptag_check_mask;
};

/**
--
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-***@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Sagi Grimberg
2014-08-13 16:54:32 UTC
Permalink
Rather than using the basic BSF layout which utilizes a pre-configured
signature settings (sufficient for current DIF implementation), we use
the extended BSF layout to expose advanced signature settings. These
settings will also be exposed to the user later.

Signed-off-by: Sagi Grimberg <***@mellanox.com>
---
drivers/infiniband/hw/mlx5/qp.c | 80 ++++++++++++++++++---------------------
include/linux/mlx5/qp.h | 32 ++++++++++++----
2 files changed, 61 insertions(+), 51 deletions(-)

diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c
index af3b7fa..8377816 100644
--- a/drivers/infiniband/hw/mlx5/qp.c
+++ b/drivers/infiniband/hw/mlx5/qp.c
@@ -2020,53 +2020,47 @@ static u8 bs_selector(int block_size)
}
}

-static int format_selector(struct ib_sig_attrs *attr,
- struct ib_sig_domain *domain,
- int *selector)
+static int mlx5_fill_inl_bsf(struct ib_sig_domain *domain,
+ struct mlx5_bsf_inl *inl)
{
-
-#define FORMAT_DIF_NONE 0
-#define FORMAT_DIF_CRC_INC 8
-#define FORMAT_DIF_CRC_NO_INC 12
-#define FORMAT_DIF_CSUM_INC 13
-#define FORMAT_DIF_CSUM_NO_INC 14
+ /* Valid inline section and allow BSF refresh */
+ inl->vld_refresh = cpu_to_be16(MLX5_BSF_INL_VALID |
+ MLX5_BSF_REFRESH_DIF);
+ inl->dif_apptag = cpu_to_be16(domain->sig.dif.app_tag);
+ inl->dif_reftag = cpu_to_be32(domain->sig.dif.ref_tag);

switch (domain->sig.dif.type) {
case IB_T10DIF_NONE:
/* No DIF */
- *selector = FORMAT_DIF_NONE;
break;
case IB_T10DIF_TYPE1: /* Fall through */
case IB_T10DIF_TYPE2:
- switch (domain->sig.dif.bg_type) {
- case IB_T10DIF_CRC:
- *selector = FORMAT_DIF_CRC_INC;
- break;
- case IB_T10DIF_CSUM:
- *selector = FORMAT_DIF_CSUM_INC;
- break;
- default:
- return 1;
- }
+ inl->sig_type = domain->sig.dif.bg_type == IB_T10DIF_CRC ?
+ MLX5_DIF_CRC : MLX5_DIF_IPCS;
+ /*
+ * increment reftag and don't check if
+ * apptag=0xffff and reftag=0xffffffff
+ */
+ inl->dif_inc_ref_guard_check = MLX5_BSF_INC_REFTAG |
+ MLX5_BSF_APPREF_ESCAPE;
+ inl->dif_app_bitmask_check = 0xffff;
+ /* repeating block */
+ inl->rp_inv_seed = MLX5_BSF_REPEAT_BLOCK;
break;
case IB_T10DIF_TYPE3:
- switch (domain->sig.dif.bg_type) {
- case IB_T10DIF_CRC:
- *selector = domain->sig.dif.type3_inc_reftag ?
- FORMAT_DIF_CRC_INC :
- FORMAT_DIF_CRC_NO_INC;
- break;
- case IB_T10DIF_CSUM:
- *selector = domain->sig.dif.type3_inc_reftag ?
- FORMAT_DIF_CSUM_INC :
- FORMAT_DIF_CSUM_NO_INC;
- break;
- default:
- return 1;
- }
+ inl->sig_type = domain->sig.dif.bg_type == IB_T10DIF_CRC ?
+ MLX5_DIF_CRC : MLX5_DIF_IPCS;
+ /*
+ * Don't inc reftag and don't check if
+ * apptag=0xffff and reftag=0xffffffff
+ */
+ inl->dif_inc_ref_guard_check = MLX5_BSF_APPREF_ESCAPE;
+ inl->dif_app_bitmask_check = 0xffff;
+ /* Repeating block */
+ inl->rp_inv_seed = MLX5_BSF_REPEAT_BLOCK;
break;
default:
- return 1;
+ return -EINVAL;
}

return 0;
@@ -2080,7 +2074,7 @@ static int mlx5_set_bsf(struct ib_mr *sig_mr,
struct mlx5_bsf_basic *basic = &bsf->basic;
struct ib_sig_domain *mem = &sig_attrs->mem;
struct ib_sig_domain *wire = &sig_attrs->wire;
- int ret, selector;
+ int ret;

memset(bsf, 0, sizeof(*bsf));
switch (sig_attrs->mem.sig_type) {
@@ -2088,12 +2082,14 @@ static int mlx5_set_bsf(struct ib_mr *sig_mr,
if (sig_attrs->wire.sig_type != IB_SIG_TYPE_T10_DIF)
return -EINVAL;

+ /* Basic + Extended + Inline */
+ basic->bsf_size_sbs = 1 << 7;
/* Input domain check byte mask */
basic->check_byte_mask = sig_attrs->check_mask;
if (mem->sig.dif.pi_interval == wire->sig.dif.pi_interval &&
mem->sig.dif.type == wire->sig.dif.type) {
/* Same block structure */
- basic->bsf_size_sbs = 1 << 4;
+ basic->bsf_size_sbs |= 1 << 4;
if (mem->sig.dif.bg_type == wire->sig.dif.bg_type)
basic->wire.copy_byte_mask |= MLX5_CPY_GRD_MASK;
if (mem->sig.dif.app_tag == wire->sig.dif.app_tag)
@@ -2105,18 +2101,16 @@ static int mlx5_set_bsf(struct ib_mr *sig_mr,

basic->mem.bs_selector = bs_selector(mem->sig.dif.pi_interval);
basic->raw_data_size = cpu_to_be32(data_size);
+ basic->m_bfs_psv = cpu_to_be32(msig->psv_memory.psv_idx);
+ basic->w_bfs_psv = cpu_to_be32(msig->psv_wire.psv_idx);

- ret = format_selector(sig_attrs, mem, &selector);
+ ret = mlx5_fill_inl_bsf(wire, &bsf->w_inl);
if (ret)
return -EINVAL;
- basic->m_bfs_psv = cpu_to_be32(selector << 24 |
- msig->psv_memory.psv_idx);

- ret = format_selector(sig_attrs, wire, &selector);
+ ret = mlx5_fill_inl_bsf(mem, &bsf->m_inl);
if (ret)
return -EINVAL;
- basic->w_bfs_psv = cpu_to_be32(selector << 24 |
- msig->psv_wire.psv_idx);
break;

default:
diff --git a/include/linux/mlx5/qp.h b/include/linux/mlx5/qp.h
index 4aa5634..69f5378 100644
--- a/include/linux/mlx5/qp.h
+++ b/include/linux/mlx5/qp.h
@@ -43,6 +43,12 @@
#define MLX5_CPY_GRD_MASK 0xc0
#define MLX5_CPY_APP_MASK 0x30
#define MLX5_CPY_REF_MASK 0x0f
+#define MLX5_BSF_INC_REFTAG (1 << 6)
+#define MLX5_BSF_INL_VALID (1 << 15)
+#define MLX5_BSF_REFRESH_DIF (1 << 14)
+#define MLX5_BSF_REPEAT_BLOCK (1 << 7)
+#define MLX5_BSF_APPTAG_ESCAPE 0x1
+#define MLX5_BSF_APPREF_ESCAPE 0x2

enum mlx5_qp_optpar {
MLX5_QP_OPTPAR_ALT_ADDR_PATH = 1 << 0,
@@ -290,6 +296,22 @@ struct mlx5_wqe_inline_seg {
__be32 byte_count;
};

+enum mlx5_sig_type {
+ MLX5_DIF_CRC = 0x1,
+ MLX5_DIF_IPCS = 0x2,
+};
+
+struct mlx5_bsf_inl {
+ __be16 vld_refresh;
+ __be16 dif_apptag;
+ __be32 dif_reftag;
+ u8 sig_type;
+ u8 rp_inv_seed;
+ u8 rsvd[3];
+ u8 dif_inc_ref_guard_check;
+ __be16 dif_app_bitmask_check;
+};
+
struct mlx5_bsf {
struct mlx5_bsf_basic {
u8 bsf_size_sbs;
@@ -313,14 +335,8 @@ struct mlx5_bsf {
__be32 w_tfs_psv;
__be32 m_tfs_psv;
} ext;
- struct mlx5_bsf_inl {
- __be32 w_inl_vld;
- __be32 w_rsvd;
- __be64 w_block_format;
- __be32 m_inl_vld;
- __be32 m_rsvd;
- __be64 m_block_format;
- } inl;
+ struct mlx5_bsf_inl w_inl;
+ struct mlx5_bsf_inl m_inl;
};

struct mlx5_klm {
--
1.7.1
Sagi Grimberg
2014-08-13 16:54:33 UTC
Permalink
Later there will be more parameters to set, so
we want to do it in a centralized place.

This patch does not change any functionality.

Signed-off-by: Sagi Grimberg <sagig-VPRAkNaXOzVWk0Htik3J/***@public.gmane.org>
---
drivers/infiniband/ulp/iser/iser_memory.c | 36 ++++++++++++++--------------
1 files changed, 18 insertions(+), 18 deletions(-)

diff --git a/drivers/infiniband/ulp/iser/iser_memory.c b/drivers/infiniband/ulp/iser/iser_memory.c
index bf0d1cc..5842d50 100644
--- a/drivers/infiniband/ulp/iser/iser_memory.c
+++ b/drivers/infiniband/ulp/iser/iser_memory.c
@@ -457,44 +457,44 @@ scsi2ib_prot_type(unsigned char prot_type)
}
}

+static inline void
+iser_set_dif_domain(struct scsi_cmnd *sc, struct ib_sig_attrs *sig_attrs,
+ struct ib_sig_domain *domain)
+{
+ unsigned char scsi_ptype = scsi_get_prot_type(sc);
+
+ domain->sig.dif.type = scsi2ib_prot_type(scsi_ptype);
+ domain->sig.dif.pi_interval = sc->device->sector_size;
+ domain->sig.dif.ref_tag = scsi_get_lba(sc) & 0xffffffff;
+};

static int
iser_set_sig_attrs(struct scsi_cmnd *sc, struct ib_sig_attrs *sig_attrs)
{
- unsigned char scsi_ptype = scsi_get_prot_type(sc);
-
sig_attrs->mem.sig_type = IB_SIG_TYPE_T10_DIF;
sig_attrs->wire.sig_type = IB_SIG_TYPE_T10_DIF;
- sig_attrs->mem.sig.dif.pi_interval = sc->device->sector_size;
- sig_attrs->wire.sig.dif.pi_interval = sc->device->sector_size;

switch (scsi_get_prot_op(sc)) {
case SCSI_PROT_WRITE_INSERT:
case SCSI_PROT_READ_STRIP:
sig_attrs->mem.sig.dif.type = IB_T10DIF_NONE;
- sig_attrs->wire.sig.dif.type = scsi2ib_prot_type(scsi_ptype);
+ iser_set_dif_domain(sc, sig_attrs, &sig_attrs->wire);
sig_attrs->wire.sig.dif.bg_type = IB_T10DIF_CRC;
- sig_attrs->wire.sig.dif.ref_tag = scsi_get_lba(sc) &
- 0xffffffff;
break;
case SCSI_PROT_READ_INSERT:
case SCSI_PROT_WRITE_STRIP:
- sig_attrs->mem.sig.dif.type = scsi2ib_prot_type(scsi_ptype);
- sig_attrs->mem.sig.dif.bg_type = IB_T10DIF_CRC;
- sig_attrs->mem.sig.dif.ref_tag = scsi_get_lba(sc) &
- 0xffffffff;
sig_attrs->wire.sig.dif.type = IB_T10DIF_NONE;
+ iser_set_dif_domain(sc, sig_attrs, &sig_attrs->mem);
+ sig_attrs->mem.sig.dif.bg_type = iser_pi_guard ? IB_T10DIF_CSUM :
+ IB_T10DIF_CRC;
break;
case SCSI_PROT_READ_PASS:
case SCSI_PROT_WRITE_PASS:
- sig_attrs->mem.sig.dif.type = scsi2ib_prot_type(scsi_ptype);
- sig_attrs->mem.sig.dif.bg_type = IB_T10DIF_CRC;
- sig_attrs->mem.sig.dif.ref_tag = scsi_get_lba(sc) &
- 0xffffffff;
- sig_attrs->wire.sig.dif.type = scsi2ib_prot_type(scsi_ptype);
+ iser_set_dif_domain(sc, sig_attrs, &sig_attrs->wire);
sig_attrs->wire.sig.dif.bg_type = IB_T10DIF_CRC;
- sig_attrs->wire.sig.dif.ref_tag = scsi_get_lba(sc) &
- 0xffffffff;
+ iser_set_dif_domain(sc, sig_attrs, &sig_attrs->mem);
+ sig_attrs->mem.sig.dif.bg_type = iser_pi_guard ? IB_T10DIF_CSUM :
+ IB_T10DIF_CRC;
break;
default:
iser_err("Unsupported PI operation %d\n",
--
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-***@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Sagi Grimberg
2014-08-13 16:54:34 UTC
Permalink
Later there will be more parameters to set, so
we want to do it in a centralized place.

This patch does not change any functionality.

Signed-off-by: Sagi Grimberg <sagig-VPRAkNaXOzVWk0Htik3J/***@public.gmane.org>
---
drivers/infiniband/ulp/isert/ib_isert.c | 33 +++++++++++++++----------------
1 files changed, 16 insertions(+), 17 deletions(-)

diff --git a/drivers/infiniband/ulp/isert/ib_isert.c b/drivers/infiniband/ulp/isert/ib_isert.c
index da8ff12..7309275 100644
--- a/drivers/infiniband/ulp/isert/ib_isert.c
+++ b/drivers/infiniband/ulp/isert/ib_isert.c
@@ -2626,41 +2626,40 @@ se2ib_prot_type(enum target_prot_type prot_type)
}
}

+static inline void
+isert_set_dif_domain(struct se_cmd *se_cmd, struct ib_sig_attrs *sig_attrs,
+ struct ib_sig_domain *domain)
+{
+ enum ib_t10_dif_type ib_prot_type = se2ib_prot_type(se_cmd->prot_type);
+
+ domain->sig.dif.type = ib_prot_type;
+ domain->sig.dif.bg_type = IB_T10DIF_CRC;
+ domain->sig.dif.pi_interval = se_cmd->se_dev->dev_attrib.block_size;
+ domain->sig.dif.ref_tag = se_cmd->reftag_seed;
+};
+
static int
isert_set_sig_attrs(struct se_cmd *se_cmd, struct ib_sig_attrs *sig_attrs)
{
- enum ib_t10_dif_type ib_prot_type = se2ib_prot_type(se_cmd->prot_type);

sig_attrs->mem.sig_type = IB_SIG_TYPE_T10_DIF;
sig_attrs->wire.sig_type = IB_SIG_TYPE_T10_DIF;
- sig_attrs->mem.sig.dif.pi_interval =
- se_cmd->se_dev->dev_attrib.block_size;
- sig_attrs->wire.sig.dif.pi_interval =
- se_cmd->se_dev->dev_attrib.block_size;

switch (se_cmd->prot_op) {
case TARGET_PROT_DIN_INSERT:
case TARGET_PROT_DOUT_STRIP:
sig_attrs->mem.sig.dif.type = IB_T10DIF_NONE;
- sig_attrs->wire.sig.dif.type = ib_prot_type;
- sig_attrs->wire.sig.dif.bg_type = IB_T10DIF_CRC;
- sig_attrs->wire.sig.dif.ref_tag = se_cmd->reftag_seed;
+ isert_set_dif_domain(se_cmd, sig_attrs, &sig_attrs->wire);
break;
case TARGET_PROT_DOUT_INSERT:
case TARGET_PROT_DIN_STRIP:
- sig_attrs->mem.sig.dif.type = ib_prot_type;
- sig_attrs->mem.sig.dif.bg_type = IB_T10DIF_CRC;
- sig_attrs->mem.sig.dif.ref_tag = se_cmd->reftag_seed;
sig_attrs->wire.sig.dif.type = IB_T10DIF_NONE;
+ isert_set_dif_domain(se_cmd, sig_attrs, &sig_attrs->mem);
break;
case TARGET_PROT_DIN_PASS:
case TARGET_PROT_DOUT_PASS:
- sig_attrs->mem.sig.dif.type = ib_prot_type;
- sig_attrs->mem.sig.dif.bg_type = IB_T10DIF_CRC;
- sig_attrs->mem.sig.dif.ref_tag = se_cmd->reftag_seed;
- sig_attrs->wire.sig.dif.type = ib_prot_type;
- sig_attrs->wire.sig.dif.bg_type = IB_T10DIF_CRC;
- sig_attrs->wire.sig.dif.ref_tag = se_cmd->reftag_seed;
+ isert_set_dif_domain(se_cmd, sig_attrs, &sig_attrs->wire);
+ isert_set_dif_domain(se_cmd, sig_attrs, &sig_attrs->mem);
break;
default:
pr_err("Unsupported PI operation %d\n", se_cmd->prot_op);
--
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-***@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Nicholas A. Bellinger
2014-08-22 18:22:46 UTC
Permalink
Hi Sagi & Co,
Post by Sagi Grimberg
Lately MKP posted some block data integrity updates over Linux-scsi (see https://lwn.net/Articles/606820/).
These changes follow DIX draft 1.1 (see see https://oss.oracle.com/~mkp/docs/dix-1.1.pdf).
The draft updates the execution parameters passed from SCSI midlayer
to the LLDs with respect to data integrity feature.
This set updates signature feature accordingly.
Once Martin's patches will land mainline I'll also modify iSER
to take relevant parameters from the scsi command structure.
- Patches #1, #2, #3 are minor fixes
- Patch #4 is a preparation patch
- Patches #5, #6 are code centralization
- Patch #7 is an API update (modifies ib_core, mlx5, iser, isert)
Roland, there are some patches in iser-target code, but I'm pretty
sure that they can go from your tree. Right Nic?
Yep, no target dependencies here, so they should go through
infiniband.git.

Roland, are you planning to pick these up for v3.18..?

--nab

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-***@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Roland Dreier
2014-08-22 18:35:37 UTC
Permalink
On Fri, Aug 22, 2014 at 11:22 AM, Nicholas A. Bellinger
Post by Nicholas A. Bellinger
Roland, are you planning to pick these up for v3.18..?
Sure.

Loading...