[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