From 8844fba3fdafa823590b56af583a2d558bcdcd24 Mon Sep 17 00:00:00 2001 From: Andrei Tatar Date: Wed, 22 Jan 2025 23:26:44 +0100 Subject: [PATCH] lib/posix-timerfd: Fix counter on subsequent reads The internal counter of a timerfd is returned on read() and reset to 0, and should be increased by 1 for every subsequent expiration. A logic error in the current code makes every update set the counter to the total expirations rather than since last read, leading to subsequent successful reads returning wrong counts. This change fixes this error. Signed-off-by: Andrei Tatar Approved-by: Sergiu Moga Reviewed-by: Sergiu Moga GitHub-Closes: #1567 --- lib/posix-timerfd/timerfd.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/lib/posix-timerfd/timerfd.c b/lib/posix-timerfd/timerfd.c index eb1614165..1e1b32719 100644 --- a/lib/posix-timerfd/timerfd.c +++ b/lib/posix-timerfd/timerfd.c @@ -32,6 +32,7 @@ static const char TIMERFD_VOLID[] = "timerfd_vol"; struct timerfd_node { struct itimerspec set; __u64 val; + __u64 total; clockid_t clkid; struct uk_thread *upthread; }; @@ -102,12 +103,11 @@ static __nsec _timerfd_update(const struct uk_file *f) deadline = now + st.next; /* Update val & events */ - if (st.exp != d->val) { - d->val = st.exp; - if (st.exp) - uk_file_event_set(f, UKFD_POLLIN); - else - uk_file_event_clear(f, UKFD_POLLIN); + UK_ASSERT(st.exp >= d->total); + if (st.exp > d->total) { + d->val += st.exp - d->total; + d->total = st.exp; + uk_file_event_set(f, UKFD_POLLIN); } return deadline; } @@ -124,6 +124,7 @@ static void _timerfd_set(struct timerfd_node *d, const struct itimerspec *set) /* Arm */ d->set.it_value = set->it_value; d->set.it_interval = set->it_interval; + d->total = 0; uk_thread_wake(d->upthread); } } -- 2.39.5