#include <afsconfig.h>
#include "afs/param.h"
-RCSID
- ("$Header$");
#include "afs/sysincludes.h"
#include "afsincludes.h"
-#include "h/mm.h"
-#include "h/slab.h"
+#include <linux/mm.h>
+#include <linux/slab.h>
#include "afs_atomlist.h"
#include "afs_lhash.h"
#define MAX_KMALLOC_SIZE PAGE_SIZE /* 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 */
/* types of alloc */
#define KM_TYPE 1 /* kmalloc */
unsigned int afs_linux_cur_allocs = 0;
unsigned int afs_linux_total_allocs = 0;
unsigned int afs_linux_hash_verify_count = 0; /* used by hash_verify */
-struct afs_lhash_stat afs_linux_lsb; /* hash table statistics */
-unsigned int afs_linux_hash_bucket_dist[MAX_BUCKET_LEN]; /* bucket population distribution in our hash table */
-#if defined(AFS_LINUX24_ENV)
-#include "h/vmalloc.h"
-#else
-/* externs : can we do this in a better way. Including vmalloc.h causes other
- * problems.*/
-extern void vfree(void *addr);
-extern void *vmalloc(unsigned long size);
-#endif
+#include <linux/vmalloc.h>
/* Allocator support functions (static) */
/* if we can use kmalloc use it to allocate the required memory. */
while (!new && max_retry) {
if (asize <= MAX_KMALLOC_SIZE) {
- new = (void *)(unsigned long)kmalloc(asize,
-#ifdef GFP_NOFS
- GFP_NOFS
-#else
- GFP_KERNEL
-#endif
- );
+ new = (void *)(unsigned long)kmalloc(asize, GFP_NOFS);
if (new) /* piggy back alloc type */
new = (void *)(KM_TYPE | (unsigned long)new);
} else {
* 1 - success
*/
static int
-linux_alloc_init()
+linux_alloc_init(void)
{
/* initiate our pool of osi_linux_mem structs */
al_mem_pool =
}
-/* hash_bucket_stat() : Counts the no. of elements in each bucket and
- * stores results in our bucket stats vector.
- */
-static unsigned int cur_bucket, cur_bucket_len;
-static void
-hash_bucket_stat(size_t index, unsigned key, void *data)
-{
- if (index == cur_bucket) {
- /* while still on the same bucket, inc len & return */
- cur_bucket_len++;
- return;
- } else { /* if we're on the next bucket, store the distribution */
- if (cur_bucket_len < MAX_BUCKET_LEN)
- afs_linux_hash_bucket_dist[cur_bucket_len]++;
- else
- printf
- ("afs_get_hash_stats: Warning! exceeded max bucket len %d\n",
- cur_bucket_len);
- cur_bucket = index;
- cur_bucket_len = 1;
- }
-}
-
-/* get_hash_stats() : get hash table statistics */
-static void
-get_hash_stats()
-{
- int i;
-
- afs_lhash_stat(lh_mem_htab, &afs_linux_lsb);
-
- /* clear out the bucket stat vector */
- for (i = 0; i < MAX_BUCKET_LEN; i++, afs_linux_hash_bucket_dist[i] = 0);
- cur_bucket = cur_bucket_len = 00;
-
- /* populate the bucket stat vector */
- afs_lhash_iter(lh_mem_htab, hash_bucket_stat);
-}
-
/************** Linux memory allocator interface functions **********/
-#if defined(AFS_LINUX24_ENV)
-DECLARE_MUTEX(afs_linux_alloc_sem);
-#else
-struct semaphore afs_linux_alloc_sem = MUTEX;
-#endif
+DEFINE_MUTEX(afs_linux_alloc_sem);
void *
osi_linux_alloc(unsigned int asize, int drop_glock)
return new;
}
- down(&afs_linux_alloc_sem);
+ mutex_lock(&afs_linux_alloc_sem);
/* allocator hasn't been initialized yet */
if (allocator_init == 0) {
}
afs_linux_cur_allocs++; /* no. of current allocations */
afs_linux_total_allocs++; /* total no. of allocations done so far */
- if ((afs_linux_cur_allocs % STAT_INTERVAL) == 0) {
- get_hash_stats();
- }
error:
- up(&afs_linux_alloc_sem);
+ mutex_unlock(&afs_linux_alloc_sem);
return MEMADDR(new);
free_error:
{
struct osi_linux_mem lmem, *lmp;
- down(&afs_linux_alloc_sem);
+ mutex_lock(&afs_linux_alloc_sem);
lmem.chunk = addr;
/* remove this chunk from our hash table */
afs_atomlist_put(al_mem_pool, lmp); /* return osi_linux_mem struct to pool */
afs_linux_cur_allocs--;
} else {
- printf("osi_linux_free: failed to remove chunk from hashtable\n");
+ osi_Panic("osi_linux_free: failed to remove chunk from hashtable\n");
}
- up(&afs_linux_alloc_sem);
+ mutex_unlock(&afs_linux_alloc_sem);
}
/* osi_linux_free_afs_memory() - free all chunks of memory allocated.
void
osi_linux_free_afs_memory(void)
{
- down(&afs_linux_alloc_sem);
+ mutex_lock(&afs_linux_alloc_sem);
if (allocator_init) {
/* iterate through all elements in the hash table and free both
/* change the state so that the allocator is now uninitialized. */
allocator_init = 0;
}
- up(&afs_linux_alloc_sem);
+ mutex_unlock(&afs_linux_alloc_sem);
}
/* osi_linux_verify_alloced_memory(): verify all chunks of alloced memory in
void
osi_linux_verify_alloced_memory()
{
- down(&afs_linux_alloc_sem);
+ mutex_lock(&afs_linux_alloc_sem);
/* count of times hash_verify was called. reset it to 0 before iteration */
afs_linux_hash_verify_count = 0;
afs_linux_hash_verify_count - afs_linux_cur_allocs);
}
- up(&afs_linux_alloc_sem);
+ mutex_unlock(&afs_linux_alloc_sem);
return;
}
+
+#ifdef AFS_PRIVATE_OSI_ALLOCSPACES
+
+void
+osi_FreeLargeSpace(void *p)
+{
+ kfree(p);
+}
+
+void
+osi_FreeSmallSpace(void *p)
+{
+ kfree(p);
+}
+
+void *
+osi_AllocLargeSpace(size_t size)
+{
+ if (size > AFS_LRALLOCSIZ)
+ osi_Panic("osi_AllocLargeSpace: size=%d\n", (int) size);
+ return kmalloc(AFS_LRALLOCSIZ, GFP_NOFS);
+}
+
+void *
+osi_AllocSmallSpace(size_t size)
+{
+ if (size > AFS_SMALLOCSIZ)
+ osi_Panic("osi_AllocSmallS: size=%d\n", (int)size);
+ return kmalloc(AFS_SMALLOCSIZ, GFP_NOFS);
+}
+#endif /* AFS_PRIVATE_OSI_ALLOCSPACES */