Skip to content

Commit

Permalink
Eliminate calls with FILE_FLAG_OVERLAPPED set, but no overlapped
Browse files Browse the repository at this point in the history
Signed-off-by: Alan Jowett (from Dev Box) <[email protected]>
  • Loading branch information
Alan-Jowett committed Mar 2, 2024
1 parent ff2a400 commit 8df10d3
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 6 deletions.
3 changes: 2 additions & 1 deletion libs/api/ebpf_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4472,7 +4472,8 @@ ebpf_program_test_run(fd_t program_fd, _Inout_ ebpf_test_run_options_t* options)
if (result == EBPF_PENDING) {
unsigned long bytes_returned;
completion_event.wait();
if (GetOverlappedResult(reinterpret_cast<HANDLE>(get_device_handle()), &overlapped, &bytes_returned, FALSE)) {
if (GetOverlappedResult(
reinterpret_cast<HANDLE>(get_async_device_handle()), &overlapped, &bytes_returned, FALSE)) {
result = EBPF_SUCCESS;
} else {
result = win32_error_code_to_ebpf_result(GetLastError());
Expand Down
36 changes: 32 additions & 4 deletions libs/api_common/device_helper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,10 @@ typedef struct _async_ioctl_completion_context
async_ioctl_completion_callback_t callback;
} async_ioctl_completion_context_t;

// Handle used for synchronous calls to the driver.
static ebpf_handle_t _device_handle = ebpf_handle_invalid;
// Handle used for asynchronous calls to the driver.
static ebpf_handle_t _async_device_handle = ebpf_handle_invalid;
static std::mutex _mutex;

_Must_inspect_result_ ebpf_result_t
Expand All @@ -38,13 +41,28 @@ initialize_device_handle()
return EBPF_ALREADY_INITIALIZED;
}

_device_handle = Platform::CreateFile(
EBPF_DEVICE_WIN32_NAME, GENERIC_READ | GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, FILE_FLAG_OVERLAPPED, 0);
if (_async_device_handle != ebpf_handle_invalid) {
return EBPF_ALREADY_INITIALIZED;
}

// Open the device handle without the FILE_FLAG_OVERLAPPED flag for synchronous calls.
_device_handle =
Platform::CreateFile(EBPF_DEVICE_WIN32_NAME, GENERIC_READ | GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, 0, 0);

if (_device_handle == ebpf_handle_invalid) {
return win32_error_code_to_ebpf_result(GetLastError());
}

// Open the device handle with the FILE_FLAG_OVERLAPPED flag for asynchronous calls.
_async_device_handle = Platform::CreateFile(
EBPF_DEVICE_WIN32_NAME, GENERIC_READ | GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, FILE_FLAG_OVERLAPPED, 0);

if (_async_device_handle == ebpf_handle_invalid) {
Platform::CloseHandle(_device_handle);
_device_handle = ebpf_handle_invalid;
return win32_error_code_to_ebpf_result(GetLastError());
}

return EBPF_SUCCESS;
}

Expand All @@ -70,6 +88,16 @@ get_device_handle()
return _device_handle;
}

ebpf_handle_t
get_async_device_handle()
{
if (_async_device_handle == ebpf_handle_invalid) {
// Ignore failures.
(void)initialize_device_handle();
}
return _async_device_handle;
}

void
clean_up_async_ioctl_completion(_Inout_opt_ _Post_invalid_ async_ioctl_completion_t* async_ioctl_completion)
{
Expand Down Expand Up @@ -151,7 +179,7 @@ get_async_ioctl_result(_In_ const async_ioctl_completion_t* ioctl_completion)
{
unsigned long dummy;
if (!GetOverlappedResult(
reinterpret_cast<HANDLE>(get_device_handle()),
reinterpret_cast<HANDLE>(get_async_device_handle()),
get_async_ioctl_operation_overlapped(ioctl_completion),
&dummy,
FALSE))
Expand Down Expand Up @@ -219,5 +247,5 @@ initialize_async_ioctl_operation(
bool
cancel_async_ioctl(_Inout_opt_ OVERLAPPED* overlapped = nullptr)
{
return Platform::CancelIoEx(get_device_handle(), overlapped);
return Platform::CancelIoEx(get_async_device_handle(), overlapped);
}
5 changes: 4 additions & 1 deletion libs/api_common/device_helper.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ clean_up_device_handle();
ebpf_handle_t
get_device_handle();

ebpf_handle_t
get_async_device_handle();

typedef ebpf_result_t (*async_ioctl_completion_callback_t)(_Inout_opt_ void* completion_context);

typedef struct _async_ioctl_completion_context async_ioctl_completion_t;
Expand Down Expand Up @@ -101,7 +104,7 @@ invoke_ioctl(request_t& request, reply_t& reply = _empty_reply, _Inout_opt_ OVER
}

auto success = Platform::DeviceIoControl(
get_device_handle(),
overlapped ? get_async_device_handle() : get_device_handle(),
IOCTL_EBPF_CTL_METHOD_BUFFERED,
request_ptr,
request_size,
Expand Down

0 comments on commit 8df10d3

Please sign in to comment.