4c21e2f244
Christoph Lameter demonstrated very poor scalability on the SGI 512-way, with a many-threaded application which concurrently initializes different parts of a large anonymous area. This patch corrects that, by using a separate spinlock per page table page, to guard the page table entries in that page, instead of using the mm's single page_table_lock. (But even then, page_table_lock is still used to guard page table allocation, and anon_vma allocation.) In this implementation, the spinlock is tucked inside the struct page of the page table page: with a BUILD_BUG_ON in case it overflows - which it would in the case of 32-bit PA-RISC with spinlock debugging enabled. Splitting the lock is not quite for free: another cacheline access. Ideally, I suppose we would use split ptlock only for multi-threaded processes on multi-cpu machines; but deciding that dynamically would have its own costs. So for now enable it by config, at some number of cpus - since the Kconfig language doesn't support inequalities, let preprocessor compare that with NR_CPUS. But I don't think it's worth being user-configurable: for good testing of both split and unsplit configs, split now at 4 cpus, and perhaps change that to 8 later. There is a benefit even for singly threaded processes: kswapd can be attacking one part of the mm while another part is busy faulting. Signed-off-by: Hugh Dickins <hugh@veritas.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org> |
||
---|---|---|
.. | ||
linux-2.6 | ||
quota | ||
support | ||
Kconfig | ||
Makefile | ||
Makefile-linux-2.6 | ||
xfs_acl.c | ||
xfs_acl.h | ||
xfs_ag.h | ||
xfs_alloc_btree.c | ||
xfs_alloc_btree.h | ||
xfs_alloc.c | ||
xfs_alloc.h | ||
xfs_arch.h | ||
xfs_attr_leaf.c | ||
xfs_attr_leaf.h | ||
xfs_attr_sf.h | ||
xfs_attr.c | ||
xfs_attr.h | ||
xfs_behavior.c | ||
xfs_behavior.h | ||
xfs_bit.c | ||
xfs_bit.h | ||
xfs_bmap_btree.c | ||
xfs_bmap_btree.h | ||
xfs_bmap.c | ||
xfs_bmap.h | ||
xfs_btree.c | ||
xfs_btree.h | ||
xfs_buf_item.c | ||
xfs_buf_item.h | ||
xfs_cap.h | ||
xfs_clnt.h | ||
xfs_da_btree.c | ||
xfs_da_btree.h | ||
xfs_dfrag.c | ||
xfs_dfrag.h | ||
xfs_dinode.h | ||
xfs_dir2_block.c | ||
xfs_dir2_block.h | ||
xfs_dir2_data.c | ||
xfs_dir2_data.h | ||
xfs_dir2_leaf.c | ||
xfs_dir2_leaf.h | ||
xfs_dir2_node.c | ||
xfs_dir2_node.h | ||
xfs_dir2_sf.c | ||
xfs_dir2_sf.h | ||
xfs_dir2_trace.c | ||
xfs_dir2_trace.h | ||
xfs_dir2.c | ||
xfs_dir2.h | ||
xfs_dir_leaf.c | ||
xfs_dir_leaf.h | ||
xfs_dir_sf.h | ||
xfs_dir.c | ||
xfs_dir.h | ||
xfs_dmapi.h | ||
xfs_dmops.c | ||
xfs_error.c | ||
xfs_error.h | ||
xfs_extfree_item.c | ||
xfs_extfree_item.h | ||
xfs_fs.h | ||
xfs_fsops.c | ||
xfs_fsops.h | ||
xfs_ialloc_btree.c | ||
xfs_ialloc_btree.h | ||
xfs_ialloc.c | ||
xfs_ialloc.h | ||
xfs_iget.c | ||
xfs_imap.h | ||
xfs_inode_item.c | ||
xfs_inode_item.h | ||
xfs_inode.c | ||
xfs_inode.h | ||
xfs_inum.h | ||
xfs_iocore.c | ||
xfs_iomap.c | ||
xfs_iomap.h | ||
xfs_itable.c | ||
xfs_itable.h | ||
xfs_log_priv.h | ||
xfs_log_recover.c | ||
xfs_log_recover.h | ||
xfs_log.c | ||
xfs_log.h | ||
xfs_mac.h | ||
xfs_macros.c | ||
xfs_macros.h | ||
xfs_mount.c | ||
xfs_mount.h | ||
xfs_qmops.c | ||
xfs_quota.h | ||
xfs_refcache.h | ||
xfs_rename.c | ||
xfs_rtalloc.c | ||
xfs_rtalloc.h | ||
xfs_rw.c | ||
xfs_rw.h | ||
xfs_sb.h | ||
xfs_trans_ail.c | ||
xfs_trans_buf.c | ||
xfs_trans_extfree.c | ||
xfs_trans_inode.c | ||
xfs_trans_item.c | ||
xfs_trans_priv.h | ||
xfs_trans_space.h | ||
xfs_trans.c | ||
xfs_trans.h | ||
xfs_types.h | ||
xfs_utils.c | ||
xfs_utils.h | ||
xfs_vfsops.c | ||
xfs_vnodeops.c | ||
xfs.h |