]> git.openfabrics.org - ~shefty/rdma-win.git/commitdiff
librdmacm: support sync operation
authorSean Hefty <sean.hefty@intel.com>
Fri, 13 Aug 2010 19:22:01 +0000 (12:22 -0700)
committerSean Hefty <sean.hefty@intel.com>
Fri, 13 Aug 2010 19:22:01 +0000 (12:22 -0700)
trunk/ulp/librdmacm/include/rdma/rdma_cma.h
trunk/ulp/librdmacm/src/cma.cpp

index 0c9d305af745818ea27d03dadd48d009a9031770..e4f42073567f663344b77c01bf7fc1b20e80b524 100644 (file)
@@ -74,17 +74,23 @@ enum rdma_cm_event_type
 enum rdma_port_space\r
 {\r
        RDMA_PS_IPOIB   = 0x0002,\r
+       RDMA_PS_IB              = 0x0003,\r
        RDMA_PS_TCP             = 0x0106,\r
        RDMA_PS_UDP             = 0x0111,\r
 };\r
 \r
+#define RDMA_IB_IP_PS_MASK   0xFFFFFFFFFFFF0000ULL\r
+#define RDMA_IB_IP_PORT_MASK 0x000000000000FFFFULL\r
+#define RDMA_IB_IP_PS_TCP    0x0000000001060000ULL\r
+#define RDMA_IB_IP_PS_UDP    0x0000000001110000ULL\r
+\r
 /*\r
  * Global qkey value for UDP QPs and multicast groups created via the \r
  * RDMA CM.\r
  */\r
 #define RDMA_UDP_QKEY 0x01234567\r
 \r
-struct ib_addr\r
+struct rdma_ib_addr\r
 {\r
        union ibv_gid   sgid;\r
        union ibv_gid   dgid;\r
@@ -101,7 +107,7 @@ struct rdma_addr
                                                                sizeof(struct sockaddr)];\r
        union\r
        {\r
-               struct ib_addr  ibaddr;\r
+               struct rdma_ib_addr     ibaddr;\r
        }       addr;\r
 };\r
 \r
@@ -132,6 +138,17 @@ struct rdma_cm_id
                IWVConnectEndpoint              *connect;\r
                IWVDatagramEndpoint             *datagram;\r
        }       ep;\r
+\r
+       struct rdma_cm_event            *event;\r
+       struct ibv_comp_channel         *send_cq_channel;\r
+       struct ibv_cq                           *send_cq;\r
+       struct ibv_comp_channel         *recv_cq_channel;\r
+       struct ibv_cq                           *recv_cq;\r
+};\r
+\r
+enum {\r
+       RDMA_MAX_RESP_RES = 0xFF,\r
+       RDMA_MAX_INIT_DEPTH = 0xFF\r
 };\r
 \r
 struct rdma_conn_param\r
@@ -171,6 +188,26 @@ struct rdma_cm_event
        }       param;\r
 };\r
 \r
+#define RAI_PASSIVE            0x00000001\r
+\r
+struct rdma_addrinfo {\r
+       int                                             ai_flags;\r
+       int                                             ai_family;\r
+       int                                             ai_qp_type;\r
+       int                                             ai_port_space;\r
+       socklen_t                               ai_src_len;\r
+       socklen_t                               ai_dst_len;\r
+       struct sockaddr                 *ai_src_addr;\r
+       struct sockaddr                 *ai_dst_addr;\r
+       char                                    *ai_src_canonname;\r
+       char                                    *ai_dst_canonname;\r
+       size_t                                  ai_route_len;\r
+       void                                    *ai_route;\r
+       size_t                                  ai_connect_len;\r
+       void                                    *ai_connect;\r
+       struct rdma_addrinfo    *ai_next;\r
+};\r
+\r
 /**\r
  * rdma_create_event_channel - Open a channel used to report communication events.\r
  * Description:\r
@@ -227,6 +264,43 @@ int rdma_create_id(struct rdma_event_channel *channel,
                                   struct rdma_cm_id **id, void *context,\r
                                   enum rdma_port_space ps);\r
 \r
+/**\r
+ * rdma_create_ep - Allocate a communication identifier and qp.\r
+ * @id: A reference where the allocated communication identifier will be\r
+ *   returned.\r
+ * @res: Result from rdma_getaddrinfo, which specifies the source and\r
+ *   destination addresses, plus optional routing and connection information.\r
+ * @pd: Optional protection domain.  This parameter is ignored if qp_init_attr\r
+ *   is NULL.\r
+ * @qp_init_attr: Optional attributes for a QP created on the rdma_cm_id.\r
+ * Description:\r
+ *   Create an identifier and option QP used for communication.\r
+ * Notes:\r
+ *   If qp_init_attr is provided, then a queue pair will be allocated and\r
+ *   associated with the rdma_cm_id.  If a pd is provided, the QP will be\r
+ *   created on that PD.  Otherwise, the QP will be allocated on a default\r
+ *   PD.\r
+ *   The rdma_cm_id will be set to use synchronous operations (connect,\r
+ *   listen, and get_request).  To convert to asynchronous operation, the\r
+ *   rdma_cm_id should be migrated to a user allocated event channel.\r
+ * See also:\r
+ *   rdma_create_id, rdma_create_qp, rdma_migrate_id, rdma_connect,\r
+ *   rdma_listen\r
+ */\r
+int rdma_create_ep(struct rdma_cm_id **id, struct rdma_addrinfo *res,\r
+                  struct ibv_pd *pd, struct ibv_qp_init_attr *qp_init_attr);\r
+\r
+/**\r
+ * rdma_destroy_ep - Deallocates a communication identifier and qp.\r
+ * @id: The communication identifer to destroy.\r
+ * Description:\r
+ *   Destroys the specified rdma_cm_id and any associated QP created\r
+ *   on that id.\r
+ * See also:\r
+ *   rdma_create_ep\r
+ */\r
+void rdma_destroy_ep(struct rdma_cm_id *id);\r
+\r
 /**\r
  * rdma_destroy_id - Release a communication identifier.\r
  * @id: The communication identifier to destroy.\r
index 1a96059a9253b3cec5c2a708790f8736ac4f8344..b2d225d4fdb7010aaa4a1dc941280bac9e6e6dee 100644 (file)
@@ -33,6 +33,7 @@
 #include <iphlpapi.h>\r
 \r
 #include <rdma/rdma_cma.h>\r
+#include <rdma/rdma_verbs.h>\r
 #include <infiniband/verbs.h>\r
 #include <_errno.h>\r
 #include <comp_channel.h>\r
@@ -68,6 +69,7 @@ struct cma_id_private
        struct rdma_cm_id                       id;\r
        enum cma_state                          state;\r
        struct cma_device                       *cma_dev;\r
+       int                                                     sync;\r
        int                                                     backlog;\r
        int                                                     index;\r
        volatile LONG                           refcnt;\r
@@ -77,6 +79,7 @@ struct cma_id_private
 struct cma_device\r
 {\r
        struct ibv_context      *verbs;\r
+       struct ibv_pd           *pd;\r
        uint64_t                        guid;\r
        int                                     port_cnt;\r
        uint8_t                         max_initiator_depth;\r
@@ -261,9 +264,18 @@ int rdma_create_id(struct rdma_event_channel *channel,
        RtlZeroMemory(id_priv, sizeof(struct cma_id_private));\r
        id_priv->refcnt = 1;\r
        id_priv->id.context = context;\r
-       id_priv->id.channel = channel;\r
+\r
+       if (!channel) {\r
+               id_priv->id.channel = rdma_create_event_channel();\r
+               if (!id_priv->id.channel) {\r
+                       goto err2;\r
+               }\r
+               id_priv->sync = 1;\r
+       } else {\r
+               id_priv->id.channel = channel;\r
+       }\r
        id_priv->id.ps = ps;\r
-       CompEntryInit(&channel->channel, &id_priv->id.comp_entry);\r
+       CompEntryInit(&id_priv->id.channel->channel, &id_priv->id.comp_entry);\r
 \r
        if (ps == RDMA_PS_TCP) {\r
                hr = windata.prov->CreateConnectEndpoint(&id_priv->id.ep.connect);\r
@@ -328,10 +340,16 @@ int rdma_destroy_id(struct rdma_cm_id *id)
                id_priv->id.ep.datagram->Release();\r
        }\r
 \r
+       if (id->event) {\r
+               rdma_ack_cm_event(id->event);\r
+       }\r
        InterlockedDecrement(&id_priv->refcnt);\r
        while (id_priv->refcnt) {\r
                Sleep(0);\r
        }\r
+       if (id_priv->sync) {\r
+               rdma_destroy_event_channel(id->channel);\r
+       }\r
        delete id_priv;\r
        ucma_release();\r
        return 0;\r
@@ -471,6 +489,27 @@ int rdma_bind_addr(struct rdma_cm_id *id, struct sockaddr *addr)
        return ret;\r
 }\r
 \r
+static int ucma_complete(struct cma_id_private *id_priv)\r
+{\r
+       int ret;\r
+\r
+       if (!id_priv->sync) {\r
+               return 0;\r
+       }\r
+\r
+       if (id_priv->id.event) {\r
+               rdma_ack_cm_event(id_priv->id.event);\r
+               id_priv->id.event = NULL;\r
+       }\r
+\r
+       ret = rdma_get_cm_event(id_priv->id.channel, &id_priv->id.event);\r
+       if (ret) {\r
+               return ret;\r
+       }\r
+\r
+       return id_priv->id.event->status;\r
+}\r
+\r
 __declspec(dllexport)\r
 int rdma_resolve_addr(struct rdma_cm_id *id, struct sockaddr *src_addr,\r
                                          struct sockaddr *dst_addr, int timeout_ms)\r
@@ -514,7 +553,7 @@ int rdma_resolve_addr(struct rdma_cm_id *id, struct sockaddr *src_addr,
 \r
        id_priv->refcnt++;\r
        CompEntryPost(&id->comp_entry);\r
-       return 0;\r
+       return ucma_complete(id_priv);\r
 }\r
 \r
 __declspec(dllexport)\r
@@ -542,7 +581,7 @@ int rdma_resolve_route(struct rdma_cm_id *id, int timeout_ms)
 \r
        id_priv->refcnt++;\r
        CompEntryPost(&id->comp_entry);\r
-       return 0;\r
+       return ucma_complete(id_priv);\r
 }\r
 \r
 static int ucma_modify_qp_init(struct cma_id_private *id_priv, struct ibv_qp *qp)\r
@@ -678,7 +717,7 @@ int rdma_connect(struct rdma_cm_id *id, struct rdma_conn_param *conn_param)
                return ibvw_wv_errno(hr);\r
        }\r
 \r
-       return 0;\r
+       return ucma_complete(id_priv);\r
 }\r
 \r
 static int ucma_get_request(struct cma_id_private *listen, int index)\r
@@ -805,7 +844,7 @@ int rdma_accept(struct rdma_cm_id *id, struct rdma_conn_param *conn_param)
                return ibvw_wv_errno(hr);\r
        }\r
 \r
-       return 0;\r
+       return ucma_complete(id_priv);\r
 }\r
 \r
 __declspec(dllexport)\r
@@ -847,7 +886,7 @@ int rdma_disconnect(struct rdma_cm_id *id)
                return ibvw_wv_errno(hr);\r
        }\r
 \r
-       return 0;\r
+       return ucma_complete(id_priv);\r
 }\r
 \r
 __declspec(dllexport)\r
@@ -876,21 +915,33 @@ static int ucma_process_conn_req(struct cma_event *event)
 \r
        ucma_get_request(listen, id_priv->index);\r
 \r
-       if (!event->event.status) {\r
-               event->event.status = ucma_query_connect(&id_priv->id,\r
-                                                                                                &event->event.param.conn);\r
+       if (event->event.status) {\r
+               goto err;\r
        }\r
 \r
-       if (!event->event.status) {\r
-               event->event.event = RDMA_CM_EVENT_CONNECT_REQUEST;\r
-               id_priv->state = cma_passive_connect;\r
-               event->event.listen_id = &listen->id;\r
-       } else {\r
-               InterlockedDecrement(&listen->refcnt);\r
-               InterlockedDecrement(&id_priv->refcnt);\r
-               rdma_destroy_id(&id_priv->id);\r
+       if (listen->sync) {\r
+               event->event.status = rdma_migrate_id(&id_priv->id, NULL);\r
+               if (event->event.status) {\r
+                       goto err;\r
+               }\r
+       }\r
+\r
+       event->event.status = ucma_query_connect(&id_priv->id,\r
+                                                                                        &event->event.param.conn);\r
+       if (event->event.status) {\r
+               goto err;\r
        }\r
 \r
+       event->event.event = RDMA_CM_EVENT_CONNECT_REQUEST;\r
+       id_priv->state = cma_passive_connect;\r
+       event->event.listen_id = &listen->id;\r
+\r
+       return 0;\r
+\r
+err:\r
+       InterlockedDecrement(&listen->refcnt);\r
+       InterlockedDecrement(&id_priv->refcnt);\r
+       rdma_destroy_id(&id_priv->id);\r
        return event->event.status;\r
 }\r
 \r
@@ -1043,15 +1094,13 @@ __declspec(dllexport)
 int rdma_join_multicast(struct rdma_cm_id *id, struct sockaddr *addr,\r
                                                void *context)\r
 {\r
-       _set_errno(ENOSYS);\r
-       return -1;\r
+       return rdma_seterrno(ENOSYS);\r
 }\r
 \r
 __declspec(dllexport)\r
 int rdma_leave_multicast(struct rdma_cm_id *id, struct sockaddr *addr)\r
 {\r
-       _set_errno(ENOSYS);\r
-       return -1;\r
+       return rdma_seterrno(ENOSYS);\r
 }\r
 \r
 __declspec(dllexport)\r
@@ -1099,14 +1148,42 @@ __declspec(dllexport)
 int rdma_set_option(struct rdma_cm_id *id, int level, int optname,\r
                                        void *optval, size_t optlen)\r
 {\r
-       _set_errno(ENOSYS);\r
-       return -1;\r
+       return rdma_seterrno(ENOSYS);\r
 }\r
 \r
 __declspec(dllexport)\r
 int rdma_migrate_id(struct rdma_cm_id *id, struct rdma_event_channel *channel)\r
 {\r
+       struct cma_id_private *id_priv;\r
+       int sync;\r
+\r
+       id_priv = CONTAINING_RECORD(id, struct cma_id_private, id);\r
+       if (id_priv->sync && !channel) {\r
+               return rdma_seterror(EINVAL);\r
+       }\r
+\r
+       if (id->comp_entry.Busy) {\r
+               return rdma_seterrno(EBUSY);\r
+       }\r
+\r
+       if ((sync = (channel == NULL))) {\r
+               channel = rdma_create_event_channel();\r
+               if (!channel) {\r
+                       return rdma_seterror(ENOMEM);\r
+               }\r
+       }\r
+\r
+       if (id_priv->sync) {\r
+               if (id->event) {\r
+                       rdma_ack_cm_event(id->event);\r
+                       id->event = NULL;\r
+               }\r
+               rdma_destroy_event_channel(id->channel);\r
+       }\r
+\r
+       id_priv->sync = sync;\r
        id->channel = channel;\r
+       id->comp_entry.Channel = channel->channel;\r
        return 0;\r
 }\r
 \r