Re: INFO: possible circular locking dependency detected

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



alpha @ steudten Engineering wrote:
=======================================================
[ INFO: possible circular locking dependency detected ]
2.6.18-1.2189self #1
-------------------------------------------------------
kswapd0/186 is trying to acquire lock:
 (&inode->i_mutex){--..}, at: [<c0326e32>] mutex_lock+0x21/0x24

but task is already holding lock:
 (iprune_mutex){--..}, at: [<c0326e32>] mutex_lock+0x21/0x24

which lock already depends on the new lock.

Thanks. __grab_cache_page wants to clear __GFP_FS, because it is
holding the i_mutex so we don't want to reenter the filesystem in
page reclaim.

This would be an easy two liner, except those funny page_cache_alloc
routines which take a mapping rather than a gfp_t argument :P

Anyway, I'll get around to writing the real patch and queue it up
with my other buffered write deadlock fixes. It should be fairly
unlikely to cause you a deadlock. You could give this quick patch a
try, though. Does it fix your problem?

--
SUSE Labs, Novell Inc.
Index: linux-2.6/include/linux/pagemap.h
===================================================================
--- linux-2.6.orig/include/linux/pagemap.h	2006-10-17 00:29:40.000000000 +1000
+++ linux-2.6/include/linux/pagemap.h	2006-10-17 00:29:50.000000000 +1000
@@ -57,7 +57,7 @@ extern struct page *page_cache_alloc_col
 #else
 static inline struct page *page_cache_alloc(struct address_space *x)
 {
-	return alloc_pages(mapping_gfp_mask(x), 0);
+	return alloc_pages(mapping_gfp_mask(x)&~__GFP_FS, 0);
 }
 
 static inline struct page *page_cache_alloc_cold(struct address_space *x)
Index: linux-2.6/mm/filemap.c
===================================================================
--- linux-2.6.orig/mm/filemap.c	2006-10-17 00:29:49.000000000 +1000
+++ linux-2.6/mm/filemap.c	2006-10-17 00:29:50.000000000 +1000
@@ -471,9 +471,9 @@ struct page *page_cache_alloc(struct add
 {
 	if (cpuset_do_page_mem_spread()) {
 		int n = cpuset_mem_spread_node();
-		return alloc_pages_node(n, mapping_gfp_mask(x), 0);
+		return alloc_pages_node(n, mapping_gfp_mask(x)&~__GFP_FS, 0);
 	}
-	return alloc_pages(mapping_gfp_mask(x), 0);
+	return alloc_pages(mapping_gfp_mask(x)&~__GFP_FS, 0);
 }
 EXPORT_SYMBOL(page_cache_alloc);
 
@@ -1864,7 +1864,7 @@ repeat:
 				return NULL;
 		}
 		err = add_to_page_cache(*cached_page, mapping,
-							index, GFP_KERNEL);
+						index, GFP_KERNEL&~__GFP_FS);
 		if (err == -EEXIST)
 			goto repeat;
 		if (err == 0) {

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux