[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--