From 7f2363855018b749a1391613e6ffa8d8d5932d0f Mon Sep 17 00:00:00 2001 From: Thanos Makatos Date: Mon, 18 Jul 2022 15:17:37 +0000 Subject: [PATCH] util: add function spdk_fd_group_get_epoll_event This patch introduces function spdk_fd_group_get_epoll_event, which returns the epoll(7) event that caused the file descriptor group callback function to execute. Rather than changing the signature of spdk_fd_fn in order to pass the struct epoll_event, which would result in a gigantic patch where there vast majority of users would simply have to ignore the new argument, we introduce this new API that allows to return the epoll_event only when really needed. Signed-off-by: Thanos Makatos Suggested-by: John Levon Change-Id: I3debe1382d1c2bfec6ae4fea274ee38ed0b135fe Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/14935 Tested-by: SPDK CI Jenkins Reviewed-by: Jim Harris Reviewed-by: Changpeng Liu Reviewed-by: John Levon --- CHANGELOG.md | 5 +++++ include/spdk/fd_group.h | 16 ++++++++++++++++ lib/util/fd_group.c | 20 ++++++++++++++++++++ lib/util/spdk_util.map | 1 + 4 files changed, 42 insertions(+) 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;