Blame SOURCES/librdmacm-add-support-for-extended-join-mc.patch

95af3a
commit 3c1d25b8170b0c30d723b2bf89c390293dc4477c
95af3a
Author: Jason Gunthorpe <jgg@mellanox.com>
95af3a
Date:   Fri Nov 17 11:59:13 2017 -0700
95af3a
95af3a
    librdmacm: Add support for extended join multicast API
95af3a
    
95af3a
    Add support for specifying MC join flags.  The following multicast join
95af3a
    flags will now be supported by librdmacm (as already defined in the join
95af3a
    flags in rdma_user_cm.h through the UAPI of the kernel).
95af3a
    
95af3a
    -Full Member:
95af3a
     The initiator creates the Multicast group (MCG) if it wasn't previously
95af3a
     created, can send Multicast messages to the group and receive messages
95af3a
     from the MCG.
95af3a
    
95af3a
    -Send Only Full Member:
95af3a
     The initiator creates the Multicast group (MCG) if it wasn't previously
95af3a
     created, can send Multicast messages but doesn't receive any messages
95af3a
     from the MCG (send-only).
95af3a
    
95af3a
    Tested-by: Christoph Lameter <cl@linux.com>
95af3a
    Reviewed by: Hal Rosenstock <hal@mellanox.com>
95af3a
    Signed-off-by: Alex Vesker <valex@mellanox.com>
95af3a
    Signed-off-by: Christoph Lameter <cl@linux.com>
95af3a
    Reviewed-by: Jason Gunthorpe <jgg@ziepe.ca>
95af3a
    Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
95af3a
95af3a
Index: rdma-core-15/debian/librdmacm-dev.install
95af3a
===================================================================
95af3a
--- rdma-core-15.orig/debian/librdmacm-dev.install
95af3a
+++ rdma-core-15/debian/librdmacm-dev.install
95af3a
@@ -33,6 +33,7 @@ usr/share/man/man3/rdma_get_send_comp.3
95af3a
 usr/share/man/man3/rdma_get_src_port.3
95af3a
 usr/share/man/man3/rdma_getaddrinfo.3
95af3a
 usr/share/man/man3/rdma_join_multicast.3
95af3a
+usr/share/man/man3/rdma_join_multicast_ex.3
95af3a
 usr/share/man/man3/rdma_leave_multicast.3
95af3a
 usr/share/man/man3/rdma_listen.3
95af3a
 usr/share/man/man3/rdma_migrate_id.3
95af3a
Index: rdma-core-15/debian/librdmacm1.symbols
95af3a
===================================================================
95af3a
--- rdma-core-15.orig/debian/librdmacm1.symbols
95af3a
+++ rdma-core-15/debian/librdmacm1.symbols
95af3a
@@ -1,5 +1,6 @@
95af3a
 librdmacm.so.1 librdmacm1 #MINVER#
95af3a
  RDMACM_1.0@RDMACM_1.0 1.0.15
95af3a
+ RDMACM_1.1@RDMACM_1.1 16
95af3a
  raccept@RDMACM_1.0 1.0.16
95af3a
  rbind@RDMACM_1.0 1.0.16
95af3a
  rclose@RDMACM_1.0 1.0.16
95af3a
@@ -31,6 +32,7 @@ librdmacm.so.1 librdmacm1 #MINVER#
95af3a
  rdma_get_src_port@RDMACM_1.0 1.0.19
95af3a
  rdma_getaddrinfo@RDMACM_1.0 1.0.15
95af3a
  rdma_join_multicast@RDMACM_1.0 1.0.15
95af3a
+ rdma_join_multicast_ex@RDMACM_1.1 16
95af3a
  rdma_leave_multicast@RDMACM_1.0 1.0.15
95af3a
  rdma_listen@RDMACM_1.0 1.0.15
95af3a
  rdma_migrate_id@RDMACM_1.0 1.0.15
95af3a
Index: rdma-core-15/librdmacm/CMakeLists.txt
95af3a
===================================================================
95af3a
--- rdma-core-15.orig/librdmacm/CMakeLists.txt
95af3a
+++ rdma-core-15/librdmacm/CMakeLists.txt
95af3a
@@ -10,7 +10,7 @@ publish_headers(infiniband
95af3a
 
95af3a
 rdma_library(rdmacm librdmacm.map
95af3a
   # See Documentation/versioning.md
95af3a
-  1 1.0.${PACKAGE_VERSION}
95af3a
+  1 1.1.${PACKAGE_VERSION}
95af3a
   acm.c
95af3a
   addrinfo.c
95af3a
   cma.c
95af3a
Index: rdma-core-15/librdmacm/cma.c
95af3a
===================================================================
95af3a
--- rdma-core-15.orig/librdmacm/cma.c
95af3a
+++ rdma-core-15/librdmacm/cma.c
95af3a
@@ -114,6 +114,7 @@ struct cma_multicast {
95af3a
 	uint32_t	handle;
95af3a
 	union ibv_gid	mgid;
95af3a
 	uint16_t	mlid;
95af3a
+	uint16_t	join_flags;
95af3a
 	struct sockaddr_storage addr;
95af3a
 };
95af3a
 
95af3a
@@ -1713,7 +1714,8 @@ int rdma_disconnect(struct rdma_cm_id *i
95af3a
 }
95af3a
 
95af3a
 static int rdma_join_multicast2(struct rdma_cm_id *id, struct sockaddr *addr,
95af3a
-				socklen_t addrlen, void *context)
95af3a
+				socklen_t addrlen, uint16_t join_flags,
95af3a
+				void *context)
95af3a
 {
95af3a
 	struct ucma_abi_create_id_resp resp;
95af3a
 	struct cma_id_private *id_priv;
95af3a
@@ -1727,6 +1729,7 @@ static int rdma_join_multicast2(struct r
95af3a
 
95af3a
 	mc->context = context;
95af3a
 	mc->id_priv = id_priv;
95af3a
+	mc->join_flags = join_flags;
95af3a
 	memcpy(&mc->addr, addr, addrlen);
95af3a
 	if (pthread_cond_init(&mc->cond, NULL)) {
95af3a
 		ret = -1;
95af3a
@@ -1746,7 +1749,7 @@ static int rdma_join_multicast2(struct r
95af3a
 		memcpy(&cmd.addr, addr, addrlen);
95af3a
 		cmd.addr_size = addrlen;
95af3a
 		cmd.uid = (uintptr_t) mc;
95af3a
-		cmd.reserved = 0;
95af3a
+		cmd.join_flags = join_flags;
95af3a
 
95af3a
 		ret = write(id->channel->fd, &cmd, sizeof cmd);
95af3a
 		if (ret != sizeof cmd) {
95af3a
@@ -1784,6 +1787,30 @@ err1:
95af3a
 	return ret;
95af3a
 }
95af3a
 
95af3a
+int rdma_join_multicast_ex(struct rdma_cm_id *id,
95af3a
+			   struct rdma_cm_join_mc_attr_ex *mc_join_attr,
95af3a
+			   void *context)
95af3a
+{
95af3a
+	int addrlen;
95af3a
+
95af3a
+	if (mc_join_attr->comp_mask >= RDMA_CM_JOIN_MC_ATTR_RESERVED)
95af3a
+		return ERR(ENOTSUP);
95af3a
+
95af3a
+	if (!(mc_join_attr->comp_mask & RDMA_CM_JOIN_MC_ATTR_ADDRESS))
95af3a
+		return ERR(EINVAL);
95af3a
+
95af3a
+	if (!(mc_join_attr->comp_mask & RDMA_CM_JOIN_MC_ATTR_JOIN_FLAGS) ||
95af3a
+	    (mc_join_attr->join_flags >= RDMA_MC_JOIN_FLAG_RESERVED))
95af3a
+		return ERR(EINVAL);
95af3a
+
95af3a
+	addrlen = ucma_addrlen(mc_join_attr->addr);
95af3a
+	if (!addrlen)
95af3a
+		return ERR(EINVAL);
95af3a
+
95af3a
+	return rdma_join_multicast2(id, mc_join_attr->addr, addrlen,
95af3a
+				    mc_join_attr->join_flags, context);
95af3a
+}
95af3a
+
95af3a
 int rdma_join_multicast(struct rdma_cm_id *id, struct sockaddr *addr,
95af3a
 			void *context)
95af3a
 {
95af3a
@@ -1793,7 +1820,8 @@ int rdma_join_multicast(struct rdma_cm_i
95af3a
 	if (!addrlen)
95af3a
 		return ERR(EINVAL);
95af3a
 
95af3a
-	return rdma_join_multicast2(id, addr, addrlen, context);
95af3a
+	return rdma_join_multicast2(id, addr, addrlen,
95af3a
+				    RDMA_MC_JOIN_FLAG_FULLMEMBER, context);
95af3a
 }
95af3a
 
95af3a
 int rdma_leave_multicast(struct rdma_cm_id *id, struct sockaddr *addr)
95af3a
@@ -1821,7 +1849,7 @@ int rdma_leave_multicast(struct rdma_cm_
95af3a
 	if (!mc)
95af3a
 		return ERR(EADDRNOTAVAIL);
95af3a
 
95af3a
-	if (id->qp)
95af3a
+	if (id->qp && (mc->join_flags != RDMA_MC_JOIN_FLAG_SENDONLY_FULLMEMBER))
95af3a
 		ibv_detach_mcast(id->qp, &mc->mgid, mc->mlid);
95af3a
 	
95af3a
 	CMA_INIT_CMD_RESP(&cmd, sizeof cmd, LEAVE_MCAST, &resp, sizeof resp);
95af3a
@@ -2009,6 +2037,10 @@ static int ucma_process_join(struct cma_
95af3a
 	if (!evt->id_priv->id.qp)
95af3a
 		return 0;
95af3a
 
95af3a
+	/* Don't attach QP to multicast if joined as send only full member */
95af3a
+	if (evt->mc->join_flags == RDMA_MC_JOIN_FLAG_SENDONLY_FULLMEMBER)
95af3a
+		return 0;
95af3a
+
95af3a
 	return rdma_seterrno(ibv_attach_mcast(evt->id_priv->id.qp,
95af3a
 					      &evt->mc->mgid, evt->mc->mlid));
95af3a
 }
95af3a
Index: rdma-core-15/librdmacm/librdmacm.map
95af3a
===================================================================
95af3a
--- rdma-core-15.orig/librdmacm/librdmacm.map
95af3a
+++ rdma-core-15/librdmacm/librdmacm.map
95af3a
@@ -71,3 +71,8 @@ RDMACM_1.0 {
95af3a
 		rdma_create_qp_ex;
95af3a
 	local: *;
95af3a
 };
95af3a
+
95af3a
+RDMACM_1.1 {
95af3a
+	global:
95af3a
+		rdma_join_multicast_ex;
95af3a
+} RDMACM_1.0;
95af3a
Index: rdma-core-15/librdmacm/man/CMakeLists.txt
95af3a
===================================================================
95af3a
--- rdma-core-15.orig/librdmacm/man/CMakeLists.txt
95af3a
+++ rdma-core-15/librdmacm/man/CMakeLists.txt
95af3a
@@ -33,6 +33,7 @@ rdma_man_pages(
95af3a
   rdma_get_src_port.3
95af3a
   rdma_getaddrinfo.3
95af3a
   rdma_join_multicast.3
95af3a
+  rdma_join_multicast_ex.3
95af3a
   rdma_leave_multicast.3
95af3a
   rdma_listen.3
95af3a
   rdma_migrate_id.3
95af3a
Index: rdma-core-15/librdmacm/man/rdma_join_multicast_ex.3
95af3a
===================================================================
95af3a
--- /dev/null
95af3a
+++ rdma-core-15/librdmacm/man/rdma_join_multicast_ex.3
95af3a
@@ -0,0 +1,66 @@
95af3a
+.TH "RDMA_JOIN_MULTICAST_EX" 3 "2017-11-17" "librdmacm" "Librdmacm Programmer's Manual" librdmacm
95af3a
+.SH NAME
95af3a
+rdma_join_multicast_ex \- Joins a multicast group with extended options.
95af3a
+.SH SYNOPSIS
95af3a
+.B "#include <rdma/rdma_cma.h>"
95af3a
+.P
95af3a
+.B "int" rdma_join_multicast_ex
95af3a
+.BI "(struct rdma_cm_id *" id ","
95af3a
+.BI "struct rdma_cm_join_mc_attr_ex *" mc_join_attr ","
95af3a
+.BI "void *" context ");"
95af3a
+.SH ARGUMENTS
95af3a
+.IP "id" 20
95af3a
+Communication identifier associated with the request.
95af3a
+.IP "mc_join_attr" 20
95af3a
+Is an rdma_cm_join_mc_attr_ex struct, as defined in <rdma/rdma_cma.h>.
95af3a
+.IP "context" 20
95af3a
+User-defined context associated with the join request.
95af3a
+.SH "DESCRIPTION"
95af3a
+Joins a multicast group (MCG) with extended options.
95af3a
+Currently supporting MC join with a specified join flag.
95af3a
+.P
95af3a
+.nf
95af3a
+struct rdma_cm_join_mc_attr_ex {
95af3a
+.in +8
95af3a
+uint32_t                comp_mask;      /* Bitwise OR between "rdma_cm_join_mc_attr_mask" enum */
95af3a
+uint32_t                join_flags;     /* Use a single flag from "rdma_cm_mc_join_flags" enum */
95af3a
+struct sockaddr         *addr;          /* Multicast address identifying the group to join */
95af3a
+.in -8
95af3a
+};
95af3a
+.fi
95af3a
+.P
95af3a
+The supported join flags are:
95af3a
+.P
95af3a
+.B RDMA_MC_JOIN_FLAG_FULLMEMBER
95af3a
+- Create multicast group, Send multicast messages to MCG, Receive multicast messages from MCG.
95af3a
+.P
95af3a
+.B RDMA_MC_JOIN_FLAG_SENDONLY_FULLMEMBER
95af3a
+- Create multicast group, Send multicast messages to MCG, Don't receive multicast messages from MCG (send-only).
95af3a
+.P
95af3a
+Initiating a MC join as "Send Only Full Member" on InfiniBand requires SM support, otherwise joining will fail.
95af3a
+.P
95af3a
+Initiating a MC join as "Send Only Full Member" on RoCEv2/ETH will not send any IGMP messages unlike a Full Member MC join.
95af3a
+When "Send Only Full Member" is used the QP will not be attached to the MCG.
95af3a
+.P
95af3a
+.SH "RETURN VALUE"
95af3a
+Returns 0 on success, or -1 on error.  If an error occurs, errno will be
95af3a
+set to indicate the failure reason.
95af3a
+.SH "NOTES"
95af3a
+Before joining a multicast group, the rdma_cm_id must be bound to
95af3a
+an RDMA device by calling rdma_bind_addr or rdma_resolve_addr.  Use of
95af3a
+rdma_resolve_addr requires the local routing tables to resolve the
95af3a
+multicast address to an RDMA device, unless a specific source address
95af3a
+is provided.  The user must call rdma_leave_multicast to leave the
95af3a
+multicast group and release any multicast resources.  After the join
95af3a
+operation completes, if a QP is associated with the rdma_cm_id,
95af3a
+it is automatically attached to the multicast group when the multicast
95af3a
+event is retrieved by the user.  Otherwise, the user is responsible
95af3a
+for calling ibv_attach_mcast to bind the QP to the multicast group.
95af3a
+The join context is returned to the user through the private_data
95af3a
+field in the rdma_cm_event.
95af3a
+.SH "SEE ALSO"
95af3a
+rdma_join_multicast(3), rdma_leave_multicast(3), rdma_bind_addr(3), rdma_resolve_addr(3), rdma_create_qp(3),
95af3a
+rdma_get_cm_event(3)
95af3a
+.SH "AUTHORS"
95af3a
+.TP
95af3a
+Alex Vesker <valex@mellanox.com>
95af3a
Index: rdma-core-15/librdmacm/rdma_cma.h
95af3a
===================================================================
95af3a
--- rdma-core-15.orig/librdmacm/rdma_cma.h
95af3a
+++ rdma-core-15/librdmacm/rdma_cma.h
95af3a
@@ -197,6 +197,29 @@ struct rdma_addrinfo {
95af3a
 	struct rdma_addrinfo	*ai_next;
95af3a
 };
95af3a
 
95af3a
+/* Multicast join compatibility mask attributes */
95af3a
+enum rdma_cm_join_mc_attr_mask {
95af3a
+	RDMA_CM_JOIN_MC_ATTR_ADDRESS	= 1 << 0,
95af3a
+	RDMA_CM_JOIN_MC_ATTR_JOIN_FLAGS	= 1 << 1,
95af3a
+	RDMA_CM_JOIN_MC_ATTR_RESERVED	= 1 << 2,
95af3a
+};
95af3a
+
95af3a
+/* Multicast join flags */
95af3a
+enum rdma_cm_mc_join_flags {
95af3a
+	RDMA_MC_JOIN_FLAG_FULLMEMBER,
95af3a
+	RDMA_MC_JOIN_FLAG_SENDONLY_FULLMEMBER,
95af3a
+	RDMA_MC_JOIN_FLAG_RESERVED,
95af3a
+};
95af3a
+
95af3a
+struct rdma_cm_join_mc_attr_ex {
95af3a
+	/* Bitwise OR between "rdma_cm_join_mc_attr_mask" enum */
95af3a
+	uint32_t comp_mask;
95af3a
+	/* Use a flag from "rdma_cm_mc_join_flags" enum */
95af3a
+	uint32_t join_flags;
95af3a
+	/* Multicast address identifying the group to join */
95af3a
+	struct sockaddr *addr;
95af3a
+};
95af3a
+
95af3a
 /**
95af3a
  * rdma_create_event_channel - Open a channel used to report communication events.
95af3a
  * Description:
95af3a
@@ -555,6 +578,30 @@ int rdma_join_multicast(struct rdma_cm_i
95af3a
 int rdma_leave_multicast(struct rdma_cm_id *id, struct sockaddr *addr);
95af3a
 
95af3a
 /**
95af3a
+ * rdma_multicast_ex - Joins a multicast group with options.
95af3a
+ * @id: Communication identifier associated with the request.
95af3a
+ * @mc_join_attr: Extensive struct containing multicast join parameters.
95af3a
+ * @context: User-defined context associated with the join request.
95af3a
+ * Description:
95af3a
+ *  Joins a multicast group with options. Currently supporting MC join flags.
95af3a
+ *  The QP will be attached based on the given join flag.
95af3a
+ *  Join message will be sent according to the join flag.
95af3a
+ * Notes:
95af3a
+ *  Before joining a multicast group, the rdma_cm_id must be bound to
95af3a
+ *  an RDMA device by calling rdma_bind_addr or rdma_resolve_addr.  Use of
95af3a
+ *  rdma_resolve_addr requires the local routing tables to resolve the
95af3a
+ *  multicast address to an RDMA device.  The user must call
95af3a
+ *  rdma_leave_multicast to leave the multicast group and release any
95af3a
+ *  multicast resources.  The context is returned to the user through
95af3a
+ *  the private_data field in the rdma_cm_event.
95af3a
+ * See also:
95af3a
+ *  rdma_leave_multicast, rdma_bind_addr, rdma_resolve_addr, rdma_create_qp
95af3a
+ */
95af3a
+int rdma_join_multicast_ex(struct rdma_cm_id *id,
95af3a
+			   struct rdma_cm_join_mc_attr_ex *mc_join_attr,
95af3a
+			   void *context);
95af3a
+
95af3a
+/**
95af3a
  * rdma_get_cm_event - Retrieves the next pending communication event.
95af3a
  * @channel: Event channel to check for events.
95af3a
  * @event: Allocated information about the next communication event.
95af3a
Index: rdma-core-15/librdmacm/rdma_cma_abi.h
95af3a
===================================================================
95af3a
--- rdma-core-15.orig/librdmacm/rdma_cma_abi.h
95af3a
+++ rdma-core-15/librdmacm/rdma_cma_abi.h
95af3a
@@ -302,7 +302,7 @@ struct ucma_abi_join_mcast {
95af3a
 	__u64 uid;
95af3a
 	__u32 id;
95af3a
 	__u16 addr_size;
95af3a
-	__u16 reserved;
95af3a
+	__u16 join_flags;
95af3a
 	struct sockaddr_storage addr;
95af3a
 };
95af3a