Expose multicast abstraction through the CMA to userspace.

Signed-off-by: Sean Hefty <[EMAIL PROTECTED]>
---
--- svn3/gen2/trunk/src/linux-kernel/infiniband/include/rdma/rdma_user_cm.h     
2006-06-06 16:53:46.000000000 -0700
+++ svn/gen2/trunk/src/linux-kernel/infiniband/include/rdma/rdma_user_cm.h      
2006-06-06 12:22:57.000000000 -0700
@@ -58,6 +58,8 @@ enum {
        RDMA_USER_CM_CMD_GET_EVENT,
        RDMA_USER_CM_CMD_GET_OPTION,
        RDMA_USER_CM_CMD_SET_OPTION,
+       RDMA_USER_CM_CMD_JOIN_MCAST,
+       RDMA_USER_CM_CMD_LEAVE_MCAST,
        RDMA_USER_CM_CMD_GET_DST_ATTR
 };
 
@@ -174,6 +176,17 @@ struct rdma_ucm_init_qp_attr {
        __u32 qp_state;
 };
 
+struct rdma_ucm_join_mcast {
+       __u32 id;
+       struct sockaddr_in6 addr;
+       __u64 uid;
+};
+
+struct rdma_ucm_leave_mcast {
+       __u32 id;
+       struct sockaddr_in6 addr;
+};
+
 struct rdma_ucm_dst_attr_resp {
        __u32 remote_qpn;
        __u32 remote_qkey;
--- svn3/gen2/trunk/src/linux-kernel/infiniband/core/ucma.c     2006-06-06 
16:56:53.000000000 -0700
+++ svn/gen2/trunk/src/linux-kernel/infiniband/core/ucma.c      2006-06-01 
17:48:42.000000000 -0700
@@ -167,6 +167,21 @@ error:
        return NULL;
 }
 
+static void ucma_copy_multicast_data(struct ucma_context *ctx,
+                                    struct ucma_event *uevent,
+                                    struct rdma_cm_event *event)
+{
+       struct rdma_multicast_data *mc_data = event->private_data;
+       struct rdma_ucm_join_mcast *umc_data;
+
+       umc_data = (struct rdma_ucm_join_mcast *) uevent->resp.private_data;
+
+       uevent->resp.private_data_len = sizeof *umc_data;
+       umc_data->id = ctx->id;
+       memcpy(&umc_data->addr, &mc_data->addr, ip_addr_size(&mc_data->addr));
+       umc_data->uid = (unsigned long) mc_data->context;
+}
+
 static int ucma_event_handler(struct rdma_cm_id *cm_id,
                              struct rdma_cm_event *event)
 {
@@ -184,9 +199,17 @@ static int ucma_event_handler(struct rdm
        uevent->resp.id = ctx->id;
        uevent->resp.event = event->event;
        uevent->resp.status = event->status;
-       if ((uevent->resp.private_data_len = event->private_data_len))
-               memcpy(uevent->resp.private_data, event->private_data,
-                      event->private_data_len);
+       switch (event->event) {
+       case RDMA_CM_EVENT_MULTICAST_JOIN:
+       case RDMA_CM_EVENT_MULTICAST_ERROR:
+               ucma_copy_multicast_data(ctx, uevent, event);
+               break;
+       default:
+               if ((uevent->resp.private_data_len = event->private_data_len))
+                       memcpy(uevent->resp.private_data, event->private_data,
+                              event->private_data_len);
+               break;
+       }
 
        mutex_lock(&ctx->file->file_mutex);
        if (event->event == RDMA_CM_EVENT_CONNECT_REQUEST) {
@@ -737,6 +760,45 @@ static ssize_t ucma_set_option(struct uc
        return ret;
 }
 
+static ssize_t ucma_join_mcast(struct ucma_file *file, const char __user 
*inbuf,
+                              int in_len, int out_len)
+{
+       struct rdma_ucm_join_mcast cmd;
+       struct ucma_context *ctx;
+       int ret;
+
+       if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
+               return -EFAULT;
+
+       ctx = ucma_get_ctx(file, cmd.id);
+       if (IS_ERR(ctx))
+               return PTR_ERR(ctx);
+
+       ret = rdma_join_multicast(ctx->cm_id, (struct sockaddr *) &cmd.addr,
+                                 (void *) (unsigned long) cmd.uid);
+       ucma_put_ctx(ctx);
+       return ret;
+}
+
+static ssize_t ucma_leave_mcast(struct ucma_file *file,
+                               const char __user *inbuf,
+                               int in_len, int out_len)
+{
+       struct rdma_ucm_leave_mcast cmd;
+       struct ucma_context *ctx;
+
+       if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
+               return -EFAULT;
+
+       ctx = ucma_get_ctx(file, cmd.id);
+       if (IS_ERR(ctx))
+               return PTR_ERR(ctx);
+
+       rdma_leave_multicast(ctx->cm_id, (struct sockaddr *) &cmd.addr);
+       ucma_put_ctx(ctx);
+       return 0;
+}
+
 static ssize_t ucma_get_dst_attr(struct ucma_file *file,
                                 const char __user *inbuf,
                                 int in_len, int out_len)
@@ -789,6 +851,8 @@ static ssize_t (*ucma_cmd_table[])(struc
        [RDMA_USER_CM_CMD_GET_EVENT]    = ucma_get_event,
        [RDMA_USER_CM_CMD_GET_OPTION]   = ucma_get_option,
        [RDMA_USER_CM_CMD_SET_OPTION]   = ucma_set_option,
+       [RDMA_USER_CM_CMD_JOIN_MCAST]   = ucma_join_mcast,
+       [RDMA_USER_CM_CMD_LEAVE_MCAST]  = ucma_leave_mcast,
        [RDMA_USER_CM_CMD_GET_DST_ATTR] = ucma_get_dst_attr
 };
 


_______________________________________________
openib-general mailing list
[email protected]
http://openib.org/mailman/listinfo/openib-general

To unsubscribe, please visit http://openib.org/mailman/listinfo/openib-general

Reply via email to