#include <infiniband/verbs.h>\r
#include <rdma/winverbs.h>\r
#include "..\..\..\etc\user\comp_channel.cpp"\r
+#include "..\..\..\etc\user\dlist.c"\r
\r
+CRITICAL_SECTION lock;\r
IWVProvider *prov;\r
COMP_MANAGER comp_mgr;\r
+static DWORD ref;\r
\r
struct verbs_device\r
{\r
{\r
struct ibv_context context;\r
struct verbs_device device;\r
+ uint8_t closing;\r
struct verbs_port *port;\r
verbs_port *event_port;\r
};\r
\r
-static int ibv_init(void)\r
+static int ibv_acquire(void)\r
{\r
HRESULT hr;\r
\r
- if (prov == NULL) {\r
+ EnterCriticalSection(&lock);\r
+ if (ref++ == 0) {\r
hr = WvGetObject(IID_IWVProvider, (LPVOID*) &prov);\r
if (FAILED(hr)) {\r
- return -1;\r
+ goto err1;\r
+ }\r
+ hr = CompManagerOpen(&comp_mgr);\r
+ if (FAILED(hr)) {\r
+ goto err2;\r
+ }\r
+ hr = CompManagerMonitor(&comp_mgr, prov->GetFileHandle(), 0);\r
+ if (FAILED(hr)) {\r
+ goto err3;\r
}\r
- CompManagerOpen(&comp_mgr);\r
- CompManagerMonitor(&comp_mgr, prov->GetFileHandle(), 0);\r
}\r
+ LeaveCriticalSection(&lock);\r
return 0;\r
+\r
+err3:\r
+ CompManagerClose(&comp_mgr);\r
+err2:\r
+ prov->Release();\r
+err1:\r
+ ref--;\r
+ LeaveCriticalSection(&lock);\r
+ return hr;\r
+}\r
+\r
+static void ibv_release(void)\r
+{\r
+ EnterCriticalSection(&lock);\r
+ if (--ref == 0) {\r
+ CompManagerClose(&comp_mgr);\r
+ prov->Release();\r
+ }\r
+ LeaveCriticalSection(&lock);\r
}\r
\r
__declspec(dllexport)\r
-int ibv_get_windata(struct ibv_windata *windata, int version)\r
+int ibvw_get_windata(struct ibvw_windata *windata, int version)\r
{\r
int ret;\r
\r
- if (version != IBV_WINDATA_VERSION || ibv_init()) {\r
+ if (version != IBVW_WINDATA_VERSION || ibv_acquire()) {\r
return -1;\r
}\r
\r
}\r
\r
__declspec(dllexport)\r
-void ibv_release_windata(struct ibv_windata *windata, int version)\r
+void ibvw_release_windata(struct ibvw_windata *windata, int version)\r
{\r
- windata->prov->Release();\r
+ ibv_release();\r
}\r
\r
__declspec(dllexport)\r
SIZE_T size, cnt;\r
HRESULT hr;\r
\r
- if (ibv_init()) {\r
+ if (ibv_acquire()) {\r
goto err1;\r
}\r
\r
goto err3;\r
}\r
\r
- sprintf(dev_array[cnt].device.name, "ibv_device_0x%I64x", guid[cnt]);\r
+ sprintf(dev_array[cnt].device.name, "ibv_device%d", cnt);\r
dev_array[cnt].device.node_type = IBV_NODE_UNKNOWN;\r
dev_array[cnt].device.transport_type = (ibv_transport_type) attr.DeviceType;\r
dev_array[cnt].guid = guid[cnt];\r
__declspec(dllexport)\r
void ibv_free_device_list(struct ibv_device **list)\r
{\r
+ ibv_release();\r
delete CONTAINING_RECORD(list[0], struct verbs_device, device);\r
delete list;\r
}\r
if (vcontext == NULL) {\r
return NULL;\r
}\r
+\r
+ ibv_acquire();\r
memcpy(&vcontext->device, vdev, sizeof(struct verbs_device));\r
+ vcontext->context.device = &vcontext->device.device;\r
vcontext->event_port = NULL;\r
+ vcontext->closing = 0;\r
CompChannelInit(&comp_mgr, &vcontext->context.channel, INFINITE);\r
\r
vcontext->port = new struct verbs_port[vdev->phys_port_cnt];\r
vcontext->port[i].port_num = (uint8_t) i + 1;\r
vcontext->port[i].event_flag = 0;\r
CompEntryInit(&vcontext->context.channel, &vcontext->port[i].comp_entry);\r
+ vcontext->port[i].comp_entry.Busy = 1;\r
vcontext->context.cmd_if->Notify(vcontext->port[i].port_num,\r
&vcontext->port[i].comp_entry.Overlap,\r
&vcontext->port[i].event_flag);\r
delete vcontext->port;\r
err1:\r
delete vcontext;\r
+ ibv_release();\r
return NULL;\r
}\r
\r
int i;\r
\r
vcontext = CONTAINING_RECORD(context, struct verbs_context, context);\r
+ vcontext->closing = 1;\r
context->cmd_if->CancelOverlappedRequests();\r
\r
for (i = 0; i < vcontext->device.phys_port_cnt; i++) {\r
- CompChannelRemoveEntry(&context->channel, &vcontext->port[i].comp_entry);\r
+ CompEntryCancel(&vcontext->port[i].comp_entry);\r
}\r
\r
context->cmd_if->Release();\r
+ ibv_release();\r
delete vcontext->port;\r
delete vcontext;\r
return 0;\r
ret = -1;\r
}\r
\r
- if (port->event_flag == 0) {\r
+ if (port->event_flag == 0 && !vcontext->closing) {\r
+ port->comp_entry.Busy = 1;\r
vcontext->context.cmd_if->Notify(vcontext->event_port->port_num,\r
&port->comp_entry.Overlap,\r
&port->event_flag);\r
#include <windows.h>\r
#include <winsock2.h>\r
#include <stdio.h>\r
+#include <netinet/in.h>\r
\r
#include <infiniband/verbs.h>\r
#include <comp_channel.h>\r
#include "ibverbs.h"\r
\r
+\r
__declspec(dllexport)\r
int ibv_rate_to_mult(enum ibv_rate rate)\r
{\r
delete mr;\r
return NULL;\r
}\r
+ mr->rkey = ntohl(mr->rkey);\r
return mr;\r
}\r
\r
{\r
HRESULT hr;\r
\r
- hr = cq->handle->Notify(solicited_only ? WvCqSolicited : WvCqNextCompletion,\r
- &cq->comp_entry.Overlap);\r
- if (SUCCEEDED(hr) || hr == WV_IO_PENDING) {\r
- return 0;\r
+ if (InterlockedCompareExchange(&cq->comp_entry.Busy, 1, 0) == 0) {\r
+ hr = cq->handle->Notify(solicited_only ? WvCqSolicited : WvCqNextCompletion,\r
+ &cq->comp_entry.Overlap);\r
+ if (SUCCEEDED(hr) || hr == WV_IO_PENDING) {\r
+ hr = 0;\r
+ }\r
} else {\r
- return hr;\r
+ hr = 0;\r
}\r
+ return hr;\r
}\r
\r
__declspec(dllexport)\r
int ibv_destroy_cq(struct ibv_cq *cq)\r
{\r
cq->handle->CancelOverlappedRequests();\r
-\r
if (cq->channel != NULL) {\r
- CompChannelRemoveEntry(&cq->channel->comp_channel, &cq->comp_entry);\r
+ CompEntryCancel(&cq->comp_entry);\r
}\r
-\r
cq->handle->Release();\r
delete cq;\r
return 0;\r
cur_wr->opcode = (ibv_wr_opcode) (cur_wr->opcode & ~0x80000000);\r
cur_wr->send_flags = (ibv_send_flags) (cur_wr->send_flags | WV_SEND_IMMEDIATE);\r
}\r
+\r
+ if (cur_wr->opcode != 0) {\r
+ cur_wr->wr.rdma.rkey = htonl(cur_wr->wr.rdma.rkey);\r
+ }\r
}\r
\r
hr = qp->handle->PostSend((WV_SEND_REQUEST *) wr, (WV_SEND_REQUEST **) bad_wr);\r
\r
for (cur_wr = wr; cur_wr != NULL; cur_wr = cur_wr->next) {\r
- if (qp->qp_type == IBV_QPT_UD) {\r
- cur_wr->wr.ud.ah = ah;\r
- cur_wr->wr.ud.remote_qkey = ntohl(cur_wr->wr.ud.remote_qkey);\r
- cur_wr->wr.ud.remote_qpn = ntohl(cur_wr->wr.ud.remote_qpn);\r
+ if (cur_wr->opcode != 0) {\r
+ cur_wr->wr.rdma.rkey = ntohl(cur_wr->wr.rdma.rkey);\r
}\r
\r
if ((cur_wr->send_flags & WV_SEND_IMMEDIATE) != 0) {\r
cur_wr->send_flags = (ibv_send_flags) (cur_wr->send_flags & ~WV_SEND_IMMEDIATE);\r
cur_wr->opcode = (ibv_wr_opcode) (cur_wr->opcode | 0x80000000);\r
}\r
+\r
+ if (qp->qp_type == IBV_QPT_UD) {\r
+ cur_wr->wr.ud.ah = ah;\r
+ cur_wr->wr.ud.remote_qkey = ntohl(cur_wr->wr.ud.remote_qkey);\r
+ cur_wr->wr.ud.remote_qpn = ntohl(cur_wr->wr.ud.remote_qpn);\r
+ }\r
}\r
\r
return hr;\r