mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-11-24 15:40:56 +07:00
Btrfs: avoid waiting for delayed refs when we must not
We track two conditions to decide if we should sleep while waiting for more delayed refs, the number of delayed refs (num_refs) and the first entry in the list of blockers (first_seq). When we suspect staleness, we save num_refs and do one more cycle. If nothing changes, we then save first_seq for later comparison and do wait_event. We ought to save first_seq the very same moment we're saving num_refs. Otherwise we cannot be sure that nothing has changed and we might start waiting when we shouldn't, which could lead to starvation. Signed-off-by: Jan Schmidt <list.btrfs@jan-o-sch.net>
This commit is contained in:
parent
cb77fcd885
commit
8ca78f3eda
@ -2347,12 +2347,10 @@ static noinline int run_clustered_refs(struct btrfs_trans_handle *trans,
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
static void wait_for_more_refs(struct btrfs_delayed_ref_root *delayed_refs,
|
||||
unsigned long num_refs)
|
||||
unsigned long num_refs,
|
||||
struct list_head *first_seq)
|
||||
{
|
||||
struct list_head *first_seq = delayed_refs->seq_head.next;
|
||||
|
||||
spin_unlock(&delayed_refs->lock);
|
||||
pr_debug("waiting for more refs (num %ld, first %p)\n",
|
||||
num_refs, first_seq);
|
||||
@ -2381,6 +2379,7 @@ int btrfs_run_delayed_refs(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_delayed_ref_root *delayed_refs;
|
||||
struct btrfs_delayed_ref_node *ref;
|
||||
struct list_head cluster;
|
||||
struct list_head *first_seq = NULL;
|
||||
int ret;
|
||||
u64 delayed_start;
|
||||
int run_all = count == (unsigned long)-1;
|
||||
@ -2436,8 +2435,10 @@ int btrfs_run_delayed_refs(struct btrfs_trans_handle *trans,
|
||||
*/
|
||||
consider_waiting = 1;
|
||||
num_refs = delayed_refs->num_entries;
|
||||
first_seq = root->fs_info->tree_mod_seq_list.next;
|
||||
} else {
|
||||
wait_for_more_refs(delayed_refs, num_refs);
|
||||
wait_for_more_refs(delayed_refs,
|
||||
num_refs, first_seq);
|
||||
/*
|
||||
* after waiting, things have changed. we
|
||||
* dropped the lock and someone else might have
|
||||
|
Loading…
Reference in New Issue
Block a user