Thanks Sam! Eitan -----Original Message----- From: Samuel Ghinet [mailto:sghi...@cloudbasesolutions.com] Sent: Saturday, September 06, 2014 6:03 PM To: dev@openvswitch.org; Eitan Eliahu Cc: Alin Serdean Subject: [ovs-dev] [PATCH] Windows NetLink Socket - Support for asynchronous event notification
Looks good, as far as I can tell. One minor style thing though: > + goto done; > + } > + } > + else { > + /* The I/O was completed synchronously */ > + poll_immediate_wake(); > + } I think it should have been: > } else { Regards, Sam ________________________________________ Date: Thu, 4 Sep 2014 03:18:13 -0700 From: Eitan Eliahu <elia...@vmware.com> To: dev@openvswitch.org Subject: [ovs-dev] [PATCH] Windows NetLink Socket - Support for asynchronous event notification Message-ID: <1409825893-3280-1-git-send-email-elia...@vmware.com> We keep an outstanding, out of band, I/O request in the driver at all time. Once an event generated the driver queues the event message, completes the pending I/O and unblocks the calling thread through setting the event in the overlapped structure n the NL socket. The thread will read all all event messages synchronous through the call of nl_sock_recv() --- datapath-windows/include/OvsDpInterfaceExt.h | 1 + lib/netlink-socket.c | 82 ++++++++++++++++++++++++++-- 2 files changed, 79 insertions(+), 4 deletions(-) diff --git a/datapath-windows/include/OvsDpInterfaceExt.h b/datapath-windows/include/OvsDpInterfaceExt.h index 73dfcbe..ab2088a 100644 --- a/datapath-windows/include/OvsDpInterfaceExt.h +++ b/datapath-windows/include/OvsDpInterfaceExt.h @@ -70,6 +70,7 @@ /* Commands available under the OVS_WIN_CONTROL_FAMILY. */ enum ovs_win_control_cmd { OVS_CTRL_CMD_WIN_GET_PID, + OVS_CTRL_CMD_WIN_PEND_REQ }; #endif /* __OVS_DP_INTERFACE_EXT_H_ */ diff --git a/lib/netlink-socket.c b/lib/netlink-socket.c index a6be186..4b535f0 100644 --- a/lib/netlink-socket.c +++ b/lib/netlink-socket.c @@ -80,6 +80,7 @@ static int get_sock_pid_from_kernel(struct nl_sock *sock); struct nl_sock { #ifdef _WIN32 HANDLE handle; + OVERLAPPED overlapped; #else int fd; #endif @@ -139,21 +140,30 @@ nl_sock_create(int protocol, struct nl_sock **sockp) sock = xmalloc(sizeof *sock); #ifdef _WIN32 - sock->handle = CreateFileA("\\\\.\\OpenVSwitchDevice", + sock->handle = CreateFile(TEXT("\\\\.\\OpenVSwitchDevice"), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, NULL); - - int last_error = GetLastError(); + FILE_FLAG_OVERLAPPED, NULL); if (sock->handle == INVALID_HANDLE_VALUE) { + int last_error = GetLastError(); + VLOG_ERR("fcntl: %s", ovs_strerror(last_error)); + goto error; + } + + memset(&sock->overlapped, 0, sizeof sock->overlapped); + sock->overlapped.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); + if (sock->overlapped.hEvent == NULL) { + int last_error = GetLastError(); VLOG_ERR("fcntl: %s", ovs_strerror(last_error)); goto error; } + #else sock->fd = socket(AF_NETLINK, SOCK_RAW, protocol); if (sock->fd < 0) { + int last_error = GetLastError(); VLOG_ERR("fcntl: %s", ovs_strerror(errno)); goto error; } @@ -221,6 +231,9 @@ error: } } #ifdef _WIN32 + if (sock->overlapped.hEvent) { + CloseHandle(sock->overlapped.hEvent); + } if (sock->handle != INVALID_HANDLE_VALUE) { CloseHandle(sock->handle); } @@ -248,6 +261,9 @@ nl_sock_destroy(struct nl_sock *sock) { if (sock) { #ifdef _WIN32 + if (sock->overlapped.hEvent) { + CloseHandle(sock->overlapped.hEvent); + } CloseHandle(sock->handle); #else close(sock->fd); @@ -1040,12 +1056,70 @@ nl_dump_done(struct nl_dump *dump) return status == EOF ? 0 : status; } +#ifdef _WIN32 +/* Pend an I/O request in the driver. The driver completes the I/O +whenever +* an event or a packet is ready to be read. Once the I/O is completed +* the overlapped structure event assocaited with the pending I/O will +be set */ static int pend_io_request(const struct nl_sock *sock) { + struct ofpbuf request; + uint64_t request_stub[128]; + struct ovs_header *ovs_header; + struct nlmsghdr *nlmsg; + uint32_t seq; + int retval; + int error; + DWORD bytes; + OVERLAPPED *overlapped = &sock->overlapped; + + int ovs_msg_size = sizeof (struct nlmsghdr) + sizeof (struct genlmsghdr) + + sizeof (struct ovs_header); + + ofpbuf_use_stub(&request, request_stub, sizeof request_stub); + + seq = nl_sock_allocate_seq(sock, 1); + nl_msg_put_genlmsghdr(&request, 0, OVS_WIN_NL_CTRL_FAMILY_ID, 0, + OVS_CTRL_CMD_WIN_PEND_REQ, OVS_WIN_CONTROL_VERSION); + nlmsg = nl_msg_nlmsghdr(&request); + nlmsg->nlmsg_seq = seq; + + ovs_header = ofpbuf_put_uninit(&request, sizeof *ovs_header); + ovs_header->dp_ifindex = 0; + + if (!DeviceIoControl(sock->handle, OVS_IOCTL_WRITE, + ofpbuf_data(&request), ofpbuf_size(&request), + NULL, 0, &bytes, overlapped)) { + error = GetLastError(); + /* Check if the I/O got pended */ + if (error != ERROR_IO_INCOMPLETE && error != ERROR_IO_PENDING) { + VLOG_ERR("nl_sock_wait failed - %s\n", ovs_format_message(error)); + retval = EINVAL; + goto done; + } + } + else { + /* The I/O was completed synchronously */ + poll_immediate_wake(); + } + retval = 0; + +done: + ofpbuf_uninit(&request); + return retval; +} +#endif /* _WIN32 */ + /* Causes poll_block() to wake up when any of the specified 'events' (which is * a OR'd combination of POLLIN, POLLOUT, etc.) occur on 'sock'. */ void nl_sock_wait(const struct nl_sock *sock, short int events) { #ifdef _WIN32 + if (sock->overlapped.Internal != STATUS_PENDING) { + pend_io_request(sock); + } poll_fd_wait(sock->handle, events); #else poll_fd_wait(sock->fd, events); -- 1.9.4.msysgit.0 ------------------------------ Subject: Digest Footer _______________________________________________ dev mailing list dev@openvswitch.org https://urldefense.proofpoint.com/v1/url?u=http://openvswitch.org/mailman/listinfo/dev&k=oIvRg1%2BdGAgOoM1BIlLLqw%3D%3D%0A&r=yTvML8OxA42Jb6ViHe7fUXbvPVOYDPVq87w43doxtlY%3D%0A&m=AgyAoJdlQ3RjvFB0AGfc96MMElM1dsMmFu3wHE1sRVk%3D%0A&s=11705c06638d89d6ade8dcfd306fc28bcaaf05631f779584e56ae5edff801302 ------------------------------ End of dev Digest, Vol 62, Issue 47 *********************************** _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev