[OpenAFS-devel] Linux 2.6.12 kernel BUG at fs/namei.c:1189

Rainer Toebbicke rtb@pclella.cern.ch
Tue, 31 Jan 2006 09:44:29 +0100


This is a multi-part message in MIME format.
--------------060809020106020801030407
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit

chas williams - CONTRACTOR wrote:

> 
> kmalloc() should be running under GFP_NOFS which should keep the
> the filesystem from deadlocking on AFS_GLOCK.  however, for large


What?

I'm admittedly no kernel freak but from what I read in slab.c and 
page_alloc.c GFP_NOFS does *not* protect you from sleeping and waiting 
for kswapd when you run out of free pages. Nor does GFP_KERNEL for 
that matter. And then you're in trouble if you hold the global lock as 
we know already that through put_inode kswapd might re-enter AFS and 
deadlock.

GFP_ATOMIC would probably.

You've got a point however in that osi_linux_alloc() is obviously 
prepared to drop the global lock - however this is only attempted 
*after* a kmalloc() failed!

Perhaps the fix would be to simply drop the global lock if held and 
re-acquire it afterwards in osi_alloc.c. Don't know how expensive that 
would be or whether simply avoiding the whole scanerio isn't the 
cheaper solution in the long run.

Or use GFP_ATOMIC if we hold the global lock and GFP_NOFS otherwise - 
is that starting to become a matter of taste? What do the "penguins" say?

Let me know what you'd think of the attached patch. (incomplete yet, 
as the case "not allowed to drop lock" has yet to be handled as well).


-- 
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Rainer Toebbicke
European Laboratory for Particle Physics(CERN) - Geneva, Switzerland
Phone: +41 22 767 8985       Fax: +41 22 767 7155

--------------060809020106020801030407
Content-Type: text/plain;
 name="patch_kmalloc_drop_glock"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="patch_kmalloc_drop_glock"

--- openafs/src/afs/LINUX/osi_alloc.c.o141	2004-12-07 07:12:12.000000000 +0100
+++ openafs/src/afs/LINUX/osi_alloc.c	2006-01-31 09:30:07.000000000 +0100
@@ -87,6 +87,7 @@
 
     /*  if we can use kmalloc use it to allocate the required memory. */
     while (!new && max_retry) {
+	if (drop_glock && haveGlock) AFS_GUNLOCK();	/* kmalloc may sleep */
 	if (asize <= MAX_KMALLOC_SIZE) {
 	    new = (void *)(unsigned long)kmalloc(asize,
 #ifdef GFP_NOFS
@@ -102,6 +103,7 @@
 	    if (new)		/* piggy back alloc type */
 		new = (void *)(VM_TYPE | (unsigned long)new);
 	}
+	if (drop_glock && haveGlock) AFS_GUNLOCK();
 
 	if (!new) {
 #ifdef set_current_state

--------------060809020106020801030407--