From c26e8e32e2f156163b53061a005d38c2c33ea142 Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Sat, 24 Aug 2019 23:24:45 -0400 Subject: [PATCH] add patch use-percpu_counter-for-extent_cache-hits-misses --- series | 1 + timestamps | 7 +- use-percpu_counter-for-extent_cache-hits-misses | 95 +++++++++++++++++++++++++ 3 files changed, 100 insertions(+), 3 deletions(-) create mode 100644 use-percpu_counter-for-extent_cache-hits-misses diff --git a/series b/series index 96bc9abe..7c72dde7 100644 --- a/series +++ b/series @@ -14,6 +14,7 @@ documentation-fixes rework-reserved-cluster-accounting-when-invalidating-pages fix-punch-hole-for-inline_data jbd2-add-missing-tracepoint-for-reserved-handle +use-percpu_counter-for-extent_cache-hits-misses #################################################### # unstable patches diff --git a/timestamps b/timestamps index 83f007a4..204f72c9 100755 --- a/timestamps +++ b/timestamps @@ -26,6 +26,7 @@ touch -d @1566530313 documentation-fixes touch -d @1566530534 rework-reserved-cluster-accounting-when-invalidating-pages touch -d @1566614280 fix-punch-hole-for-inline_data touch -d @1566702617 jbd2-add-missing-tracepoint-for-reserved-handle -touch -d @1566702721 series -touch -d @1566702728 status -touch -d @1566702967 timestamps +touch -d @1566703197 series +touch -d @1566703431 status +touch -d @1566703431 use-percpu_counter-for-extent_cache-hits-misses +touch -d @1566703474 timestamps diff --git a/use-percpu_counter-for-extent_cache-hits-misses b/use-percpu_counter-for-extent_cache-hits-misses new file mode 100644 index 00000000..87d61002 --- /dev/null +++ b/use-percpu_counter-for-extent_cache-hits-misses @@ -0,0 +1,95 @@ +ext4: use percpu_counters for extent_status cache hits/misses + +From: Yang Guo + +@es_stats_cache_hits and @es_stats_cache_misses are accessed frequently in +ext4_es_lookup_extent function, it would influence the ext4 read/write +performance in NUMA system. +Let's optimize it using percpu_counter, it is profitable for the +performance. + +The test command is as below: +fio -name=randwrite -numjobs=8 -filename=/mnt/test1 -rw=randwrite +-ioengine=libaio -direct=1 -iodepth=64 -sync=0 -norandommap -group_reporting +-runtime=120 -time_based -bs=4k -size=5G + +And the result is better 10% than the initial implement: +without the patch,IOPS=197k, BW=770MiB/s (808MB/s)(90.3GiB/120002msec) +with the patch, IOPS=218k, BW=852MiB/s (894MB/s)(99.9GiB/120002msec) + +Cc: Andreas Dilger +Signed-off-by: Yang Guo +Signed-off-by: Shaokun Zhang +Signed-off-by: Theodore Ts'o +--- + fs/ext4/extents_status.c | 20 +++++++++++++------- + fs/ext4/extents_status.h | 4 ++-- + 2 files changed, 15 insertions(+), 9 deletions(-) + +diff --git a/fs/ext4/extents_status.c b/fs/ext4/extents_status.c +index e977c560992c..dc28a9642452 100644 +--- a/fs/ext4/extents_status.c ++++ b/fs/ext4/extents_status.c +@@ -948,7 +948,7 @@ int ext4_es_lookup_extent(struct inode *inode, ext4_lblk_t lblk, + es->es_pblk = es1->es_pblk; + if (!ext4_es_is_referenced(es1)) + ext4_es_set_referenced(es1); +- stats->es_stats_cache_hits++; ++ percpu_counter_inc(&stats->es_stats_cache_hits); + if (next_lblk) { + node = rb_next(&es1->rb_node); + if (node) { +@@ -959,7 +959,7 @@ int ext4_es_lookup_extent(struct inode *inode, ext4_lblk_t lblk, + *next_lblk = 0; + } + } else { +- stats->es_stats_cache_misses++; ++ percpu_counter_inc(&stats->es_stats_cache_misses); + } + + read_unlock(&EXT4_I(inode)->i_es_lock); +@@ -1586,9 +1586,9 @@ int ext4_seq_es_shrinker_info_show(struct seq_file *seq, void *v) + seq_printf(seq, "stats:\n %lld objects\n %lld reclaimable objects\n", + percpu_counter_sum_positive(&es_stats->es_stats_all_cnt), + percpu_counter_sum_positive(&es_stats->es_stats_shk_cnt)); +- seq_printf(seq, " %lu/%lu cache hits/misses\n", +- es_stats->es_stats_cache_hits, +- es_stats->es_stats_cache_misses); ++ seq_printf(seq, " %llu/%llu cache hits/misses\n", ++ percpu_counter_sum_positive(&es_stats->es_stats_cache_hits), ++ percpu_counter_sum_positive(&es_stats->es_stats_cache_misses)); + if (inode_cnt) + seq_printf(seq, " %d inodes on list\n", inode_cnt); + +@@ -1615,8 +1615,14 @@ int ext4_es_register_shrinker(struct ext4_sb_info *sbi) + sbi->s_es_nr_inode = 0; + spin_lock_init(&sbi->s_es_lock); + sbi->s_es_stats.es_stats_shrunk = 0; +- sbi->s_es_stats.es_stats_cache_hits = 0; +- sbi->s_es_stats.es_stats_cache_misses = 0; ++ err = percpu_counter_init(&sbi->s_es_stats.es_stats_cache_hits, 0, ++ GFP_KERNEL); ++ if (err) ++ return err; ++ err = percpu_counter_init(&sbi->s_es_stats.es_stats_cache_misses, 0, ++ GFP_KERNEL); ++ if (err) ++ return err; + sbi->s_es_stats.es_stats_scan_time = 0; + sbi->s_es_stats.es_stats_max_scan_time = 0; + err = percpu_counter_init(&sbi->s_es_stats.es_stats_all_cnt, 0, GFP_KERNEL); +diff --git a/fs/ext4/extents_status.h b/fs/ext4/extents_status.h +index 5e5c4a40d863..825313c59752 100644 +--- a/fs/ext4/extents_status.h ++++ b/fs/ext4/extents_status.h +@@ -70,8 +70,8 @@ struct ext4_es_tree { + + struct ext4_es_stats { + unsigned long es_stats_shrunk; +- unsigned long es_stats_cache_hits; +- unsigned long es_stats_cache_misses; ++ struct percpu_counter es_stats_cache_hits; ++ struct percpu_counter es_stats_cache_misses; + u64 es_stats_scan_time; + u64 es_stats_max_scan_time; + struct percpu_counter es_stats_all_cnt; -- 2.11.4.GIT