diff options
author | Chao Yu <chao2.yu@samsung.com> | 2015-02-11 05:20:38 -0500 |
---|---|---|
committer | Jaegeuk Kim <jaegeuk@kernel.org> | 2015-02-11 20:04:51 -0500 |
commit | 1a118ccfd60fc78e64c0a3ab9e85075545839d6e (patch) | |
tree | e0cbaa9c068a063c71923a9b3a2c5d6168c70a6d | |
parent | f1a3b98e73a9f811ab4882669043c50c0e0dc7b6 (diff) |
f2fs: use spinlock for segmap_lock instead of rwlock
rwlock can provide better concurrency when there are much more readers than
writers because readers can hold the rwlock simultaneously.
But now, for segmap_lock rwlock in struct free_segmap_info, there is only one
reader 'mount' from below call path:
->f2fs_fill_super
->build_segment_manager
->build_dirty_segmap
->init_dirty_segmap
->find_next_inuse
read_lock
...
read_unlock
Now that our concurrency can not be improved since there is no other reader for
this lock, we do not need to use rwlock_t type for segmap_lock, let's replace it
with spinlock_t type.
Signed-off-by: Chao Yu <chao2.yu@samsung.com>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
-rw-r--r-- | fs/f2fs/segment.c | 6 | ||||
-rw-r--r-- | fs/f2fs/segment.h | 18 |
2 files changed, 12 insertions, 12 deletions
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index c9d314f44568..daee4ab913da 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c | |||
@@ -800,7 +800,7 @@ static void get_new_segment(struct f2fs_sb_info *sbi, | |||
800 | int go_left = 0; | 800 | int go_left = 0; |
801 | int i; | 801 | int i; |
802 | 802 | ||
803 | write_lock(&free_i->segmap_lock); | 803 | spin_lock(&free_i->segmap_lock); |
804 | 804 | ||
805 | if (!new_sec && ((*newseg + 1) % sbi->segs_per_sec)) { | 805 | if (!new_sec && ((*newseg + 1) % sbi->segs_per_sec)) { |
806 | segno = find_next_zero_bit(free_i->free_segmap, | 806 | segno = find_next_zero_bit(free_i->free_segmap, |
@@ -873,7 +873,7 @@ got_it: | |||
873 | f2fs_bug_on(sbi, test_bit(segno, free_i->free_segmap)); | 873 | f2fs_bug_on(sbi, test_bit(segno, free_i->free_segmap)); |
874 | __set_inuse(sbi, segno); | 874 | __set_inuse(sbi, segno); |
875 | *newseg = segno; | 875 | *newseg = segno; |
876 | write_unlock(&free_i->segmap_lock); | 876 | spin_unlock(&free_i->segmap_lock); |
877 | } | 877 | } |
878 | 878 | ||
879 | static void reset_curseg(struct f2fs_sb_info *sbi, int type, int modified) | 879 | static void reset_curseg(struct f2fs_sb_info *sbi, int type, int modified) |
@@ -1923,7 +1923,7 @@ static int build_free_segmap(struct f2fs_sb_info *sbi) | |||
1923 | free_i->start_segno = GET_SEGNO_FROM_SEG0(sbi, MAIN_BLKADDR(sbi)); | 1923 | free_i->start_segno = GET_SEGNO_FROM_SEG0(sbi, MAIN_BLKADDR(sbi)); |
1924 | free_i->free_segments = 0; | 1924 | free_i->free_segments = 0; |
1925 | free_i->free_sections = 0; | 1925 | free_i->free_sections = 0; |
1926 | rwlock_init(&free_i->segmap_lock); | 1926 | spin_lock_init(&free_i->segmap_lock); |
1927 | return 0; | 1927 | return 0; |
1928 | } | 1928 | } |
1929 | 1929 | ||
diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h index ba858ca01445..7fd35111cf62 100644 --- a/fs/f2fs/segment.h +++ b/fs/f2fs/segment.h | |||
@@ -208,7 +208,7 @@ struct free_segmap_info { | |||
208 | unsigned int start_segno; /* start segment number logically */ | 208 | unsigned int start_segno; /* start segment number logically */ |
209 | unsigned int free_segments; /* # of free segments */ | 209 | unsigned int free_segments; /* # of free segments */ |
210 | unsigned int free_sections; /* # of free sections */ | 210 | unsigned int free_sections; /* # of free sections */ |
211 | rwlock_t segmap_lock; /* free segmap lock */ | 211 | spinlock_t segmap_lock; /* free segmap lock */ |
212 | unsigned long *free_segmap; /* free segment bitmap */ | 212 | unsigned long *free_segmap; /* free segment bitmap */ |
213 | unsigned long *free_secmap; /* free section bitmap */ | 213 | unsigned long *free_secmap; /* free section bitmap */ |
214 | }; | 214 | }; |
@@ -319,9 +319,9 @@ static inline unsigned int find_next_inuse(struct free_segmap_info *free_i, | |||
319 | unsigned int max, unsigned int segno) | 319 | unsigned int max, unsigned int segno) |
320 | { | 320 | { |
321 | unsigned int ret; | 321 | unsigned int ret; |
322 | read_lock(&free_i->segmap_lock); | 322 | spin_lock(&free_i->segmap_lock); |
323 | ret = find_next_bit(free_i->free_segmap, max, segno); | 323 | ret = find_next_bit(free_i->free_segmap, max, segno); |
324 | read_unlock(&free_i->segmap_lock); | 324 | spin_unlock(&free_i->segmap_lock); |
325 | return ret; | 325 | return ret; |
326 | } | 326 | } |
327 | 327 | ||
@@ -332,7 +332,7 @@ static inline void __set_free(struct f2fs_sb_info *sbi, unsigned int segno) | |||
332 | unsigned int start_segno = secno * sbi->segs_per_sec; | 332 | unsigned int start_segno = secno * sbi->segs_per_sec; |
333 | unsigned int next; | 333 | unsigned int next; |
334 | 334 | ||
335 | write_lock(&free_i->segmap_lock); | 335 | spin_lock(&free_i->segmap_lock); |
336 | clear_bit(segno, free_i->free_segmap); | 336 | clear_bit(segno, free_i->free_segmap); |
337 | free_i->free_segments++; | 337 | free_i->free_segments++; |
338 | 338 | ||
@@ -341,7 +341,7 @@ static inline void __set_free(struct f2fs_sb_info *sbi, unsigned int segno) | |||
341 | clear_bit(secno, free_i->free_secmap); | 341 | clear_bit(secno, free_i->free_secmap); |
342 | free_i->free_sections++; | 342 | free_i->free_sections++; |
343 | } | 343 | } |
344 | write_unlock(&free_i->segmap_lock); | 344 | spin_unlock(&free_i->segmap_lock); |
345 | } | 345 | } |
346 | 346 | ||
347 | static inline void __set_inuse(struct f2fs_sb_info *sbi, | 347 | static inline void __set_inuse(struct f2fs_sb_info *sbi, |
@@ -363,7 +363,7 @@ static inline void __set_test_and_free(struct f2fs_sb_info *sbi, | |||
363 | unsigned int start_segno = secno * sbi->segs_per_sec; | 363 | unsigned int start_segno = secno * sbi->segs_per_sec; |
364 | unsigned int next; | 364 | unsigned int next; |
365 | 365 | ||
366 | write_lock(&free_i->segmap_lock); | 366 | spin_lock(&free_i->segmap_lock); |
367 | if (test_and_clear_bit(segno, free_i->free_segmap)) { | 367 | if (test_and_clear_bit(segno, free_i->free_segmap)) { |
368 | free_i->free_segments++; | 368 | free_i->free_segments++; |
369 | 369 | ||
@@ -374,7 +374,7 @@ static inline void __set_test_and_free(struct f2fs_sb_info *sbi, | |||
374 | free_i->free_sections++; | 374 | free_i->free_sections++; |
375 | } | 375 | } |
376 | } | 376 | } |
377 | write_unlock(&free_i->segmap_lock); | 377 | spin_unlock(&free_i->segmap_lock); |
378 | } | 378 | } |
379 | 379 | ||
380 | static inline void __set_test_and_inuse(struct f2fs_sb_info *sbi, | 380 | static inline void __set_test_and_inuse(struct f2fs_sb_info *sbi, |
@@ -382,13 +382,13 @@ static inline void __set_test_and_inuse(struct f2fs_sb_info *sbi, | |||
382 | { | 382 | { |
383 | struct free_segmap_info *free_i = FREE_I(sbi); | 383 | struct free_segmap_info *free_i = FREE_I(sbi); |
384 | unsigned int secno = segno / sbi->segs_per_sec; | 384 | unsigned int secno = segno / sbi->segs_per_sec; |
385 | write_lock(&free_i->segmap_lock); | 385 | spin_lock(&free_i->segmap_lock); |
386 | if (!test_and_set_bit(segno, free_i->free_segmap)) { | 386 | if (!test_and_set_bit(segno, free_i->free_segmap)) { |
387 | free_i->free_segments--; | 387 | free_i->free_segments--; |
388 | if (!test_and_set_bit(secno, free_i->free_secmap)) | 388 | if (!test_and_set_bit(secno, free_i->free_secmap)) |
389 | free_i->free_sections--; | 389 | free_i->free_sections--; |
390 | } | 390 | } |
391 | write_unlock(&free_i->segmap_lock); | 391 | spin_unlock(&free_i->segmap_lock); |
392 | } | 392 | } |
393 | 393 | ||
394 | static inline void get_sit_bitmap(struct f2fs_sb_info *sbi, | 394 | static inline void get_sit_bitmap(struct f2fs_sb_info *sbi, |