From e5f5440a2dc712768781cf23130459cdfc5f3323 Mon Sep 17 00:00:00 2001 From: johann Date: Tue, 30 Jun 2009 21:04:16 +0000 Subject: [PATCH] Branch b1_8 b=20011 i=shadow i=panda ll_shrink_cache() can sleep while holding the ll_sb_lock. Convert ll_sb_lock to a read/write semaphore to fix the problem. --- lustre/ChangeLog | 7 +++++++ lustre/llite/llite_internal.h | 1 + lustre/llite/llite_lib.c | 14 +++++++------- lustre/llite/super25.c | 1 + 4 files changed, 16 insertions(+), 7 deletions(-) diff --git a/lustre/ChangeLog b/lustre/ChangeLog index a8b57ae..ab5c7ba 100644 --- a/lustre/ChangeLog +++ b/lustre/ChangeLog @@ -292,6 +292,13 @@ Description: MMP check in ext3_remount() fails without displaying any error Details : When multiple mount protection fails during remount, proper error should be returned +Severity : normal +Bugzilla : 20011 +Description: Client locked up when running multiple instances of an app. on + multiple mount points +Details : ll_shrink_cache() can sleep while holding the ll_sb_lock. + Convert ll_sb_lock to a read/write semaphore to fix the problem. + ------------------------------------------------------------------------------- 2008-12-31 Sun Microsystems, Inc. * version 1.8.0 diff --git a/lustre/llite/llite_internal.h b/lustre/llite/llite_internal.h index 68bfeda..6d2a39d 100644 --- a/lustre/llite/llite_internal.h +++ b/lustre/llite/llite_internal.h @@ -559,6 +559,7 @@ struct ll_readahead_state { }; extern cfs_mem_cache_t *ll_file_data_slab; +extern struct rw_semaphore ll_sb_sem; struct lustre_handle; struct ll_file_data { struct ll_readahead_state fd_ras; diff --git a/lustre/llite/llite_lib.c b/lustre/llite/llite_lib.c index f9fedf2..320e948 100644 --- a/lustre/llite/llite_lib.c +++ b/lustre/llite/llite_lib.c @@ -58,7 +58,7 @@ cfs_mem_cache_t *ll_file_data_slab; LIST_HEAD(ll_super_blocks); -spinlock_t ll_sb_lock = SPIN_LOCK_UNLOCKED; +struct rw_semaphore ll_sb_sem; extern struct address_space_operations ll_aops; extern struct address_space_operations ll_dir_aops; @@ -183,9 +183,9 @@ static struct ll_sb_info *ll_init_sbi(void) class_uuid_unparse(uuid, &sbi->ll_sb_uuid); CDEBUG(D_CONFIG, "generated uuid: %s\n", sbi->ll_sb_uuid.uuid); - spin_lock(&ll_sb_lock); + down_write(&ll_sb_sem); list_add_tail(&sbi->ll_list, &ll_super_blocks); - spin_unlock(&ll_sb_lock); + up_write(&ll_sb_sem); #ifdef ENABLE_CHECKSUM sbi->ll_flags |= LL_SBI_DATA_CHECKSUM; @@ -227,9 +227,9 @@ void ll_free_sbi(struct super_block *sb) ENTRY; if (sbi != NULL) { - spin_lock(&ll_sb_lock); + down_write(&ll_sb_sem); list_del(&sbi->ll_list); - spin_unlock(&ll_sb_lock); + up_write(&ll_sb_sem); /* dont allow find cache via sb list first */ ll_pglist_fini(sbi); lcounter_destroy(&sbi->ll_async_page_count); @@ -1310,10 +1310,10 @@ ll_shrink_cache(int priority, unsigned int gfp_mask) int count = 0; /* don't race with umount */ - spin_lock(&ll_sb_lock); + down_read(&ll_sb_sem); list_for_each_entry(sbi, &ll_super_blocks, ll_list) count += llap_shrink_cache(sbi, priority); - spin_unlock(&ll_sb_lock); + up_read(&ll_sb_sem); #if defined(HAVE_CACHE_RETURN_INT) return count; diff --git a/lustre/llite/super25.c b/lustre/llite/super25.c index 2078b04..6d8103a 100644 --- a/lustre/llite/super25.c +++ b/lustre/llite/super25.c @@ -126,6 +126,7 @@ static int __init init_lustre_lite(void) proc_lustre_fs_root = proc_lustre_root ? proc_mkdir("llite", proc_lustre_root) : NULL; + init_rwsem(&ll_sb_sem); ll_register_cache(&ll_cache_definition); lustre_register_client_fill_super(ll_fill_super); -- 1.8.3.1