Skip to content

Commit 0a2326f

Browse files
LiBaokun96tytso
authored andcommitted
ext4: convert sbi->s_mb_free_pending to atomic_t
Previously, s_md_lock was used to protect s_mb_free_pending during modifications, while smp_mb() ensured fresh reads, so s_md_lock just guarantees the atomicity of s_mb_free_pending. Thus we optimized it by converting s_mb_free_pending into an atomic variable, thereby eliminating s_md_lock and minimizing lock contention. This also prepares for future lockless merging of free extents. Following this modification, s_md_lock is exclusively responsible for managing insertions and deletions within s_freed_data_list, along with operations involving list_splice. Performance test data follows: Test: Running will-it-scale/fallocate2 on CPU-bound containers. Observation: Average fallocate operations per container per second. |CPU: Kunpeng 920 | P80 | P1 | |Memory: 512GB |------------------------|-------------------------| |960GB SSD (0.5GB/s)| base | patched | base | patched | |-------------------|-------|----------------|--------|----------------| |mb_optimize_scan=0 | 19628 | 20043 (+2.1%) | 320885 | 314331 (-2.0%) | |mb_optimize_scan=1 | 7129 | 7290 (+2.2%) | 321275 | 324226 (+0.9%) | |CPU: AMD 9654 * 2 | P96 | P1 | |Memory: 1536GB |------------------------|-------------------------| |960GB SSD (1GB/s) | base | patched | base | patched | |-------------------|-------|----------------|--------|----------------| |mb_optimize_scan=0 | 53760 | 54999 (+2.3%) | 213145 | 214380 (+0.5%) | |mb_optimize_scan=1 | 12716 | 13497 (+6.1%) | 215262 | 216276 (+0.4%) | Signed-off-by: Baokun Li <[email protected]> Reviewed-by: Jan Kara <[email protected]> Reviewed-by: Zhang Yi <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Theodore Ts'o <[email protected]>
1 parent 9a0ed16 commit 0a2326f

File tree

3 files changed

+5
-8
lines changed

3 files changed

+5
-8
lines changed

fs/ext4/balloc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -703,7 +703,7 @@ int ext4_should_retry_alloc(struct super_block *sb, int *retries)
703703
* possible we just missed a transaction commit that did so
704704
*/
705705
smp_mb();
706-
if (sbi->s_mb_free_pending == 0) {
706+
if (atomic_read(&sbi->s_mb_free_pending) == 0) {
707707
if (test_opt(sb, DISCARD)) {
708708
atomic_inc(&sbi->s_retry_alloc_pending);
709709
flush_work(&sbi->s_discard_work);

fs/ext4/ext4.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1602,7 +1602,7 @@ struct ext4_sb_info {
16021602
unsigned short *s_mb_offsets;
16031603
unsigned int *s_mb_maxs;
16041604
unsigned int s_group_info_size;
1605-
unsigned int s_mb_free_pending;
1605+
atomic_t s_mb_free_pending;
16061606
struct list_head s_freed_data_list[2]; /* List of blocks to be freed
16071607
after commit completed */
16081608
struct list_head s_discard_list;

fs/ext4/mballoc.c

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3687,7 +3687,7 @@ int ext4_mb_init(struct super_block *sb)
36873687
}
36883688

36893689
spin_lock_init(&sbi->s_md_lock);
3690-
sbi->s_mb_free_pending = 0;
3690+
atomic_set(&sbi->s_mb_free_pending, 0);
36913691
INIT_LIST_HEAD(&sbi->s_freed_data_list[0]);
36923692
INIT_LIST_HEAD(&sbi->s_freed_data_list[1]);
36933693
INIT_LIST_HEAD(&sbi->s_discard_list);
@@ -3903,10 +3903,7 @@ static void ext4_free_data_in_buddy(struct super_block *sb,
39033903
/* we expect to find existing buddy because it's pinned */
39043904
BUG_ON(err != 0);
39053905

3906-
spin_lock(&EXT4_SB(sb)->s_md_lock);
3907-
EXT4_SB(sb)->s_mb_free_pending -= entry->efd_count;
3908-
spin_unlock(&EXT4_SB(sb)->s_md_lock);
3909-
3906+
atomic_sub(entry->efd_count, &EXT4_SB(sb)->s_mb_free_pending);
39103907
db = e4b.bd_info;
39113908
/* there are blocks to put in buddy to make them really free */
39123909
count += entry->efd_count;
@@ -6401,7 +6398,7 @@ ext4_mb_free_metadata(handle_t *handle, struct ext4_buddy *e4b,
64016398

64026399
spin_lock(&sbi->s_md_lock);
64036400
list_add_tail(&new_entry->efd_list, &sbi->s_freed_data_list[new_entry->efd_tid & 1]);
6404-
sbi->s_mb_free_pending += clusters;
6401+
atomic_add(clusters, &sbi->s_mb_free_pending);
64056402
spin_unlock(&sbi->s_md_lock);
64066403
}
64076404

0 commit comments

Comments
 (0)