diff options
Diffstat (limited to 'fs/ext4/ext4.h')
-rw-r--r-- | fs/ext4/ext4.h | 30 |
1 files changed, 29 insertions, 1 deletions
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 70aa951ecb3c..2e9a2036c114 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h | |||
@@ -952,6 +952,7 @@ struct ext4_sb_info { | |||
952 | atomic_t s_mb_lost_chunks; | 952 | atomic_t s_mb_lost_chunks; |
953 | atomic_t s_mb_preallocated; | 953 | atomic_t s_mb_preallocated; |
954 | atomic_t s_mb_discarded; | 954 | atomic_t s_mb_discarded; |
955 | atomic_t s_lock_busy; | ||
955 | 956 | ||
956 | /* locality groups */ | 957 | /* locality groups */ |
957 | struct ext4_locality_group *s_locality_groups; | 958 | struct ext4_locality_group *s_locality_groups; |
@@ -1593,15 +1594,42 @@ struct ext4_group_info { | |||
1593 | #define EXT4_MB_GRP_NEED_INIT(grp) \ | 1594 | #define EXT4_MB_GRP_NEED_INIT(grp) \ |
1594 | (test_bit(EXT4_GROUP_INFO_NEED_INIT_BIT, &((grp)->bb_state))) | 1595 | (test_bit(EXT4_GROUP_INFO_NEED_INIT_BIT, &((grp)->bb_state))) |
1595 | 1596 | ||
1597 | #define EXT4_MAX_CONTENTION 8 | ||
1598 | #define EXT4_CONTENTION_THRESHOLD 2 | ||
1599 | |||
1596 | static inline spinlock_t *ext4_group_lock_ptr(struct super_block *sb, | 1600 | static inline spinlock_t *ext4_group_lock_ptr(struct super_block *sb, |
1597 | ext4_group_t group) | 1601 | ext4_group_t group) |
1598 | { | 1602 | { |
1599 | return bgl_lock_ptr(EXT4_SB(sb)->s_blockgroup_lock, group); | 1603 | return bgl_lock_ptr(EXT4_SB(sb)->s_blockgroup_lock, group); |
1600 | } | 1604 | } |
1601 | 1605 | ||
1606 | /* | ||
1607 | * Returns true if the filesystem is busy enough that attempts to | ||
1608 | * access the block group locks has run into contention. | ||
1609 | */ | ||
1610 | static inline int ext4_fs_is_busy(struct ext4_sb_info *sbi) | ||
1611 | { | ||
1612 | return (atomic_read(&sbi->s_lock_busy) > EXT4_CONTENTION_THRESHOLD); | ||
1613 | } | ||
1614 | |||
1602 | static inline void ext4_lock_group(struct super_block *sb, ext4_group_t group) | 1615 | static inline void ext4_lock_group(struct super_block *sb, ext4_group_t group) |
1603 | { | 1616 | { |
1604 | spin_lock(ext4_group_lock_ptr(sb, group)); | 1617 | spinlock_t *lock = ext4_group_lock_ptr(sb, group); |
1618 | if (spin_trylock(lock)) | ||
1619 | /* | ||
1620 | * We're able to grab the lock right away, so drop the | ||
1621 | * lock contention counter. | ||
1622 | */ | ||
1623 | atomic_add_unless(&EXT4_SB(sb)->s_lock_busy, -1, 0); | ||
1624 | else { | ||
1625 | /* | ||
1626 | * The lock is busy, so bump the contention counter, | ||
1627 | * and then wait on the spin lock. | ||
1628 | */ | ||
1629 | atomic_add_unless(&EXT4_SB(sb)->s_lock_busy, 1, | ||
1630 | EXT4_MAX_CONTENTION); | ||
1631 | spin_lock(lock); | ||
1632 | } | ||
1605 | } | 1633 | } |
1606 | 1634 | ||
1607 | static inline void ext4_unlock_group(struct super_block *sb, | 1635 | static inline void ext4_unlock_group(struct super_block *sb, |