]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
bcachefs: io clock: run timer fns under clock lock
authorKent Overstreet <kent.overstreet@linux.dev>
Sun, 30 Jun 2024 01:02:17 +0000 (21:02 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Tue, 2 Jul 2024 02:56:28 +0000 (22:56 -0400)
We don't have a way to flush a timer that's executing the callback, and
this is simple and limited enough in scope that we can just use the lock
instead.

Needed for the next patch that adds direct wakeups from the allocator to
copygc, where we're now more frequently calling io_timer_del() on an
expiring timer.

Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/clock.c

index 3636444511064b51e5a004b953eacf94e7c70d12..0f40b585ce2b5b7f0065c6489d64c8714e218006 100644 (file)
@@ -132,14 +132,9 @@ static struct io_timer *get_expired_timer(struct io_clock *clock,
 {
        struct io_timer *ret = NULL;
 
-       spin_lock(&clock->timer_lock);
-
        if (clock->timers.used &&
            time_after_eq(now, clock->timers.data[0]->expire))
                heap_pop(&clock->timers, ret, io_timer_cmp, NULL);
-
-       spin_unlock(&clock->timer_lock);
-
        return ret;
 }
 
@@ -148,8 +143,10 @@ void __bch2_increment_clock(struct io_clock *clock, unsigned sectors)
        struct io_timer *timer;
        unsigned long now = atomic64_add_return(sectors, &clock->now);
 
+       spin_lock(&clock->timer_lock);
        while ((timer = get_expired_timer(clock, now)))
                timer->fn(timer);
+       spin_unlock(&clock->timer_lock);
 }
 
 void bch2_io_timers_to_text(struct printbuf *out, struct io_clock *clock)