diff --git a/fs/bcachefs/journal.c b/fs/bcachefs/journal.c index 2724a58ada05..a70540853586 100644 --- a/fs/bcachefs/journal.c +++ b/fs/bcachefs/journal.c @@ -1189,6 +1189,8 @@ void __bch2_journal_debug_to_text(struct printbuf *out, struct journal *j) "nr noflush writes:\t%llu\n" "nr direct reclaim:\t%llu\n" "nr background reclaim:\t%llu\n" + "reclaim kicked:\t\t%u\n" + "reclaim runs in:\t%u ms\n" "current entry sectors:\t%u\n" "current entry error:\t%u\n" "current entry:\t\t", @@ -1204,6 +1206,8 @@ void __bch2_journal_debug_to_text(struct printbuf *out, struct journal *j) j->nr_noflush_writes, j->nr_direct_reclaim, j->nr_background_reclaim, + j->reclaim_kicked, + jiffies_to_msecs(j->next_reclaim - jiffies), j->cur_entry_sectors, j->cur_entry_error); diff --git a/fs/bcachefs/journal_reclaim.c b/fs/bcachefs/journal_reclaim.c index 416f8611f008..812620d3de31 100644 --- a/fs/bcachefs/journal_reclaim.c +++ b/fs/bcachefs/journal_reclaim.c @@ -677,13 +677,15 @@ int bch2_journal_reclaim(struct journal *j) static int bch2_journal_reclaim_thread(void *arg) { struct journal *j = arg; - unsigned long next; + unsigned long delay, now; int ret = 0; set_freezable(); kthread_wait_freezable(test_bit(JOURNAL_RECLAIM_STARTED, &j->flags)); + j->last_flushed = jiffies; + while (!ret && !kthread_should_stop()) { j->reclaim_kicked = false; @@ -691,18 +693,22 @@ static int bch2_journal_reclaim_thread(void *arg) ret = __bch2_journal_reclaim(j, false); mutex_unlock(&j->reclaim_lock); - next = j->last_flushed + msecs_to_jiffies(j->reclaim_delay_ms); + now = jiffies; + delay = msecs_to_jiffies(j->reclaim_delay_ms); + j->next_reclaim = j->last_flushed + delay; + + if (!time_in_range(j->next_reclaim, now, now + delay)) + j->next_reclaim = now + delay; while (1) { - set_current_state(TASK_INTERRUPTIBLE); + set_current_state(TASK_INTERRUPTIBLE|TASK_FREEZABLE); if (kthread_should_stop()) break; if (j->reclaim_kicked) break; - if (time_after_eq(jiffies, next)) + if (time_after_eq(jiffies, j->next_reclaim)) break; - schedule_timeout(next - jiffies); - try_to_freeze(); + schedule_timeout(j->next_reclaim - jiffies); } __set_current_state(TASK_RUNNING); diff --git a/fs/bcachefs/journal_reclaim.h b/fs/bcachefs/journal_reclaim.h index adf1f5c981cd..0fd1af120db5 100644 --- a/fs/bcachefs/journal_reclaim.h +++ b/fs/bcachefs/journal_reclaim.h @@ -8,11 +8,9 @@ static inline void journal_reclaim_kick(struct journal *j) { struct task_struct *p = READ_ONCE(j->reclaim_thread); - if (p && !j->reclaim_kicked) { - j->reclaim_kicked = true; - if (p) - wake_up_process(p); - } + j->reclaim_kicked = true; + if (p) + wake_up_process(p); } unsigned bch2_journal_dev_buckets_available(struct journal *, diff --git a/fs/bcachefs/journal_types.h b/fs/bcachefs/journal_types.h index f597eb78e66e..6e2a2d6b8346 100644 --- a/fs/bcachefs/journal_types.h +++ b/fs/bcachefs/journal_types.h @@ -248,6 +248,7 @@ struct journal { wait_queue_head_t reclaim_wait; struct task_struct *reclaim_thread; bool reclaim_kicked; + unsigned long next_reclaim; u64 nr_direct_reclaim; u64 nr_background_reclaim;