From c1d2386e44573722f2cb16ee148b14960cd39670 Mon Sep 17 00:00:00 2001 From: David Howells Date: Tue, 25 Dec 2001 18:19:20 +0000 Subject: [PATCH] linux-alloc-avoid-potential-recursion-freeing-memory-and-schedule-when-vmalloc-fails-20011225 "The first is to change the gfp_mask passed to kmalloc(). Using GFP_KERNEL, it is possible that the VM will call back to the filesystem to free up memory to satisfy the kmalloc request. GFP_NOFS will prevent this possible recursion. I believe GFP_NOFS first appeared in the 2.4.6 kernel. The second change involves the call to schedule() when vmalloc() fails. This can also cause a hang. The schedule() call could be replaced with: set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(HZ);" --- src/afs/LINUX/osi_alloc.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/afs/LINUX/osi_alloc.c b/src/afs/LINUX/osi_alloc.c index 9169ed624d..580e899610 100644 --- a/src/afs/LINUX/osi_alloc.c +++ b/src/afs/LINUX/osi_alloc.c @@ -87,7 +87,13 @@ static void *linux_alloc(unsigned int asize) /* if we can use kmalloc use it to allocate the required memory. */ if (asize < MAX_KMALLOC_SIZE) { - new = (void *)(unsigned long)kmalloc(asize, GFP_KERNEL); + new = (void *)(unsigned long)kmalloc(asize, +#ifdef GFP_NOFS + GFP_NOFS +#else + GFP_KERNEL +#endif + ); if (new) /* piggy back alloc type */ (unsigned long)new |= KM_TYPE; } @@ -97,7 +103,8 @@ static void *linux_alloc(unsigned int asize) if (--max_wait <=0) { break; } - schedule(); + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(HZ); } if (new) /* piggy back alloc type */ (unsigned long)new |= VM_TYPE;