linux-rdma.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Leon Romanovsky <leon@kernel.org>
To: Doug Ledford <dledford@redhat.com>, Jason Gunthorpe <jgg@mellanox.com>
Cc: Leon Romanovsky <leonro@mellanox.com>,
	RDMA mailing list <linux-rdma@vger.kernel.org>,
	Bart Van Assche <bvanassche@acm.org>,
	Sean Hefty <sean.hefty@intel.com>
Subject: [PATCH rdma-rc v2 04/48] RDMA/cm: Add SET/GET implementations to hide IBA wire format
Date: Thu, 12 Dec 2019 11:37:46 +0200	[thread overview]
Message-ID: <20191212093830.316934-5-leon@kernel.org> (raw)
In-Reply-To: <20191212093830.316934-1-leon@kernel.org>

From: Leon Romanovsky <leonro@mellanox.com>

There is no separation between RDMA-CM wire format as it is declared in
IBTA and kernel logic which implements needed support. Such situation
causes to many mistakes in conversion between big-endian (wire format)
and CPU format used by kernel. It also mixes RDMA core code with
combination of uXX and beXX variables.

The idea that all accesses to IBA definitions will go through special
GET/SET macros to ensure that no conversion mistakes are done.

Signed-off-by: Leon Romanovsky <leonro@mellanox.com>
---
 drivers/infiniband/core/cm_msgs.h |   6 +-
 include/rdma/iba.h                | 138 ++++++++++++++++++++++++++++++
 2 files changed, 139 insertions(+), 5 deletions(-)
 create mode 100644 include/rdma/iba.h

diff --git a/drivers/infiniband/core/cm_msgs.h b/drivers/infiniband/core/cm_msgs.h
index 92d7260ac913..9bc468833831 100644
--- a/drivers/infiniband/core/cm_msgs.h
+++ b/drivers/infiniband/core/cm_msgs.h
@@ -8,14 +8,10 @@
 #ifndef CM_MSGS_H
 #define CM_MSGS_H
 
+#include <rdma/iba.h>
 #include <rdma/ib_mad.h>
 #include <rdma/ib_cm.h>
 
-/*
- * Parameters to routines below should be in network-byte order, and values
- * are returned in network-byte order.
- */
-
 #define IB_CM_CLASS_VERSION	2 /* IB specification 1.2 */
 
 struct cm_req_msg {
diff --git a/include/rdma/iba.h b/include/rdma/iba.h
new file mode 100644
index 000000000000..a77cc89f9f3f
--- /dev/null
+++ b/include/rdma/iba.h
@@ -0,0 +1,138 @@
+/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */
+/*
+ * Copyright (c) 2019, Mellanox Technologies inc.  All rights reserved.
+ */
+#ifndef _IBA_DEFS_H_
+#define _IBA_DEFS_H_
+
+#include <linux/kernel.h>
+#include <linux/bitfield.h>
+#include <asm/unaligned.h>
+
+static inline u32 _iba_get8(const u8 *ptr)
+{
+	return *ptr;
+}
+
+static inline void _iba_set8(u8 *ptr, u32 mask, u32 prep_value)
+{
+	*ptr = (*ptr & ~mask) | prep_value;
+}
+
+static inline u16 _iba_get16(const __be16 *ptr)
+{
+	return be16_to_cpu(*ptr);
+}
+
+static inline void _iba_set16(__be16 *ptr, u16 mask, u16 prep_value)
+{
+	*ptr = cpu_to_be16((be16_to_cpu(*ptr) & ~mask) | prep_value);
+}
+
+static inline u32 _iba_get32(const __be32 *ptr)
+{
+	return be32_to_cpu(*ptr);
+}
+
+static inline void _iba_set32(__be32 *ptr, u32 mask, u32 prep_value)
+{
+	*ptr = cpu_to_be32((be32_to_cpu(*ptr) & ~mask) | prep_value);
+}
+
+static inline u64 _iba_get64(const __be64 *ptr)
+{
+	/*
+	 * The mads are constructed so that 32 bit and smaller are naturally
+	 * aligned, everything larger has a max alignment of 4 bytes.
+	 */
+	return be64_to_cpu(get_unaligned(ptr));
+}
+
+static inline void _iba_set64(__be64 *ptr, u64 mask, u64 prep_value)
+{
+	put_unaligned(cpu_to_be64((_iba_get64(ptr) & ~mask) | prep_value), ptr);
+}
+
+#define _IBA_SET(field_struct, field_offset, field_mask, mask_width, ptr,      \
+		 value)                                                        \
+	({                                                                     \
+		field_struct *_ptr = ptr;                                      \
+		_iba_set##mask_width((void *)_ptr + (field_offset),            \
+				     field_mask,                               \
+				     FIELD_PREP(field_mask, value));           \
+	})
+#define IBA_SET(field, ptr, value) _IBA_SET(field, ptr, value)
+
+#define _IBA_SET_MEM(field_struct, field_offset, byte_size, ptr, in, bytes)    \
+	({                                                                     \
+		WARN_ON(bytes > byte_size);                                    \
+		if (in && bytes) {                                             \
+			field_struct *_ptr = ptr;                              \
+			memcpy((void *)_ptr + (field_offset), in, bytes);      \
+		}                                                              \
+	})
+#define IBA_SET_MEM(field, ptr, in, bytes) _IBA_SET_MEM(field, ptr, in, bytes)
+
+#define _IBA_GET(field_struct, field_offset, field_mask, mask_width, ptr)      \
+	({                                                                     \
+		const field_struct *_ptr = ptr;                                \
+		(u##mask_width) FIELD_GET(                                     \
+			field_mask, _iba_get##mask_width((const void *)_ptr +  \
+							 (field_offset)));     \
+	})
+#define IBA_GET(field, ptr) _IBA_GET(field, ptr)
+
+#define _IBA_GET_MEM(field_struct, field_offset, byte_size, ptr, out, bytes)   \
+	({                                                                     \
+		WARN_ON(bytes > byte_size);                                    \
+		if (out && bytes) {                                            \
+			const field_struct *_ptr = ptr;                        \
+			memcpy(out, (void *)_ptr + (field_offset), bytes);     \
+		}                                                              \
+	})
+#define IBA_GET_MEM(field, ptr, out, bytes) _IBA_GET_MEM(field, ptr, out, bytes)
+
+/*
+ * The generated list becomes the parameters to the macros, the order is:
+ *  - struct this applies to
+ *  - starting offset of the max
+ *  - GENMASK or GENMASK_ULL in CPU order
+ *  - The width of data the mask operations should work on, in bits
+ */
+
+/*
+ * Extraction using a tabular description like table 106. bit_offset is from
+ * the Byte[Bit] notation.
+ */
+#define IBA_FIELD_BLOC(field_struct, byte_offset, bit_offset, num_bits)        \
+	field_struct, byte_offset,                                             \
+		GENMASK(7 - (bit_offset), 7 - (bit_offset) - (num_bits - 1)),  \
+		8
+#define IBA_FIELD8_LOC(field_struct, byte_offset, num_bits)                    \
+	IBA_FIELD_BLOC(field_struct, byte_offset, 0, num_bits)
+
+#define IBA_FIELD16_LOC(field_struct, byte_offset, num_bits)                   \
+	field_struct, (byte_offset)&0xFFFE,                                    \
+		GENMASK(15 - (((byte_offset) % 2) * 8),                        \
+			15 - (((byte_offset) % 2) * 8) - (num_bits - 1)),      \
+		16
+
+#define IBA_FIELD32_LOC(field_struct, byte_offset, num_bits)                   \
+	field_struct, (byte_offset)&0xFFFC,                                    \
+		GENMASK(31 - (((byte_offset) % 4) * 8),                        \
+			31 - (((byte_offset) % 4) * 8) - (num_bits - 1)),      \
+		32
+
+#define IBA_FIELD64_LOC(field_struct, byte_offset, num_bits)                   \
+	field_struct, (byte_offset)&0xFFF8,                                    \
+		GENMASK_ULL(63 - (((byte_offset) % 8) * 8),                    \
+			    63 - (((byte_offset) % 8) * 8) - (num_bits - 1)),  \
+		64
+/*
+ * In IBTA spec, everything that is more than 64bits is multiple
+ * of bytes without leftover bits.
+ */
+#define IBA_FIELD_MLOC(field_struct, byte_offset, num_bits)                    \
+	field_struct, (byte_offset)&0xFFFC, (num_bits / 8)
+
+#endif /* _IBA_DEFS_H_ */
-- 
2.20.1


  parent reply	other threads:[~2019-12-12  9:38 UTC|newest]

Thread overview: 57+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-12-12  9:37 [PATCH rdma-rc v2 00/48] Organize code according to IBTA layout Leon Romanovsky
2019-12-12  9:37 ` [PATCH rdma-rc v2 01/48] RDMA/cm: Provide private data size to CM users Leon Romanovsky
2019-12-12  9:37 ` [PATCH rdma-rc v2 02/48] RDMA/srpt: Use private_data_len instead of hardcoded value Leon Romanovsky
2019-12-12  9:37 ` [PATCH rdma-rc v2 03/48] RDMA/ucma: Mask QPN to be 24 bits according to IBTA Leon Romanovsky
2019-12-12  9:37 ` Leon Romanovsky [this message]
2020-01-04  2:15   ` [PATCH rdma-rc v2 04/48] RDMA/cm: Add SET/GET implementations to hide IBA wire format Jason Gunthorpe
2019-12-12  9:37 ` [PATCH rdma-rc v2 05/48] RDMA/cm: Request For Communication (REQ) message definitions Leon Romanovsky
2020-01-07  1:17   ` Jason Gunthorpe
2019-12-12  9:37 ` [PATCH rdma-rc v2 06/48] RDMA/cm: Message Receipt Acknowledgment (MRA) " Leon Romanovsky
2019-12-12  9:37 ` [PATCH rdma-rc v2 07/48] RDMA/cm: Reject (REJ) " Leon Romanovsky
2019-12-12  9:37 ` [PATCH rdma-rc v2 08/48] RDMA/cm: Reply To Request for communication (REP) definitions Leon Romanovsky
2019-12-12  9:37 ` [PATCH rdma-rc v2 09/48] RDMA/cm: Ready To Use (RTU) definitions Leon Romanovsky
2019-12-12  9:37 ` [PATCH rdma-rc v2 10/48] RDMA/cm: Request For Communication Release (DREQ) definitions Leon Romanovsky
2019-12-12  9:37 ` [PATCH rdma-rc v2 11/48] RDMA/cm: Reply To Request For Communication Release (DREP) definitions Leon Romanovsky
2019-12-12  9:37 ` [PATCH rdma-rc v2 12/48] RDMA/cm: Load Alternate Path (LAP) definitions Leon Romanovsky
2019-12-12  9:37 ` [PATCH rdma-rc v2 13/48] RDMA/cm: Alternate Path Response (APR) message definitions Leon Romanovsky
2019-12-12  9:37 ` [PATCH rdma-rc v2 14/48] RDMA/cm: Service ID Resolution Request (SIDR_REQ) definitions Leon Romanovsky
2019-12-12  9:37 ` [PATCH rdma-rc v2 15/48] RDMA/cm: Service ID Resolution Response (SIDR_REP) definitions Leon Romanovsky
2019-12-12  9:37 ` [PATCH rdma-rc v2 16/48] RDMA/cm: Convert QPN and EECN to be u32 variables Leon Romanovsky
2019-12-12  9:37 ` [PATCH rdma-rc v2 17/48] RDMA/cm: Convert REQ responded resources to the new scheme Leon Romanovsky
2019-12-12  9:38 ` [PATCH rdma-rc v2 18/48] RDMA/cm: Convert REQ initiator depth " Leon Romanovsky
2019-12-12  9:38 ` [PATCH rdma-rc v2 19/48] RDMA/cm: Convert REQ remote response timeout Leon Romanovsky
2019-12-12  9:38 ` [PATCH rdma-rc v2 20/48] RDMA/cm: Simplify QP type to wire protocol translation Leon Romanovsky
2019-12-12  9:38 ` [PATCH rdma-rc v2 21/48] RDMA/cm: Convert REQ flow control Leon Romanovsky
2019-12-12  9:38 ` [PATCH rdma-rc v2 22/48] RDMA/cm: Convert starting PSN to be u32 variable Leon Romanovsky
2019-12-12  9:38 ` [PATCH rdma-rc v2 23/48] RDMA/cm: Update REQ local response timeout Leon Romanovsky
2019-12-12  9:38 ` [PATCH rdma-rc v2 24/48] RDMA/cm: Convert REQ retry count to use new scheme Leon Romanovsky
2019-12-12  9:38 ` [PATCH rdma-rc v2 25/48] RDMA/cm: Update REQ path MTU field Leon Romanovsky
2019-12-12  9:38 ` [PATCH rdma-rc v2 26/48] RDMA/cm: Convert REQ RNR retry timeout counter Leon Romanovsky
2019-12-12  9:38 ` [PATCH rdma-rc v2 27/48] RDMA/cm: Convert REQ MAX CM retries Leon Romanovsky
2019-12-12  9:38 ` [PATCH rdma-rc v2 28/48] RDMA/cm: Convert REQ SRQ field Leon Romanovsky
2019-12-12  9:38 ` [PATCH rdma-rc v2 29/48] RDMA/cm: Convert REQ flow label field Leon Romanovsky
2019-12-12  9:38 ` [PATCH rdma-rc v2 30/48] RDMA/cm: Convert REQ packet rate Leon Romanovsky
2019-12-12  9:38 ` [PATCH rdma-rc v2 31/48] RDMA/cm: Convert REQ SL fields Leon Romanovsky
2019-12-12  9:38 ` [PATCH rdma-rc v2 32/48] RDMA/cm: Convert REQ subnet local fields Leon Romanovsky
2019-12-12  9:38 ` [PATCH rdma-rc v2 33/48] RDMA/cm: Convert REQ local ack timeout Leon Romanovsky
2019-12-12  9:38 ` [PATCH rdma-rc v2 34/48] RDMA/cm: Convert MRA MRAed field Leon Romanovsky
2019-12-12  9:38 ` [PATCH rdma-rc v2 35/48] RDMA/cm: Convert MRA service timeout Leon Romanovsky
2019-12-12  9:38 ` [PATCH rdma-rc v2 36/48] RDMA/cm: Update REJ struct to use new scheme Leon Romanovsky
2019-12-12  9:38 ` [PATCH rdma-rc v2 37/48] RDMA/cm: Convert REP target ack delay field Leon Romanovsky
2019-12-12  9:38 ` [PATCH rdma-rc v2 38/48] RDMA/cm: Convert REP failover accepted field Leon Romanovsky
2019-12-12  9:38 ` [PATCH rdma-rc v2 39/48] RDMA/cm: Convert REP flow control field Leon Romanovsky
2019-12-12  9:38 ` [PATCH rdma-rc v2 40/48] RDMA/cm: Convert REP RNR retry count field Leon Romanovsky
2019-12-12  9:38 ` [PATCH rdma-rc v2 41/48] RDMA/cm: Convert REP SRQ field Leon Romanovsky
2019-12-12  9:38 ` [PATCH rdma-rc v2 42/48] RDMA/cm: Delete unused CM LAP functions Leon Romanovsky
2019-12-12  9:38 ` [PATCH rdma-rc v2 43/48] RDMA/cm: Convert LAP flow label field Leon Romanovsky
2019-12-12  9:38 ` [PATCH rdma-rc v2 44/48] RDMA/cm: Convert LAP fields Leon Romanovsky
2019-12-12  9:38 ` [PATCH rdma-rc v2 45/48] RDMA/cm: Delete unused CM ARP functions Leon Romanovsky
2019-12-12  9:38 ` [PATCH rdma-rc v2 46/48] RDMA/cm: Convert SIDR_REP to new scheme Leon Romanovsky
2019-12-12  9:38 ` [PATCH rdma-rc v2 47/48] RDMA/cm: Add Enhanced Connection Establishment (ECE) bits Leon Romanovsky
2019-12-17 12:33   ` Leon Romanovsky
2019-12-12  9:38 ` [PATCH rdma-rc v2 48/48] RDMA/cm: Convert private_date access Leon Romanovsky
2019-12-12 12:06 ` [PATCH rdma-rc v2 00/48] Organize code according to IBTA layout Leon Romanovsky
2020-01-07 18:40 ` Jason Gunthorpe
2020-01-16  7:32   ` Leon Romanovsky
2020-01-16 19:24     ` Jason Gunthorpe
2020-01-16 19:31       ` Leon Romanovsky

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20191212093830.316934-5-leon@kernel.org \
    --to=leon@kernel.org \
    --cc=bvanassche@acm.org \
    --cc=dledford@redhat.com \
    --cc=jgg@mellanox.com \
    --cc=leonro@mellanox.com \
    --cc=linux-rdma@vger.kernel.org \
    --cc=sean.hefty@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).