/** * Allocate memory * @size: how many bytes of memory are required. * @flags: the type of memory to allocate. * * kmalloc is the normal method of allocating memory * in the kernel. */ void *__kmalloc(size_t size, gfp_t flags) { /* add space for back-pointer */ size += sizeof(void *); /* find appropriate cache */ struct kmem_cache *cache = find_cache(size); void **p; if (cache) /* allocate from cache */ p = kmem_cache_alloc(cache, flags); else /* no cache for this size - use ddekit malloc */ p = ddekit_large_malloc(size); ddekit_log(DEBUG_MALLOC, "size=%d, cache=%p (%d) => %p", size, cache, cache ? kmem_cache_size(cache) : 0, p); /* return pointer to actual chunk */ if (p) { *p = cache; p++; } /* Need to zero out mem? */ if (p && (flags & __GFP_ZERO)) { size -= sizeof(void*); memset(p, 0, size); } return p; }
/** * kmem_cache_destroy - delete a cache * @cachep: the cache to destroy * * Remove a struct kmem_cache object from the slab cache. * Returns 0 on success. * * It is expected this function will be called by a module when it is * unloaded. This will remove the cache completely, and avoid a duplicate * cache being allocated each time a module is loaded and unloaded, if the * module doesn't have persistent in-kernel storage across loads and unloads. * * The cache must be empty before calling this function. * * The caller must guarantee that noone will allocate memory from the cache * during the kmem_cache_destroy(). */ void kmem_cache_destroy(struct kmem_cache *cache) { ddekit_log(DEBUG_SLAB, "\"%s\"", cache->name); ddekit_slab_destroy(cache->ddekit_slab_cache); ddekit_simple_free(cache); }
/** * kmem_cache_free - Deallocate an object * @cachep: The cache the allocation was from. * @objp: The previously allocated object. * * Free an object which was previously allocated from this * cache. */ void kmem_cache_free(struct kmem_cache *cache, void *objp) { ddekit_log(DEBUG_SLAB_ALLOC, "\"%s\" (%p)", cache->name, objp); ddekit_lock_lock(&cache->cache_lock); ddekit_slab_free(cache->ddekit_slab_cache, objp); ddekit_lock_unlock(&cache->cache_lock); }
/** * Free previously allocated memory * @objp: pointer returned by kmalloc. * * If @objp is NULL, no operation is performed. * * Don't free memory not originally allocated by kmalloc() * or you will run into trouble. */ void kfree(const void *objp) { if (!objp) return; /* find cache back-pointer */ void **p = (void **)objp - 1; ddekit_log(DEBUG_MALLOC, "objp=%p cache=%p (%d)", p, *p, *p ? kmem_cache_size(*p) : 0); if (*p) /* free from cache */ kmem_cache_free(*p, p); else /* no cache for this size - use ddekit free */ ddekit_large_free(p); }
/** * kmem_cache_alloc - Allocate an object * @cachep: The cache to allocate from. * @flags: See kmalloc(). * * Allocate an object from this cache. The flags are only relevant * if the cache has no available objects. */ void *kmem_cache_alloc(struct kmem_cache *cache, gfp_t flags) { void *ret; ddekit_lock_lock(&cache->cache_lock); ret = ddekit_slab_alloc(cache->ddekit_slab_cache); ddekit_lock_unlock(&cache->cache_lock); // XXX: is it valid to run ctor AND memset to zero? if (flags & __GFP_ZERO) memset(ret, 0, cache->size); else if (cache->ctor) cache->ctor(ret); ddekit_log(DEBUG_SLAB_ALLOC, "\"%s\" flags=%x (%p, %d)", cache->name, flags, ret, cache->size); return ret; }
/** * kmem_cache_create - Create a cache. * @name: A string which is used in /proc/slabinfo to identify this cache. * @size: The size of objects to be created in this cache. * @align: The required alignment for the objects. * @flags: SLAB flags * @ctor: A constructor for the objects. * * Returns a ptr to the cache on success, NULL on failure. * Cannot be called within a int, but can be interrupted. * The @ctor is run when new pages are allocated by the cache * and the @dtor is run before the pages are handed back. * * @name must be valid until the cache is destroyed. This implies that * the module calling this has to destroy the cache before getting unloaded. * * The flags are * * %SLAB_POISON - Poison the slab with a known test pattern (a5a5a5a5) * to catch references to uninitialised memory. * * %SLAB_RED_ZONE - Insert `Red' zones around the allocated memory to check * for buffer overruns. * * %SLAB_HWCACHE_ALIGN - Align the objects in this cache to a hardware * cacheline. This can be beneficial if you're counting cycles as closely * as davem. */ struct kmem_cache * kmem_cache_create(const char *name, size_t size, size_t align, unsigned long flags, void (*ctor)(void *)) { ddekit_log(DEBUG_SLAB, "\"%s\" obj_size=%d", name, size); struct kmem_cache *cache; if (!name) { printk("kmem_cache name reqeuired\n"); return 0; } cache = ddekit_simple_malloc(sizeof(*cache)); if (!cache) { printk("No memory for slab cache\n"); return 0; } /* Initialize a physically contiguous cache for kmem */ if (!(cache->ddekit_slab_cache = ddekit_slab_init(size, 1))) { printk("DDEKit slab init failed\n"); ddekit_simple_free(cache); return 0; } cache->name = name; cache->size = size; cache->ctor = ctor; ddekit_lock_init_unlocked(&cache->cache_lock); ddekit_printf("Created cache %p with lock %p\n", cache, &cache->cache_lock); return cache; }