diff options
author | Eric Dumazet <eric.dumazet@gmail.com> | 2010-10-23 11:18:01 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2010-10-25 21:26:11 -0400 |
commit | f991bd2e14210fb93d722cb23e54991de20e8a3d (patch) | |
tree | 60643fb9d828c388d963ceb26504dce9890eabbb /fs/inode.c | |
parent | 7de9c6ee3ecffd99e1628e81a5ea5468f7581a1f (diff) |
fs: introduce a per-cpu last_ino allocator
new_inode() dirties a contended cache line to get increasing
inode numbers. This limits performance on workloads that cause
significant parallel inode allocation.
Solve this problem by using a per_cpu variable fed by the shared
last_ino in batches of 1024 allocations. This reduces contention on
the shared last_ino, and give same spreading ino numbers than before
(i.e. same wraparound after 2^32 allocations).
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: Nick Piggin <npiggin@suse.de>
Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/inode.c')
-rw-r--r-- | fs/inode.c | 45 |
1 files changed, 38 insertions, 7 deletions
diff --git a/fs/inode.c b/fs/inode.c index 05ea293d5f3..46a3e120b19 100644 --- a/fs/inode.c +++ b/fs/inode.c | |||
@@ -717,6 +717,43 @@ repeat: | |||
717 | return NULL; | 717 | return NULL; |
718 | } | 718 | } |
719 | 719 | ||
720 | /* | ||
721 | * Each cpu owns a range of LAST_INO_BATCH numbers. | ||
722 | * 'shared_last_ino' is dirtied only once out of LAST_INO_BATCH allocations, | ||
723 | * to renew the exhausted range. | ||
724 | * | ||
725 | * This does not significantly increase overflow rate because every CPU can | ||
726 | * consume at most LAST_INO_BATCH-1 unused inode numbers. So there is | ||
727 | * NR_CPUS*(LAST_INO_BATCH-1) wastage. At 4096 and 1024, this is ~0.1% of the | ||
728 | * 2^32 range, and is a worst-case. Even a 50% wastage would only increase | ||
729 | * overflow rate by 2x, which does not seem too significant. | ||
730 | * | ||
731 | * On a 32bit, non LFS stat() call, glibc will generate an EOVERFLOW | ||
732 | * error if st_ino won't fit in target struct field. Use 32bit counter | ||
733 | * here to attempt to avoid that. | ||
734 | */ | ||
735 | #define LAST_INO_BATCH 1024 | ||
736 | static DEFINE_PER_CPU(unsigned int, last_ino); | ||
737 | |||
738 | static unsigned int get_next_ino(void) | ||
739 | { | ||
740 | unsigned int *p = &get_cpu_var(last_ino); | ||
741 | unsigned int res = *p; | ||
742 | |||
743 | #ifdef CONFIG_SMP | ||
744 | if (unlikely((res & (LAST_INO_BATCH-1)) == 0)) { | ||
745 | static atomic_t shared_last_ino; | ||
746 | int next = atomic_add_return(LAST_INO_BATCH, &shared_last_ino); | ||
747 | |||
748 | res = next - LAST_INO_BATCH; | ||
749 | } | ||
750 | #endif | ||
751 | |||
752 | *p = ++res; | ||
753 | put_cpu_var(last_ino); | ||
754 | return res; | ||
755 | } | ||
756 | |||
720 | /** | 757 | /** |
721 | * new_inode - obtain an inode | 758 | * new_inode - obtain an inode |
722 | * @sb: superblock | 759 | * @sb: superblock |
@@ -731,12 +768,6 @@ repeat: | |||
731 | */ | 768 | */ |
732 | struct inode *new_inode(struct super_block *sb) | 769 | struct inode *new_inode(struct super_block *sb) |
733 | { | 770 | { |
734 | /* | ||
735 | * On a 32bit, non LFS stat() call, glibc will generate an EOVERFLOW | ||
736 | * error if st_ino won't fit in target struct field. Use 32bit counter | ||
737 | * here to attempt to avoid that. | ||
738 | */ | ||
739 | static unsigned int last_ino; | ||
740 | struct inode *inode; | 771 | struct inode *inode; |
741 | 772 | ||
742 | spin_lock_prefetch(&inode_lock); | 773 | spin_lock_prefetch(&inode_lock); |
@@ -745,7 +776,7 @@ struct inode *new_inode(struct super_block *sb) | |||
745 | if (inode) { | 776 | if (inode) { |
746 | spin_lock(&inode_lock); | 777 | spin_lock(&inode_lock); |
747 | __inode_sb_list_add(inode); | 778 | __inode_sb_list_add(inode); |
748 | inode->i_ino = ++last_ino; | 779 | inode->i_ino = get_next_ino(); |
749 | inode->i_state = 0; | 780 | inode->i_state = 0; |
750 | spin_unlock(&inode_lock); | 781 | spin_unlock(&inode_lock); |
751 | } | 782 | } |