X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;ds=sidebyside;f=libbcachefs%2Fclock.c;h=d9de0d1302e28a182e7c64d96eaa48df8b9b4347;hb=fec2d17f20a2fd290a1f85eee0a5e1a1c5e9ddfd;hp=c67376f96f5ae635d63840654f4254db6226d5a6;hpb=ff86d4722124c300c40b85b6eb8ef2d410ab303c;p=bcachefs-tools-debian diff --git a/libbcachefs/clock.c b/libbcachefs/clock.c index c67376f..d9de0d1 100644 --- a/libbcachefs/clock.c +++ b/libbcachefs/clock.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "bcachefs.h" #include "clock.h" @@ -17,11 +18,19 @@ void bch2_io_timer_add(struct io_clock *clock, struct io_timer *timer) size_t i; spin_lock(&clock->timer_lock); + + if (time_after_eq((unsigned long) atomic_long_read(&clock->now), + timer->expire)) { + spin_unlock(&clock->timer_lock); + timer->fn(timer); + return; + } + for (i = 0; i < clock->timers.used; i++) if (clock->timers.data[i] == timer) goto out; - BUG_ON(!heap_add(&clock->timers, timer, io_timer_cmp)); + BUG_ON(!heap_add(&clock->timers, timer, io_timer_cmp, NULL)); out: spin_unlock(&clock->timer_lock); } @@ -34,7 +43,7 @@ void bch2_io_timer_del(struct io_clock *clock, struct io_timer *timer) for (i = 0; i < clock->timers.used; i++) if (clock->timers.data[i] == timer) { - heap_del(&clock->timers, i, io_timer_cmp); + heap_del(&clock->timers, i, io_timer_cmp, NULL); break; } @@ -127,34 +136,38 @@ static struct io_timer *get_expired_timer(struct io_clock *clock, if (clock->timers.used && time_after_eq(now, clock->timers.data[0]->expire)) - heap_pop(&clock->timers, ret, io_timer_cmp); + heap_pop(&clock->timers, ret, io_timer_cmp, NULL); spin_unlock(&clock->timer_lock); return ret; } -void bch2_increment_clock(struct bch_fs *c, unsigned sectors, int rw) +void __bch2_increment_clock(struct io_clock *clock, unsigned sectors) { - struct io_clock *clock = &c->io_clock[rw]; struct io_timer *timer; - unsigned long now; + unsigned long now = atomic_long_add_return(sectors, &clock->now); - /* Buffer up one megabyte worth of IO in the percpu counter */ - preempt_disable(); + while ((timer = get_expired_timer(clock, now))) + timer->fn(timer); +} - if (likely(this_cpu_add_return(*clock->pcpu_buf, sectors) < - IO_CLOCK_PCPU_SECTORS)) { - preempt_enable(); - return; - } +ssize_t bch2_io_timers_show(struct io_clock *clock, char *buf) +{ + struct printbuf out = _PBUF(buf, PAGE_SIZE); + unsigned long now; + unsigned i; - sectors = this_cpu_xchg(*clock->pcpu_buf, 0); - preempt_enable(); - now = atomic_long_add_return(sectors, &clock->now); + spin_lock(&clock->timer_lock); + now = atomic_long_read(&clock->now); - while ((timer = get_expired_timer(clock, now))) - timer->fn(timer); + for (i = 0; i < clock->timers.used; i++) + pr_buf(&out, "%pf:\t%li\n", + clock->timers.data[i]->fn, + clock->timers.data[i]->expire - now); + spin_unlock(&clock->timer_lock); + + return out.pos - buf; } void bch2_io_clock_exit(struct io_clock *clock) @@ -168,6 +181,8 @@ int bch2_io_clock_init(struct io_clock *clock) atomic_long_set(&clock->now, 0); spin_lock_init(&clock->timer_lock); + clock->max_slop = IO_CLOCK_PCPU_SECTORS * num_possible_cpus(); + clock->pcpu_buf = alloc_percpu(*clock->pcpu_buf); if (!clock->pcpu_buf) return -ENOMEM;