Whamcloud - gitweb
Branch b_release_1_8_1
authorjohann <johann>
Tue, 30 Jun 2009 21:03:21 +0000 (21:03 +0000)
committerjohann <johann>
Tue, 30 Jun 2009 21:03:21 +0000 (21:03 +0000)
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
lustre/llite/llite_internal.h
lustre/llite/llite_lib.c
lustre/llite/super25.c

index b3c338d..d386fc9 100644 (file)
@@ -176,6 +176,13 @@ Details    : ext3-based ldiskfs does not support greater than 8TB LUNs.
             Don't allow >8TB ldiskfs filesystems to be mounted without
             force_over_8tb mount option
 
+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.
+
 -------------------------------------------------------------------------------
 
 tbd Sun Microsystems, Inc.
index ddf85ec..e809294 100644 (file)
@@ -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;
index 88c2c1c..7b67bf2 100644 (file)
@@ -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);
@@ -1308,10 +1308,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;
index 2078b04..6d8103a 100644 (file)
@@ -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);