[openib-general] [PATCH 1/2] librdmacm: userspace support for multicast abstraction

Sean Hefty sean.hefty at intel.com
Mon Jun 12 10:39:53 PDT 2006


Add support to the userspace RDMA CM library for joining multicast group
based on IP addressing.

Signed-off-by: Sean Hefty <sean.hefty at intel.com>
---
diff -up svn3/gen2/trunk/src/userspace/librdmacm/include/rdma/rdma_cma_abi.h
svn/gen2/trunk/src/userspace/librdmacm/include/rdma/rdma_cma_abi.h
--- svn3/gen2/trunk/src/userspace/librdmacm/include/rdma/rdma_cma_abi.h	2006-06-06 17:35:31.000000000 -0700
+++ svn/gen2/trunk/src/userspace/librdmacm/include/rdma/rdma_cma_abi.h	2006-06-12 10:16:44.598117880 -0700
@@ -60,7 +60,9 @@ enum {
 	UCMA_CMD_GET_EVENT,
 	UCMA_CMD_GET_OPTION,
 	UCMA_CMD_SET_OPTION,
-	UCMA_CMD_GET_DST_ATTR
+	UCMA_CMD_GET_DST_ATTR,
+	UCMA_CMD_JOIN_MCAST,
+	UCMA_CMD_LEAVE_MCAST
 };
 
 struct ucma_abi_cmd_hdr {
@@ -178,6 +180,17 @@ struct ucma_abi_init_qp_attr {
 	__u32 qp_state;
 };
 
+struct ucma_abi_join_mcast {
+	__u32 id;
+	struct sockaddr_in6 addr;
+	__u64 uid;
+};
+
+struct ucma_abi_leave_mcast {
+	__u32 id;
+	struct sockaddr_in6 addr;
+};
+
 struct ucma_abi_dst_attr_resp {
 	__u32 remote_qpn;
 	__u32 remote_qkey;
diff -up svn3/gen2/trunk/src/userspace/librdmacm/include/rdma/rdma_cma.h
svn/gen2/trunk/src/userspace/librdmacm/include/rdma/rdma_cma.h
--- svn3/gen2/trunk/src/userspace/librdmacm/include/rdma/rdma_cma.h	2006-06-06 17:35:31.000000000 -0700
+++ svn/gen2/trunk/src/userspace/librdmacm/include/rdma/rdma_cma.h	2006-06-06 12:26:21.000000000 -0700
@@ -52,6 +52,8 @@ enum rdma_cm_event_type {
 	RDMA_CM_EVENT_ESTABLISHED,
 	RDMA_CM_EVENT_DISCONNECTED,
 	RDMA_CM_EVENT_DEVICE_REMOVAL,
+	RDMA_CM_EVENT_MULTICAST_JOIN,
+	RDMA_CM_EVENT_MULTICAST_ERROR
 };
 
 enum rdma_port_space {
@@ -99,6 +101,13 @@ struct rdma_cm_id {
 	uint8_t			 port_num;
 };
 
+struct rdma_multicast_data {
+	void		*context;
+	struct sockaddr addr;
+	uint8_t		pad[sizeof(struct sockaddr_in6) -
+			    sizeof(struct sockaddr)];
+};
+
 struct rdma_cm_event {
 	struct rdma_cm_id	*id;
 	struct rdma_cm_id	*listen_id;
@@ -245,6 +254,24 @@ int rdma_reject(struct rdma_cm_id *id, c
 int rdma_disconnect(struct rdma_cm_id *id);
 
 /**
+ * rdma_join_multicast - Join the multicast group specified by the given
+ *   address.
+ * @id: Communication identifier associated with the request.
+ * @addr: Multicast address identifying the group to join.
+ * @context: User-defined context associated with the join request.  The
+ *   context is returned to the user through the private_data field in
+ *   the rdma_cm_event.
+ */
+int rdma_join_multicast(struct rdma_cm_id *id, struct sockaddr *addr,
+			void *context);
+
+/**
+ * rdma_leave_multicast - Leave the multicast group specified by the given
+ *   address.
+ */
+int rdma_leave_multicast(struct rdma_cm_id *id, struct sockaddr *addr);
+
+/**
  * rdma_get_cm_event - Retrieves the next pending communications event,
  *   if no event is pending waits for an event.
  * @channel: Event channel to check for events.
diff -up svn3/gen2/trunk/src/userspace/librdmacm/src/cma.c svn/gen2/trunk/src/userspace/librdmacm/src/cma.c
--- svn3/gen2/trunk/src/userspace/librdmacm/src/cma.c	2006-06-06 17:35:31.000000000 -0700
+++ svn/gen2/trunk/src/userspace/librdmacm/src/cma.c	2006-06-06 17:30:17.000000000 -0700
@@ -896,6 +896,66 @@ int rdma_disconnect(struct rdma_cm_id *i
 	return 0;
 }
 
+int rdma_join_multicast(struct rdma_cm_id *id, struct sockaddr *addr,
+			void *context)
+{
+	struct ucma_abi_join_mcast *cmd;
+	struct cma_id_private *id_priv;
+	void *msg;
+	int ret, size, addrlen;
+	
+	addrlen = ucma_addrlen(addr);
+	if (!addrlen)
+		return -EINVAL;
+
+	CMA_CREATE_MSG_CMD(msg, cmd, UCMA_CMD_JOIN_MCAST, size);
+	id_priv = container_of(id, struct cma_id_private, id);
+	cmd->id = id_priv->handle;
+	memcpy(&cmd->addr, addr, addrlen);
+	cmd->uid = (uintptr_t) context;
+
+	ret = write(id->channel->fd, msg, size);
+	if (ret != size)
+		return (ret > 0) ? -ENODATA : ret;
+
+	return 0;
+}
+
+int rdma_leave_multicast(struct rdma_cm_id *id, struct sockaddr *addr)
+{
+	struct ucma_abi_leave_mcast *cmd;
+	struct cma_id_private *id_priv;
+	void *msg;
+	int ret, size, addrlen;
+	struct ibv_ah_attr ah_attr;
+	uint32_t qp_info;
+	
+	addrlen = ucma_addrlen(addr);
+	if (!addrlen)
+		return -EINVAL;
+
+	CMA_CREATE_MSG_CMD(msg, cmd, UCMA_CMD_LEAVE_MCAST, size);
+	id_priv = container_of(id, struct cma_id_private, id);
+	cmd->id = id_priv->handle;
+	memcpy(&cmd->addr, addr, addrlen);
+
+	if (id->qp) {
+		ret = rdma_get_dst_attr(id, addr, &ah_attr, &qp_info, &qp_info);
+		if (ret)
+			goto out;
+
+		ret = ibv_detach_mcast(id->qp, &ah_attr.grh.dgid, ah_attr.dlid);
+		if (ret)
+			goto out;
+	}
+	
+	ret = write(id->channel->fd, msg, size);
+	if (ret != size)
+		ret = (ret > 0) ? -ENODATA : ret;
+out:
+	return ret;
+}
+
 static void ucma_copy_event_from_kern(struct rdma_cm_event *dst,
 				      struct ucma_abi_event_resp *src)
 {
@@ -1004,6 +1064,36 @@ static int ucma_process_establish(struct
 	return ret;
 }
 
+static void ucma_process_mcast(struct rdma_cm_id *id, struct rdma_cm_event *evt)
+{
+	struct ucma_abi_join_mcast kmc_data;
+	struct rdma_multicast_data *mc_data;
+	struct ibv_ah_attr ah_attr;
+	uint32_t qp_info;
+
+	kmc_data = *(struct ucma_abi_join_mcast *) evt->private_data;
+
+	mc_data = evt->private_data;
+	mc_data->context = (void *) (uintptr_t) kmc_data.uid;
+	memcpy(&mc_data->addr, &kmc_data.addr,
+	       ucma_addrlen((struct sockaddr *) &kmc_data.addr));
+
+	if (evt->status || !id->qp)
+		return;
+
+	evt->status = rdma_get_dst_attr(id, &mc_data->addr, &ah_attr,
+					&qp_info, &qp_info);
+	if (evt->status)
+		goto err;
+
+	evt->status = ibv_attach_mcast(id->qp, &ah_attr.grh.dgid, ah_attr.dlid);
+	if (evt->status)
+		goto err;
+	return;
+err:
+	evt->event = RDMA_CM_EVENT_MULTICAST_ERROR;
+}
+
 int rdma_get_cm_event(struct rdma_event_channel *channel,
 		      struct rdma_cm_event **event)
 {
@@ -1085,6 +1175,10 @@ retry:
 			goto retry;
 		}
 		break;
+	case RDMA_CM_EVENT_MULTICAST_JOIN:
+	case RDMA_CM_EVENT_MULTICAST_ERROR:
+		ucma_process_mcast(&id_priv->id, evt);
+		break;
 	default:
 		break;
 	}
diff -up svn3/gen2/trunk/src/userspace/librdmacm/src/librdmacm.map svn/gen2/trunk/src/userspace/librdmacm/src/librdmacm.map
--- svn3/gen2/trunk/src/userspace/librdmacm/src/librdmacm.map	2006-06-06 17:35:31.000000000 -0700
+++ svn/gen2/trunk/src/userspace/librdmacm/src/librdmacm.map	2006-06-01 15:03:13.000000000 -0700
@@ -19,5 +19,7 @@ RDMACM_1.0 {
 		rdma_get_option;
 		rdma_set_option;
 		rdma_get_dst_attr;
+		rdma_join_multicast;
+		rdma_leave_multicast;
 	local: *;
 };





More information about the general mailing list