diff options
| author | Theodore Ts'o <tytso@mit.edu> | 2009-03-04 19:09:10 -0500 |
|---|---|---|
| committer | Theodore Ts'o <tytso@mit.edu> | 2009-03-04 19:09:10 -0500 |
| commit | 9f24e4208f7ee2748f157368b63287dc903fcf60 (patch) | |
| tree | 255989fe69ebfb2b031dc7cf6dbe975df67c711a | |
| parent | b713a5ec55bf73c833f9883cdd761b20ee61a1ab (diff) | |
ext4: Use atomic_t's in struct flex_groups
Reduce pressure on the sb_bgl_lock family of locks by using atomic_t's
to track the number of free blocks and inodes in each flex_group.
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
| -rw-r--r-- | fs/ext4/balloc.c | 5 | ||||
| -rw-r--r-- | fs/ext4/ext4.h | 4 | ||||
| -rw-r--r-- | fs/ext4/ialloc.c | 33 | ||||
| -rw-r--r-- | fs/ext4/mballoc.c | 9 | ||||
| -rw-r--r-- | fs/ext4/resize.c | 8 | ||||
| -rw-r--r-- | fs/ext4/super.c | 8 |
6 files changed, 30 insertions, 37 deletions
diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c index b37b12875582..53c72ad85877 100644 --- a/fs/ext4/balloc.c +++ b/fs/ext4/balloc.c | |||
| @@ -470,9 +470,8 @@ void ext4_add_groupblocks(handle_t *handle, struct super_block *sb, | |||
| 470 | 470 | ||
| 471 | if (sbi->s_log_groups_per_flex) { | 471 | if (sbi->s_log_groups_per_flex) { |
| 472 | ext4_group_t flex_group = ext4_flex_group(sbi, block_group); | 472 | ext4_group_t flex_group = ext4_flex_group(sbi, block_group); |
| 473 | spin_lock(sb_bgl_lock(sbi, flex_group)); | 473 | atomic_add(blocks_freed, |
| 474 | sbi->s_flex_groups[flex_group].free_blocks += blocks_freed; | 474 | &sbi->s_flex_groups[flex_group].free_blocks); |
| 475 | spin_unlock(sb_bgl_lock(sbi, flex_group)); | ||
| 476 | } | 475 | } |
| 477 | /* | 476 | /* |
| 478 | * request to reload the buddy with the | 477 | * request to reload the buddy with the |
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index e5c273ff928b..e52b48f86ed4 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h | |||
| @@ -170,8 +170,8 @@ struct ext4_group_desc | |||
| 170 | */ | 170 | */ |
| 171 | 171 | ||
| 172 | struct flex_groups { | 172 | struct flex_groups { |
| 173 | __u32 free_inodes; | 173 | atomic_t free_inodes; |
| 174 | __u32 free_blocks; | 174 | atomic_t free_blocks; |
| 175 | }; | 175 | }; |
| 176 | 176 | ||
| 177 | #define EXT4_BG_INODE_UNINIT 0x0001 /* Inode table/bitmap not in use */ | 177 | #define EXT4_BG_INODE_UNINIT 0x0001 /* Inode table/bitmap not in use */ |
diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c index 617f5a2d800a..5f393927fd25 100644 --- a/fs/ext4/ialloc.c +++ b/fs/ext4/ialloc.c | |||
| @@ -189,7 +189,6 @@ void ext4_free_inode(handle_t *handle, struct inode *inode) | |||
| 189 | struct ext4_super_block *es; | 189 | struct ext4_super_block *es; |
| 190 | struct ext4_sb_info *sbi; | 190 | struct ext4_sb_info *sbi; |
| 191 | int fatal = 0, err, count, cleared; | 191 | int fatal = 0, err, count, cleared; |
| 192 | ext4_group_t flex_group; | ||
| 193 | 192 | ||
| 194 | if (atomic_read(&inode->i_count) > 1) { | 193 | if (atomic_read(&inode->i_count) > 1) { |
| 195 | printk(KERN_ERR "ext4_free_inode: inode has count=%d\n", | 194 | printk(KERN_ERR "ext4_free_inode: inode has count=%d\n", |
| @@ -277,10 +276,10 @@ void ext4_free_inode(handle_t *handle, struct inode *inode) | |||
| 277 | percpu_counter_dec(&sbi->s_dirs_counter); | 276 | percpu_counter_dec(&sbi->s_dirs_counter); |
| 278 | 277 | ||
| 279 | if (sbi->s_log_groups_per_flex) { | 278 | if (sbi->s_log_groups_per_flex) { |
| 280 | flex_group = ext4_flex_group(sbi, block_group); | 279 | ext4_group_t f; |
| 281 | spin_lock(sb_bgl_lock(sbi, flex_group)); | 280 | |
| 282 | sbi->s_flex_groups[flex_group].free_inodes++; | 281 | f = ext4_flex_group(sbi, block_group); |
| 283 | spin_unlock(sb_bgl_lock(sbi, flex_group)); | 282 | atomic_inc(&sbi->s_flex_groups[f].free_inodes); |
| 284 | } | 283 | } |
| 285 | } | 284 | } |
| 286 | BUFFER_TRACE(bh2, "call ext4_handle_dirty_metadata"); | 285 | BUFFER_TRACE(bh2, "call ext4_handle_dirty_metadata"); |
| @@ -360,9 +359,9 @@ static int find_group_flex(struct super_block *sb, struct inode *parent, | |||
| 360 | sbi->s_log_groups_per_flex; | 359 | sbi->s_log_groups_per_flex; |
| 361 | 360 | ||
| 362 | find_close_to_parent: | 361 | find_close_to_parent: |
| 363 | flexbg_free_blocks = flex_group[best_flex].free_blocks; | 362 | flexbg_free_blocks = atomic_read(&flex_group[best_flex].free_blocks); |
| 364 | flex_freeb_ratio = flexbg_free_blocks * 100 / blocks_per_flex; | 363 | flex_freeb_ratio = flexbg_free_blocks * 100 / blocks_per_flex; |
| 365 | if (flex_group[best_flex].free_inodes && | 364 | if (atomic_read(&flex_group[best_flex].free_inodes) && |
| 366 | flex_freeb_ratio > free_block_ratio) | 365 | flex_freeb_ratio > free_block_ratio) |
| 367 | goto found_flexbg; | 366 | goto found_flexbg; |
| 368 | 367 | ||
| @@ -375,24 +374,24 @@ find_close_to_parent: | |||
| 375 | if (i == parent_fbg_group || i == parent_fbg_group - 1) | 374 | if (i == parent_fbg_group || i == parent_fbg_group - 1) |
| 376 | continue; | 375 | continue; |
| 377 | 376 | ||
| 378 | flexbg_free_blocks = flex_group[i].free_blocks; | 377 | flexbg_free_blocks = atomic_read(&flex_group[i].free_blocks); |
| 379 | flex_freeb_ratio = flexbg_free_blocks * 100 / blocks_per_flex; | 378 | flex_freeb_ratio = flexbg_free_blocks * 100 / blocks_per_flex; |
| 380 | 379 | ||
| 381 | if (flex_freeb_ratio > free_block_ratio && | 380 | if (flex_freeb_ratio > free_block_ratio && |
| 382 | flex_group[i].free_inodes) { | 381 | (atomic_read(&flex_group[i].free_inodes))) { |
| 383 | best_flex = i; | 382 | best_flex = i; |
| 384 | goto found_flexbg; | 383 | goto found_flexbg; |
| 385 | } | 384 | } |
| 386 | 385 | ||
| 387 | if (flex_group[best_flex].free_inodes == 0 || | 386 | if ((atomic_read(&flex_group[best_flex].free_inodes) == 0) || |
| 388 | (flex_group[i].free_blocks > | 387 | ((atomic_read(&flex_group[i].free_blocks) > |
| 389 | flex_group[best_flex].free_blocks && | 388 | atomic_read(&flex_group[best_flex].free_blocks)) && |
| 390 | flex_group[i].free_inodes)) | 389 | atomic_read(&flex_group[i].free_inodes))) |
| 391 | best_flex = i; | 390 | best_flex = i; |
| 392 | } | 391 | } |
| 393 | 392 | ||
| 394 | if (!flex_group[best_flex].free_inodes || | 393 | if (!atomic_read(&flex_group[best_flex].free_inodes) || |
| 395 | !flex_group[best_flex].free_blocks) | 394 | !atomic_read(&flex_group[best_flex].free_blocks)) |
| 396 | return -1; | 395 | return -1; |
| 397 | 396 | ||
| 398 | found_flexbg: | 397 | found_flexbg: |
| @@ -960,9 +959,7 @@ got: | |||
| 960 | 959 | ||
| 961 | if (sbi->s_log_groups_per_flex) { | 960 | if (sbi->s_log_groups_per_flex) { |
| 962 | flex_group = ext4_flex_group(sbi, group); | 961 | flex_group = ext4_flex_group(sbi, group); |
| 963 | spin_lock(sb_bgl_lock(sbi, flex_group)); | 962 | atomic_dec(&sbi->s_flex_groups[flex_group].free_inodes); |
| 964 | sbi->s_flex_groups[flex_group].free_inodes--; | ||
| 965 | spin_unlock(sb_bgl_lock(sbi, flex_group)); | ||
| 966 | } | 963 | } |
| 967 | 964 | ||
| 968 | inode->i_uid = current_fsuid(); | 965 | inode->i_uid = current_fsuid(); |
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index c4c430977622..e72c72a0b807 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c | |||
| @@ -3044,9 +3044,8 @@ ext4_mb_mark_diskspace_used(struct ext4_allocation_context *ac, | |||
| 3044 | if (sbi->s_log_groups_per_flex) { | 3044 | if (sbi->s_log_groups_per_flex) { |
| 3045 | ext4_group_t flex_group = ext4_flex_group(sbi, | 3045 | ext4_group_t flex_group = ext4_flex_group(sbi, |
| 3046 | ac->ac_b_ex.fe_group); | 3046 | ac->ac_b_ex.fe_group); |
| 3047 | spin_lock(sb_bgl_lock(sbi, flex_group)); | 3047 | atomic_sub(ac->ac_b_ex.fe_len, |
| 3048 | sbi->s_flex_groups[flex_group].free_blocks -= ac->ac_b_ex.fe_len; | 3048 | &sbi->s_flex_groups[flex_group].free_blocks); |
| 3049 | spin_unlock(sb_bgl_lock(sbi, flex_group)); | ||
| 3050 | } | 3049 | } |
| 3051 | 3050 | ||
| 3052 | err = ext4_handle_dirty_metadata(handle, NULL, bitmap_bh); | 3051 | err = ext4_handle_dirty_metadata(handle, NULL, bitmap_bh); |
| @@ -4884,9 +4883,7 @@ do_more: | |||
| 4884 | 4883 | ||
| 4885 | if (sbi->s_log_groups_per_flex) { | 4884 | if (sbi->s_log_groups_per_flex) { |
| 4886 | ext4_group_t flex_group = ext4_flex_group(sbi, block_group); | 4885 | ext4_group_t flex_group = ext4_flex_group(sbi, block_group); |
| 4887 | spin_lock(sb_bgl_lock(sbi, flex_group)); | 4886 | atomic_add(count, &sbi->s_flex_groups[flex_group].free_blocks); |
| 4888 | sbi->s_flex_groups[flex_group].free_blocks += count; | ||
| 4889 | spin_unlock(sb_bgl_lock(sbi, flex_group)); | ||
| 4890 | } | 4887 | } |
| 4891 | 4888 | ||
| 4892 | ext4_mb_release_desc(&e4b); | 4889 | ext4_mb_release_desc(&e4b); |
diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c index c06886abd658..546c7dd869e1 100644 --- a/fs/ext4/resize.c +++ b/fs/ext4/resize.c | |||
| @@ -938,10 +938,10 @@ int ext4_group_add(struct super_block *sb, struct ext4_new_group_data *input) | |||
| 938 | if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_FLEX_BG)) { | 938 | if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_FLEX_BG)) { |
| 939 | ext4_group_t flex_group; | 939 | ext4_group_t flex_group; |
| 940 | flex_group = ext4_flex_group(sbi, input->group); | 940 | flex_group = ext4_flex_group(sbi, input->group); |
| 941 | sbi->s_flex_groups[flex_group].free_blocks += | 941 | atomic_add(input->free_blocks_count, |
| 942 | input->free_blocks_count; | 942 | &sbi->s_flex_groups[flex_group].free_blocks); |
| 943 | sbi->s_flex_groups[flex_group].free_inodes += | 943 | atomic_add(EXT4_INODES_PER_GROUP(sb), |
| 944 | EXT4_INODES_PER_GROUP(sb); | 944 | &sbi->s_flex_groups[flex_group].free_inodes); |
| 945 | } | 945 | } |
| 946 | 946 | ||
| 947 | ext4_handle_dirty_metadata(handle, NULL, sbi->s_sbh); | 947 | ext4_handle_dirty_metadata(handle, NULL, sbi->s_sbh); |
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 1ec554cc107a..6b5d5c6399fa 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c | |||
| @@ -1630,10 +1630,10 @@ static int ext4_fill_flex_info(struct super_block *sb) | |||
| 1630 | gdp = ext4_get_group_desc(sb, i, &bh); | 1630 | gdp = ext4_get_group_desc(sb, i, &bh); |
| 1631 | 1631 | ||
| 1632 | flex_group = ext4_flex_group(sbi, i); | 1632 | flex_group = ext4_flex_group(sbi, i); |
| 1633 | sbi->s_flex_groups[flex_group].free_inodes += | 1633 | atomic_set(&sbi->s_flex_groups[flex_group].free_inodes, |
| 1634 | ext4_free_inodes_count(sb, gdp); | 1634 | ext4_free_inodes_count(sb, gdp)); |
| 1635 | sbi->s_flex_groups[flex_group].free_blocks += | 1635 | atomic_set(&sbi->s_flex_groups[flex_group].free_blocks, |
| 1636 | ext4_free_blks_count(sb, gdp); | 1636 | ext4_free_blks_count(sb, gdp)); |
| 1637 | } | 1637 | } |
| 1638 | 1638 | ||
| 1639 | return 1; | 1639 | return 1; |
