bcachefs: Make sure to initialize j->last_flushed
If the journal reclaim thread makes it to the timeout without ever initializing j->last_flushed, we could end up sleeping for a very long time. Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com> Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
parent
050197b1c1
commit
2ce867df31
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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 *,
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user