diff --git a/CHANGELOG.md b/CHANGELOG.md index 266d1f571..210ade406 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -55,6 +55,11 @@ Added spdk_rpc_set_allowlist to restrict allowed RPCs to the specified list. Promoted the application to example to match similar programs: fio_plugin and perf. It can now be found inside `examples/bdev/bdevperf`. +### util + +New API `spdk_fd_group_get_epoll_event` that returns the epoll(7) event that +caused a function callback in file descriptor group to execute. + ## v22.09 ### accel diff --git a/include/spdk/fd_group.h b/include/spdk/fd_group.h index b4dbd1d9f..fdc22da8f 100644 --- a/include/spdk/fd_group.h +++ b/include/spdk/fd_group.h @@ -118,6 +118,22 @@ void spdk_fd_group_remove(struct spdk_fd_group *fgrp, int efd); int spdk_fd_group_event_modify(struct spdk_fd_group *fgrp, int efd, int event_types); +/* + * Forward declaration of epoll_event to avoid having to conditionally compile + * spdk_fd_group_get_epoll_event on non-Linux systems. + */ +struct epoll_event; + +/** + * Copies the epoll(7) event that caused a callback function to execute. + * This function can only be called by the callback function, doing otherwise + * results in undefined behavior. + * + * \param event pointer to an epoll(7) event to copy to + * \return 0 on success, -errno on error + */ +int spdk_fd_group_get_epoll_event(struct epoll_event *event); + #ifdef __cplusplus } #endif diff --git a/lib/util/fd_group.c b/lib/util/fd_group.c index 749c55b01..3d85cec0f 100644 --- a/lib/util/fd_group.c +++ b/lib/util/fd_group.c @@ -60,6 +60,18 @@ spdk_fd_group_get_fd(struct spdk_fd_group *fgrp) #ifdef __linux__ +static __thread struct epoll_event *g_event = NULL; + +int +spdk_fd_group_get_epoll_event(struct epoll_event *event) +{ + if (g_event == NULL) { + return -EINVAL; + } + *event = *g_event; + return 0; +} + int spdk_fd_group_add(struct spdk_fd_group *fgrp, int efd, spdk_fd_fn fn, void *arg, const char *name) @@ -277,8 +289,10 @@ spdk_fd_group_wait(struct spdk_fd_group *fgrp, int timeout) SPDK_DTRACE_PROBE4(interrupt_fd_process, ehdlr->name, ehdlr->fd, ehdlr->fn, ehdlr->fn_arg); + g_event = &events[n]; /* call the interrupt response function */ ehdlr->fn(ehdlr->fn_arg); + g_event = NULL; /* It is possible that the ehdlr was removed * during this wait loop when it get executed. @@ -295,6 +309,12 @@ spdk_fd_group_wait(struct spdk_fd_group *fgrp, int timeout) #else +int +spdk_fd_group_get_epoll_event(struct epoll_event *event) +{ + return -ENOTSUP; +} + int spdk_fd_group_add(struct spdk_fd_group *fgrp, int efd, spdk_fd_fn fn, void *arg, const char *name) diff --git a/lib/util/spdk_util.map b/lib/util/spdk_util.map index ffe9253ca..b73ff7722 100644 --- a/lib/util/spdk_util.map +++ b/lib/util/spdk_util.map @@ -150,6 +150,7 @@ # public functions in fd_group.h spdk_fd_group_create; spdk_fd_group_destroy; + spdk_fd_group_get_epoll_event; spdk_fd_group_wait; spdk_fd_group_add; spdk_fd_group_remove;