All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH RFC 0/9] Introduce Signature feature
@ 2013-10-15 15:38 Sagi Grimberg
       [not found] ` <1381851510-17290-1-git-send-email-sagig-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
  0 siblings, 1 reply; 21+ messages in thread
From: Sagi Grimberg @ 2013-10-15 15:38 UTC (permalink / raw)
  To: linux-rdma-u79uwXL29TY76Z2rM5mHXA

This patchset Introduces Verbs level support for signature handover
feature. Siganture is intended to implement end-to-end data integrity
on a transactional basis in a completely offloaded manner.
A signature handover operation is basically a translation of
the data layout between the so called memory domain and wire domain
in the context of data integrity support.

There are several end-to-end data integrity methods used today in various
applications and/or upper layer protocols such as T10-DIF defined by SCSI
specifications (SBC), CRC32, XOR8 and more. This patchset adds verbs
support only for T10-DIF. The proposed framework allows adding more
signature methods.

The way that data integrity is performed is by registering a protected
region with siganture handover attributes and memory domain layout and
in addition define the wire domain layout. defining both domains is
equivalent to determining the signature hanover operation which can be
strip/add/pass and validate data integrity when performing data transfer
from input space and output space. When the data transfer is completed,
the user may check the signature status of the handover operation and
in case some data integrity error has occured receive a signature error
item providing the relevant info on the error.

This feature shall be used in storage upper layer protocols iSER/SRP
implementing end-to-end data integrity T10-DIF. Following this patchset,
we will soon submit krping activation code which will demonstrate
the usage and activation of protected RDMA transactions using signature verbs.

Patchset summary:
- Intoduce verbs for create/destroy memory regions supporting signature.
- Introduce IB core signature verbs API.
- Implement mr create/destroy verbs in mlx5 driver.
- Preperation patches for signature support in mlx5 driver.
- Implement signature handover work request in mlx5 driver.
- Implement signature error collection and handling in mlx5 driver.

Sagi Grimberg (9):
  IB/core: Introduce indirect and protected memory regions
  IB/core: Introduce Signature Verbs API
  IB/mlx5, mlx5_core: Support for create_mr and destroy_mr
  IB/mlx5: Initialize mlx5_ib_qp signature related
  IB/mlx5: Break wqe handling to begin & finish routines
  IB/mlx5: remove MTT access mode from umr flags helper function
  IB/mlx5: Support IB_WR_REG_SIG_MR
  IB/mlx5: Collect signature error completion
  IB/mlx5: Publish support in signature feature

 drivers/infiniband/core/verbs.c              |   47 +++
 drivers/infiniband/hw/mlx5/cq.c              |   49 +++
 drivers/infiniband/hw/mlx5/main.c            |   12 +
 drivers/infiniband/hw/mlx5/mlx5_ib.h         |   11 +
 drivers/infiniband/hw/mlx5/mr.c              |  154 ++++++++
 drivers/infiniband/hw/mlx5/qp.c              |  532 ++++++++++++++++++++++++--
 drivers/net/ethernet/mellanox/mlx5/core/mr.c |   64 +++
 include/linux/mlx5/cq.h                      |    1 +
 include/linux/mlx5/device.h                  |   42 ++
 include/linux/mlx5/driver.h                  |   24 ++
 include/linux/mlx5/qp.h                      |   57 +++
 include/rdma/ib_verbs.h                      |  186 +++++++++-
 12 files changed, 1140 insertions(+), 39 deletions(-)

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH RFC 1/9] IB/core: Introduce indirect and protected memory regions
       [not found] ` <1381851510-17290-1-git-send-email-sagig-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
@ 2013-10-15 15:38   ` Sagi Grimberg
       [not found]     ` <1381851510-17290-2-git-send-email-sagig-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
  2013-10-15 15:38   ` [PATCH RFC 2/9] IB/core: Introduce Signature Verbs API Sagi Grimberg
                     ` (7 subsequent siblings)
  8 siblings, 1 reply; 21+ messages in thread
From: Sagi Grimberg @ 2013-10-15 15:38 UTC (permalink / raw)
  To: linux-rdma-u79uwXL29TY76Z2rM5mHXA

This commit introduces verbs for creating memory regions
which will allow new types of memory key operations such
as indirect memory registration and protected memory
registration.

Indirect memory registration is registering several (one
of more) pre-registered memory regions in a specific layout.
The Indirect region may potentialy describe several regions
and some repitition format between them.

Protected Memory registration is registering a memory region
with various data integrity attributes that will describe protection
schemes that will be enforced by the HCA in an offloaded manner.

In the future these routines may replace current memory regions creation
routines existing today:
- ib_reg_user_mr
- ib_alloc_fast_reg_mr
- ib_get_dma_mr
- ib_dereg_mr

Signed-off-by: Sagi Grimberg <sagig-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
---
 drivers/infiniband/core/verbs.c |   39 +++++++++++++++++++++++++++++++++
 include/rdma/ib_verbs.h         |   46 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 85 insertions(+), 0 deletions(-)

diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c
index 22192de..1d94a5c 100644
--- a/drivers/infiniband/core/verbs.c
+++ b/drivers/infiniband/core/verbs.c
@@ -1052,6 +1052,45 @@ int ib_dereg_mr(struct ib_mr *mr)
 }
 EXPORT_SYMBOL(ib_dereg_mr);
 
+struct ib_mr *ib_create_mr(struct ib_pd *pd,
+			   struct ib_mr_init_attr *mr_init_attr)
+{
+	struct ib_mr *mr;
+
+	if (!pd->device->create_mr)
+		return ERR_PTR(-ENOSYS);
+
+	mr = pd->device->create_mr(pd, mr_init_attr);
+
+	if (!IS_ERR(mr)) {
+		mr->device  = pd->device;
+		mr->pd      = pd;
+		mr->uobject = NULL;
+		atomic_inc(&pd->usecnt);
+		atomic_set(&mr->usecnt, 0);
+	}
+
+	return mr;
+}
+EXPORT_SYMBOL(ib_create_mr);
+
+int ib_destroy_mr(struct ib_mr *mr)
+{
+	struct ib_pd *pd;
+	int ret;
+
+	if (atomic_read(&mr->usecnt))
+		return -EBUSY;
+
+	pd = mr->pd;
+	ret = mr->device->destroy_mr(mr);
+	if (!ret)
+		atomic_dec(&pd->usecnt);
+
+	return ret;
+}
+EXPORT_SYMBOL(ib_destroy_mr);
+
 struct ib_mr *ib_alloc_fast_reg_mr(struct ib_pd *pd, int max_page_list_len)
 {
 	struct ib_mr *mr;
diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h
index 645c3ce..65b7e79 100644
--- a/include/rdma/ib_verbs.h
+++ b/include/rdma/ib_verbs.h
@@ -925,6 +925,30 @@ enum ib_mr_rereg_flags {
 	IB_MR_REREG_ACCESS	= (1<<2)
 };
 
+enum ib_mr_create_flags {
+		IB_MR_SIGNATURE_EN = 1,
+};
+
+enum ib_mr_reg_type {
+	IB_MR_REG_DIRECT,
+	IB_MR_REG_INDIRECT,
+};
+
+/**
+ * ib_mr_init_attr - Memory region init attributes passed to routine
+ *	ib_create_mr.
+ * @reg_type: requested mapping type, this can be direct/indirect
+ *   registration or repetitive structure registration.
+ * @max_reg_descriptors: max number of registration units that
+ *   may be used with UMR work requests.
+ * @flags: MR creation flags bit mask.
+ */
+struct ib_mr_init_attr {
+	enum ib_mr_reg_type	reg_type;
+	int			max_reg_descriptors;
+	enum ib_mr_create_flags	flags;
+};
+
 /**
  * struct ib_mw_bind - Parameters for a type 1 memory window bind operation.
  * @wr_id:      Work request id.
@@ -1257,6 +1281,9 @@ struct ib_device {
 	int                        (*query_mr)(struct ib_mr *mr,
 					       struct ib_mr_attr *mr_attr);
 	int                        (*dereg_mr)(struct ib_mr *mr);
+	int                        (*destroy_mr)(struct ib_mr *mr);
+	struct ib_mr *		   (*create_mr)(struct ib_pd *pd,
+						struct ib_mr_init_attr *mr_init_attr);
 	struct ib_mr *		   (*alloc_fast_reg_mr)(struct ib_pd *pd,
 					       int max_page_list_len);
 	struct ib_fast_reg_page_list * (*alloc_fast_reg_page_list)(struct ib_device *device,
@@ -2092,6 +2119,25 @@ int ib_query_mr(struct ib_mr *mr, struct ib_mr_attr *mr_attr);
  */
 int ib_dereg_mr(struct ib_mr *mr);
 
+
+/**
+ * ib_create_mr - creates memory region that may be used for
+ *   direct or indirect registration models via UMR WR.
+ * @pd: The protection domain associated with the region.
+ * @mr_init_attr: memory region init attributes.
+ */
+struct ib_mr *ib_create_mr(struct ib_pd *pd,
+			   struct ib_mr_init_attr *mr_init_attr);
+
+/**
+ * ib_destroy_mr - Destroys a memory region that was created using
+ * 	ib_create_mr and removes it from HW translation tables.
+ * @mr: The memory region to destroy.
+ *
+ * This function can fail, if the memory region has memory windows bound to it.
+ */
+int ib_destroy_mr(struct ib_mr *mr);
+
 /**
  * ib_alloc_fast_reg_mr - Allocates memory region usable with the
  *   IB_WR_FAST_REG_MR send work request.
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH RFC 2/9] IB/core: Introduce Signature Verbs API
       [not found] ` <1381851510-17290-1-git-send-email-sagig-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
  2013-10-15 15:38   ` [PATCH RFC 1/9] IB/core: Introduce indirect and protected memory regions Sagi Grimberg
@ 2013-10-15 15:38   ` Sagi Grimberg
       [not found]     ` <1381851510-17290-3-git-send-email-sagig-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
  2013-10-15 15:38   ` [PATCH RFC 3/9] IB/mlx5, mlx5_core: Support for create_mr and destroy_mr Sagi Grimberg
                     ` (6 subsequent siblings)
  8 siblings, 1 reply; 21+ messages in thread
From: Sagi Grimberg @ 2013-10-15 15:38 UTC (permalink / raw)
  To: linux-rdma-u79uwXL29TY76Z2rM5mHXA

This commit Introduces the Verbs Interface for signature related
operations. A signature handover operation shall configure the
layouts of data and protection attributes both in memory and wire
domains. Once the signature handover opration is done, the HCA will
offload data integrity generation/validation while performing
the actual data transfer.

Additions:
1. HCA signature capabilities in device attributes
    Verbs provider supporting Signature handover operations shall
    fill relevant fields in device attributes structure returned
    by ib_query_device.

2. QP creation flag IB_QP_CREATE_SIGNATURE_EN
    Creating QP that will carry signature handover operations
    may require some special preperations from the verbs provider.
    So we add QP creation flag IB_QP_CREATE_SIGNATURE_EN to declare
    that the created QP may carry out signature handover operations.
    Expose signature support to verbs layer (no support for now)

3. New send work request IB_WR_REG_SIG_MR
    Signature handover work request. This WR will define
    the signature handover properties of the memory/wire
    domains as well as the domains layout.
    * Currently expose just T10-DIF layout.

4. New Verb ib_check_sig_status
    check_sig_status Verb shall check if any signature errors
    are pending for a specific signature related ib_mr.
    User should provide the ib_qp that executed the RDMA operation
    involving the given ib_mr.

Signed-off-by: Sagi Grimberg <sagig-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
---
 drivers/infiniband/core/verbs.c |    8 ++
 include/rdma/ib_verbs.h         |  140 ++++++++++++++++++++++++++++++++++++++-
 2 files changed, 147 insertions(+), 1 deletions(-)

diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c
index 1d94a5c..5636d65 100644
--- a/drivers/infiniband/core/verbs.c
+++ b/drivers/infiniband/core/verbs.c
@@ -1293,3 +1293,11 @@ int ib_dealloc_xrcd(struct ib_xrcd *xrcd)
 	return xrcd->device->dealloc_xrcd(xrcd);
 }
 EXPORT_SYMBOL(ib_dealloc_xrcd);
+
+int ib_check_sig_status(struct ib_mr *sig_mr,
+			struct ib_sig_err *sig_err)
+{
+	return sig_mr->device->check_sig_status ?
+		sig_mr->device->check_sig_status(sig_mr, sig_err) : -ENOSYS;
+}
+EXPORT_SYMBOL(ib_check_sig_status);
diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h
index 65b7e79..cf46a83 100644
--- a/include/rdma/ib_verbs.h
+++ b/include/rdma/ib_verbs.h
@@ -116,7 +116,19 @@ enum ib_device_cap_flags {
 	IB_DEVICE_MEM_MGT_EXTENSIONS	= (1<<21),
 	IB_DEVICE_BLOCK_MULTICAST_LOOPBACK = (1<<22),
 	IB_DEVICE_MEM_WINDOW_TYPE_2A	= (1<<23),
-	IB_DEVICE_MEM_WINDOW_TYPE_2B	= (1<<24)
+	IB_DEVICE_MEM_WINDOW_TYPE_2B	= (1<<24),
+	IB_DEVICE_SIGNATURE_HANDOVER	= (1<<25),
+};
+
+enum ib_signature_prot_cap {
+	IB_PROT_T10DIF_TYPE_1 = 1,
+	IB_PROT_T10DIF_TYPE_2 = 1 << 1,
+	IB_PROT_T10DIF_TYPE_3 = 1 << 2,
+};
+
+enum ib_signature_guard_cap {
+	IB_GUARD_T10DIF_CRC	= 1,
+	IB_GUARD_T10DIF_CSUM	= 1 << 1,
 };
 
 enum ib_atomic_cap {
@@ -166,6 +178,8 @@ struct ib_device_attr {
 	unsigned int		max_fast_reg_page_list_len;
 	u16			max_pkeys;
 	u8			local_ca_ack_delay;
+	enum ib_signature_prot_cap	sig_prot_cap;
+	enum ib_signature_guard_cap	sig_guard_cap;
 };
 
 enum ib_mtu {
@@ -630,6 +644,7 @@ enum ib_qp_type {
 enum ib_qp_create_flags {
 	IB_QP_CREATE_IPOIB_UD_LSO		= 1 << 0,
 	IB_QP_CREATE_BLOCK_MULTICAST_LOOPBACK	= 1 << 1,
+	IB_QP_CREATE_SIGNATURE_EN		= 1 << 2,
 	/* reserve bits 26-31 for low level drivers' internal use */
 	IB_QP_CREATE_RESERVED_START		= 1 << 26,
 	IB_QP_CREATE_RESERVED_END		= 1 << 31,
@@ -780,6 +795,7 @@ enum ib_wr_opcode {
 	IB_WR_MASKED_ATOMIC_CMP_AND_SWP,
 	IB_WR_MASKED_ATOMIC_FETCH_AND_ADD,
 	IB_WR_BIND_MW,
+	IB_WR_REG_SIG_MR,
 	/* reserve values for low level drivers' internal use.
 	 * These values will not be used at all in the ib core layer.
 	 */
@@ -885,6 +901,19 @@ struct ib_send_wr {
 			u32                      rkey;
 			struct ib_mw_bind_info   bind_info;
 		} bind_mw;
+		struct {
+			struct ib_sig_attrs    *sig_attrs;
+			struct ib_mr	       *sig_mr;
+			int			access_flags;
+			/* Registered data mr */
+			struct ib_mr	       *data_mr;
+			u32			data_size;
+			u64			data_va;
+			/* Registered protection mr */
+			struct ib_mr	       *prot_mr;
+			u32			prot_size;
+			u64			prot_va;
+		} sig_handover;
 	} wr;
 	u32			xrc_remote_srq_num;	/* XRC TGT QPs only */
 };
@@ -949,6 +978,97 @@ struct ib_mr_init_attr {
 	enum ib_mr_create_flags	flags;
 };
 
+enum ib_signature_type {
+	IB_SIG_TYPE_T10_DIF,
+};
+
+/**
+ * T10-DIF Signature types
+ * T10-DIF types are defined by SCSI
+ * specifications.
+ */
+enum ib_t10_dif_type {
+	IB_T10DIF_NONE,
+	IB_T10DIF_TYPE1,
+	IB_T10DIF_TYPE2,
+	IB_T10DIF_TYPE3
+};
+
+/**
+ * Signature T10-DIF block-guard types
+ */
+enum ib_t10_dif_bg_type {
+	IB_T10DIF_CRC,
+	IB_T10DIF_CSUM
+};
+
+/**
+ * struct ib_sig_domain - Parameters specific for T10-DIF
+ * 	domain.
+ * @sig_type: specific signauture type
+ * @sig: union of all signature domain attributes that may
+ * 	 be used to set domaim layout.
+ * 	 @dif:
+ * 		@type: T10-DIF type (0|1|2|3)
+ * 		@bg_type: T10-DIF block guard type (CRC|CSUM)
+ * 		@block_size: block size in signature domain.
+ * 		@app_tag: if app_tag is not owned be the user
+ * 			HCA will take this value to be app_tag.
+ * 		@ref_tag: initial ref_tag of signature handover.
+ * 		@type3_inc_reftag: T10-DIF type 3 does not state
+ *			about the reference tag, it is the user
+ *			choice to increment it or not.
+ */
+struct ib_sig_domain {
+	enum ib_signature_type 	sig_type;
+	union {
+		struct {
+			enum ib_t10_dif_type	type;
+			enum ib_t10_dif_bg_type bg_type;
+			u16			block_size;
+			u16			bg;
+			u16			app_tag;
+			u32			ref_tag;
+			bool			type3_inc_reftag;
+		} dif;
+	} sig;
+};
+
+/**
+ * struct ib_sig_attrs - Parameters for signature handover operation
+ * @check_mask: bitmask for signature byte check (8 bytes)
+ * @mem: memory domain layout desciptor.
+ * @wire: wire domain layout desciptor.
+ */
+struct ib_sig_attrs {
+	u8			check_mask;
+	struct ib_sig_domain	mem;
+	struct ib_sig_domain	wire;
+};
+
+enum ib_sig_err_type {
+	IB_SIG_BAD_CRC,
+	IB_SIG_BAD_REFTAG,
+	IB_SIG_BAD_APPTAG,
+};
+
+/**
+ * struct ib_sig_err - signature error descriptor
+ * @err_type: Type of signature error.
+ * @err_block_idx: Block index of signature error.
+ */
+struct ib_sig_err {
+	enum ib_sig_err_type	err_type;
+	u16			expected_guard;
+	u16			actual_guard;
+	u32			expected_logical_block;
+	u32			actual_logical_block;
+	u64			sig_err_offset;
+	u32			qpn;
+	u32			key;
+	struct list_head	list;
+};
+
 /**
  * struct ib_mw_bind - Parameters for a type 1 memory window bind operation.
  * @wr_id:      Work request id.
@@ -1327,6 +1447,8 @@ struct ib_device {
 						 struct ib_ucontext *ucontext,
 						 struct ib_udata *udata);
 	int			   (*dealloc_xrcd)(struct ib_xrcd *xrcd);
+	int			   (*check_sig_status)(struct ib_mr *sig_mr,
+						       struct ib_sig_err *sig_err);
 
 	struct ib_dma_mapping_ops   *dma_ops;
 
@@ -2306,4 +2428,20 @@ struct ib_xrcd *ib_alloc_xrcd(struct ib_device *device);
  */
 int ib_dealloc_xrcd(struct ib_xrcd *xrcd);
 
+/**
+ * ib_check_sig_result: lightweight check of signature result
+ * 	on specific signature enabled MR and QP.
+ * Return value:
+ * - 0 for signature status SUCCESS.
+ * - 1 for signature status FAILURE.
+ *
+ * @qp: The signature enabled QP that was used in signature
+ * 	transaction.
+ * @sig_mr: The signature enabled MR that describes the
+ * 	protected domain.
+ * @sig_err: The container of the signature error in
+ * 	case of signature error indeed occured.
+ */
+int ib_check_sig_status(struct ib_mr *sig_mr, struct ib_sig_err *sig_err);
+
 #endif /* IB_VERBS_H */
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH RFC 3/9] IB/mlx5, mlx5_core: Support for create_mr and destroy_mr
       [not found] ` <1381851510-17290-1-git-send-email-sagig-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
  2013-10-15 15:38   ` [PATCH RFC 1/9] IB/core: Introduce indirect and protected memory regions Sagi Grimberg
  2013-10-15 15:38   ` [PATCH RFC 2/9] IB/core: Introduce Signature Verbs API Sagi Grimberg
@ 2013-10-15 15:38   ` Sagi Grimberg
  2013-10-15 15:38   ` [PATCH RFC 4/9] IB/mlx5: Initialize mlx5_ib_qp signature related Sagi Grimberg
                     ` (5 subsequent siblings)
  8 siblings, 0 replies; 21+ messages in thread
From: Sagi Grimberg @ 2013-10-15 15:38 UTC (permalink / raw)
  To: linux-rdma-u79uwXL29TY76Z2rM5mHXA

Support create_mr and destroy_mr verbs.
Creating ib_mr may be done for either ib_mr that will
register regular page lists like alloc_fast_reg_mr routine,
or indirect ib_mr's that can register other (pre-registered)
ib_mr's in an indirect manner.

In addition user may request signature enable, that will mean
that the created ib_mr may be attached with signature attributes
(BSF, PSVs).

Currently we only allow direct/indirect registration modes.

Signed-off-by: Sagi Grimberg <sagig-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
---
 drivers/infiniband/hw/mlx5/main.c            |    2 +
 drivers/infiniband/hw/mlx5/mlx5_ib.h         |    4 +
 drivers/infiniband/hw/mlx5/mr.c              |  120 ++++++++++++++++++++++++++
 drivers/net/ethernet/mellanox/mlx5/core/mr.c |   64 ++++++++++++++
 include/linux/mlx5/device.h                  |   25 ++++++
 include/linux/mlx5/driver.h                  |   22 +++++
 6 files changed, 237 insertions(+), 0 deletions(-)

diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c
index 3f831de..2e67a37 100644
--- a/drivers/infiniband/hw/mlx5/main.c
+++ b/drivers/infiniband/hw/mlx5/main.c
@@ -1401,9 +1401,11 @@ static int init_one(struct pci_dev *pdev,
 	dev->ib_dev.get_dma_mr		= mlx5_ib_get_dma_mr;
 	dev->ib_dev.reg_user_mr		= mlx5_ib_reg_user_mr;
 	dev->ib_dev.dereg_mr		= mlx5_ib_dereg_mr;
+	dev->ib_dev.destroy_mr		= mlx5_ib_destroy_mr;
 	dev->ib_dev.attach_mcast	= mlx5_ib_mcg_attach;
 	dev->ib_dev.detach_mcast	= mlx5_ib_mcg_detach;
 	dev->ib_dev.process_mad		= mlx5_ib_process_mad;
+	dev->ib_dev.create_mr		= mlx5_ib_create_mr;
 	dev->ib_dev.alloc_fast_reg_mr	= mlx5_ib_alloc_fast_reg_mr;
 	dev->ib_dev.alloc_fast_reg_page_list = mlx5_ib_alloc_fast_reg_page_list;
 	dev->ib_dev.free_fast_reg_page_list  = mlx5_ib_free_fast_reg_page_list;
diff --git a/drivers/infiniband/hw/mlx5/mlx5_ib.h b/drivers/infiniband/hw/mlx5/mlx5_ib.h
index 836be91..45d7424 100644
--- a/drivers/infiniband/hw/mlx5/mlx5_ib.h
+++ b/drivers/infiniband/hw/mlx5/mlx5_ib.h
@@ -262,6 +262,7 @@ struct mlx5_ib_mr {
 	int			npages;
 	struct completion	done;
 	enum ib_wc_status	status;
+	struct mlx5_core_sig_ctx    *sig;
 };
 
 struct mlx5_ib_fast_reg_page_list {
@@ -489,6 +490,9 @@ struct ib_mr *mlx5_ib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
 				  u64 virt_addr, int access_flags,
 				  struct ib_udata *udata);
 int mlx5_ib_dereg_mr(struct ib_mr *ibmr);
+int mlx5_ib_destroy_mr(struct ib_mr *ibmr);
+struct ib_mr *mlx5_ib_create_mr(struct ib_pd *pd,
+				struct ib_mr_init_attr *mr_init_attr);
 struct ib_mr *mlx5_ib_alloc_fast_reg_mr(struct ib_pd *pd,
 					int max_page_list_len);
 struct ib_fast_reg_page_list *mlx5_ib_alloc_fast_reg_page_list(struct ib_device *ibdev,
diff --git a/drivers/infiniband/hw/mlx5/mr.c b/drivers/infiniband/hw/mlx5/mr.c
index bd41df9..2f6758c 100644
--- a/drivers/infiniband/hw/mlx5/mr.c
+++ b/drivers/infiniband/hw/mlx5/mr.c
@@ -921,6 +921,126 @@ int mlx5_ib_dereg_mr(struct ib_mr *ibmr)
 	return 0;
 }
 
+struct ib_mr *mlx5_ib_create_mr(struct ib_pd *pd,
+				struct ib_mr_init_attr *mr_init_attr)
+{
+	struct mlx5_ib_dev *dev = to_mdev(pd->device);
+	struct mlx5_create_mkey_mbox_in *in;
+	struct mlx5_ib_mr *mr;
+	int access_mode, err;
+	int ndescs = roundup(mr_init_attr->max_reg_descriptors, 4);
+
+	mr = kzalloc(sizeof(*mr), GFP_KERNEL);
+	if (!mr)
+		return ERR_PTR(-ENOMEM);
+
+	in = kzalloc(sizeof(*in), GFP_KERNEL);
+	if (!in) {
+		err = -ENOMEM;
+		goto err_free;
+	}
+
+	in->seg.status = 1 << 6; /* free */
+	in->seg.xlt_oct_size = cpu_to_be32(ndescs);
+	in->seg.qpn_mkey7_0 = cpu_to_be32(0xffffff << 8);
+	in->seg.flags_pd = cpu_to_be32(to_mpd(pd)->pdn);
+
+	switch (mr_init_attr->reg_type) {
+	case IB_MR_REG_DIRECT:
+		access_mode = MLX5_ACCESS_MODE_MTT;
+		break;
+	case IB_MR_REG_INDIRECT:
+		access_mode = MLX5_ACCESS_MODE_KLM;
+		break;
+	default:
+		err = -EINVAL;
+		goto err_free;
+	}
+	in->seg.flags = MLX5_PERM_UMR_EN | access_mode;
+
+	if (mr_init_attr->flags & IB_MR_SIGNATURE_EN) {
+		u32 psv_index[2];
+
+		in->seg.flags_pd = cpu_to_be32(be32_to_cpu(in->seg.flags_pd) |
+							   MLX5_MKEY_BSF_EN);
+		in->seg.bsfs_octo_size = cpu_to_be32(MLX5_MKEY_BSF_OCTO_SIZE);
+		mr->sig = kzalloc(sizeof(*mr->sig), GFP_KERNEL);
+		if (!mr->sig) {
+			err = -ENOMEM;
+			goto err_free;
+		}
+
+		/* create mem & wire PSVs */
+		err = mlx5_core_create_psv(&dev->mdev, to_mpd(pd)->pdn,
+					   2, psv_index);
+		if (err)
+			goto err_free_sig;
+
+		mr->sig->psv_memory.psv_idx = psv_index[0];
+		mr->sig->psv_wire.psv_idx = psv_index[1];
+		mr->sig->sig_status_collected = true;
+	}
+
+	err = mlx5_core_create_mkey(&dev->mdev, &mr->mmr, in, sizeof(*in));
+	kfree(in);
+	if (err)
+		goto err_destroy_psv;
+
+	mr->ibmr.lkey = mr->mmr.key;
+	mr->ibmr.rkey = mr->mmr.key;
+	mr->umem = NULL;
+
+	return &mr->ibmr;
+
+err_destroy_psv:
+	if (mr->sig) {
+		if (mlx5_core_destroy_psv(&dev->mdev,
+					  mr->sig->psv_memory.psv_idx))
+			mlx5_ib_warn(dev, "failed to destroy mem psv %d\n",
+				     mr->sig->psv_memory.psv_idx);
+		if (mlx5_core_destroy_psv(&dev->mdev,
+					  mr->sig->psv_wire.psv_idx))
+			mlx5_ib_warn(dev, "failed to destroy wire psv %d\n",
+				     mr->sig->psv_wire.psv_idx);
+	}
+err_free_sig:
+	if (mr->sig)
+		kfree(mr->sig);
+err_free:
+	kfree(mr);
+	return ERR_PTR(err);
+}
+
+int mlx5_ib_destroy_mr(struct ib_mr *ibmr)
+{
+	struct mlx5_ib_dev *dev = to_mdev(ibmr->device);
+	struct mlx5_ib_mr *mr = to_mmr(ibmr);
+	int err;
+
+	if (mr->sig) {
+		if (mlx5_core_destroy_psv(&dev->mdev,
+					  mr->sig->psv_memory.psv_idx))
+			mlx5_ib_warn(dev, "failed to destroy mem psv %d\n",
+				     mr->sig->psv_memory.psv_idx);
+		if (mlx5_core_destroy_psv(&dev->mdev,
+					  mr->sig->psv_wire.psv_idx))
+			mlx5_ib_warn(dev, "failed to destroy wire psv %d\n",
+				     mr->sig->psv_wire.psv_idx);
+		kfree(mr->sig);
+	}
+
+	err = mlx5_core_destroy_mkey(&dev->mdev, &mr->mmr);
+	if (err) {
+		mlx5_ib_warn(dev, "failed to destroy mkey 0x%x (%d)\n",
+			     mr->mmr.key, err);
+		return err;
+	}
+
+	kfree(mr);
+
+	return err;
+}
+
 struct ib_mr *mlx5_ib_alloc_fast_reg_mr(struct ib_pd *pd,
 					int max_page_list_len)
 {
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/mr.c b/drivers/net/ethernet/mellanox/mlx5/core/mr.c
index 5b44e2e..2ade604 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/mr.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/mr.c
@@ -134,3 +134,67 @@ int mlx5_core_dump_fill_mkey(struct mlx5_core_dev *dev, struct mlx5_core_mr *mr,
 	return err;
 }
 EXPORT_SYMBOL(mlx5_core_dump_fill_mkey);
+
+int mlx5_core_create_psv(struct mlx5_core_dev *dev, u32 pdn,
+			 int npsvs, u32 *sig_index)
+{
+	struct mlx5_allocate_psv_in in;
+	struct mlx5_allocate_psv_out out;
+	int i, err;
+
+	if (npsvs > MLX5_MAX_PSVS) {
+		err = -EINVAL;
+		goto out;
+	}
+
+	memset(&in, 0, sizeof(in));
+	memset(&out, 0, sizeof(out));
+
+	in.hdr.opcode = cpu_to_be16(MLX5_CMD_OP_CREATE_PSV);
+	in.npsv_pd = cpu_to_be32((npsvs << 28) | pdn);
+	err = mlx5_cmd_exec(dev, &in, sizeof(in), &out, sizeof(out));
+	if (err) {
+		mlx5_core_err(dev, "cmd exec failed %d\n", err);
+		return err;
+	}
+
+	if (out.hdr.status) {
+		mlx5_core_err(dev, "create_psv bad status %d\n", out.hdr.status);
+		return mlx5_cmd_status_to_err(&out.hdr);
+	}
+
+	for (i = 0; i < npsvs; i++)
+		sig_index[i] = be32_to_cpu(out.psv_idx[i]) & 0xffffff;
+
+out:
+	return err;
+}
+EXPORT_SYMBOL(mlx5_core_create_psv);
+
+int mlx5_core_destroy_psv(struct mlx5_core_dev *dev, int psv_num)
+{
+	struct mlx5_destroy_psv_in in;
+	struct mlx5_destroy_psv_out out;
+	int err;
+
+	memset(&in, 0, sizeof(in));
+	memset(&out, 0, sizeof(out));
+
+	in.psv_number = cpu_to_be32(psv_num);
+	in.hdr.opcode = cpu_to_be16(MLX5_CMD_OP_DESTROY_PSV);
+	err = mlx5_cmd_exec(dev, &in, sizeof(in), &out, sizeof(out));
+	if (err) {
+		mlx5_core_err(dev, "destroy_psv cmd exec failed %d\n", err);
+		goto out;
+	}
+
+	if (out.hdr.status) {
+		mlx5_core_err(dev, "destroy_psv bad status %d\n", out.hdr.status);
+		err = mlx5_cmd_status_to_err(&out.hdr);
+		goto out;
+	}
+
+out:
+	return err;
+}
+EXPORT_SYMBOL(mlx5_core_destroy_psv);
diff --git a/include/linux/mlx5/device.h b/include/linux/mlx5/device.h
index 68029b3..aef7eed 100644
--- a/include/linux/mlx5/device.h
+++ b/include/linux/mlx5/device.h
@@ -48,6 +48,8 @@ enum {
 	MLX5_MAX_COMMANDS		= 32,
 	MLX5_CMD_DATA_BLOCK_SIZE	= 512,
 	MLX5_PCI_CMD_XPORT		= 7,
+	MLX5_MKEY_BSF_OCTO_SIZE		= 4,
+	MLX5_MAX_PSVS			= 4,
 };
 
 enum {
@@ -908,4 +910,27 @@ enum {
 	MLX_EXT_PORT_CAP_FLAG_EXTENDED_PORT_INFO	= 1 <<  0
 };
 
+struct mlx5_allocate_psv_in {
+	struct mlx5_inbox_hdr   hdr;
+	__be32			npsv_pd;
+	__be32			rsvd_psv0;
+};
+
+struct mlx5_allocate_psv_out {
+	struct mlx5_outbox_hdr  hdr;
+	u8			rsvd[8];
+	__be32			psv_idx[4];
+};
+
+struct mlx5_destroy_psv_in {
+	struct mlx5_inbox_hdr	hdr;
+	__be32                  psv_number;
+	u8                      rsvd[4];
+};
+
+struct mlx5_destroy_psv_out {
+	struct mlx5_outbox_hdr  hdr;
+	u8                      rsvd[8];
+};
+
 #endif /* MLX5_DEVICE_H */
diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h
index 8888381..e7eb977 100644
--- a/include/linux/mlx5/driver.h
+++ b/include/linux/mlx5/driver.h
@@ -398,6 +398,25 @@ struct mlx5_eq {
 	struct mlx5_rsc_debug	*dbg;
 };
 
+struct mlx5_core_psv {
+	u32	psv_idx;
+	struct psv_layout {
+		u32	pd;
+		u16	syndrome;
+		u16	reserved;
+		u16	bg;
+		u16	app_tag;
+		u32	ref_tag;
+	} psv;
+};
+
+struct mlx5_core_sig_ctx {
+	struct mlx5_core_psv	psv_memory;
+	struct mlx5_core_psv	psv_wire;
+	struct mlx5_core_mr    *data_mr;
+	struct mlx5_core_mr    *prot_mr;
+	bool			sig_status_collected;
+};
 
 struct mlx5_core_mr {
 	u64			iova;
@@ -734,6 +753,9 @@ void mlx5_db_free(struct mlx5_core_dev *dev, struct mlx5_db *db);
 const char *mlx5_command_str(int command);
 int mlx5_cmdif_debugfs_init(struct mlx5_core_dev *dev);
 void mlx5_cmdif_debugfs_cleanup(struct mlx5_core_dev *dev);
+int mlx5_core_create_psv(struct mlx5_core_dev *dev, u32 pdn,
+			 int npsvs, u32 *sig_index);
+int mlx5_core_destroy_psv(struct mlx5_core_dev *dev, int psv_num);
 
 static inline u32 mlx5_mkey_to_idx(u32 mkey)
 {
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH RFC 4/9] IB/mlx5: Initialize mlx5_ib_qp signature related
       [not found] ` <1381851510-17290-1-git-send-email-sagig-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
                     ` (2 preceding siblings ...)
  2013-10-15 15:38   ` [PATCH RFC 3/9] IB/mlx5, mlx5_core: Support for create_mr and destroy_mr Sagi Grimberg
@ 2013-10-15 15:38   ` Sagi Grimberg
  2013-10-15 15:38   ` [PATCH RFC 5/9] IB/mlx5: Break wqe handling to begin & finish routines Sagi Grimberg
                     ` (4 subsequent siblings)
  8 siblings, 0 replies; 21+ messages in thread
From: Sagi Grimberg @ 2013-10-15 15:38 UTC (permalink / raw)
  To: linux-rdma-u79uwXL29TY76Z2rM5mHXA

If user requested signature enable we Initialize
relevant mlx5_ib_qp members. we mark the qp as sig_enable
we initiatlize empty sig_err_list, and we increase qp size.

Signed-off-by: Sagi Grimberg <sagig-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
---
 drivers/infiniband/hw/mlx5/mlx5_ib.h |    5 +++++
 drivers/infiniband/hw/mlx5/qp.c      |    7 +++++++
 include/linux/mlx5/qp.h              |    1 +
 3 files changed, 13 insertions(+), 0 deletions(-)

diff --git a/drivers/infiniband/hw/mlx5/mlx5_ib.h b/drivers/infiniband/hw/mlx5/mlx5_ib.h
index 45d7424..1d5793e 100644
--- a/drivers/infiniband/hw/mlx5/mlx5_ib.h
+++ b/drivers/infiniband/hw/mlx5/mlx5_ib.h
@@ -189,6 +189,11 @@ struct mlx5_ib_qp {
 
 	int			create_type;
 	u32			pa_lkey;
+
+	/* Store signature errors */
+	bool			signature_en;
+	struct list_head	sig_err_list;
+	spinlock_t		sig_err_lock;
 };
 
 struct mlx5_ib_cq_buf {
diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c
index 045f8cd..9a8c622 100644
--- a/drivers/infiniband/hw/mlx5/qp.c
+++ b/drivers/infiniband/hw/mlx5/qp.c
@@ -734,6 +734,13 @@ static int create_qp_common(struct mlx5_ib_dev *dev, struct ib_pd *pd,
 	spin_lock_init(&qp->sq.lock);
 	spin_lock_init(&qp->rq.lock);
 
+	if (init_attr->create_flags == IB_QP_CREATE_SIGNATURE_EN) {
+		init_attr->cap.max_send_wr *= MLX5_SIGNATURE_SQ_MULT;
+		spin_lock_init(&qp->sig_err_lock);
+		INIT_LIST_HEAD(&qp->sig_err_list);
+		qp->signature_en = true;
+	}
+
 	if (init_attr->sq_sig_type == IB_SIGNAL_ALL_WR)
 		qp->sq_signal_bits = MLX5_WQE_CTRL_CQ_UPDATE;
 
diff --git a/include/linux/mlx5/qp.h b/include/linux/mlx5/qp.h
index d9e3eac..174805c 100644
--- a/include/linux/mlx5/qp.h
+++ b/include/linux/mlx5/qp.h
@@ -37,6 +37,7 @@
 #include <linux/mlx5/driver.h>
 
 #define MLX5_INVALID_LKEY	0x100
+#define MLX5_SIGNATURE_SQ_MULT	3
 
 enum mlx5_qp_optpar {
 	MLX5_QP_OPTPAR_ALT_ADDR_PATH		= 1 << 0,
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH RFC 5/9] IB/mlx5: Break wqe handling to begin & finish routines
       [not found] ` <1381851510-17290-1-git-send-email-sagig-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
                     ` (3 preceding siblings ...)
  2013-10-15 15:38   ` [PATCH RFC 4/9] IB/mlx5: Initialize mlx5_ib_qp signature related Sagi Grimberg
@ 2013-10-15 15:38   ` Sagi Grimberg
  2013-10-15 15:38   ` [PATCH RFC 6/9] IB/mlx5: remove MTT access mode from umr flags helper function Sagi Grimberg
                     ` (3 subsequent siblings)
  8 siblings, 0 replies; 21+ messages in thread
From: Sagi Grimberg @ 2013-10-15 15:38 UTC (permalink / raw)
  To: linux-rdma-u79uwXL29TY76Z2rM5mHXA

As a preliminary step for signature feature which will
reuqire posting multiple (3) WQEs for a single WR, we
break post_send routine WQE indexing into begin and
finish routines.

This patch does not change any functionality.

Signed-off-by: Sagi Grimberg <sagig-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
---
 drivers/infiniband/hw/mlx5/qp.c |   95 ++++++++++++++++++++++++---------------
 1 files changed, 59 insertions(+), 36 deletions(-)

diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c
index 9a8c622..57733a5 100644
--- a/drivers/infiniband/hw/mlx5/qp.c
+++ b/drivers/infiniband/hw/mlx5/qp.c
@@ -1985,6 +1985,57 @@ static u8 get_fence(u8 fence, struct ib_send_wr *wr)
 	}
 }
 
+static int begin_wqe(struct mlx5_ib_qp *qp, void **seg,
+		     struct mlx5_wqe_ctrl_seg **ctrl,
+		     struct ib_send_wr *wr, int *idx,
+		     int *size, int nreq)
+{
+	int err = 0;
+	if (unlikely(mlx5_wq_overflow(&qp->sq, nreq, qp->ibqp.send_cq))) {
+		err = -ENOMEM;
+		return err;
+	}
+
+	*idx = qp->sq.cur_post & (qp->sq.wqe_cnt - 1);
+	*seg = mlx5_get_send_wqe(qp, *idx);
+	*ctrl = *seg;
+	*(uint32_t *)(*seg + 8) = 0;
+	(*ctrl)->imm = send_ieth(wr);
+	(*ctrl)->fm_ce_se = qp->sq_signal_bits |
+		(wr->send_flags & IB_SEND_SIGNALED ?
+		 MLX5_WQE_CTRL_CQ_UPDATE : 0) |
+		(wr->send_flags & IB_SEND_SOLICITED ?
+		 MLX5_WQE_CTRL_SOLICITED : 0);
+
+	*seg += sizeof(**ctrl);
+	*size = sizeof(**ctrl) / 16;
+
+	return err;
+}
+
+static void finish_wqe(struct mlx5_ib_qp *qp,
+		       struct mlx5_wqe_ctrl_seg *ctrl,
+		       u8 size, unsigned idx, u64 wr_id,
+		       int *nreq, u8 fence, u8 next_fence,
+		       u32 mlx5_opcode)
+{
+	u8 opmod = 0;
+	ctrl->opmod_idx_opcode = cpu_to_be32(((u32)(qp->sq.cur_post) << 8) |
+					     mlx5_opcode | ((u32)opmod << 24));
+	ctrl->qpn_ds = cpu_to_be32(size | (qp->mqp.qpn << 8));
+	ctrl->fm_ce_se |= fence;
+	qp->fm_cache = next_fence;
+	if (unlikely(qp->wq_sig))
+		ctrl->signature = wq_sig(ctrl);
+
+	qp->sq.wrid[idx] = wr_id;
+	qp->sq.w_list[idx].opcode = mlx5_opcode;
+	qp->sq.wqe_head[idx] = qp->sq.head + (*nreq)++;
+	qp->sq.cur_post += DIV_ROUND_UP(size * 16, MLX5_SEND_WQE_BB);
+	qp->sq.w_list[idx].next = qp->sq.cur_post;
+}
+
+
 int mlx5_ib_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
 		      struct ib_send_wr **bad_wr)
 {
@@ -1998,7 +2049,6 @@ int mlx5_ib_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
 	int uninitialized_var(size);
 	void *qend = qp->sq.qend;
 	unsigned long flags;
-	u32 mlx5_opcode;
 	unsigned idx;
 	int err = 0;
 	int inl = 0;
@@ -2007,7 +2057,6 @@ int mlx5_ib_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
 	int nreq;
 	int i;
 	u8 next_fence = 0;
-	u8 opmod = 0;
 	u8 fence;
 
 	spin_lock_irqsave(&qp->sq.lock, flags);
@@ -2020,36 +2069,23 @@ int mlx5_ib_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
 			goto out;
 		}
 
-		if (unlikely(mlx5_wq_overflow(&qp->sq, nreq, qp->ibqp.send_cq))) {
+		fence = qp->fm_cache;
+		num_sge = wr->num_sge;
+		if (unlikely(num_sge > qp->sq.max_gs)) {
 			mlx5_ib_warn(dev, "\n");
 			err = -ENOMEM;
 			*bad_wr = wr;
 			goto out;
 		}
 
-		fence = qp->fm_cache;
-		num_sge = wr->num_sge;
-		if (unlikely(num_sge > qp->sq.max_gs)) {
+		err = begin_wqe(qp, &seg, &ctrl, wr, &idx, &size, nreq);
+		if (err) {
 			mlx5_ib_warn(dev, "\n");
 			err = -ENOMEM;
 			*bad_wr = wr;
 			goto out;
 		}
 
-		idx = qp->sq.cur_post & (qp->sq.wqe_cnt - 1);
-		seg = mlx5_get_send_wqe(qp, idx);
-		ctrl = seg;
-		*(uint32_t *)(seg + 8) = 0;
-		ctrl->imm = send_ieth(wr);
-		ctrl->fm_ce_se = qp->sq_signal_bits |
-			(wr->send_flags & IB_SEND_SIGNALED ?
-			 MLX5_WQE_CTRL_CQ_UPDATE : 0) |
-			(wr->send_flags & IB_SEND_SOLICITED ?
-			 MLX5_WQE_CTRL_SOLICITED : 0);
-
-		seg += sizeof(*ctrl);
-		size = sizeof(*ctrl) / 16;
-
 		switch (ibqp->qp_type) {
 		case IB_QPT_XRC_INI:
 			xrc = seg;
@@ -2199,22 +2235,9 @@ int mlx5_ib_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
 			}
 		}
 
-		mlx5_opcode = mlx5_ib_opcode[wr->opcode];
-		ctrl->opmod_idx_opcode = cpu_to_be32(((u32)(qp->sq.cur_post) << 8)	|
-						     mlx5_opcode			|
-						     ((u32)opmod << 24));
-		ctrl->qpn_ds = cpu_to_be32(size | (qp->mqp.qpn << 8));
-		ctrl->fm_ce_se |= get_fence(fence, wr);
-		qp->fm_cache = next_fence;
-		if (unlikely(qp->wq_sig))
-			ctrl->signature = wq_sig(ctrl);
-
-		qp->sq.wrid[idx] = wr->wr_id;
-		qp->sq.w_list[idx].opcode = mlx5_opcode;
-		qp->sq.wqe_head[idx] = qp->sq.head + nreq;
-		qp->sq.cur_post += DIV_ROUND_UP(size * 16, MLX5_SEND_WQE_BB);
-		qp->sq.w_list[idx].next = qp->sq.cur_post;
-
+		finish_wqe(qp, ctrl, size, idx, wr->wr_id,&nreq,
+			   get_fence(fence, wr), next_fence,
+			   mlx5_ib_opcode[wr->opcode]);
 		if (0)
 			dump_wqe(qp, idx, size);
 	}
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH RFC 6/9] IB/mlx5: remove MTT access mode from umr flags helper function
       [not found] ` <1381851510-17290-1-git-send-email-sagig-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
                     ` (4 preceding siblings ...)
  2013-10-15 15:38   ` [PATCH RFC 5/9] IB/mlx5: Break wqe handling to begin & finish routines Sagi Grimberg
@ 2013-10-15 15:38   ` Sagi Grimberg
  2013-10-15 15:38   ` [PATCH RFC 7/9] IB/mlx5: Support IB_WR_REG_SIG_MR Sagi Grimberg
                     ` (2 subsequent siblings)
  8 siblings, 0 replies; 21+ messages in thread
From: Sagi Grimberg @ 2013-10-15 15:38 UTC (permalink / raw)
  To: linux-rdma-u79uwXL29TY76Z2rM5mHXA

get_umr_flags helper function might be used for types
of access modes other than ACCESS_MODE_MTT, such as
ACCESS_MODE_KLM. so remove it from helper and caller
will add it's own access mode flag.

This commit does not add/change functionality.

Signed-off-by: Sagi Grimberg <sagig-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
---
 drivers/infiniband/hw/mlx5/qp.c |    5 +++--
 1 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c
index 57733a5..2517fb3 100644
--- a/drivers/infiniband/hw/mlx5/qp.c
+++ b/drivers/infiniband/hw/mlx5/qp.c
@@ -1775,7 +1775,7 @@ static u8 get_umr_flags(int acc)
 	       (acc & IB_ACCESS_REMOTE_WRITE  ? MLX5_PERM_REMOTE_WRITE : 0) |
 	       (acc & IB_ACCESS_REMOTE_READ   ? MLX5_PERM_REMOTE_READ  : 0) |
 	       (acc & IB_ACCESS_LOCAL_WRITE   ? MLX5_PERM_LOCAL_WRITE  : 0) |
-		MLX5_PERM_LOCAL_READ | MLX5_PERM_UMR_EN | MLX5_ACCESS_MODE_MTT;
+		MLX5_PERM_LOCAL_READ | MLX5_PERM_UMR_EN;
 }
 
 static void set_mkey_segment(struct mlx5_mkey_seg *seg, struct ib_send_wr *wr,
@@ -1787,7 +1787,8 @@ static void set_mkey_segment(struct mlx5_mkey_seg *seg, struct ib_send_wr *wr,
 		return;
 	}
 
-	seg->flags = get_umr_flags(wr->wr.fast_reg.access_flags);
+	seg->flags = get_umr_flags(wr->wr.fast_reg.access_flags) |
+		     MLX5_ACCESS_MODE_MTT;
 	*writ = seg->flags & (MLX5_PERM_LOCAL_WRITE | IB_ACCESS_REMOTE_WRITE);
 	seg->qpn_mkey7_0 = cpu_to_be32((wr->wr.fast_reg.rkey & 0xff) | 0xffffff00);
 	seg->flags_pd = cpu_to_be32(MLX5_MKEY_REMOTE_INVAL);
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH RFC 7/9] IB/mlx5: Support IB_WR_REG_SIG_MR
       [not found] ` <1381851510-17290-1-git-send-email-sagig-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
                     ` (5 preceding siblings ...)
  2013-10-15 15:38   ` [PATCH RFC 6/9] IB/mlx5: remove MTT access mode from umr flags helper function Sagi Grimberg
@ 2013-10-15 15:38   ` Sagi Grimberg
  2013-10-15 15:38   ` [PATCH RFC 8/9] IB/mlx5: Collect signature error completion Sagi Grimberg
  2013-10-15 15:38   ` [PATCH RFC 9/9] IB/mlx5: Publish support in signature feature Sagi Grimberg
  8 siblings, 0 replies; 21+ messages in thread
From: Sagi Grimberg @ 2013-10-15 15:38 UTC (permalink / raw)
  To: linux-rdma-u79uwXL29TY76Z2rM5mHXA

This patch implements IB_WR_REG_SIG_MR posted by the user.

Baisically this WR involvs 3 WQEs in order to prepare and properly
register the signature layout:

1. post UMR WR to register the sig_mr in one of two possible ways:
    * In case the user registered a single MR for data so the UMR data segment
      consists of:
      - single klm (data MR) passed by the user
      - BSF with signature attributes requested by the user.
    * In case the user registered 2 MRs, one for data and one for protection,
      the UMR consists of:
      - strided block format which includes data and protection MRs and
        their repetitive block format.
      - BSF with signature attributes requested by the user.

2. post SET_PSV in order to set the for the memory domain initial
   signature parameters passed by the user.

3. post SET_PSV in order to set the for the wire domain initial
   signature parameters passed by the user.

This patch also introduces some helper functions to set the BSF correctly
and determining the signature format selectors.

Signed-off-by: Sagi Grimberg <sagig-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
---
 drivers/infiniband/hw/mlx5/qp.c |  413 +++++++++++++++++++++++++++++++++++++++
 include/linux/mlx5/qp.h         |   56 ++++++
 2 files changed, 469 insertions(+), 0 deletions(-)

diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c
index 2517fb3..971d434 100644
--- a/drivers/infiniband/hw/mlx5/qp.c
+++ b/drivers/infiniband/hw/mlx5/qp.c
@@ -1721,6 +1721,26 @@ static __be64 frwr_mkey_mask(void)
 	return cpu_to_be64(result);
 }
 
+static __be64 sig_mkey_mask(void)
+{
+	u64 result;
+
+	result = MLX5_MKEY_MASK_LEN		|
+		MLX5_MKEY_MASK_PAGE_SIZE	|
+		MLX5_MKEY_MASK_START_ADDR	|
+		MLX5_MKEY_MASK_EN_RINVAL	|
+		MLX5_MKEY_MASK_KEY		|
+		MLX5_MKEY_MASK_LR		|
+		MLX5_MKEY_MASK_LW		|
+		MLX5_MKEY_MASK_RR		|
+		MLX5_MKEY_MASK_RW		|
+		MLX5_MKEY_MASK_SMALL_FENCE	|
+		MLX5_MKEY_MASK_FREE		|
+		MLX5_MKEY_MASK_BSF_EN;
+
+	return cpu_to_be64(result);
+}
+
 static void set_frwr_umr_segment(struct mlx5_wqe_umr_ctrl_seg *umr,
 				 struct ib_send_wr *wr, int li)
 {
@@ -1903,6 +1923,336 @@ static int set_data_inl_seg(struct mlx5_ib_qp *qp, struct ib_send_wr *wr,
 	return 0;
 }
 
+static u16 prot_field_size(enum ib_signature_type type, u16 block_size)
+{
+	switch (type) {
+	case IB_SIG_TYPE_T10_DIF:
+		return MLX5_DIF_SIZE;
+	default:
+		return 0;
+	}
+}
+
+static u8 bs_selector(int block_size)
+{
+	switch (block_size) {
+	case 512:	    return 0x1;
+	case 520:	    return 0x2;
+	case 4096:	    return 0x3;
+	case 4160:	    return 0x4;
+	case 1073741824:    return 0x5;
+	default:	    return 0;
+	}
+}
+
+static int format_selector(struct ib_sig_attrs *attr,
+			   struct ib_sig_domain *domain,
+			   int *selector)
+{
+
+#define FORMAT_DIF_NONE		0
+#define FORMAT_DIF_CRC_INC	4
+#define FORMAT_DIF_CSUM_INC	12
+#define FORMAT_DIF_CRC_NO_INC	13
+#define FORMAT_DIF_CSUM_NO_INC	14
+
+	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;
+		}
+		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;
+		}
+		break;
+	default:
+		return 1;
+	}
+
+	return 0;
+}
+
+static int mlx5_set_bsf(struct ib_mr *sig_mr,
+			struct ib_sig_attrs *sig_attrs,
+			struct mlx5_bsf *bsf, u32 data_size)
+{
+	struct mlx5_core_sig_ctx *msig = to_mmr(sig_mr)->sig;
+	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;
+
+	switch (sig_attrs->mem.sig_type) {
+	case IB_SIG_TYPE_T10_DIF:
+		if (sig_attrs->wire.sig_type != IB_SIG_TYPE_T10_DIF)
+			return -EINVAL;
+
+		/* Input domain check byte mask */
+		basic->check_byte_mask = sig_attrs->check_mask;
+		if (mem->sig.dif.block_size == wire->sig.dif.block_size &&
+		    mem->sig.dif.type == wire->sig.dif.type) {
+			/* 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 = 0xff;
+			else
+				basic->wire.copy_byte_mask = 0x3f;
+		} else
+			basic->wire.bs_selector = bs_selector(wire->sig.dif.block_size);
+
+		basic->mem.bs_selector = bs_selector(mem->sig.dif.block_size);
+		basic->raw_data_size = cpu_to_be32(data_size);
+
+		ret = format_selector(sig_attrs, mem, &selector);
+		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);
+		if (ret)
+			return -EINVAL;
+		basic->w_bfs_psv = cpu_to_be32(selector << 24 |
+					       msig->psv_wire.psv_idx);
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int set_sig_data_segment(struct ib_send_wr *wr, void **seg, int *size)
+{
+	struct ib_sig_attrs *sig_attrs = wr->wr.sig_handover.sig_attrs;
+	struct ib_mr *sig_mr = wr->wr.sig_handover.sig_mr;
+	struct ib_mr *data_mr = wr->wr.sig_handover.data_mr;
+	struct mlx5_bsf *bsf;
+	u32 data_size = wr->wr.sig_handover.data_size;
+	u64 data_va = wr->wr.sig_handover.data_va;
+	int ret;
+	int wqe_size;
+
+	if (!wr->wr.sig_handover.prot_mr) {
+		/**
+		 * Source domain doesn't contain signature information
+		 * So need construct:
+		 * 		    ------------------
+		 * 		   |     data_klm     |
+		 * 		    ------------------
+		 * 		   |       BSF        |
+		 * 		    ------------------
+		 **/
+		struct mlx5_klm *data_klm = *seg;
+
+		data_klm->bcount = cpu_to_be32(data_size);
+		data_klm->key = cpu_to_be32(data_mr->lkey);
+		data_klm->va = cpu_to_be64(data_va);
+		wqe_size = ALIGN(sizeof(*data_klm), 64);
+	} else {
+		/**
+		 * Source domain contains signature information
+		 * So need construct a strided block format:
+		 * 		 ---------------------------
+		 * 		|     stride_block_ctrl	    |
+		 * 		 ---------------------------
+		 * 		|          data_klm	    |
+		 * 		 ---------------------------
+		 * 		|          prot_klm	    |
+		 * 		 ---------------------------
+		 * 		|             BSF           |
+		 * 		 ---------------------------
+		 **/
+		struct ib_mr *prot_mr = wr->wr.sig_handover.prot_mr;
+		struct mlx5_stride_block_ctrl_seg *sblock_ctrl;
+		struct mlx5_stride_block_entry *data_sentry;
+		struct mlx5_stride_block_entry *prot_sentry;
+		u64 prot_va = wr->wr.sig_handover.prot_va;
+		u16 block_size = sig_attrs->mem.sig.dif.block_size;
+		int prot_size;
+
+		sblock_ctrl = *seg;
+		data_sentry = (void *)sblock_ctrl + sizeof(*sblock_ctrl);
+		prot_sentry = (void *)data_sentry + sizeof(*data_sentry);
+
+		prot_size = prot_field_size(sig_attrs->mem.sig_type,
+					    block_size);
+		if (!prot_size) {
+			pr_err("Bad block size given: %u\n", block_size);
+			return -EINVAL;
+		}
+		sblock_ctrl->bcount_per_cycle = cpu_to_be32(block_size +
+							    prot_size);
+		sblock_ctrl->op = cpu_to_be32(MLX5_STRIDE_BLOCK_OP);
+		sblock_ctrl->repeat_count = cpu_to_be32(data_size / block_size);
+		sblock_ctrl->num_entries = cpu_to_be16(2);
+
+		data_sentry->bcount = cpu_to_be16(block_size);
+		data_sentry->key = cpu_to_be32(data_mr->lkey);
+		data_sentry->va = cpu_to_be64(data_va);
+		prot_sentry->bcount = cpu_to_be16(prot_size);
+		prot_sentry->key = cpu_to_be32(prot_mr->lkey);
+
+		if (prot_mr == data_mr && prot_va == data_va) {
+			/**
+			 * The data and protection are interleaved
+			 * in a single memory region
+			 **/
+			prot_sentry->va = cpu_to_be64(data_va + block_size);
+			prot_sentry->stride = sblock_ctrl->bcount_per_cycle;
+			data_sentry->stride = prot_sentry->stride;
+		} else {
+			/* The data and protection are two different buffers */
+			prot_sentry->va = cpu_to_be64(prot_va);
+			data_sentry->stride = cpu_to_be16(block_size);
+			prot_sentry->stride = cpu_to_be16(prot_size);
+		}
+		wqe_size = ALIGN(sizeof(*sblock_ctrl) + sizeof(*data_sentry) +
+				 sizeof(*prot_sentry), 64);
+	}
+
+	bsf = *seg + wqe_size;
+	ret = mlx5_set_bsf(sig_mr, sig_attrs, bsf, data_size);
+	if (ret)
+		return -EINVAL;
+
+	*seg = (void *)bsf + ALIGN(sizeof(*bsf), 64);
+	*size += (wqe_size + sizeof(*bsf)) / 16;
+
+	return 0;
+}
+
+static void set_sig_mkey_segment(struct mlx5_mkey_seg *seg,
+				 struct ib_send_wr *wr, u32 nelements,
+				 u32 length, u32 pdn)
+{
+	struct ib_mr *sig_mr = wr->wr.sig_handover.sig_mr;
+	u32 sig_key = sig_mr->rkey;
+
+	memset(seg, 0, sizeof(*seg));
+
+	seg->status = 0x4; /*set free*/
+	seg->flags = get_umr_flags(wr->wr.sig_handover.access_flags) |
+				   MLX5_ACCESS_MODE_KLM;
+	seg->qpn_mkey7_0 = cpu_to_be32((sig_key & 0xff) | 0xffffff00);
+	seg->flags_pd = cpu_to_be32(MLX5_MKEY_REMOTE_INVAL |
+				    MLX5_MKEY_BSF_EN | pdn);
+	seg->start_addr = 0;
+	seg->len = cpu_to_be64(length);
+	seg->xlt_oct_size = cpu_to_be32(be16_to_cpu(get_klm_octo(nelements)));
+	seg->bsfs_octo_size = cpu_to_be32(MLX5_MKEY_BSF_OCTO_SIZE);
+}
+
+static void set_sig_umr_segment(struct mlx5_wqe_umr_ctrl_seg *umr,
+				struct ib_send_wr *wr, u32 nelements)
+{
+	memset(umr, 0, sizeof(*umr));
+
+	umr->flags = 1 << 7 | 1 << 5; /* inline | check free */
+	umr->klm_octowords = get_klm_octo(nelements);
+	umr->bsf_octowords = cpu_to_be16(MLX5_MKEY_BSF_OCTO_SIZE);
+	umr->mkey_mask = sig_mkey_mask();
+}
+
+
+static int set_sig_umr_wr(struct ib_send_wr *wr, struct mlx5_ib_qp *qp,
+			  void **seg, int *size)
+{
+	struct mlx5_ib_mr *sig_mr = to_mmr(wr->wr.sig_handover.sig_mr);
+	u32 pdn = get_pd(qp)->pdn;
+	u32 klm_oct_size;
+	int region_len, ret;
+
+	if (unlikely(wr->wr.sig_handover.access_flags &
+		     IB_ACCESS_REMOTE_ATOMIC) ||
+	    unlikely(!sig_mr->sig) || unlikely(!qp->signature_en) ||
+	    unlikely(!sig_mr->sig->sig_status_collected))
+		return -EINVAL;
+
+	/* length of the protected region, data + protection */
+	region_len = wr->wr.sig_handover.data_size +
+		     wr->wr.sig_handover.prot_size;
+
+	/**
+	 * KLM octoword size - if protection was provided
+	 * then we use strided block format (3 octowords),
+	 * else we use single KLM (1 octoword)
+	 **/
+	klm_oct_size = wr->wr.sig_handover.prot_mr ? 3 : 1;
+
+	set_sig_umr_segment(*seg, wr, klm_oct_size);
+	*seg += sizeof(struct mlx5_wqe_umr_ctrl_seg);
+	*size += sizeof(struct mlx5_wqe_umr_ctrl_seg) / 16;
+	if (unlikely((*seg == qp->sq.qend)))
+		*seg = mlx5_get_send_wqe(qp, 0);
+
+	set_sig_mkey_segment(*seg, wr, klm_oct_size, region_len, pdn);
+	*seg += sizeof(struct mlx5_mkey_seg);
+	*size += sizeof(struct mlx5_mkey_seg) / 16;
+	if (unlikely((*seg == qp->sq.qend)))
+		*seg = mlx5_get_send_wqe(qp, 0);
+
+	ret = set_sig_data_segment(wr, seg, size);
+	if (ret)
+		return ret;
+
+	if (unlikely((*seg == qp->sq.qend)))
+		*seg = mlx5_get_send_wqe(qp, 0);
+
+	sig_mr->sig->sig_status_collected = false;
+	return 0;
+}
+
+static int set_psv_wr(struct ib_sig_domain *domain,
+		      u32 psv_idx, void **seg, int *size)
+{
+	struct mlx5_seg_set_psv *psv_seg = *seg;
+
+	psv_seg->psv_num = cpu_to_be32(psv_idx);
+	switch (domain->sig_type) {
+	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;
+	}
+
+	return 0;
+}
+
 static int set_frwr_li_wr(void **seg, struct ib_send_wr *wr, int *size,
 			  struct mlx5_core_dev *mdev, struct mlx5_ib_pd *pd, struct mlx5_ib_qp *qp)
 {
@@ -2044,6 +2394,7 @@ int mlx5_ib_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
 	struct mlx5_ib_dev *dev = to_mdev(ibqp->device);
 	struct mlx5_core_dev *mdev = &dev->mdev;
 	struct mlx5_ib_qp *qp = to_mqp(ibqp);
+	struct mlx5_ib_mr *mr;
 	struct mlx5_wqe_data_seg *dpseg;
 	struct mlx5_wqe_xrc_seg *xrc;
 	struct mlx5_bf *bf = qp->bf;
@@ -2156,6 +2507,67 @@ int mlx5_ib_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
 				num_sge = 0;
 				break;
 
+			case IB_WR_REG_SIG_MR:
+				next_fence = MLX5_FENCE_MODE_INITIATOR_SMALL;
+				qp->sq.wr_data[idx] = IB_WR_REG_SIG_MR;
+				mr = to_mmr(wr->wr.sig_handover.sig_mr);
+
+				ctrl->imm = cpu_to_be32(mr->ibmr.rkey);
+				err = set_sig_umr_wr(wr, qp, &seg, &size);
+				if (err) {
+					mlx5_ib_warn(dev, "\n");
+					*bad_wr = wr;
+					goto out;
+				}
+
+				finish_wqe(qp, ctrl, size, idx, wr->wr_id,
+					   &nreq, get_fence(fence, wr),
+					   next_fence, MLX5_OPCODE_UMR);
+				err = begin_wqe(qp, &seg, &ctrl, wr,
+						&idx, &size, nreq);
+				if (err) {
+						mlx5_ib_warn(dev, "\n");
+						err = -ENOMEM;
+						*bad_wr = wr;
+						goto out;
+				}
+
+				err = set_psv_wr(&wr->wr.sig_handover.sig_attrs->mem,
+						 mr->sig->psv_memory.psv_idx, &seg,
+						 &size);
+				if (err) {
+					mlx5_ib_warn(dev, "\n");
+					*bad_wr = wr;
+					goto out;
+				}
+
+				finish_wqe(qp, ctrl, size, idx, wr->wr_id,
+					   &nreq, get_fence(fence, wr),
+					   next_fence, MLX5_OPCODE_SET_PSV);
+				err = begin_wqe(qp, &seg, &ctrl, wr,
+						&idx, &size, nreq);
+				if (err) {
+						mlx5_ib_warn(dev, "\n");
+						err = -ENOMEM;
+						*bad_wr = wr;
+						goto out;
+				}
+
+				err = set_psv_wr(&wr->wr.sig_handover.sig_attrs->wire,
+						 mr->sig->psv_wire.psv_idx, &seg,
+						 &size);
+				if (err) {
+					mlx5_ib_warn(dev, "\n");
+					*bad_wr = wr;
+					goto out;
+				}
+
+				finish_wqe(qp, ctrl, size, idx, wr->wr_id,
+					   &nreq, get_fence(fence, wr),
+					   next_fence, MLX5_OPCODE_SET_PSV);
+				num_sge = 0;
+				goto skip_psv;
+
 			default:
 				break;
 			}
@@ -2239,6 +2651,7 @@ int mlx5_ib_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
 		finish_wqe(qp, ctrl, size, idx, wr->wr_id,&nreq,
 			   get_fence(fence, wr), next_fence,
 			   mlx5_ib_opcode[wr->opcode]);
+skip_psv:
 		if (0)
 			dump_wqe(qp, idx, size);
 	}
diff --git a/include/linux/mlx5/qp.h b/include/linux/mlx5/qp.h
index 174805c..9ea6cf6 100644
--- a/include/linux/mlx5/qp.h
+++ b/include/linux/mlx5/qp.h
@@ -38,6 +38,8 @@
 
 #define MLX5_INVALID_LKEY	0x100
 #define MLX5_SIGNATURE_SQ_MULT	3
+#define MLX5_DIF_SIZE		8
+#define MLX5_STRIDE_BLOCK_OP	0x400
 
 enum mlx5_qp_optpar {
 	MLX5_QP_OPTPAR_ALT_ADDR_PATH		= 1 << 0,
@@ -279,6 +281,60 @@ struct mlx5_wqe_inline_seg {
 	__be32	byte_count;
 };
 
+struct mlx5_bsf {
+	struct mlx5_bsf_basic {
+		u8		bsf_size_sbs;
+		u8		check_byte_mask;
+		union {
+			u8	copy_byte_mask;
+			u8	bs_selector;
+			u8	rsvd_wflags;
+		} wire;
+		union {
+			u8	bs_selector;
+			u8	rsvd_mflags;
+		} mem;
+		__be32		raw_data_size;
+		__be32		w_bfs_psv;
+		__be32		m_bfs_psv;
+	} basic;
+	struct mlx5_bsf_ext {
+		__be32		t_init_gen_pro_size;
+		__be32		rsvd_epi_size;
+		__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_klm {
+	__be32		bcount;
+	__be32		key;
+	__be64		va;
+};
+
+struct mlx5_stride_block_entry {
+	__be16		stride;
+	__be16		bcount;
+	__be32		key;
+	__be64		va;
+};
+
+struct mlx5_stride_block_ctrl_seg {
+	__be32		bcount_per_cycle;
+	__be32		op;
+	__be32		repeat_count;
+	u16		rsvd;
+	__be16		num_entries;
+};
+
 struct mlx5_core_qp {
 	void (*event)		(struct mlx5_core_qp *, int);
 	int			qpn;
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH RFC 8/9] IB/mlx5: Collect signature error completion
       [not found] ` <1381851510-17290-1-git-send-email-sagig-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
                     ` (6 preceding siblings ...)
  2013-10-15 15:38   ` [PATCH RFC 7/9] IB/mlx5: Support IB_WR_REG_SIG_MR Sagi Grimberg
@ 2013-10-15 15:38   ` Sagi Grimberg
  2013-10-15 15:38   ` [PATCH RFC 9/9] IB/mlx5: Publish support in signature feature Sagi Grimberg
  8 siblings, 0 replies; 21+ messages in thread
From: Sagi Grimberg @ 2013-10-15 15:38 UTC (permalink / raw)
  To: linux-rdma-u79uwXL29TY76Z2rM5mHXA

This commit takes care of the generated signature
error cqe generated by the HW (if happened) and stores
it on the QP signature error list.

Once the user will get the completion for the transaction
he must check for signature errors on signature memory region
using a new lightweight verb ib_check_sig_status and if such
exsists, get the signature error information.

In case the user will not check for signature error, i.e.
call ib_check_sig_status, it will not be allowed to use
the memory region for another signature operation
(REG_SIG_MR work request will fail).

Signed-off-by: Sagi Grimberg <sagig-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
---
 drivers/infiniband/hw/mlx5/cq.c      |   49 ++++++++++++++++++++++++++++++++++
 drivers/infiniband/hw/mlx5/main.c    |    1 +
 drivers/infiniband/hw/mlx5/mlx5_ib.h |    2 +
 drivers/infiniband/hw/mlx5/mr.c      |   34 +++++++++++++++++++++++
 drivers/infiniband/hw/mlx5/qp.c      |   14 +++++++++-
 include/linux/mlx5/cq.h              |    1 +
 include/linux/mlx5/device.h          |   17 ++++++++++++
 include/linux/mlx5/driver.h          |    2 +
 8 files changed, 119 insertions(+), 1 deletions(-)

diff --git a/drivers/infiniband/hw/mlx5/cq.c b/drivers/infiniband/hw/mlx5/cq.c
index 344ab03..c1d4029 100644
--- a/drivers/infiniband/hw/mlx5/cq.c
+++ b/drivers/infiniband/hw/mlx5/cq.c
@@ -351,6 +351,34 @@ static void handle_atomics(struct mlx5_ib_qp *qp, struct mlx5_cqe64 *cqe64,
 	qp->sq.last_poll = tail;
 }
 
+static void get_sig_err_item(struct mlx5_sig_err_cqe *cqe,
+			     struct ib_sig_err *item)
+{
+	u16 syndrome = be16_to_cpu(cqe->syndrome);
+
+	switch (syndrome) {
+	case 13:
+		item->err_type = IB_SIG_BAD_CRC;
+		break;
+	case 12:
+		item->err_type = IB_SIG_BAD_APPTAG;
+		break;
+	case 11:
+		item->err_type = IB_SIG_BAD_REFTAG;
+		break;
+	default:
+		break;
+	}
+
+	item->expected_guard = be32_to_cpu(cqe->expected_trans_sig) >> 16;
+	item->actual_guard = be32_to_cpu(cqe->actual_trans_sig) >> 16;
+	item->expected_logical_block = be32_to_cpu(cqe->expected_reftag);
+	item->actual_logical_block = be32_to_cpu(cqe->actual_reftag);
+	item->sig_err_offset = be64_to_cpu(cqe->err_offset);
+	item->qpn = be32_to_cpu(cqe->qpn);
+	item->key = be32_to_cpu(cqe->mkey);
+}
+
 static int mlx5_poll_one(struct mlx5_ib_cq *cq,
 			 struct mlx5_ib_qp **cur_qp,
 			 struct ib_wc *wc)
@@ -360,12 +388,15 @@ static int mlx5_poll_one(struct mlx5_ib_cq *cq,
 	struct mlx5_cqe64 *cqe64;
 	struct mlx5_core_qp *mqp;
 	struct mlx5_ib_wq *wq;
+	struct mlx5_sig_err_cqe *sig_err_cqe;
+	struct ib_sig_err *err_item;
 	uint8_t opcode;
 	uint32_t qpn;
 	u16 wqe_ctr;
 	void *cqe;
 	int idx;
 
+repoll:
 	cqe = next_cqe_sw(cq);
 	if (!cqe)
 		return -EAGAIN;
@@ -449,6 +480,24 @@ static int mlx5_poll_one(struct mlx5_ib_cq *cq,
 			}
 		}
 		break;
+	case MLX5_CQE_SIG_ERR:
+		sig_err_cqe = (struct mlx5_sig_err_cqe *)cqe64;
+		err_item = kzalloc(sizeof(*err_item), GFP_ATOMIC);
+		if (!err_item) {
+			mlx5_ib_err(dev, "Failed to allocate sig_err item\n");
+			return -ENOMEM;
+		}
+
+		get_sig_err_item(sig_err_cqe, err_item);
+
+		mlx5_ib_dbg(dev, "Got SIGERR on key: 0x%x\n",
+			    err_item->key);
+
+		spin_lock(&(*cur_qp)->sig_err_lock);
+		list_add(&err_item->list, &(*cur_qp)->sig_err_list);
+		spin_unlock(&(*cur_qp)->sig_err_lock);
+
+		goto repoll;
 	}
 
 	return 0;
diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c
index 2e67a37..f3c7111 100644
--- a/drivers/infiniband/hw/mlx5/main.c
+++ b/drivers/infiniband/hw/mlx5/main.c
@@ -1409,6 +1409,7 @@ static int init_one(struct pci_dev *pdev,
 	dev->ib_dev.alloc_fast_reg_mr	= mlx5_ib_alloc_fast_reg_mr;
 	dev->ib_dev.alloc_fast_reg_page_list = mlx5_ib_alloc_fast_reg_page_list;
 	dev->ib_dev.free_fast_reg_page_list  = mlx5_ib_free_fast_reg_page_list;
+	dev->ib_dev.check_sig_status	= mlx5_ib_check_sig_status;
 
 	if (mdev->caps.flags & MLX5_DEV_CAP_FLAG_XRC) {
 		dev->ib_dev.alloc_xrcd = mlx5_ib_alloc_xrcd;
diff --git a/drivers/infiniband/hw/mlx5/mlx5_ib.h b/drivers/infiniband/hw/mlx5/mlx5_ib.h
index 1d5793e..73b8cf0 100644
--- a/drivers/infiniband/hw/mlx5/mlx5_ib.h
+++ b/drivers/infiniband/hw/mlx5/mlx5_ib.h
@@ -533,6 +533,8 @@ int mlx5_mr_cache_init(struct mlx5_ib_dev *dev);
 int mlx5_mr_cache_cleanup(struct mlx5_ib_dev *dev);
 int mlx5_mr_ib_cont_pages(struct ib_umem *umem, u64 addr, int *count, int *shift);
 void mlx5_umr_cq_handler(struct ib_cq *cq, void *cq_context);
+int mlx5_ib_check_sig_status(struct ib_mr *sig_mr,
+			     struct ib_sig_err *sig_err);
 
 static inline void init_query_mad(struct ib_smp *mad)
 {
diff --git a/drivers/infiniband/hw/mlx5/mr.c b/drivers/infiniband/hw/mlx5/mr.c
index 2f6758c..de0e102 100644
--- a/drivers/infiniband/hw/mlx5/mr.c
+++ b/drivers/infiniband/hw/mlx5/mr.c
@@ -979,6 +979,8 @@ struct ib_mr *mlx5_ib_create_mr(struct ib_pd *pd,
 		mr->sig->psv_memory.psv_idx = psv_index[0];
 		mr->sig->psv_wire.psv_idx = psv_index[1];
 		mr->sig->sig_status_collected = true;
+		/* Next UMR, Arm SIGERR */
+		++mr->sig->sig_err;
 	}
 
 	err = mlx5_core_create_mkey(&dev->mdev, &mr->mmr, in, sizeof(*in));
@@ -1125,3 +1127,35 @@ void mlx5_ib_free_fast_reg_page_list(struct ib_fast_reg_page_list *page_list)
 	kfree(mfrpl->ibfrpl.page_list);
 	kfree(mfrpl);
 }
+
+int mlx5_ib_check_sig_status(struct ib_mr *sig_mr,
+			     struct ib_sig_err *sig_err)
+{
+	struct mlx5_ib_mr *mmr = to_mmr(sig_mr);
+	struct mlx5_ib_qp *mqp = mmr->sig->last_qp;
+	struct ib_sig_err *err_item;
+	int ret = 0;
+
+	if (list_empty(&mqp->sig_err_list))
+		goto out;
+
+	spin_lock(&mqp->sig_err_lock);
+	list_for_each_entry(err_item, &mqp->sig_err_list, list)
+		if ((sig_mr->lkey >> 8) == (err_item->key >> 8)) {
+			list_del(&err_item->list);
+			spin_unlock(&mqp->sig_err_lock);
+			memcpy(sig_err, err_item, sizeof(*err_item));
+			kfree(err_item);
+			if ((sig_mr->lkey & 0xff) == (err_item->key & 0xff))
+				ret = 1;
+
+			/* Increment SW number of sig errors */
+			++mmr->sig->sig_err;
+			goto out;
+		}
+
+	spin_unlock(&mqp->sig_err_lock);
+out:
+	mmr->sig->sig_status_collected = true;
+	return ret;
+}
diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c
index 971d434..7663102 100644
--- a/drivers/infiniband/hw/mlx5/qp.c
+++ b/drivers/infiniband/hw/mlx5/qp.c
@@ -993,6 +993,7 @@ static void destroy_qp_common(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp)
 {
 	struct mlx5_ib_cq *send_cq, *recv_cq;
 	struct mlx5_modify_qp_mbox_in *in;
+	struct ib_sig_err *item, *tmp;
 	int err;
 
 	in = kzalloc(sizeof(*in), GFP_KERNEL);
@@ -1004,6 +1005,12 @@ static void destroy_qp_common(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp)
 			mlx5_ib_warn(dev, "mlx5_ib: modify QP %06x to RESET failed\n",
 				     qp->mqp.qpn);
 
+	if (qp->signature_en && !list_empty(&qp->sig_err_list))
+		list_for_each_entry_safe(item, tmp, &qp->sig_err_list, list) {
+			list_del(&item->list);
+			kfree(item);
+		}
+
 	get_cqs(qp, &send_cq, &recv_cq);
 
 	if (qp->create_type == MLX5_QP_KERNEL) {
@@ -2154,6 +2161,7 @@ static void set_sig_mkey_segment(struct mlx5_mkey_seg *seg,
 {
 	struct ib_mr *sig_mr = wr->wr.sig_handover.sig_mr;
 	u32 sig_key = sig_mr->rkey;
+	u8 sigerr = to_mmr(sig_mr)->sig->sig_err & 1;
 
 	memset(seg, 0, sizeof(*seg));
 
@@ -2161,7 +2169,7 @@ static void set_sig_mkey_segment(struct mlx5_mkey_seg *seg,
 	seg->flags = get_umr_flags(wr->wr.sig_handover.access_flags) |
 				   MLX5_ACCESS_MODE_KLM;
 	seg->qpn_mkey7_0 = cpu_to_be32((sig_key & 0xff) | 0xffffff00);
-	seg->flags_pd = cpu_to_be32(MLX5_MKEY_REMOTE_INVAL |
+	seg->flags_pd = cpu_to_be32(MLX5_MKEY_REMOTE_INVAL | sigerr << 26 |
 				    MLX5_MKEY_BSF_EN | pdn);
 	seg->start_addr = 0;
 	seg->len = cpu_to_be64(length);
@@ -2195,6 +2203,10 @@ static int set_sig_umr_wr(struct ib_send_wr *wr, struct mlx5_ib_qp *qp,
 	    unlikely(!sig_mr->sig->sig_status_collected))
 		return -EINVAL;
 
+
+	/* record last active qp */
+	sig_mr->sig->last_qp = qp;
+
 	/* length of the protected region, data + protection */
 	region_len = wr->wr.sig_handover.data_size +
 		     wr->wr.sig_handover.prot_size;
diff --git a/include/linux/mlx5/cq.h b/include/linux/mlx5/cq.h
index 3db67f7..e1974b0 100644
--- a/include/linux/mlx5/cq.h
+++ b/include/linux/mlx5/cq.h
@@ -80,6 +80,7 @@ enum {
 	MLX5_CQE_RESP_SEND_IMM	= 3,
 	MLX5_CQE_RESP_SEND_INV	= 4,
 	MLX5_CQE_RESIZE_CQ	= 0xff, /* TBD */
+	MLX5_CQE_SIG_ERR	= 12,
 	MLX5_CQE_REQ_ERR	= 13,
 	MLX5_CQE_RESP_ERR	= 14,
 };
diff --git a/include/linux/mlx5/device.h b/include/linux/mlx5/device.h
index aef7eed..8c43971 100644
--- a/include/linux/mlx5/device.h
+++ b/include/linux/mlx5/device.h
@@ -544,6 +544,23 @@ struct mlx5_cqe64 {
 	u8		op_own;
 };
 
+struct mlx5_sig_err_cqe {
+	u8		rsvd0[16];
+	__be32		expected_trans_sig;
+	__be32		actual_trans_sig;
+	__be32		expected_reftag;
+	__be32		actual_reftag;
+	__be16		syndrome;
+	u8		rsvd22[2];
+	__be32		mkey;
+	__be64		err_offset;
+	u8		rsvd30[8];
+	__be32		qpn;
+	u8		rsvd38[2];
+	u8		signature;
+	u8		opcode;
+};
+
 struct mlx5_wqe_srq_next_seg {
 	u8			rsvd0[2];
 	__be16			next_wqe_index;
diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h
index e7eb977..6839e24 100644
--- a/include/linux/mlx5/driver.h
+++ b/include/linux/mlx5/driver.h
@@ -415,7 +415,9 @@ struct mlx5_core_sig_ctx {
 	struct mlx5_core_psv	psv_wire;
 	struct mlx5_core_mr    *data_mr;
 	struct mlx5_core_mr    *prot_mr;
+	struct mlx5_ib_qp      *last_qp;
 	bool			sig_status_collected;
+	u8			sig_err;
 };
 
 struct mlx5_core_mr {
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH RFC 9/9] IB/mlx5: Publish support in signature feature
       [not found] ` <1381851510-17290-1-git-send-email-sagig-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
                     ` (7 preceding siblings ...)
  2013-10-15 15:38   ` [PATCH RFC 8/9] IB/mlx5: Collect signature error completion Sagi Grimberg
@ 2013-10-15 15:38   ` Sagi Grimberg
  8 siblings, 0 replies; 21+ messages in thread
From: Sagi Grimberg @ 2013-10-15 15:38 UTC (permalink / raw)
  To: linux-rdma-u79uwXL29TY76Z2rM5mHXA

Currently support only T10-DIF types of signature
handover operations (typs 1|2|3).

Signed-off-by: Sagi Grimberg <sagig-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
---
 drivers/infiniband/hw/mlx5/main.c |    9 +++++++++
 1 files changed, 9 insertions(+), 0 deletions(-)

diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c
index f3c7111..3dd8219 100644
--- a/drivers/infiniband/hw/mlx5/main.c
+++ b/drivers/infiniband/hw/mlx5/main.c
@@ -274,6 +274,15 @@ static int mlx5_ib_query_device(struct ib_device *ibdev,
 	if (flags & MLX5_DEV_CAP_FLAG_XRC)
 		props->device_cap_flags |= IB_DEVICE_XRC;
 	props->device_cap_flags |= IB_DEVICE_MEM_MGT_EXTENSIONS;
+	if (flags & MLX5_DEV_CAP_FLAG_SIG_HAND_OVER) {
+		props->device_cap_flags |= IB_DEVICE_SIGNATURE_HANDOVER;
+		/* At this stage no support for signature handover */
+		props->sig_prot_cap = IB_PROT_T10DIF_TYPE_1 |
+				      IB_PROT_T10DIF_TYPE_2 |
+				      IB_PROT_T10DIF_TYPE_3;
+		props->sig_guard_cap = IB_GUARD_T10DIF_CRC |
+				       IB_GUARD_T10DIF_CSUM;
+	}
 
 	props->vendor_id	   = be32_to_cpup((__be32 *)(out_mad->data + 36)) &
 		0xffffff;
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* RE: [PATCH RFC 1/9] IB/core: Introduce indirect and protected memory regions
       [not found]     ` <1381851510-17290-2-git-send-email-sagig-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
@ 2013-10-17 22:43       ` Hefty, Sean
       [not found]         ` <1828884A29C6694DAF28B7E6B8A8237388CE2BE0-P5GAC/sN6hkd3b2yrw5b5LfspsVTdybXVpNB7YpNyf8@public.gmane.org>
       [not found]         ` <5263CC09.6030103@mellanox.com>
  0 siblings, 2 replies; 21+ messages in thread
From: Hefty, Sean @ 2013-10-17 22:43 UTC (permalink / raw)
  To: Sagi Grimberg, linux-rdma-u79uwXL29TY76Z2rM5mHXA

> This commit introduces verbs for creating memory regions
> which will allow new types of memory key operations such
> as indirect memory registration and protected memory
> registration.
> 
> Indirect memory registration is registering several (one
> of more) pre-registered memory regions in a specific layout.
> The Indirect region may potentialy describe several regions
> and some repitition format between them.

I didn't follow this direct versus indirect difference.  See below.
 
> +struct ib_mr *ib_create_mr(struct ib_pd *pd,
> +			   struct ib_mr_init_attr *mr_init_attr)
> +{
> +	struct ib_mr *mr;
> +
> +	if (!pd->device->create_mr)
> +		return ERR_PTR(-ENOSYS);
> +
> +	mr = pd->device->create_mr(pd, mr_init_attr);
> +
> +	if (!IS_ERR(mr)) {
> +		mr->device  = pd->device;
> +		mr->pd      = pd;
> +		mr->uobject = NULL;
> +		atomic_inc(&pd->usecnt);
> +		atomic_set(&mr->usecnt, 0);
> +	}
> +
> +	return mr;
> +}
> +EXPORT_SYMBOL(ib_create_mr);
> +
> +int ib_destroy_mr(struct ib_mr *mr)
> +{
> +	struct ib_pd *pd;
> +	int ret;
> +
> +	if (atomic_read(&mr->usecnt))
> +		return -EBUSY;
> +
> +	pd = mr->pd;
> +	ret = mr->device->destroy_mr(mr);
> +	if (!ret)
> +		atomic_dec(&pd->usecnt);
> +
> +	return ret;
> +}
> +EXPORT_SYMBOL(ib_destroy_mr);
> +
>  struct ib_mr *ib_alloc_fast_reg_mr(struct ib_pd *pd, int
> max_page_list_len)
>  {
>  	struct ib_mr *mr;
> diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h
> index 645c3ce..65b7e79 100644
> --- a/include/rdma/ib_verbs.h
> +++ b/include/rdma/ib_verbs.h
> @@ -925,6 +925,30 @@ enum ib_mr_rereg_flags {
>  	IB_MR_REREG_ACCESS	= (1<<2)
>  };
> 
> +enum ib_mr_create_flags {
> +		IB_MR_SIGNATURE_EN = 1,
> +};
> +
> +enum ib_mr_reg_type {
> +	IB_MR_REG_DIRECT,
> +	IB_MR_REG_INDIRECT,
> +};
> +
> +/**
> + * ib_mr_init_attr - Memory region init attributes passed to routine
> + *	ib_create_mr.
> + * @reg_type: requested mapping type, this can be direct/indirect
> + *   registration or repetitive structure registration.
> + * @max_reg_descriptors: max number of registration units that
> + *   may be used with UMR work requests.
> + * @flags: MR creation flags bit mask.
> + */
> +struct ib_mr_init_attr {
> +	enum ib_mr_reg_type	reg_type;
> +	int			max_reg_descriptors;
> +	enum ib_mr_create_flags	flags;
> +};
> +
>  /**
>   * struct ib_mw_bind - Parameters for a type 1 memory window bind
> operation.
>   * @wr_id:      Work request id.
> @@ -1257,6 +1281,9 @@ struct ib_device {
>  	int                        (*query_mr)(struct ib_mr *mr,
>  					       struct ib_mr_attr *mr_attr);
>  	int                        (*dereg_mr)(struct ib_mr *mr);
> +	int                        (*destroy_mr)(struct ib_mr *mr);
> +	struct ib_mr *		   (*create_mr)(struct ib_pd *pd,
> +						struct ib_mr_init_attr *mr_init_attr);

These create and destroy something called an 'MR', but are not actually associated with any memory buffers.  Is this some sort of conceptual sub-protection domain?  Why is this needed, versus defining new ib_mr_attr fields?

- Sean
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 21+ messages in thread

* RE: [PATCH RFC 2/9] IB/core: Introduce Signature Verbs API
       [not found]     ` <1381851510-17290-3-git-send-email-sagig-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
@ 2013-10-17 22:51       ` Hefty, Sean
       [not found]         ` <1828884A29C6694DAF28B7E6B8A8237388CE2BFF-P5GAC/sN6hkd3b2yrw5b5LfspsVTdybXVpNB7YpNyf8@public.gmane.org>
  0 siblings, 1 reply; 21+ messages in thread
From: Hefty, Sean @ 2013-10-17 22:51 UTC (permalink / raw)
  To: Sagi Grimberg, linux-rdma-u79uwXL29TY76Z2rM5mHXA

> @@ -885,6 +901,19 @@ struct ib_send_wr {
>  			u32                      rkey;
>  			struct ib_mw_bind_info   bind_info;
>  		} bind_mw;
> +		struct {
> +			struct ib_sig_attrs    *sig_attrs;
> +			struct ib_mr	       *sig_mr;
> +			int			access_flags;
> +			/* Registered data mr */
> +			struct ib_mr	       *data_mr;
> +			u32			data_size;
> +			u64			data_va;
> +			/* Registered protection mr */
> +			struct ib_mr	       *prot_mr;
> +			u32			prot_size;
> +			u64			prot_va;
> +		} sig_handover;

At what point do we admit that this is a ridiculous structure?

Help me understand what this WR is doing.  Is this telling the HCA to copy data between local MRs?  What is a 'data MR' versus a 'protected MR'?  (I'm not hip on T10-DIF.)
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH RFC 2/9] IB/core: Introduce Signature Verbs API
       [not found]         ` <1828884A29C6694DAF28B7E6B8A8237388CE2BFF-P5GAC/sN6hkd3b2yrw5b5LfspsVTdybXVpNB7YpNyf8@public.gmane.org>
@ 2013-10-20 12:55           ` Sagi Grimberg
       [not found]             ` <5263D2DE.8010500-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
  0 siblings, 1 reply; 21+ messages in thread
From: Sagi Grimberg @ 2013-10-20 12:55 UTC (permalink / raw)
  To: Hefty, Sean; +Cc: linux-rdma-u79uwXL29TY76Z2rM5mHXA, Oren Duer

On 10/18/2013 1:51 AM, Hefty, Sean wrote:
>> @@ -885,6 +901,19 @@ struct ib_send_wr {
>>   			u32                      rkey;
>>   			struct ib_mw_bind_info   bind_info;
>>   		} bind_mw;
>> +		struct {
>> +			struct ib_sig_attrs    *sig_attrs;
>> +			struct ib_mr	       *sig_mr;
>> +			int			access_flags;
>> +			/* Registered data mr */
>> +			struct ib_mr	       *data_mr;
>> +			u32			data_size;
>> +			u64			data_va;
>> +			/* Registered protection mr */
>> +			struct ib_mr	       *prot_mr;
>> +			u32			prot_size;
>> +			u64			prot_va;
>> +		} sig_handover;
> At what point do we admit that this is a ridiculous structure?

If you are referring to ib_send_wr, I agree, shall we modify it to a 
union of typedefs so it becomes more readable?

> Help me understand what this WR is doing.  Is this telling the HCA to copy data between local MRs?  What is a 'data MR' versus a 'protected MR'?  (I'm not hip on T10-DIF.)

No data copy, god forbids... :)

Let me start by giving a short intro on signature (and T10-DIF).
In signature world, data may exist with protection information which is 
the guarding the data. In T10-DIF (Data Integrity Fields) for example, 
these are 8-byte guards which includes CRC for each 512 bytes of data 
(block).
An HCA which support signature offload, is expected to validate that the 
data is intact (each block matches its guard) and send it correctly over 
the wire (in T10-DIF case the data and protection should be interleaved 
i.e. 512B of data followed by 8B of protection guard) or alternatively, 
validate data (+ protection) coming from the wire and write it to the 
associated memory areas.
In the general case, the data and the protection guards may lie in 
different memory areas. SCSI mid-layer for instance, passes the 
transport driver 2 buffers using 2 scatterlists.
The transport driver (or application in the general case), is expected 
to register each buffer (as it normally would in order to use RDMA) 
using 2 MRs.

The signature handover operation is binding all the necessary 
information for the HCA together: where is the data (data_mr), where is 
the protection information (prot_mr), what are the signature properties 
(sig_attrs).
Once this step is taken (WR is posted), a single MR (sig_mr) describes 
the signature handover operation and can be used to perform RDMA under 
signature presence.
Once the HCA will perform RDMA over this MR, it will take into account 
the signature context of the transaction and will follow the signature 
attributes configured.

Hope this helps,

Sagi.
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH RFC 1/9] IB/core: Introduce indirect and protected memory regions
       [not found]         ` <1828884A29C6694DAF28B7E6B8A8237388CE2BE0-P5GAC/sN6hkd3b2yrw5b5LfspsVTdybXVpNB7YpNyf8@public.gmane.org>
@ 2013-10-20 13:05           ` Sagi Grimberg
  0 siblings, 0 replies; 21+ messages in thread
From: Sagi Grimberg @ 2013-10-20 13:05 UTC (permalink / raw)
  To: Hefty, Sean; +Cc: linux-rdma-u79uwXL29TY76Z2rM5mHXA, Oren Duer

On 10/18/2013 1:43 AM, Hefty, Sean wrote:
>> This commit introduces verbs for creating memory regions
>> which will allow new types of memory key operations such
>> as indirect memory registration and protected memory
>> registration.
>>
>> Indirect memory registration is registering several (one
>> of more) pre-registered memory regions in a specific layout.
>> The Indirect region may potentialy describe several regions
>> and some repitition format between them.
> I didn't follow this direct versus indirect difference.  See below.
>   

Hey Sean, thanks for looking into this!

Indirect memory registration feature will be submitted in the future. 
Signature feature is using it "under the hood".
I'll remove it from v2 as it creates a source of confusion and I want to 
concentrate on signature.

Now since you opened this door, briefly,
unlike direct (known) MRs which are associated with a page-list, 
indirect MRs can be associated with other MRs in the form of a list of 
tuples {lkey, addr, len} providing more flexible memory registrations.

>> +struct ib_mr *ib_create_mr(struct ib_pd *pd,
>> +			   struct ib_mr_init_attr *mr_init_attr)
>> +{
>> +	struct ib_mr *mr;
>> +
>> +	if (!pd->device->create_mr)
>> +		return ERR_PTR(-ENOSYS);
>> +
>> +	mr = pd->device->create_mr(pd, mr_init_attr);
>> +
>> +	if (!IS_ERR(mr)) {
>> +		mr->device  = pd->device;
>> +		mr->pd      = pd;
>> +		mr->uobject = NULL;
>> +		atomic_inc(&pd->usecnt);
>> +		atomic_set(&mr->usecnt, 0);
>> +	}
>> +
>> +	return mr;
>> +}
>> +EXPORT_SYMBOL(ib_create_mr);
>> +
>> +int ib_destroy_mr(struct ib_mr *mr)
>> +{
>> +	struct ib_pd *pd;
>> +	int ret;
>> +
>> +	if (atomic_read(&mr->usecnt))
>> +		return -EBUSY;
>> +
>> +	pd = mr->pd;
>> +	ret = mr->device->destroy_mr(mr);
>> +	if (!ret)
>> +		atomic_dec(&pd->usecnt);
>> +
>> +	return ret;
>> +}
>> +EXPORT_SYMBOL(ib_destroy_mr);
>> +
>>   struct ib_mr *ib_alloc_fast_reg_mr(struct ib_pd *pd, int
>> max_page_list_len)
>>   {
>>   	struct ib_mr *mr;
>> diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h
>> index 645c3ce..65b7e79 100644
>> --- a/include/rdma/ib_verbs.h
>> +++ b/include/rdma/ib_verbs.h
>> @@ -925,6 +925,30 @@ enum ib_mr_rereg_flags {
>>   	IB_MR_REREG_ACCESS	= (1<<2)
>>   };
>>
>> +enum ib_mr_create_flags {
>> +		IB_MR_SIGNATURE_EN = 1,
>> +};
>> +
>> +enum ib_mr_reg_type {
>> +	IB_MR_REG_DIRECT,
>> +	IB_MR_REG_INDIRECT,
>> +};
>> +
>> +/**
>> + * ib_mr_init_attr - Memory region init attributes passed to routine
>> + *	ib_create_mr.
>> + * @reg_type: requested mapping type, this can be direct/indirect
>> + *   registration or repetitive structure registration.
>> + * @max_reg_descriptors: max number of registration units that
>> + *   may be used with UMR work requests.
>> + * @flags: MR creation flags bit mask.
>> + */
>> +struct ib_mr_init_attr {
>> +	enum ib_mr_reg_type	reg_type;
>> +	int			max_reg_descriptors;
>> +	enum ib_mr_create_flags	flags;
>> +};
>> +
>>   /**
>>    * struct ib_mw_bind - Parameters for a type 1 memory window bind
>> operation.
>>    * @wr_id:      Work request id.
>> @@ -1257,6 +1281,9 @@ struct ib_device {
>>   	int                        (*query_mr)(struct ib_mr *mr,
>>   					       struct ib_mr_attr *mr_attr);
>>   	int                        (*dereg_mr)(struct ib_mr *mr);
>> +	int                        (*destroy_mr)(struct ib_mr *mr);
>> +	struct ib_mr *		   (*create_mr)(struct ib_pd *pd,
>> +						struct ib_mr_init_attr *mr_init_attr);
> These create and destroy something called an 'MR', but are not actually associated with any memory buffers.  Is this some sort of conceptual sub-protection domain?  Why is this needed, versus defining new ib_mr_attr fields?

This MR can be perceived as a generalization of fast_reg MR. When using 
fast memory registration the verbs user will call ib_alloc_fast_reg_mr() 
in order to allocate an MR that may be used for fast registration method 
by posting
a fast registration work-request on the send-queue (FRWR). The user does 
not pass any memory buffers to ib_alloc_fast_reg_mr() as the actual 
registration is done via posting WR. This follows the same notation, but 
allows new functionality (such as signature enable).

As things are today, No MR creation method (fast_reg, dma, phys, 
user...) allows passing initialization parameters. signature feature 
requires some internal resources management, and we need some kind of 
indication that signature is requested for this MR. I'm suggesting that 
this verb will cover the general case and later on, it is possible to 
extend this method to cover all existing flavors of MR creation 
(implement the existing ones with it).

Do you agree? or do you prefer to extend other MR allocation methods to 
receive initialization parameters?

> - Sean

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 21+ messages in thread

* RE: [PATCH RFC 2/9] IB/core: Introduce Signature Verbs API
       [not found]             ` <5263D2DE.8010500-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
@ 2013-10-21 14:34               ` Hefty, Sean
       [not found]                 ` <1828884A29C6694DAF28B7E6B8A8237388CEA91E-P5GAC/sN6hkd3b2yrw5b5LfspsVTdybXVpNB7YpNyf8@public.gmane.org>
  0 siblings, 1 reply; 21+ messages in thread
From: Hefty, Sean @ 2013-10-21 14:34 UTC (permalink / raw)
  To: Sagi Grimberg; +Cc: linux-rdma-u79uwXL29TY76Z2rM5mHXA, Oren Duer

> The signature handover operation is binding all the necessary
> information for the HCA together: where is the data (data_mr), where is
> the protection information (prot_mr), what are the signature properties
> (sig_attrs).
> Once this step is taken (WR is posted), a single MR (sig_mr) describes
> the signature handover operation and can be used to perform RDMA under
> signature presence.
> Once the HCA will perform RDMA over this MR, it will take into account
> the signature context of the transaction and will follow the signature
> attributes configured.

It seems like this changes loses the ability to use an SGL.  Why are the signature properties separate from the protection information? 
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 21+ messages in thread

* RE: [PATCH RFC 1/9] IB/core: Introduce indirect and protected memory regions
       [not found]           ` <5263CC09.6030103-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
@ 2013-10-21 14:39             ` Hefty, Sean
  0 siblings, 0 replies; 21+ messages in thread
From: Hefty, Sean @ 2013-10-21 14:39 UTC (permalink / raw)
  To: Sagi Grimberg; +Cc: linux-rdma-u79uwXL29TY76Z2rM5mHXA, Oren Duer

> This MR can be perceived as a generalization of fast_reg MR. When using
> fast memory registration the verbs user will call ib_alloc_fast_reg_mr() in
> order to allocate an MR that may be used for fast registration method by
> posting
> a fast registration work-request on the send-queue (FRWR). The user does
> not pass any memory buffers to ib_alloc_fast_reg_mr() as the actual
> registration is done via posting WR. This follows the same notation, but
> allows new functionality (such as signature enable).

This makes sense to me.

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH RFC 2/9] IB/core: Introduce Signature Verbs API
       [not found]                 ` <1828884A29C6694DAF28B7E6B8A8237388CEA91E-P5GAC/sN6hkd3b2yrw5b5LfspsVTdybXVpNB7YpNyf8@public.gmane.org>
@ 2013-10-21 16:12                   ` Sagi Grimberg
       [not found]                     ` <52655282.1000505-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
  0 siblings, 1 reply; 21+ messages in thread
From: Sagi Grimberg @ 2013-10-21 16:12 UTC (permalink / raw)
  To: Hefty, Sean; +Cc: linux-rdma-u79uwXL29TY76Z2rM5mHXA, Oren Duer

On 10/21/2013 5:34 PM, Hefty, Sean wrote:
>> The signature handover operation is binding all the necessary
>> information for the HCA together: where is the data (data_mr), where is
>> the protection information (prot_mr), what are the signature properties
>> (sig_attrs).
>> Once this step is taken (WR is posted), a single MR (sig_mr) describes
>> the signature handover operation and can be used to perform RDMA under
>> signature presence.
>> Once the HCA will perform RDMA over this MR, it will take into account
>> the signature context of the transaction and will follow the signature
>> attributes configured.
> It seems like this changes loses the ability to use an SGL.

I don't think so,
Signature MR simply describes a "signature associated" memory region 
i.e. it is a memory region that
also defines some signature operation offload aside from normal RDMA 
(for example validate & strip).
SGL are used to publish several rkeys for the server/target/peer to 
perform RDMA on each.
In this case the user previously registered each MR which he wishes it's 
peer to RDMA over.
Same story here, if user has several signature associated MRs, where he 
wish his peer to RDMA over (in a protected manner),
he can use these rkeys to construct SGL.

>    Why are the signature properties separate from the protection information?

Well,
Protection information is the actual protection block guards of the data 
(i.e. CRCs, XORs, DIFs etc..), while the signature properties
structure is the descriptor telling the HCA how to 
treat/validate/generate the protection information.

Note that signature support requires the HCA to be able to support 
INSERT operations.
This means that there is no protection information and the HCA is asked 
to generate it and add it to the data stream
(which may be incoming or outgoing...),

Hope this helps.

Sagi.
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 21+ messages in thread

* RE: [PATCH RFC 2/9] IB/core: Introduce Signature Verbs API
       [not found]                     ` <52655282.1000505-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
@ 2013-10-22 16:41                       ` Hefty, Sean
       [not found]                         ` <1828884A29C6694DAF28B7E6B8A8237388CEE1C7-P5GAC/sN6hkd3b2yrw5b5LfspsVTdybXVpNB7YpNyf8@public.gmane.org>
  0 siblings, 1 reply; 21+ messages in thread
From: Hefty, Sean @ 2013-10-22 16:41 UTC (permalink / raw)
  To: Sagi Grimberg; +Cc: linux-rdma-u79uwXL29TY76Z2rM5mHXA, Oren Duer

> I don't think so,
> Signature MR simply describes a "signature associated" memory region
> i.e. it is a memory region that
> also defines some signature operation offload aside from normal RDMA
> (for example validate & strip).
> SGL are used to publish several rkeys for the server/target/peer to
> perform RDMA on each.
> In this case the user previously registered each MR which he wishes it's
> peer to RDMA over.
> Same story here, if user has several signature associated MRs, where he
> wish his peer to RDMA over (in a protected manner),
> he can use these rkeys to construct SGL.
> 
> >    Why are the signature properties separate from the protection
> information?
> 
> Well,
> Protection information is the actual protection block guards of the data
> (i.e. CRCs, XORs, DIFs etc..), while the signature properties
> structure is the descriptor telling the HCA how to
> treat/validate/generate the protection information.
> 
> Note that signature support requires the HCA to be able to support
> INSERT operations.
> This means that there is no protection information and the HCA is asked
> to generate it and add it to the data stream
> (which may be incoming or outgoing...),

Would we lose anything making this a new operation for the QP, versus trying to hook it into the existing ib_post_send call?
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH RFC 2/9] IB/core: Introduce Signature Verbs API
       [not found]                         ` <1828884A29C6694DAF28B7E6B8A8237388CEE1C7-P5GAC/sN6hkd3b2yrw5b5LfspsVTdybXVpNB7YpNyf8@public.gmane.org>
@ 2013-10-22 17:46                           ` Sagi Grimberg
       [not found]                             ` <5266BA11.6090300-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
  0 siblings, 1 reply; 21+ messages in thread
From: Sagi Grimberg @ 2013-10-22 17:46 UTC (permalink / raw)
  To: Hefty, Sean; +Cc: linux-rdma-u79uwXL29TY76Z2rM5mHXA, Oren Duer

On 10/22/2013 7:41 PM, Hefty, Sean wrote:
>> I don't think so,
>> Signature MR simply describes a "signature associated" memory region
>> i.e. it is a memory region that
>> also defines some signature operation offload aside from normal RDMA
>> (for example validate & strip).
>> SGL are used to publish several rkeys for the server/target/peer to
>> perform RDMA on each.
>> In this case the user previously registered each MR which he wishes it's
>> peer to RDMA over.
>> Same story here, if user has several signature associated MRs, where he
>> wish his peer to RDMA over (in a protected manner),
>> he can use these rkeys to construct SGL.
>>
>>>     Why are the signature properties separate from the protection
>> information?
>>
>> Well,
>> Protection information is the actual protection block guards of the data
>> (i.e. CRCs, XORs, DIFs etc..), while the signature properties
>> structure is the descriptor telling the HCA how to
>> treat/validate/generate the protection information.
>>
>> Note that signature support requires the HCA to be able to support
>> INSERT operations.
>> This means that there is no protection information and the HCA is asked
>> to generate it and add it to the data stream
>> (which may be incoming or outgoing...),
> Would we lose anything making this a new operation for the QP, versus trying to hook it into the existing ib_post_send call?

If I understand correctly you are suggesting making it a verb? Well this 
operation is a fast-path operation - so I guess we will loose it in this 
case.
Take SCSI for example, for each IO operation submitted by SCSI 
mid-layer, transport layer should perform any protection policy that 
SCSI asked for.
 From this point of view, signature operation resembles fast 
registration (since the transport does not own the IOP data buffers, so 
it uses fast registration methods).
That is why we are hooking into ib_post_send.

Hope this helps.

Sagi.

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 21+ messages in thread

* RE: [PATCH RFC 2/9] IB/core: Introduce Signature Verbs API
       [not found]                             ` <5266BA11.6090300-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
@ 2013-10-22 18:20                               ` Hefty, Sean
       [not found]                                 ` <1828884A29C6694DAF28B7E6B8A8237388CEE286-P5GAC/sN6hkd3b2yrw5b5LfspsVTdybXVpNB7YpNyf8@public.gmane.org>
  0 siblings, 1 reply; 21+ messages in thread
From: Hefty, Sean @ 2013-10-22 18:20 UTC (permalink / raw)
  To: Sagi Grimberg; +Cc: linux-rdma-u79uwXL29TY76Z2rM5mHXA, Oren Duer

> > Would we lose anything making this a new operation for the QP, versus
> trying to hook it into the existing ib_post_send call?
> 
> If I understand correctly you are suggesting making it a verb? Well this
> operation is a fast-path operation - so I guess we will loose it in this
> case.
> Take SCSI for example, for each IO operation submitted by SCSI
> mid-layer, transport layer should perform any protection policy that
> SCSI asked for.
>  From this point of view, signature operation resembles fast
> registration (since the transport does not own the IOP data buffers, so
> it uses fast registration methods).
> That is why we are hooking into ib_post_send.

I'm suggesting multiple calls that can post to the send queue, rather than one call that does a giant switch statement at the beginning based on the opcode.
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH RFC 2/9] IB/core: Introduce Signature Verbs API
       [not found]                                 ` <1828884A29C6694DAF28B7E6B8A8237388CEE286-P5GAC/sN6hkd3b2yrw5b5LfspsVTdybXVpNB7YpNyf8@public.gmane.org>
@ 2013-10-23 10:42                                   ` Sagi Grimberg
  0 siblings, 0 replies; 21+ messages in thread
From: Sagi Grimberg @ 2013-10-23 10:42 UTC (permalink / raw)
  To: Hefty, Sean
  Cc: linux-rdma-u79uwXL29TY76Z2rM5mHXA, Oren Duer,
	tzahio-VPRAkNaXOzVWk0Htik3J/w

On 10/22/2013 9:20 PM, Hefty, Sean wrote:
>>> Would we lose anything making this a new operation for the QP, versus
>> trying to hook it into the existing ib_post_send call?
>>
>> If I understand correctly you are suggesting making it a verb? Well this
>> operation is a fast-path operation - so I guess we will loose it in this
>> case.
>> Take SCSI for example, for each IO operation submitted by SCSI
>> mid-layer, transport layer should perform any protection policy that
>> SCSI asked for.
>>   From this point of view, signature operation resembles fast
>> registration (since the transport does not own the IOP data buffers, so
>> it uses fast registration methods).
>> That is why we are hooking into ib_post_send.
> I'm suggesting multiple calls that can post to the send queue, rather than one call that does a giant switch statement at the beginning based on the opcode.

Although I understand where you are coming from, We also lose in this case.
If we go down this rode, we block the user from saving a HW doorbell by 
concatenating signature and RDMA WRs to a post list.
I assume this is why fast_reg is also an extension of ib_post_send.

> --
> To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
> the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 21+ messages in thread

end of thread, other threads:[~2013-10-23 10:42 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-10-15 15:38 [PATCH RFC 0/9] Introduce Signature feature Sagi Grimberg
     [not found] ` <1381851510-17290-1-git-send-email-sagig-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
2013-10-15 15:38   ` [PATCH RFC 1/9] IB/core: Introduce indirect and protected memory regions Sagi Grimberg
     [not found]     ` <1381851510-17290-2-git-send-email-sagig-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
2013-10-17 22:43       ` Hefty, Sean
     [not found]         ` <1828884A29C6694DAF28B7E6B8A8237388CE2BE0-P5GAC/sN6hkd3b2yrw5b5LfspsVTdybXVpNB7YpNyf8@public.gmane.org>
2013-10-20 13:05           ` Sagi Grimberg
     [not found]         ` <5263CC09.6030103@mellanox.com>
     [not found]           ` <5263CC09.6030103-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
2013-10-21 14:39             ` Hefty, Sean
2013-10-15 15:38   ` [PATCH RFC 2/9] IB/core: Introduce Signature Verbs API Sagi Grimberg
     [not found]     ` <1381851510-17290-3-git-send-email-sagig-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
2013-10-17 22:51       ` Hefty, Sean
     [not found]         ` <1828884A29C6694DAF28B7E6B8A8237388CE2BFF-P5GAC/sN6hkd3b2yrw5b5LfspsVTdybXVpNB7YpNyf8@public.gmane.org>
2013-10-20 12:55           ` Sagi Grimberg
     [not found]             ` <5263D2DE.8010500-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
2013-10-21 14:34               ` Hefty, Sean
     [not found]                 ` <1828884A29C6694DAF28B7E6B8A8237388CEA91E-P5GAC/sN6hkd3b2yrw5b5LfspsVTdybXVpNB7YpNyf8@public.gmane.org>
2013-10-21 16:12                   ` Sagi Grimberg
     [not found]                     ` <52655282.1000505-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
2013-10-22 16:41                       ` Hefty, Sean
     [not found]                         ` <1828884A29C6694DAF28B7E6B8A8237388CEE1C7-P5GAC/sN6hkd3b2yrw5b5LfspsVTdybXVpNB7YpNyf8@public.gmane.org>
2013-10-22 17:46                           ` Sagi Grimberg
     [not found]                             ` <5266BA11.6090300-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
2013-10-22 18:20                               ` Hefty, Sean
     [not found]                                 ` <1828884A29C6694DAF28B7E6B8A8237388CEE286-P5GAC/sN6hkd3b2yrw5b5LfspsVTdybXVpNB7YpNyf8@public.gmane.org>
2013-10-23 10:42                                   ` Sagi Grimberg
2013-10-15 15:38   ` [PATCH RFC 3/9] IB/mlx5, mlx5_core: Support for create_mr and destroy_mr Sagi Grimberg
2013-10-15 15:38   ` [PATCH RFC 4/9] IB/mlx5: Initialize mlx5_ib_qp signature related Sagi Grimberg
2013-10-15 15:38   ` [PATCH RFC 5/9] IB/mlx5: Break wqe handling to begin & finish routines Sagi Grimberg
2013-10-15 15:38   ` [PATCH RFC 6/9] IB/mlx5: remove MTT access mode from umr flags helper function Sagi Grimberg
2013-10-15 15:38   ` [PATCH RFC 7/9] IB/mlx5: Support IB_WR_REG_SIG_MR Sagi Grimberg
2013-10-15 15:38   ` [PATCH RFC 8/9] IB/mlx5: Collect signature error completion Sagi Grimberg
2013-10-15 15:38   ` [PATCH RFC 9/9] IB/mlx5: Publish support in signature feature Sagi Grimberg

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.