1 Memory Management April, 216 Dept. of software Dankook University http://embedded.dankook.ac.kr/~baeksj
Program, Process & Virtual Address 2 32bit 64bit 4GB 3GB stack 16EB 128TB Kernel Space heap User Space data text B B
가상주소확인 C 프로그램에서본태스크이미지 : 주소출력 #include <stdlib.h> int glob1, glob2; int func2() { int f2_local1, f2_local2; printf("func2 local: n t%p, n t%p n", &f2_local1, &f2_local2); } int func1() { int f1_local1, f1_local2; printf("func1 local: n t%p, n t%p n", &f1_local1, &f1_local2); func2(); } main() { int m_local1, m_local2; int *dynamic_addr; printf("main local: n t%p, n t%p n", &m_local1, &m_local2); func1(); dynamic_addr = malloc(16); printf("dynamic: n t%p n", dynamic_addr); printf("global: n t%p, n t%p n", &glob2, &glob1); printf("functions: n t%p, n t%p, n t%p n", main, func1, func2); } 3
가상주소확인결과 4 C 프로그램에서본태스크이미지 : 주소출력결과 xbfffec14 xbfffec1 xbfffebf4 xbfffebf xbfffebe4 xbfffebe stack for main stack for func1 stack for func2 x8496c8 x849674 x84967 x8483a1 x84837c x84835c heap data text for main text for func1 text for func2
가상메모리관리구조 5 Linux 커널에서가상메모리구조 xffffffff xc env_end arg_end arg_start start_stack end_bss end_data end_code start_code kernel stack bss data text bss data text shared memory other shared library shared C library x brk end_data end_code start_code bss data text program (Source : Linux kernel Internals)
메모리관리기법 6 물리메모리관리 할당 / 해제기법 가상메모리관리 할당 / 해제기법 물리메모리와가상메모리 연결혹은변환기법
Memory Model(1/2) 7 Bus UMA Bus NUMA (Source : Unix Internals)
Memory Model(2/2) 8 Hybrid NUMA NORMA (Source : Unix Internals)
9
Bank and Node 1 UMA Bus Bus Bank Bank NUMA Bank struct pglist_data contig_page_data Node struct pglist_data *pgdat_list[ ] typedef struct pglist_data { struct zone node_zones[max_nr_zones]; struct zonelist node_zonelists[gfp_zonetypes]; int nr_zones; struct page *node_mem_map; struct bootmem_data *bdata; unsigned long node_start_pfn; unsigned long node_present_pages; unsigned long node_spanned_pages; int node_id; wait_queue_head_t kswapd_wait; wait_queue_head_t } pg_data_t; pfmemalloc_wait;
NODE 자료구조 11 typedef struct pglist_data{ zone_t node_zones[max_nr_zones]; // node 를위한 zone 은 ZONE_HIGHMEM, ZONE_NORMAL, ZONE_DMA 3 개이다. // 각 zone 을가리키기위한배열임 zonelist_t node_zonelists[gfp_zonemask+1]; // ((xf=15)+1=16) 할당시에우선시되는 zone 순서를나타냄 // free_area_init_core() 에의해 // mm/page_alloc.c 내의 build_zonelists() 가호출되면이순서를정렬해놓는다 int nr_zones; // 이 node 에몇개의 zone 이있는지나타내는 1~3 사이의값. // 예를들어어떤 CPU 는 ZONE_DMA 에해당되는메모리영역이없을수도있으므로항상 3 은아니다 struct page *node_mem_map; // node 의각 physical frame 을나타내는 struct page 배열의첫번째 page 임. // 이는전역배열인 mem_map 의어딘가에들어갈것이다 unsigned long *valid_addr_bitmap; // memory node 상에서, 실제로존재하지않는 'holes' 를나타내기위한 BITMAP // 사실상, Sparc 과 Sparc64 에서만사용되며다른 arch 에선무시됨 struct bootmem_data *bdata // boot memory allocator 가사용하는필드 unsigned long node_start_paddr; // node 의 physical 한시작주소 // unsigned long 은 PAE(physical Address Extension) 을사용하는 IA32 나 // PPC44GP 같은 PowerPC 의변종들에선최적화되어작동하지않는다 // 좀더나은방법은 PFN(Page Frame Number) 를기록하는것이다. // PFN 은간단히말해서 page-size 단위로계산되는 physical memory 의 index 이다 // PFN 은보통 (page_phys_addr >> PAGE_SHIFT) 로정의된다. unsigned long node_start_mapnr; // mem_map 내에서의 page offset 을나타냄 // 이숫자는,mem_map 과 lmem_map 이라고불리는 local mem_map 사이의 page 갯수를계산하는, // free_area_init_core() 에서계산됨 unsigned long node_size; // 이 node 내의총 page 수 int node_id; // 에서시작되는 Node ID(NID) struct pglist_data *node_next; // NULL 로끝나도록되어있는, 다음 node 를가리키는 pointer }pg_data_t;
NODE 자료구조확인 12 xa 실험을진행하고있는보드의물리메모리시작주소
Node and Zone 13 ZONE_DM ZONE_NOR A MAL ZONE_DM X86 System 에서는 A32 896M end Node ZONE_MOVA BLE ZONE ZONE ZONE ZONE ZONE_HIGHM EM ZONE_DMA, 32 ~ 16M ZONE_NORMAL 16 ~ ZONE_HIGHMEM 896 ~ struct zone { unsigned long watermark[nr_wmark]; unsigned long lowmem_reserve[max_nr_zones]; unsigned long dirty_balance_reserve; int node; unsigned long min_unmapped_pages; unsigned long min_slab_pages; spinlock_t lock; struct free_area free_area[max_order]; spinlock_t lru_lock; struct lruvec lruvec; atomic_long_t inactive_age; unsigned long pages_scanned; unsigned long flags; atomic_long_t vm_stat[nr_vm_zone_stat_items]; unsigned int inactive_ratio; wait_queue_head_t * wait_table; unsigned long wait_table_hash_nr_entries; unsigned long wait_table_bits; struct per_cpu_pageset *pageset; struct pglist_data *zone_pgdat; struct page *zone_mem_map; unsigned long zone_start_pfn; char *name; unsigned long spanned_pages; unsigned long present_pages; }
Kernel Address Space(1/13) 14 Physical Address S/W CPU Data
Kernel Address Space(2/13) 15 Physical Address Linux CPU Data
Kernel Address Space(3/13) 16 Physical Address Linux CPU Data 1M Physical Memory Linux zimage 1G
Kernel Address Space(4/13) 17 Physical Address Linux CPU Data 4G Virtual Address Space 1G Physical Memory 1M Linux zimage
Kernel Address Space(5/13) 18 Physical Address Linux CPU Data 4G Virtual Address Space 1G Physical Memory Kernel 이사용 3G User APP 가사용 1M Linux zimage
Kernel Address Space(6/13) 19 Physical Address Linux CPU Data 4G Virtual Address Space 1G Physical Memory 3G 1M Linux zimage
Kernel Address Space(7/13) 2 Physical Address Linux CPU Data 4G Virtual Address Space 1G Physical Memory Paging 3G 1M Linux zimage
Kernel Address Space(8/13) 21 Physical Address Linux CPU Data 4G Virtual Address Space 1G Physical Memory 3G 1M Linux zimage
Kernel Address Space(9/13) 22 Physical Address Linux CPU Data 4G Virtual Address Space 1G Physical Memory 3G Kernel have no mm_struct! 1M Linux zimage
Kernel Address Space(1/13) 23 Physical Address Linux CPU Data 4G Virtual Address Space 1G Physical Memory Kernel 을위한 Page Global Directory 즉, Master Kernel Page Global Directory 3G swapper_pg_dir 1M Linux zimage
Kernel Address Space(11/13) 24 Physical Address Linux CPU Data 4G Virtual Address Space 1G Physical Memory 이제 Kernel 도 Physical Memory 에접근할수있게되었습니다. Linux Kernel 은 OS 입니다. 모든 Physical Memory 에접근해야합니다. 3G 1M Linux zimage
Kernel Address Space(12/13) 25 Physical Address Linux CPU Data 4G Virtual Address Space 1G Physical Memory 1:1 매핑은어떨까요? 문제점은? 3G 1M Linux zimage
Kernel Address Space(13/13) 26 Physical Address Linux CPU Data 4G Virtual Address Space 1G Physical Memory 896M 896M 까지만 1:1 매핑하고 그이상의메모리는임시로매핑하여사용 3G 1M Linux zimage
ZONE 자료구조 27 typedef struct zone_struct{ spinlock_t }zone_t; lock; //concurrent 한접근으로부터 zone 을보호하는 spinlock unsigned long free_pages; // 현재 zone내의 free page들의총개수 unsigned long pages_min, pages_los, pages_high; //zone watermarks int need_balance; // 이플래그는zone의균형을유지하기위해 kswapd 에게 pageout요청을하는데사용되는 flag이다 free_area_t free_area[mar_order]; //buddy allocator이사용하는 free area bitmaps wait_queue_head_t *wait_table; // Process들이 page가 free되기를기다릴때사용되는 wait queues의 hash table이다 // 이는 wait_on_page() 와 unlock_page() 에서매우중요하다 // 물론 process들은한개의 queue에서대기할수도있지만, 이렇게하게된다면 // wake up 하게되는때에, 모든 process들은 lock걸리기전까지는 page를얻기위해경쟁하게된다 // 이렇게공유자원을얻기위해다투는프로세스들의큰그룹을 // Thundering herd라고부른다. // (thundering herd : 여러프로세스가깨어나서, 이중, 하나만사용할수있는자원을차지하려고경쟁하고, // 나머지프로세스는다시잠든상태로돌아가는상황 ) unsigned long wait_table_size; //hash table 내의 queue 개수를결정하는, 2 의제곱의수 unsigned long wait_table_shift; // 위에정의된 table size를계산하는데사용되는이진비트조합 struct pglist_data *zone_pgdat; // 부모 pg_data_t를가리키는 pointer struct page *zone_mem_map; // 현재 zone 이참조하게되는전역배열 mem_map 내의첫번째 page unsigned long zone_start_paddr; //node_start_paddr과유사하게사용됨 unsigned long zone_start_mapnr; //node_start_mapnr과유사하게사용됨 char *name; //ZONE 을나타내는 'DMA', 'NORMAL', 'HIGHMEM' 중하나의문자열 unsigned long size; // page 단위로표현되는 zone 의크기
ZONE 의 watermarks 28 Zone Watermarks
Watermarks 계산 29 Zone Watermarks page_low, pages_min, pages_high 보통 pages_low = pages_min * 2 pages_high = pages_min * 3 pages_min 필드는 free_area_init_core() 함수내에서계산됨 보통 (ZoneSizeInPages / 128)
ZONE 과 PageFrame 3 Page frame Page frame Page frame Page frame Page frame Page frame ZONE Page frame Page frame Page frame Page frame Page frame Page frame Page frame Page frame 각 NODE 의모든 page 구조체는보통 ZONE_NORMAL 의시작부분 ( 혹은커널이올라오기위해예약해놓은메모리바로다음 ) 위치에있는전역배열인 mem_map 에유지된다 Page frame struct page { page_flags_t flags; union { struct address_space *mapping; void *s_mem; } struct { union { pgoff_t index; void *freelist; bool pfmemalloc }; union{ } } union { struct list_head lru; struct { struct page *next; int pages; pobjects; } struct slab *slab_page; struct rcu_head rcu_head; } #if defined(want_page_virtual) void *virtual; #endif /* WANT_PAGE_VIRTUAL */ };
Page Frame 자료구조 31 typedef struct page{ struct list_head list; // page는많은list에속해있을수있고, 이필드는list head를위해사용된다. // 예를들어, mapping되어있는 page는 address_space에의해관리되는세개의원형링크드리스트중하나에속해있을것이다. // 이세개의원형링크드리스트는 clean_pages, dirty_pages, locked_pages이다. // slab allocator에서이필드는슬랩할당자에의해할당되었을때 page를관리하기위해 // slab이나 cache structures로의포인터를저장하는역할을한다. // 또한 free pages의 link blocks 에서도사용된다. struct address_space *mapping // 파일이나 device가 memory mapped되어있을때, 그들의 inode는 address_space와연결되어있다. // 만약이 page가파일에연결되어있다면이필드는 address space를가리킨다. // 만약 page가 anonymous이며 mapping이 set되어있다면, // address_space는 swap address space를관리하는swapper_space이다. unsigned long index; // 이필드는두가지용도를가지며, 이는 page의 state가결정한다. // 만약이 page가 file mapping의일부라면이는 file내의 offset이다 // 만약이 page가 swap cache의일부라면이는swap address space(swapper_space) 를위한address_space내의 offset이됨 // 둘째, 만약 page들의블록이특정 process를위해free되었다면 // 블록내에서의순서가저장될것이다. 이는 free_pages_ok() 함수내에서 set 된다 struct page *next_hash; // 파일매핑의일부인 page는 inode와 offset에의해hash된다. // 이필드는같은hash bucket을공유하는페이지들을 link시켜주는필드이다.
Page Frame 자료구조 32 atomic_t count; // page의참조횟수이다. 만약 이되면이페이지는 free될것이다. // 그보다크다면, 하나이상의프로세스에서사용중이거나, // I/O를기다리기위한작업등으로인해커널내에서사용중임을나타낸다. unsigned long flags; // page의상태를나타내는flags이다. 이는 <linux/mm.h> 내에모두정의되어있고, 표 2.1에나열해놓았다. // bit를 test, clear, set하기위한여러개의매크로가정의되어있으며, 이를표 2.2에보였다. // 사실유일하게관심있는함수는아키텍쳐에의존적인함수인 arch_set_page_uptodate() 를 call하는setpageuptodate() 이다. struct list_head lru; // page 교체정책을위해, 교체되어나갈 page는 // page_alloc.c내에정의되어있는 active_list나 inactive_list 둘중하나에존재해야한다. // 이필드는이러한LRU리스트의 list head를가리키게된다. struct page **pprev_hash; // next_hash의보완책인이필드로인해 hash는 doubly lonked list로동작할수있다. struct buffer_head *buffers; // 만약 page가연결되어있는block device를위한buffer를가지고있다면 // buffer_head에대한정보를유지하기위해사용된다. // 만약 (it is backed by a swap file) 이면프로세스에의해 mapped된 anonymous page인경우엔 // 연결되어있는 buffer_head 를가리킬수도있다. // 이때 page는, 속해있는파일시스템에서정하는 block size단위로, // 저장장치로저장되는 sync작업이일어나야하므로필요하다. #if defined (CONFIG_HIGHMEM) defined(waant_page_virtual) void *virtual; // 일반적으로는 ZONE_NORMAL에속해있는 page만이커널에의해직접지정이가능하다 // ZONE_HIGHMEM zone내에있는 page를주소지정하기위해kmap() 함수가사용되며 // 이함수는page를 kernel과 map시켜주는역할을한다.(9장에서논의됨 ) // 고정된개수의 page만이 map 될수있다. 만약 page가 map 되었다면, 이필드는page의가상주소를나타낸다. #endif /*CONFIG_HIGHMEM WANT_PAGE_VIRTUAL */ }mem_map_t;
ZONE wait queue 33 Process A Want to Use Page wate_on_page() wate_on_page() UnlockPage() unlock_page() Wait Queue ZONE Page frame Page frame Page frame Page frame Page frame Page frame Page frame Page frame Page frame Page frame Page frame Page frame Page frame Page Page frame frame
Buddy Allocator 34 To reduce external fragmentation Fast allocation and de-allocation of pages 연속적인 page( block ) 단위별로관리 1, 2, 4, 8.. pages each one block
free_area_t 구조체 35 /* ~/include/linux/mmzone.h #define MAX_ORDER 1 typedef struct zone_struct { free_area_t free_area[max_order]; } zone_t; typedef struct free_area_struct { struct list_head unsigned long }free_area_t; free_list; *map;
Data structure 36 free_area.[order].free_list 특정크기의 free page block 들의이중연결리스트 free_area.[order].map ((number of pages) -1 ) >> (order + 4)) + 1bytes 한비트가하나의버디의상태를나타낸다
Memory allocation 37 15 14. 2 page 요청 alloc 13. free 12 4 11 3 1 2 12 9 8 1 8 5 1 7 6 5 free_area.free_list free_area[order].map 4 3 2 1 Physical Memory Pages order() order(1) order(2) order(3) 1 2 3 4 5 6 7 8 9 1 11 12 13 14 15 1 1 1-> 1
Memory allocation 38 15 14. 2 page 요청 alloc 13. free 12 4 11 3 1 2 12 9 14 1 8 5 1 7 6 5 free_area.free_list free_area[order].map 4 3 2 1 Physical Memory Pages order() order(1) order(2) order(3) 1 2 3 4 5 6 7 8 9 1 11 12 13 14 15 1 1 -> 1 1 ->
Memory de-allocation 39 15 14. 11 번 page 해제요청 alloc 13 12. 4 index = page_idx >> (order + 1) => 11 >> ( + 1 ) = 5 free 11 8 3 1 2 12 9 8 1 8 7 6 5 free_area.free_list 5 1 free_area[order].map index >>= 1 4 3 2 1 Physical Memory Pages order() order(1) order(2) order(3) 1 2 3 4 5 6 7 8 9 1 11 12 13 14 15 1 1-> 1 -> 1-> -> 1
Buddy 관련함수 4
Slab Allocator 41 슬랩할당자 버디알고리즘은적은메모리할당엔부적절 같은크기의메모리공간에대한할당을반복하는경향있으므로캐시개념도입 캐시 : 객체의모음 같은크기메모리공간의창고슬랩 : 캐시가들어있는주메모리영역을나눈것 (/proc/slabinfo) 연속된 PF하나이상으로구성됨 할당한객체와여유객체를모두포함 빈슬랩의 PF스스로해제안함
Slab Allocator 구조 42 kmem_cache cache_cache cache cache cache kmem_cache_node slabs_full slabs_free slabs_partial slab slab slab slab (full) (full) (full) slab (free) slab (partial) slab (partial) object object
슬랩관련함수 43
GFP_MASK 44
가상주소공간할당 / 해제 45 일부가상주소공간 = region = 영역 = 구간 = vm_area_struct 메모리구역겹치는일은없음 인접한두구역은접근권한일치시합침
Creating a memory region ex. 46 case 1 arch_get_unmapped_area if addr!= null if addr + len < vma->start VMA. 1G next len addr VMA next VMA. 3G
Creating a memory region ex. 47 case 2 addr!= null addr + len > vma->start OR addr == null VMA. 1G next len addr VMA next VMA return ENOMEM If last vm_end + len > 3G len. addr 3G
Creating a memory region ex. 48 do_mmap_pgoff. 1G VMA next next new VMA len addr next VMA next VMA. 3G
Merging contiguous region 49 do_mmap_pgoff merge-able. 1G VMA next len addr next VMA next VMA. 3G
Remapping and Moving a memory region 5 do_mmap_pgoff memory region growing or shrink find another region VMA. 1G next next VMA VMA len new VMA. 3G
Delete a memory region 51 do_munmap. 1G VMA next VMA next VMA. 3G
Delete a memory region 52 do_munmap. 1G VMA next VMA next next next new VMA VMA. 3G
간단한 ELF 구조 53 test.c 의컴파일결과 : ELF format gcc test.c e_ident e_type e_machine e_phnum e_flags ELF header phdr 1 phdr 2. phdr n Section 1 Section 2. Section n p_flags p_offset p_vaddr p_filesz p_memsz p_types a.out : (ELF format) /*include/linux/elf.h */
가상메모리와 ELF 파일 54 가상메모리와 ELF format 의대응 disk virtual memory a.out 4 GB kernel kernel stack text ELF header phdrs 3 GB stack kernel data kernel text data 28 KB data stack 12 KB KB text page
가상메모리와태스크실행 55 페이지시스템 : 태스크로딩 ( execve() ) test.exe 라는프로그램을수행시킨다고가정 (ELF format) 이응용의 text 는 12KB, data 는 8KB, 초기 stack 은 4KB 로가정 이응용은 malloc 을사용하지않음 커널 test.exe stack data inode Disk t1 t3 t2 d1 d2 t1 t2 d1 pf5 pf3 pf2 text virtual memory test.exe 가수행되려면디스크에서메모리로이동되어야함 physical memory
태스크와페이지테이블 56 페이지시스템 : 주소변환 디스크내용을물리메모리에로딩 (loading) 하면서위치정보기록 page page frame t1 pf3 t2 pf5 t3 - d1 pf2 d2 - s1 pf6 Page table t1 s1 t2 d1 pf6 pf5 pf3 pf2 physical memory 태스크자료구조 (task struct) 에서 page table 을관리 : 메모리문맥 위의구조에서프로그램이가상주소 1 번지에접근하면메모리어디에접근하는가? 가상주소 5 번지에접근하면? 또한가상주소 9 에접근하면?
페이지폴트 57 페이지시스템 : 페이지부재결함 페이지프레임에존재하지않는페이지를접근할때 task struct t1 pf3 t2 pf5 t3 pf4 - d1 pf2 d2 - s1 pf6 Page table test.exe t1 s1 t2 t3 d1 physical memory pf6 pf5 pf4 pf3 pf2 inode Disk t3 t1 t2 d1 d2
Linux 의 Page Table Management 전체구조 58
Linux 의 PGD 59 task_struct mm mm_struct pgd include/asm-i386/page.h <<pgd_t>> typedef struct { unsigned long long pgd; } pgd_t; include/asm-arm/page.h <<pgd_t>> typedef unsigned long pgd_t; Page Frame Array of pgd_t type Physical Memory pgd 로딩? X86 이라면 mm->pgd 를 cr3 에복사함으로써이뤄짐 flush_tlb() (cr3 복사는 TLB flushing 을유발하는단점이있음 )
task_struct mm Linux 의 PGD, PMD, PTE mm_struct pgd 6 Physical Memory Page Frame Page Frame Page Frame Page Frame Page Frame pud_t pgd_t pmd_t pte_t pud_t pgd_t pmd_t pte_t pud_t pgd_t pmd_t pte_t pud_t pgd_t pmd_t pte_t pud_t PUD pgd_t pmd_t pte_t PGD PMD PTE Swap out 된경우에는? Swap entry 가 PTE 에저장되어있음 Fault 맞으면이 swap entry 를이용해 do_swap_page() 함수가 page 를처리해줌
주소변환을위한매크로 61
주소변환과정의이해 62 /* mm/memory.c */ static struct page * follow_page(struct vm_area_struct *vma, unsigned long address, unsigned int flags, unsigned int *page_mask) { pgd_t *pgd; pud_t *pud; pmd_t *pmd; pte_t *ptep, pte; pgd = pgd_offset(mm, address); if( pgd_none(*pgd) pgd_bad(*pgd)) pud = pud_offset(pgd, address); if( pud_nond(*pud) ) pmd = pmd_offset(pgd, address); if( pmd_none(*pmd) pmd_bad(*pmd)) goto out; goto out; goto out; } return follow_page_pte(vma, address, pmd, flags);
태스크와가상주소공간 63 태스크의메모리관리전체구조 (global view) task_struct mm mm_struct map_count pgd mmap vm_area_struct vm_end vm_start vm_flags vm_file vm_offset vm_ops vm_next 가상메모리공간 vm area (data or parts of data) vm_area_struct vm_end vm_start vm_flags vm_file vm_offset vm_ops vm_next vm_area (text)
mm_struct 와가상주소공간구조 64 mm_struct 자료구조분석 include/linux/mm_types.h struct mm_struct { struct vm_area_struct *mmap; struct rb_root mm_rb; struct vm_area_struct *mmap_cache; atomic_t mm_users, mm_count pgd_t *pgd; int map_count; struct semaphore mmap_sem; mm_context_t context; unsigned long start_code, end_code, start_data; unsigned long end_data, start_brk, brk, start_stack; unsigned long arg_start, arg_end, env_start, env_end; unsigned long total_vm, locked_vm, def_flags; } include/x86/include/asm/pgtable_types.h typedef struct {pgdval_t pgd;} pgd_t; env_end arg_end arg_start start_stack brk end_data end_code start_code include/x86/asm/pgtable_64_types.h typedef struct {pgdval_t pgd;} pgd_t; kernel stack bss data text xffffffff xc x
vm_area_struct 자료구조 65 vm_area_struct 자료구조분석 include/linux/mm.h struct vm_area_struct { struct mm_struct *vm_mm; unsigned long vm_start, vm_end; struct vm_area_struct *vm_next pgprot_t vm_page_prot; unsigned short vm_flags; short vm_avl_height; struct vm_area_struct *vm_avl_left; struct vm_area_struct *vm_avl_right; struct vm_area_struct *vm_next_share; struct vm_operations_struct *vm_ops; unsigned long vm_offset; struct file *vm_file; unsigned long vm_pte; /* for SVR4 SM */ } Virtual Memory Area PAGE_SHARED (COPY, READONLY, KERNEL) open(vm_area) close(vm_area) do_mmap(file, addr, len, prot, flags, off) unmap() protect() nopage() wppage() swapout() swapin()
Memory Region 66 task_struct mm mm_struct pgd mmap vm_area_struct vm_end vm_start vm_prot vm_flags vm_next shared libraries pgd: page directory address vm_prot: read/write permissions for this area vm_flags shared with other processes or private to this process vm_end vm_start vm_prot vm_flags vm_next vm_end vm_start vm_prot vm_flags vm_next data text
2.6.11 부터도입된 4 단계페이징 (x86_64 기준 ) 67 64bit address translation 4-level translation 63 48 47 39 38 3 29 21 2 12 11 Sign Extended PML4 Directory Ptr Directory Table Offset PML4 Page-Directory- Pointer Table Page-Directory Page-Table Physical-Address entry entry entry entry 4K Page ( In Physical Memory ) CR3 (PML4) 512 PML4 * 512 PDPTE * 512 PDE * 512 PTE = 2 36 Page frames (256TB)
커널의가상주소사용 (32bit 처리기기준 ) 68 Kernel address space( 32bit ) Virtual Memory 1MB 8MB 16MB 896MB 124MB Dynamically allocated VM_RESERVE (128M) Physical Memory BIOS comm area kernel code image DMA region mem_map
커널의가상주소사용 (64bit 처리기기준 ) 69 xffff ffff ffff ffff xffff ffff fff xffff ffff 88 xffff ffff 828 xffff ffff 8 xffff e2 xffff c2 xffff c1 xffff 81 xffff 8 x 7fff ffff ffff x module mapping space (1919MB) unused hole kernel text mapping (4MB) unused hole ioremap space (32TB) hole (1 TB) direct mapping space (64TB) guard hole. stack heap data text 가상메모리 kernel space user space
Linux 커널메모리관리함수 7 Interface struct page * alloc_pages(unsigned int gfp_mask, unsigned int order) 2^order 크기의연속된물리적페이지들을할당후, 첫페이지의 page 구조체포인터를리턴 void * page_address(struct page *page) 매개변수로넘긴물리적페이지가현재포함돼있는논리적주소에대한포인터반환 Wrapping Function Page-level allocator : get_free_page() 요청된만큼의연속된메모리를할당 Kernel-level allocator 물리적으로연속하며, 128KB 이하임의길의의메모리할당 : kmalloc() 물리적으로비연속적인메모리할당 : vmalloc() Non-Contiguous Allocation Contiguous Allocation Slab Allocator Page-level Allocation Buddy System
VFS inode object Page Cache 관리자료구조 /* ~/include/linux/fs.h */ struct inode { struct address_space *i_mapping; struct address_space i_data; }; inode 구조체가저장되어있는 page owner 의 address_space 구조체를가리킴 /* ~/include/linux/fs.h */ struct address_space { struct inode *host; const struct address_space_operations *a_ops; struct radix_tree_root page_tree; }; 71 Radix tree /* ~/lib/radix-tree.c */ struct radix_tree_node { unsigned int height; unsigned int count; struct rcu_head rcu_head; void *slots[radix_tree_map_size]; unsigned long tags[radix_tree_max_tags][radix_tree_tag_longs]; }; /* ~/lib/radix-tree.c */ struct radix_tree_root { unsigned int height; gfp_t gfp_mask; struct radix_tree_node *rnode; }; Memory /* ~/include/linux/mm_types.h */ struct page { union { struct { unsigned long private; struct address_space *mapping; }; }; union{ pgoff_t index; void *freelist; }; }; page(4kb) 1KB 1KB 1KB 1KB /* ~/include/linux/buffer_head.h */ struct buffer_head { struct buffer_head *b_this_page; struct page *b_page; char *b_data; }; struct buffer_head struct buffer_head struct buffer_head Owner 의 view 에서페이지크기단위의 offset
Page Cache related Interfaces 72 Radix Tree find_get_page(); add_to_page_cache(); remove_from_page_cache(); read_cache_page(); // 메모리상의내용을최신으로유지 Buffer Head grow_buffers(); try_to_release_page(); find_get_block(); // 찾는내용이없으면 NULL return get_blk(); // 찾는내용이없으면이를위한자료구조만들고 return bread(); // 찾는내용이없으면이를위한자료구조만들고필요시 I/O 수행
Page Cache Reclaim 73 When? The page cache gets too full and more pages are needed Too many dirty pages Too much time has elapsed since a page has stayed dirty The flush request are invoked Parameters Dirty background threshold 보통약 4%(/proc/sys/vm/dirty_ration) Dirty writeback centisecs 보통 5 Pdflush daemon Evicting background_writeout() Flush 대상 dirty page 주기적인탐색 wb_kupdate() 너무오래된 dirty 탐색 submit_bh(); suber_block 은 5 초 일반 data page 는 3 초 ll_rw_block(); // 불연속블록에대한 I/O 처리