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; |