mirror of
https://git.openafs.org/openafs.git
synced 2025-01-22 08:50:17 +00:00
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."
This commit is contained in:
parent
60659d2c8f
commit
fe1648ca02
@ -24,7 +24,7 @@ RCSID("$Header$");
|
|||||||
#include "../afs/afs_atomlist.h"
|
#include "../afs/afs_atomlist.h"
|
||||||
#include "../afs/afs_lhash.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 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*/
|
#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)
|
static void *linux_alloc(unsigned int asize)
|
||||||
{
|
{
|
||||||
void *new = NULL;
|
void *new = NULL;
|
||||||
int has_afs_glock = ISAFS_GLOCK();
|
int max_retry = 10;
|
||||||
|
|
||||||
/* if global lock has been held save this info and unlock it. */
|
|
||||||
if (has_afs_glock)
|
|
||||||
AFS_GUNLOCK();
|
|
||||||
|
|
||||||
/* if we can use kmalloc use it to allocate the required memory. */
|
/* 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,
|
new = (void *)(unsigned long)kmalloc(asize,
|
||||||
#ifdef GFP_NOFS
|
#ifdef GFP_NOFS
|
||||||
GFP_NOFS
|
GFP_NOFS
|
||||||
@ -96,30 +94,30 @@ static void *linux_alloc(unsigned int asize)
|
|||||||
);
|
);
|
||||||
if (new) /* piggy back alloc type */
|
if (new) /* piggy back alloc type */
|
||||||
(unsigned long)new |= KM_TYPE;
|
(unsigned long)new |= KM_TYPE;
|
||||||
}
|
} else {
|
||||||
if (!new) { /* otherwise use vmalloc */
|
new = (void *)vmalloc(asize);
|
||||||
int max_wait = 10;
|
if (new) /* piggy back alloc type */
|
||||||
while (!(new = (void *)vmalloc(asize))) {
|
(unsigned long)new |= VM_TYPE;
|
||||||
if (--max_wait <=0) {
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!new) {
|
||||||
#ifdef set_current_state
|
#ifdef set_current_state
|
||||||
set_current_state(TASK_INTERRUPTIBLE);
|
set_current_state(TASK_INTERRUPTIBLE);
|
||||||
#else
|
#else
|
||||||
current->state = TASK_INTERRUPTIBLE;
|
current->state = TASK_INTERRUPTIBLE;
|
||||||
#endif
|
#endif
|
||||||
schedule_timeout(HZ);
|
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)
|
if (new)
|
||||||
memset(MEMADDR(new), 0, asize);
|
memset(MEMADDR(new), 0, asize);
|
||||||
|
|
||||||
/* if the global lock had been held, lock it again. */
|
|
||||||
if (has_afs_glock)
|
|
||||||
AFS_GLOCK();
|
|
||||||
|
|
||||||
return new;
|
return new;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -287,22 +285,22 @@ void *osi_linux_alloc(unsigned int asize)
|
|||||||
void *new = NULL;
|
void *new = NULL;
|
||||||
struct osi_linux_mem *lmem;
|
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);
|
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) {
|
if (linux_alloc_init() == 0) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
allocator_init = 1; /* initialization complete */
|
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 */
|
/* get an atom to store the pointer to the chunk */
|
||||||
lmem = (struct osi_linux_mem *)afs_atomlist_get(al_mem_pool);
|
lmem = (struct osi_linux_mem *)afs_atomlist_get(al_mem_pool);
|
||||||
|
Loading…
Reference in New Issue
Block a user