allocating memory

Click here to load reader

Post on 02-Jan-2016




3 download

Embed Size (px)


Allocating Memory. Ted Baker  Andy Wang CIS 4930 / COP 5641. Topics. kmalloc and friends get_free_page and “friends” vmalloc and “friends” Memory usage pitfalls. Linux Memory Manager (1). Page allocator maintains individual pages. Page allocator. Zone allocator. - PowerPoint PPT Presentation


  • Allocating MemoryTed Baker Andy WangCIS 4930 / COP 5641

  • Topicskmalloc and friendsget_free_page and friendsvmalloc and friendsMemory usage pitfalls

  • Linux Memory Manager (1)Page allocator maintains individual pagesPage allocator

  • Linux Memory Manager (2)Zone allocator allocates memory in power-of-two sizesPage allocator

  • Linux Memory Manager (3)Slab allocator groups allocations by sizes to reduce internal memory fragmentationPage allocatorZone allocator

  • kmallocDoes not clear the memoryAllocates consecutive virtual/physical memory pagesOffset by PAGE_OFFSETNo changes to page tablesTries its best to fulfill allocation requestsLarge memory allocations can degrade the system performance significantly

  • The Flags Argumentkmalloc prototype#include void *kmalloc(size_t size, int flags);

    GFP_KERNEL is the most commonly used flagEventually calls __get_free_pages The origin of the GFP prefixCan put the current process to sleep while waiting for a page in low-memory situationsCannot be used in atomic context

  • The Flags ArgumentTo obtain more memoryFlush dirty buffers to diskSwapping out memory from user processesGFP_ATOMIC is called in atomic contextInterrupt handlers, tasklets, and kernel timersDoes not sleepIf the memory is used up, the allocation failsNo flushing and swapping

  • The Flags ArgumentOther flags are availableDefined in GFP_USER allocates user pages; it may sleepGFP_HIGHUSER allocates high memory user pagesGFP_NOIO disallows I/OsGFP_NOFS does not allow making FS callsUsed in file system and virtual memory codeDisallow kmalloc to make recursive calls

  • Priority FlagsUsed in combination with GFP flags (via ORs) __GFP_DMA requests allocation to happen in the DMA-capable memory zone__GFP_HIGHMEM indicates that the allocation may be allocated in high memory__GFP_COLD requests for a page not used for some time (to avoid DMA contention)__GFP_NOWARN disables printk warnings when an allocation cannot be satisfied

  • Priority Flags__GFP_HIGH marks a high priority requestNot for kmalloc__GFP_REPEATTry harder__GFP_NOFAILFailure is not an option (strongly discouraged)__GFP_NORETRYGive up immediately if the requested memory is not available

  • Memory ZonesDMA-capable memoryPlatform dependentFirst 16MB of RAM on the x86 for ISA devicesPCI devices have no such limitNormal memoryHigh memoryPlatform dependent> 32-bit addressable range

  • Memory ZonesIf __GFP_DMA is specifiedAllocation will only search for the DMA zoneIf nothing is specifiedAllocation will search both normal and DMA zonesIf __GFP_HIGHMEM is specifiedAllocation will search all three zones

  • The Size ArgumentKernel manages physical memory in pagesNeeds special management to allocate small memory chunksLinux creates pools of memory objects in predefined fixed sizes (32-byte, 64-byte, 128-byte memory objects)Smallest allocation unit for kmalloc is 32 or 64 bytesLargest portable allocation unit is 128KB

  • Lookaside Caches (Slab Allocator)Nothing to do with TLB or hardware cachingUseful for USB and SCSI driversImproved performanceTo create a cache for a tailored size#include

    kmem_cache_t *kmem_cache_create(const char *name, size_t size, size_t offset, unsigned long flags, void (*constructor) (void *, kmem_cache_t *, unsigned long flags));

  • Lookaside Caches (Slab Allocator)name: memory cache identifierAllocated string without blankssize: allocation unitoffset: starting offset in a page to align memoryMost likely 0

  • Lookaside Caches (Slab Allocator)flags: control how the allocation is doneSLAB_HWCACHE_ALIGNRequires each data object to be aligned to a cache line Good option for frequently accessed objects on SMP machinesPotential fragmentation problemsSLAB_CACHE_DMARequires each object to be allocated in the DMA zoneSee linux/slab.h for other flags

  • Lookaside Caches (Slab Allocator)constructor: initialize newly allocated objectsConstructor may not sleep due to atomic context

  • Lookaside Caches (Slab Allocator)To allocate an memory object from the memory cache, callvoid *kmem_cache_alloc(kmem_cache_t *cache, int flags);cache: the cache created previouslyflags: same flags for kmallocFailure rate is rather highMust check the return valueTo free an memory object, callvoid kmem_cache_free(kmem_cache_t *cache, const void *obj);

  • Lookaside Caches (Slab Allocator)To free a memory cache, callint kmem_cache_destroy(kmem_cache_t *cache);Need to check the return valueFailure indicates memory leakSlab statistics are kept in /proc/slabinfo

  • A scull Based on the Slab Caches: scullcDeclare slab cachekmem_cache_t *scullc_cache;Create a slab cache in the init function/* no constructor */scullc_cache = kmem_cache_create("scullc", scullc_quantum, 0, SLAB_HWCACHE_ALIGN, NULL); if (!scullc_cache) { scullc_cleanup(); return -ENOMEM;}

  • A scull Based on the Slab Caches: scullcTo allocate memory quantaif (!dptr->data[s_pos]) { dptr->data[s_pos] = kmem_cache_alloc(scullc_cache, GFP_KERNEL); if (!dptr->data[s_pos]) goto nomem; memset(dptr->data[s_pos], 0, scullc_quantum);}To release memoryfor (i = 0; i < qset; i++) { if (dptr->data[i]) { kmem_cache_free(scullc_cache, dptr->data[i]); }}

  • A scull Based on the Slab Caches: scullcTo destroy the memory cache at module unload time/* scullc_cleanup: release the cache of our quanta */if (scullc_cache) { kmem_cache_destroy(scullc_cache);}

  • Memory PoolsSimilar to memory cacheReserve a pool of memory to guarantee the success of memory allocationsCan be wastefulTo create a memory pool, call#include

    mempool_t *mempool_create(int min_nr, mempool_alloc_t *alloc_fn, mempool_free_t *free_fn, void *pool_data);

  • Memory Poolsmin_nr is the minimum number of allocation objectsalloc_fn and free_fn are the allocation and freeing functionstypedef void *(mempool_alloc_t)(int gfp_mask, void *pool_data);typedef void (mempool_free_t)(void *element, void *pool_data);pool_data is passed to the allocation and freeing functions

  • Memory PoolsTo allow the slab allocator to handle allocation and deallocation, use predefined functionscache = kmem_cache_create(...);pool = mempool_create(MY_POOL_MINIMUM, mempool_alloc_slab, mempool_free_slab, cache);To allocate and deallocate a memory pool object, callvoid *mempool_alloc(mempool_t *pool, int gfp_mask);void mempool_free(void *element, mempool_t *pool);

  • Memory PoolsTo resize the memory pool, callint mempool_resize(mempool_t *pool, int new_min_nr, int gfp_mask);To deallocate the memory poll, callvoid mempool_destroy(mempool_t *pool);

  • get_free_page and FriendsFor allocating big chunks of memory, it is more efficient to use a page-oriented allocatorTo allocate pages, call/* returns a pointer to a zeroed page */get_zeroed_page(unsigned int flags);

    /* does not clear the page */__get_free_page(unsigned int flags);

    /* allocates multiple physically contiguous pages */ __get_free_pages(unsigned int flags, unsigned int order);

  • get_free_page and FriendsflagsSame as flags for kmallocorder Allocate 2order pages order = 0 for 1 pageorder = 3 for 8 pagesCan use get_order(size)to find out orderMaximum allowed value is about 10 or 11See /proc/buddyinfo statistics

  • get_free_page and FriendsSubject to the same rules as kmallocTo free pages, callvoid free_page(unsigned long addr);void free_pages(unsigned long addr, unsigned long order);Make sure to free the same number of pagesOr the memory map becomes corrupted

  • A scull Using Whole Pages: scullpMemory allocationif (!dptr->data[s_pos]) { dptr->data[s_pos] = (void *) __get_free_pages(GFP_KERNEL, dptr->order); if (!dptr->data[s_pos]) goto nomem; memset(dptr->data[s_pos], 0, PAGE_SIZE order);}Memory deallocationfor (i = 0; i < qset; i++) { if (dptr->data[i]) { free_pages((unsigned long) (dptr->data[i]), dptr->order); }}

  • The alloc_pages InterfaceCore Linux page allocator functionstruct page *alloc_pages_node(int nid, unsigned int flags, unsigned int order);nid: NUMA node IDTwo higher level macrosstruct page *alloc_pages(unsigned int flags, unsigned int order);struct page *alloc_page(unsigned int flags);Allocate memory on the current NUMA node

  • The alloc_pages InterfaceTo release pages, call

    void __free_page(struct page *page);void __free_pages(struct page *page, unsigned int order);

    /* optimized calls for cache-resident or non-cache-resident pages */void free_hot_page(struct page *page);void free_cold_page(struct page *page);

  • vmalloc and FriendsAllocates a virtually contiguous memory regionNot consecutive pages in physical memoryEach page retrieved with a separate alloc_page callLess efficientCan sleep (cannot be used in atomic context)Returns 0 on error, or a pointer to the allocated memory Its use is discouraged

  • vmalloc and Friendsvmalloc-related prototypes#include

    void *vmalloc(unsigned long size);void vfree(void *addr);

    #include void *ioremap(unsigned long offset, unsigned long size);void iounmap(void *addr);

  • vmalloc and FriendsEach allocation via vmalloc involves setting up and modifying page tablesReturn address range between VMALLOC_START and VMALLOC_END (defined in )Used for allocati