01 July 2009

Linux Kernel Memory - 1

The code and data portion of every program should be loaded to physical memory before execution. Virtual memory technique enables operating system to execute a program which is larger than the physical memory.

The binary addresses that the processor issues for either instructions or data are called virtual or logical addresses. These addresses are translated to physical addresses by a combination of hardware and software components. And the special hardware is called MMU.

Information about the main memory location of each page is kept in a page table. Though MMU is implemented in hardware, page table is kept in main memory because of its large size. For faster access a small portion page table is kept in a small cache called TLB.

Address translation proceeds as follows:
Given a virtual address, the MMU looks in the TLB for the reference page.
-> If the page table entry for this page is found in the TLB, the physical address is obtained immediately.
-> If there is a miss the TLB, then the required entry is obtained from the page table in the main memory, and the TLB is updated.

The kernel treats physical pages as the basic unit of memory management.
In terms of virtual memory, pages are the smallest.

Possible owners of pages include user-space process, dynamically allocated kernel data, static kernel code, the page cache, and so on.

The kernel uses zones to group pages of similar properties.
ZONE_DMA DMA-able pages < 16MB
ZONE_NORMAL Normal addressable pages 16-896MB
ZONE_HIGHMEM Dynamically mapped pages > 896MB

alloc_page(gpf_mask) -> allocate from high memory, returns struct page.
kmap(*page) -> to map high memory into the kernel's logical address space.
get_free_page(gfp_mask)
get_zeroed_page(gfp_mask)
free_page(addr)

kmalloc returns logical address,,, but its physically and virtually contiguous.
vmalloc returns logical address,,, but its only virtually contiguous.

kmalloc(size, flags) -> it’s the simple interface to obtain kernel memory in byte-sized chunks. The region of memory allocated is physically contiguous.
Process context, can sleep      GFP_KERNEL
Process context, cannot sleep GFP_ATOMIC (from emergency pool)
Interrupt handler GFP_ATOMIC
Bottom half GFP_ATOMIC
Need DMA,can sleep GFP_DMA | GFP_KERNEL
Need DMA,cannot sleep GFP_DMA | GFP_ATOMIC

vmalloc(size) -> it allocates memory that is only virtually contiguous and not necessarily physically contiguous. Its does this by allocating potentially noncontiguous chunks of physical memory and “fixing up” the page tables to map the memory into a contiguous chunk of the logical address space.

Why kmalloc is used more than vmalloc?
-> The vmalloc() function must specifically set up the page table entries.
-> Page obtained via vmalloc() cause greater TLB trashing than when using directly mapped memory.
-> vmalloc() is used when modules are dynamically inserted into the kernel.

Slab Layer:
Thw slab layer divides different objects into groups called caches, each of which stores a different type of object. There is one cache per object type.

cache(DATA STRUCT) -> slabs(PAGES) -> objects(STRUCT)

Caches are created at system startup for process descriptor, inode, etc. The kmalloc() interface is built on top of the slab layer using a family of general purpose caches.

kmem_cache_create(name. size, offset, size, ctor, dtor) -> mm_cachep, task_struct_cachep, inode_cachep, etc
kmem_getpages(cachep, flags) -> slabs
kmem_cahe_alloc(cachep, flags) -> objects

Most 32-it architectures have 4KB pages.
And most 64-bit architectures have 8KB pages.
kernel stack for 32-bit architecture 8KB.
kernel stack for 64-bit architecture 16KB.

Reference:
Linux Kernel Development - Robert Love

No comments:

Post a Comment