From fe1648ca02137cac306d5f5002d8f79b580694ba Mon Sep 17 00:00:00 2001 From: Chas Williams Date: Mon, 24 Jun 2002 16:40:41 +0000 Subject: [PATCH] linux-more-osi-sleep-wakeup-fun-20020624 "the attached patch 'fixes', in my opinion, in osi_alloc. objects <= AFS_SMALLOCSIZ are alloced with kmalloc, other vmalloc. if kmalloc fails it doesnt fail over to vmalloc. TASK_RUNNING is set after schedule. it doesnt drop the GLOCK. i moved the allocator init later so that it doesnt need to toggle the semaphore just before going to linux_alloc." --- src/afs/LINUX/osi_alloc.c | 54 +++++++++++++++++++-------------------- 1 file changed, 26 insertions(+), 28 deletions(-) diff --git a/src/afs/LINUX/osi_alloc.c b/src/afs/LINUX/osi_alloc.c index b0b9389416..20fc7b7026 100644 --- a/src/afs/LINUX/osi_alloc.c +++ b/src/afs/LINUX/osi_alloc.c @@ -24,7 +24,7 @@ RCSID("$Header$"); #include "../afs/afs_atomlist.h" #include "../afs/afs_lhash.h" -#define MAX_KMALLOC_SIZE (131072-16) /* Max we can alloc in physmem */ +#define MAX_KMALLOC_SIZE AFS_SMALLOCSIZ /* Max we should alloc with kmalloc */ #define MAX_BUCKET_LEN 30 /* max. no. of entries per buckets we expect to see */ #define STAT_INTERVAL 8192 /* we collect stats once every STAT_INTERVAL allocs*/ @@ -79,14 +79,12 @@ static int hash_equal(const void *a, const void *b) static void *linux_alloc(unsigned int asize) { void *new = NULL; - int has_afs_glock = ISAFS_GLOCK(); - - /* if global lock has been held save this info and unlock it. */ - if (has_afs_glock) - AFS_GUNLOCK(); + int max_retry = 10; /* if we can use kmalloc use it to allocate the required memory. */ - if (asize < MAX_KMALLOC_SIZE) { + while(!new && max_retry) + { + if (asize <= MAX_KMALLOC_SIZE) { new = (void *)(unsigned long)kmalloc(asize, #ifdef GFP_NOFS GFP_NOFS @@ -96,30 +94,30 @@ static void *linux_alloc(unsigned int asize) ); if (new) /* piggy back alloc type */ (unsigned long)new |= KM_TYPE; - } - if (!new) { /* otherwise use vmalloc */ - int max_wait = 10; - while (!(new = (void *)vmalloc(asize))) { - if (--max_wait <=0) { - break; + } else { + new = (void *)vmalloc(asize); + if (new) /* piggy back alloc type */ + (unsigned long)new |= VM_TYPE; } + + if (!new) { #ifdef set_current_state set_current_state(TASK_INTERRUPTIBLE); #else current->state = TASK_INTERRUPTIBLE; #endif schedule_timeout(HZ); +#ifdef set_current_state + set_current_state(TASK_RUNNING); +#else + current->state = TASK_RUNNING; +#endif + --max_retry; } - if (new) /* piggy back alloc type */ - (unsigned long)new |= VM_TYPE; } if (new) memset(MEMADDR(new), 0, asize); - /* if the global lock had been held, lock it again. */ - if (has_afs_glock) - AFS_GLOCK(); - return new; } @@ -287,22 +285,22 @@ void *osi_linux_alloc(unsigned int asize) void *new = NULL; struct osi_linux_mem *lmem; + new = linux_alloc(asize); /* get a chunk of memory of size asize */ + + if (!new) { + printf("afs_osi_Alloc: Can't vmalloc %d bytes.\n", asize); + return new; + } + down(&afs_linux_alloc_sem); - if (allocator_init == 0) { /* allocator hasn't been initialized yet */ + /* allocator hasn't been initialized yet */ + if (allocator_init == 0) { if (linux_alloc_init() == 0) { goto error; } allocator_init = 1; /* initialization complete */ } - - up(&afs_linux_alloc_sem); - new = linux_alloc(asize); /* get a chunk of memory of size asize */ - down(&afs_linux_alloc_sem); - if (!new) { - printf("afs_osi_Alloc: Can't vmalloc %d bytes.\n", asize); - goto error; - } /* get an atom to store the pointer to the chunk */ lmem = (struct osi_linux_mem *)afs_atomlist_get(al_mem_pool);