\r
#include <rdma/rdma_cma.h>\r
#include <infiniband/verbs.h>\r
+#include <comp_channel.h>\r
#include <iba/ibat.h>\r
#include "cma.h"\r
+#include "..\..\..\etc\user\comp_channel.cpp"\r
\r
-IWVProvider *prov;\r
-__declspec(dllexport)\r
-IWVProvider *ibv_get_winverbs(void);\r
+static struct ibvw_windata windata;\r
\r
enum cma_state\r
{\r
cma_idle,\r
cma_listening,\r
cma_get_request,\r
+ cma_addr_bind,\r
cma_addr_resolve,\r
cma_route_resolve,\r
cma_passive_connect,\r
cma_connected,\r
cma_active_disconnect,\r
cma_passive_disconnect,\r
- cma_disconnected\r
+ cma_disconnected,\r
+ cma_destroying\r
};\r
\r
#define CMA_DEFAULT_BACKLOG 16\r
{\r
struct rdma_cm_id id;\r
enum cma_state state;\r
- int channel_index;\r
struct cma_device *cma_dev;\r
int backlog;\r
int index;\r
+ volatile LONG refcnt;\r
struct rdma_cm_id **req_list;\r
};\r
\r
-struct cma_event_channel\r
-{\r
- struct rdma_event_channel channel;\r
- CRITICAL_SECTION lock;\r
- struct cma_id_private *id[MAXIMUM_WAIT_OBJECTS];\r
- HANDLE event[MAXIMUM_WAIT_OBJECTS];\r
- int count;\r
-};\r
-\r
struct cma_device\r
{\r
struct ibv_context *verbs;\r
static struct cma_device *cma_dev_array;\r
static int cma_dev_cnt;\r
\r
-static void ucma_cleanup(void)\r
-{\r
- if (cma_dev_cnt > 0) {\r
- while (cma_dev_cnt > 0) {\r
- ibv_close_device(cma_dev_array[--cma_dev_cnt].verbs);\r
- }\r
- delete cma_dev_array;\r
- cma_dev_cnt = 0;\r
- }\r
- if (prov != NULL) {\r
- prov->Release();\r
- prov = NULL;\r
- }\r
-}\r
-\r
static int ucma_init(void)\r
{\r
struct ibv_device **dev_list = NULL;\r
struct cma_device *cma_dev;\r
struct ibv_device_attr attr;\r
- int i, ret;\r
+ int i, ret, dev_cnt;\r
\r
EnterCriticalSection(&lock);\r
- if (cma_dev_cnt > 0) {\r
+ if (cma_dev_cnt) {\r
goto out;\r
}\r
\r
- prov = ibv_get_winverbs();\r
- if (prov == NULL) {\r
- ret = -1;\r
- goto err;\r
+ ret = ibvw_get_windata(&windata, IBVW_WINDATA_VERSION);\r
+ if (ret) {\r
+ goto err1;\r
}\r
\r
- dev_list = ibv_get_device_list(&cma_dev_cnt);\r
+ dev_list = ibv_get_device_list(&dev_cnt);\r
if (dev_list == NULL) {\r
ret = -1;\r
- goto err;\r
+ goto err2;\r
}\r
\r
- cma_dev_array = new struct cma_device[cma_dev_cnt];\r
+ cma_dev_array = new struct cma_device[dev_cnt];\r
if (cma_dev_array == NULL) {\r
ret = -1;\r
- goto err;\r
+ goto err3;\r
}\r
\r
- for (i = 0; dev_list[i]; ++i) {\r
+ for (i = 0; dev_list[i];) {\r
cma_dev = &cma_dev_array[i];\r
\r
cma_dev->guid = ibv_get_device_guid(dev_list[i]);\r
cma_dev->verbs = ibv_open_device(dev_list[i]);\r
if (cma_dev->verbs == NULL) {\r
ret = -1;\r
- goto err;\r
+ goto err4;\r
}\r
\r
+ ++i;\r
ret = ibv_query_device(cma_dev->verbs, &attr);\r
if (ret) {\r
- goto err;\r
+ goto err4;\r
}\r
\r
cma_dev->port_cnt = attr.phys_port_cnt;\r
cma_dev->max_responder_resources = (uint8_t) attr.max_qp_rd_atom;\r
}\r
ibv_free_device_list(dev_list);\r
+ cma_dev_cnt = dev_cnt;\r
out:\r
LeaveCriticalSection(&lock);\r
return 0;\r
\r
-err:\r
- ucma_cleanup();\r
- LeaveCriticalSection(&lock);\r
- if (dev_list) {\r
- ibv_free_device_list(dev_list);\r
+err4:\r
+ while (i) {\r
+ ibv_close_device(cma_dev_array[--i].verbs);\r
}\r
+ delete cma_dev_array;\r
+err3:\r
+ ibv_free_device_list(dev_list);\r
+err2:\r
+ ibvw_release_windata(&windata, IBVW_WINDATA_VERSION);\r
+err1:\r
+ LeaveCriticalSection(&lock);\r
return ret;\r
}\r
\r
__declspec(dllexport)\r
struct rdma_event_channel *rdma_create_event_channel(void)\r
{\r
- struct cma_event_channel *chan;\r
+ struct rdma_event_channel *channel;\r
\r
if (!cma_dev_cnt && ucma_init()) {\r
return NULL;\r
}\r
\r
- chan = new struct cma_event_channel;\r
- if (chan == NULL) {\r
+ channel = new struct rdma_event_channel;\r
+ if (channel == NULL) {\r
return NULL;\r
}\r
\r
- InitializeCriticalSection(&chan->lock);\r
- chan->count = 0;\r
- chan->channel.timeout = INFINITE;\r
-\r
- return &chan->channel;\r
+ CompChannelInit(windata.comp_mgr, &channel->channel, INFINITE);\r
+ return channel;\r
}\r
\r
__declspec(dllexport)\r
void rdma_destroy_event_channel(struct rdma_event_channel *channel)\r
{\r
- struct cma_event_channel *chan;\r
-\r
- chan = CONTAINING_RECORD(channel, struct cma_event_channel, channel);\r
- DeleteCriticalSection(&chan->lock); \r
- delete chan;\r
-}\r
-\r
-static int cma_event_channel_insert_id(struct rdma_event_channel *channel,\r
- struct cma_id_private *id_priv)\r
-{\r
- struct cma_event_channel *chan;\r
- int ret = 0;\r
-\r
- chan = CONTAINING_RECORD(channel, struct cma_event_channel, channel);\r
-\r
- EnterCriticalSection(&chan->lock);\r
- if (chan->count == MAXIMUM_WAIT_OBJECTS) {\r
- ret = -1;\r
- goto out;\r
- }\r
-\r
- chan->id[chan->count] = id_priv;\r
- chan->event[chan->count] = id_priv->id.overlap.hEvent;\r
- id_priv->channel_index = chan->count++;\r
-out:\r
- LeaveCriticalSection(&chan->lock);\r
- return ret;\r
-}\r
-\r
-/*\r
- * TODO: we cannot call cma_event_channel_remove_id() while another\r
- * thread is calling rdma_get_event(). If this is needed, then we\r
- * need to halt the rdma_get_event() thread, modify the event list,\r
- * then restart the rdma_get_event() thread.\r
- */\r
-static void cma_event_channel_remove_id(struct rdma_event_channel *channel,\r
- struct cma_id_private *id_priv)\r
-{\r
- struct cma_event_channel *chan;\r
-\r
- chan = CONTAINING_RECORD(channel, struct cma_event_channel, channel);\r
-\r
- EnterCriticalSection(&chan->lock);\r
- chan->count--;\r
- chan->id[id_priv->channel_index] = chan->id[chan->count];\r
- chan->event[id_priv->channel_index] = chan->event[chan->count];\r
- chan->id[id_priv->channel_index]->channel_index = id_priv->channel_index;\r
- LeaveCriticalSection(&chan->lock);\r
+ CompChannelCleanup(&channel->channel);\r
+ delete channel;\r
}\r
\r
__declspec(dllexport)\r
}\r
\r
RtlZeroMemory(id_priv, sizeof(struct cma_id_private));\r
- id_priv->id.overlap.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);\r
- if (id_priv->id.overlap.hEvent == NULL) {\r
- goto err1;\r
- }\r
-\r
+ id_priv->refcnt = 1;\r
id_priv->id.context = context;\r
id_priv->id.channel = channel;\r
id_priv->id.ps = ps;\r
+ CompEntryInit(&channel->channel, &id_priv->id.comp_entry);\r
\r
if (ps == RDMA_PS_TCP) {\r
- hr = prov->CreateConnectEndpoint(&id_priv->id.ep.connect);\r
+ hr = windata.prov->CreateConnectEndpoint(&id_priv->id.ep.connect);\r
} else {\r
- hr = prov->CreateDatagramEndpoint(&id_priv->id.ep.datagram);\r
- }\r
- if (FAILED(hr)) {\r
- goto err2;\r
+ hr = windata.prov->CreateDatagramEndpoint(&id_priv->id.ep.datagram);\r
}\r
-\r
- hr = cma_event_channel_insert_id(channel, id_priv);\r
if (FAILED(hr)) {\r
- goto err3;\r
+ goto err;\r
}\r
\r
*id = &id_priv->id;\r
return 0;\r
\r
-err3:\r
- if (ps == RDMA_PS_TCP) {\r
- id_priv->id.ep.connect->Release();\r
- } else {\r
- id_priv->id.ep.datagram->Release();\r
- }\r
-err2:\r
- CloseHandle(id_priv->id.overlap.hEvent);\r
-err1:\r
+err:\r
delete id_priv;\r
- return -1;\r
+ return hr;\r
}\r
\r
static void ucma_destroy_listen(struct cma_id_private *id_priv)\r
{\r
while (--id_priv->backlog >= 0) {\r
if (id_priv->req_list[id_priv->backlog] != NULL) {\r
+ InterlockedDecrement(&id_priv->refcnt);\r
rdma_destroy_id(id_priv->req_list[id_priv->backlog]);\r
}\r
}\r
__declspec(dllexport)\r
int rdma_destroy_id(struct rdma_cm_id *id)\r
{\r
- struct cma_id_private *id_priv;\r
+ struct cma_id_private *id_priv;\r
\r
id_priv = CONTAINING_RECORD(id, struct cma_id_private, id);\r
+\r
+ EnterCriticalSection(&lock);\r
+ id_priv->state = cma_destroying;\r
+ LeaveCriticalSection(&lock);\r
+\r
if (id->ps == RDMA_PS_TCP) {\r
id->ep.connect->CancelOverlappedRequests();\r
} else {\r
id->ep.datagram->CancelOverlappedRequests();\r
}\r
\r
- cma_event_channel_remove_id(id->channel, id_priv);\r
+ if (CompEntryCancel(&id->comp_entry) != NULL) {\r
+ InterlockedDecrement(&id_priv->refcnt);\r
+ }\r
\r
if (id_priv->backlog > 0) {\r
ucma_destroy_listen(id_priv);\r
id_priv->id.ep.datagram->Release();\r
}\r
\r
+ InterlockedDecrement(&id_priv->refcnt);\r
+ while (id_priv->refcnt) {\r
+ Sleep(0);\r
+ }\r
delete id_priv;\r
return 0;\r
}\r
__declspec(dllexport)\r
int rdma_bind_addr(struct rdma_cm_id *id, struct sockaddr *addr)\r
{\r
+ struct cma_id_private *id_priv;\r
HRESULT hr;\r
\r
if (id->ps == RDMA_PS_TCP) {\r
}\r
}\r
\r
+ if (SUCCEEDED(hr)) {\r
+ id_priv = CONTAINING_RECORD(id, struct cma_id_private, id);\r
+ id_priv->state = cma_addr_bind;\r
+ }\r
return hr;\r
}\r
\r
DWORD size;\r
HRESULT hr;\r
\r
- if (src_addr == NULL) {\r
- if (id->ps == RDMA_PS_TCP) {\r
- s = socket(dst_addr->sa_family, SOCK_STREAM, IPPROTO_TCP);\r
- } else {\r
- s = socket(dst_addr->sa_family, SOCK_DGRAM, IPPROTO_UDP);\r
- }\r
- if (s == INVALID_SOCKET) {\r
- return WSAGetLastError();\r
+ id_priv = CONTAINING_RECORD(id, struct cma_id_private, id);\r
+ if (id_priv->state == cma_idle) {\r
+ if (src_addr == NULL) {\r
+ if (id->ps == RDMA_PS_TCP) {\r
+ s = socket(dst_addr->sa_family, SOCK_STREAM, IPPROTO_TCP);\r
+ } else {\r
+ s = socket(dst_addr->sa_family, SOCK_DGRAM, IPPROTO_UDP);\r
+ }\r
+ if (s == INVALID_SOCKET) {\r
+ return WSAGetLastError();\r
+ }\r
+\r
+ hr = WSAIoctl(s, SIO_ROUTING_INTERFACE_QUERY, dst_addr, ucma_addrlen(dst_addr),\r
+ &addr, sizeof addr, &size, NULL, NULL);\r
+ closesocket(s);\r
+ if (FAILED(hr)) {\r
+ return WSAGetLastError();\r
+ }\r
+ src_addr = &addr.Sa;\r
}\r
\r
- hr = WSAIoctl(s, SIO_ROUTING_INTERFACE_QUERY, dst_addr, ucma_addrlen(dst_addr),\r
- &addr, sizeof addr, &size, NULL, NULL);\r
- closesocket(s);\r
+ hr = rdma_bind_addr(id, src_addr);\r
if (FAILED(hr)) {\r
- return WSAGetLastError();\r
+ return hr;\r
}\r
- src_addr = &addr.Sa;\r
- }\r
-\r
- hr = rdma_bind_addr(id, src_addr);\r
- if (FAILED(hr)) {\r
- return hr;\r
}\r
\r
RtlCopyMemory(&id->route.addr.dst_addr, dst_addr, ucma_addrlen(dst_addr));\r
- id_priv = CONTAINING_RECORD(id, struct cma_id_private, id);\r
id_priv->state = cma_addr_resolve;\r
- SetEvent(id->overlap.hEvent);\r
+\r
+ id_priv->refcnt++;\r
+ CompEntryPost(&id->comp_entry);\r
return 0;\r
}\r
\r
IBAT_PATH_BLOB path;\r
HRESULT hr;\r
\r
- hr = IBAT::Resolve(&id->route.addr.src_addr, &id->route.addr.dst_addr, &path);\r
+ do {\r
+ hr = IBAT::Resolve(&id->route.addr.src_addr, &id->route.addr.dst_addr, &path);\r
+ if (hr != E_PENDING) {\r
+ break;\r
+ }\r
+ timeout_ms -= 10;\r
+ if (timeout_ms > 0)\r
+ Sleep(10);\r
+ } while (timeout_ms > 0);\r
+\r
if (FAILED(hr)) {\r
return hr;\r
}\r
\r
id_priv = CONTAINING_RECORD(id, struct cma_id_private, id);\r
id_priv->state = cma_route_resolve;\r
- SetEvent(id->overlap.hEvent);\r
+\r
+ id_priv->refcnt++;\r
+ CompEntryPost(&id->comp_entry);\r
return 0;\r
}\r
\r
static int ucma_modify_qp_init(struct cma_id_private *id_priv, struct ibv_qp *qp)\r
{\r
struct ibv_qp_attr qp_attr;\r
- DWORD index;\r
+ UINT16 index;\r
HRESULT hr;\r
\r
RtlZeroMemory(&qp_attr, sizeof qp_attr);\r
return hr;\r
}\r
\r
- qp_attr.pkey_index = (uint16_t) index;\r
+ qp_attr.pkey_index = index;\r
return ibv_modify_qp(qp, &qp_attr, (enum ibv_qp_attr_mask)\r
(IBV_QP_STATE | IBV_QP_PKEY_INDEX | IBV_QP_PORT));\r
}\r
}\r
\r
id_priv->state = cma_active_connect;\r
+ id_priv->refcnt++;\r
+ id->comp_entry.Busy = 1;\r
hr = id->ep.connect->Connect(id->qp->conn_handle, &id->route.addr.dst_addr,\r
- &attr, &id->overlap);\r
+ &attr, &id->comp_entry.Overlap);\r
if (FAILED(hr) && hr != WV_IO_PENDING) {\r
+ id_priv->refcnt--;\r
+ id->comp_entry.Busy = 0;\r
id_priv->state = cma_route_resolve;\r
return hr;\r
}\r
\r
static int ucma_get_request(struct cma_id_private *listen, int index)\r
{\r
- struct cma_id_private *id_priv;\r
+ struct cma_id_private *id_priv = NULL;\r
HRESULT hr;\r
\r
+ EnterCriticalSection(&lock);\r
+ if (listen->state != cma_listening) {\r
+ hr = WV_INVALID_PARAMETER;\r
+ goto err1;\r
+ }\r
+\r
+ InterlockedIncrement(&listen->refcnt);\r
hr = rdma_create_id(listen->id.channel, &listen->req_list[index],\r
listen, listen->id.ps);\r
if (FAILED(hr)) {\r
- return hr;\r
+ goto err2;\r
}\r
\r
id_priv = CONTAINING_RECORD(listen->req_list[index], struct cma_id_private, id);\r
id_priv->index = index;\r
id_priv->state = cma_get_request;\r
\r
+ id_priv->refcnt++;\r
+ id_priv->id.comp_entry.Busy = 1;\r
if (listen->id.ps == RDMA_PS_TCP) {\r
hr = listen->id.ep.connect->GetRequest(id_priv->id.ep.connect,\r
- &id_priv->id.overlap);\r
+ &id_priv->id.comp_entry.Overlap);\r
} else {\r
hr = listen->id.ep.datagram->GetRequest(id_priv->id.ep.datagram,\r
- &id_priv->id.overlap);\r
+ &id_priv->id.comp_entry.Overlap);\r
}\r
+ if (FAILED(hr) && hr != WV_IO_PENDING) {\r
+ id_priv->id.comp_entry.Busy = 0;\r
+ id_priv->refcnt--;\r
+ goto err2;\r
+ }\r
+ LeaveCriticalSection(&lock);\r
\r
- return (FAILED(hr) && hr != WV_IO_PENDING) ? hr : 0;\r
+ return 0;\r
+\r
+err2:\r
+ InterlockedDecrement(&listen->refcnt);\r
+err1:\r
+ LeaveCriticalSection(&lock);\r
+ if (id_priv != NULL) {\r
+ rdma_destroy_id(&id_priv->id);\r
+ }\r
+ return hr;\r
}\r
\r
__declspec(dllexport)\r
HRESULT hr;\r
int i;\r
\r
- if (backlog <= 0 || backlog > CMA_DEFAULT_BACKLOG) {\r
+ if (backlog <= 0) {\r
backlog = CMA_DEFAULT_BACKLOG;\r
}\r
\r
}\r
\r
id_priv->state = cma_accepting;\r
- hr = id->ep.connect->Accept(id->qp->conn_handle, &attr, &id->overlap);\r
+ id_priv->refcnt++;\r
+ id->comp_entry.Busy = 1;\r
+ hr = id->ep.connect->Accept(id->qp->conn_handle, &attr,\r
+ &id->comp_entry.Overlap);\r
if (FAILED(hr) && hr != WV_IO_PENDING) {\r
+ id_priv->refcnt--;\r
+ id->comp_entry.Busy = 0;\r
id_priv->state = cma_disconnected;\r
return hr;\r
}\r
} else {\r
id_priv->state = cma_disconnected;\r
}\r
- hr = id->ep.connect->Disconnect();\r
+ hr = id->ep.connect->Disconnect(NULL);\r
if (FAILED(hr)) {\r
return hr;\r
}\r
int rdma_ack_cm_event(struct rdma_cm_event *event)\r
{\r
struct cma_event *evt;\r
+ struct cma_id_private *listen;\r
\r
evt = CONTAINING_RECORD(event, struct cma_event, event);\r
+ InterlockedDecrement(&evt->id_priv->refcnt);\r
+ if (evt->event.listen_id) {\r
+ listen = CONTAINING_RECORD(evt->event.listen_id, struct cma_id_private, id);\r
+ InterlockedDecrement(&listen->refcnt);\r
+ }\r
delete evt;\r
return 0;\r
}\r
\r
static int ucma_process_conn_req(struct cma_event *event)\r
{\r
- struct cma_id_private *listen;\r
- HRESULT hr = 0;\r
+ struct cma_id_private *listen, *id_priv;\r
+ struct cma_event_channel *chan;\r
\r
listen = (struct cma_id_private *) event->id_priv->id.context;\r
+ id_priv = event->id_priv;\r
+\r
+ ucma_get_request(listen, id_priv->index);\r
\r
if (SUCCEEDED(event->event.status)) {\r
- event->event.status = ucma_query_connect(&event->id_priv->id,\r
+ event->event.status = ucma_query_connect(&id_priv->id,\r
&event->event.param.conn);\r
}\r
\r
if (SUCCEEDED(event->event.status)) {\r
event->event.event = RDMA_CM_EVENT_CONNECT_REQUEST;\r
- event->id_priv->state = cma_passive_connect;\r
-\r
- listen->req_list[event->id_priv->index] = NULL;\r
- ucma_get_request(listen, event->id_priv->index);\r
+ id_priv->state = cma_passive_connect;\r
+ event->event.listen_id = &listen->id;\r
} else {\r
- hr = listen->id.ep.connect->GetRequest(event->id_priv->id.ep.connect,\r
- &event->id_priv->id.overlap);\r
- if (hr == WV_IO_PENDING) {\r
- hr = 0;\r
- }\r
+ InterlockedDecrement(&listen->refcnt);\r
+ InterlockedDecrement(&id_priv->refcnt);\r
+ rdma_destroy_id(&id_priv->id);\r
}\r
\r
- return hr;\r
+ return event->event.status;\r
}\r
\r
static int ucma_process_conn_resp(struct cma_event *event)\r
{\r
- struct rdma_cm_id *id;\r
- WV_CONNECT_PARAM attr;\r
- HRESULT hr;\r
+ struct rdma_cm_id *id;\r
+ WV_CONNECT_PARAM attr;\r
+ HRESULT hr;\r
\r
if (FAILED(event->event.status)) {\r
goto err;\r
event->id_priv->state = cma_accepting;\r
\r
id = &event->id_priv->id;\r
- hr = id->ep.connect->Accept(id->qp->conn_handle, &attr, &id->overlap);\r
+ id->comp_entry.Busy = 1;\r
+ hr = id->ep.connect->Accept(id->qp->conn_handle, &attr,\r
+ &id->comp_entry.Overlap);\r
if (FAILED(hr) && hr != WV_IO_PENDING) {\r
+ id->comp_entry.Busy = 0;\r
event->event.status = hr;\r
goto err;\r
}\r
\r
static void ucma_process_establish(struct cma_event *event)\r
{\r
+ struct cma_id_private *id_priv = event->id_priv;\r
+\r
if (SUCCEEDED(event->event.status)) {\r
- event->event.status = ucma_query_connect(&event->id_priv->id,\r
+ event->event.status = ucma_query_connect(&id_priv->id,\r
&event->event.param.conn);\r
}\r
\r
if (SUCCEEDED(event->event.status)) {\r
event->event.event = RDMA_CM_EVENT_ESTABLISHED;\r
- event->id_priv->state = cma_connected;\r
\r
- event->id_priv->id.ep.connect->NotifyDisconnect(&event->id_priv->id.overlap);\r
+ id_priv->state = cma_connected;\r
+ InterlockedIncrement(&id_priv->refcnt);\r
+ id_priv->id.comp_entry.Busy = 1;\r
+ id_priv->id.ep.connect->NotifyDisconnect(&id_priv->id.comp_entry.Overlap);\r
} else {\r
event->event.event = RDMA_CM_EVENT_CONNECT_ERROR;\r
event->id_priv->state = cma_disconnected;\r
\r
static int ucma_process_event(struct cma_event *event)\r
{\r
+ struct cma_id_private *listen, *id_priv;\r
WV_CONNECT_ATTRIBUTES attr;\r
HRESULT hr = 0;\r
\r
- switch (event->id_priv->state) {\r
+ id_priv = event->id_priv;\r
+\r
+ EnterCriticalSection(&lock);\r
+ switch (id_priv->state) {\r
case cma_get_request:\r
- hr = ucma_process_conn_req(event);\r
- break;\r
+ listen = (struct cma_id_private *) id_priv->id.context;\r
+ if (listen->state != cma_listening) {\r
+ InterlockedDecrement(&id_priv->refcnt);\r
+ hr = WV_CANCELLED;\r
+ break;\r
+ }\r
+\r
+ listen->req_list[id_priv->index] = NULL;\r
+ LeaveCriticalSection(&lock);\r
+ return ucma_process_conn_req(event);\r
case cma_addr_resolve:\r
event->event.event = RDMA_CM_EVENT_ADDR_RESOLVED;\r
break;\r
break;\r
case cma_connected:\r
event->event.event = RDMA_CM_EVENT_DISCONNECTED;\r
- event->id_priv->state = cma_passive_disconnect;\r
+ id_priv->state = cma_passive_disconnect;\r
break;\r
case cma_active_disconnect:\r
event->event.event = RDMA_CM_EVENT_DISCONNECTED;\r
- event->id_priv->state = cma_disconnected;\r
+ id_priv->state = cma_disconnected;\r
break;\r
default:\r
- return -1;\r
+ InterlockedDecrement(&id_priv->refcnt);\r
+ hr = WV_CANCELLED;\r
}\r
+ LeaveCriticalSection(&lock);\r
\r
return hr;\r
}\r
int rdma_get_cm_event(struct rdma_event_channel *channel,\r
struct rdma_cm_event **event)\r
{\r
- struct cma_event_channel *chan;\r
struct cma_event *evt;\r
- struct cma_id_private *id_priv;\r
struct rdma_cm_id *id;\r
- DWORD bytes;\r
- HRESULT hr;\r
+ COMP_ENTRY *entry;\r
+ DWORD bytes, ret;\r
\r
evt = new struct cma_event;\r
if (evt == NULL) {\r
do {\r
RtlZeroMemory(evt, sizeof(struct cma_event));\r
\r
- chan = CONTAINING_RECORD(channel, struct cma_event_channel, channel);\r
- hr = WaitForMultipleObjects(chan->count, chan->event, FALSE,\r
- chan->channel.timeout);\r
- if (hr == WAIT_TIMEOUT) {\r
- return hr;\r
- } else if (hr == WAIT_FAILED) {\r
- return HRESULT_FROM_WIN32(GetLastError());\r
+ ret = CompChannelPoll(&channel->channel, &entry);\r
+ if (ret) {\r
+ delete evt;\r
+ return ret;\r
}\r
\r
- EnterCriticalSection(&chan->lock);\r
- evt->id_priv = chan->id[hr];\r
- LeaveCriticalSection(&chan->lock);\r
-\r
- id = &evt->id_priv->id;\r
+ id = CONTAINING_RECORD(entry, struct rdma_cm_id, comp_entry);\r
+ evt->id_priv = CONTAINING_RECORD(id, struct cma_id_private, id);\r
evt->event.id = id;\r
evt->event.param.conn.private_data = evt->private_data;\r
- if (id->ep.connect->GetOverlappedResult(&id->overlap, &bytes, FALSE) == 0) {\r
- evt->event.status = HRESULT_FROM_WIN32(GetLastError());\r
- }\r
+ evt->event.status = id->ep.connect->\r
+ GetOverlappedResult(&entry->Overlap, &bytes, FALSE);\r
\r
- hr = ucma_process_event(evt);\r
- } while (FAILED(hr));\r
+ ret = ucma_process_event(evt);\r
+ } while (ret);\r
\r
*event = &evt->event;\r
return 0;\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
-\r
- id_priv = CONTAINING_RECORD(id, struct cma_id_private, id);\r
- cma_event_channel_remove_id(id->channel, id_priv);\r
- /*\r
- * TODO: To support calling this routine while processing events on the old\r
- * channel, we need to wait for all old events to be acknowledged.\r
- */\r
id->channel = channel;\r
- cma_event_channel_insert_id(channel, id_priv);\r
-\r
return 0;\r
}\r