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