@@ -620,7 +620,14 @@ struct btrfs_fs_info {
u64 generation;
u64 last_trans_committed;
+
+ /*
+ * This is for keeping track of how long it takes to run delayed refs so
+ * that our delayed ref timing doesn't hurt us.
+ */
u64 avg_delayed_ref_runtime;
+ u64 delayed_ref_runtime;
+ u64 delayed_ref_nr_run;
/*
* this is updated to the current trans every time a full commit
@@ -2734,6 +2734,9 @@ void btrfs_init_fs_info(struct btrfs_fs_info *fs_info)
fs_info->tree_mod_log = RB_ROOT;
fs_info->commit_interval = BTRFS_DEFAULT_COMMIT_INTERVAL;
fs_info->avg_delayed_ref_runtime = NSEC_PER_SEC >> 6; /* div by 64 */
+ fs_info->delayed_ref_runtime = NSEC_PER_SEC;
+ fs_info->delayed_ref_nr_run = 64;
+
/* readahead state */
INIT_RADIX_TREE(&fs_info->reada_tree, GFP_NOFS & ~__GFP_DIRECT_RECLAIM);
spin_lock_init(&fs_info->reada_lock);
@@ -2082,8 +2082,23 @@ static noinline int __btrfs_run_delayed_refs(struct btrfs_trans_handle *trans,
* to avoid large swings in the average.
*/
spin_lock(&delayed_refs->lock);
- avg = fs_info->avg_delayed_ref_runtime * 3 + runtime;
- fs_info->avg_delayed_ref_runtime = avg >> 2; /* div by 4 */
+ fs_info->delayed_ref_nr_run += actual_count;
+ fs_info->delayed_ref_runtime += runtime;
+ avg = div64_u64(fs_info->delayed_ref_runtime,
+ fs_info->delayed_ref_nr_run);
+
+ /*
+ * Once we've built up a fair bit of data, start decaying
+ * everything by 3/4.
+ */
+ if (fs_info->delayed_ref_runtime >= (NSEC_PER_SEC * 1000ULL) &&
+ fs_info->delayed_ref_nr_run > 1000) {
+ fs_info->delayed_ref_runtime *= 3;
+ fs_info->delayed_ref_runtime >>= 2;
+ fs_info->delayed_ref_nr_run *= 3;
+ fs_info->delayed_ref_nr_run >>= 2;
+ }
+ fs_info->avg_delayed_ref_runtime = avg;
spin_unlock(&delayed_refs->lock);
}
return 0;