12장 Memory Management 15.06.29 CSLAB Park Se Won.

Slides:



Advertisements
Similar presentations
UNIX 운영 체제의 설계 - Chapter 4. 파일의 내부 표현
Advertisements

Chapter 7. Getting Hold of Memory
리눅스 커널의 이해 중에서 6장. 메모리 관리 김영재 데이터베이스 실험실.
ㅎㅎ 구조체 구조체 사용하기 함수 매개변수로서의 구조체 구조체 포인터와 레퍼런스 구조체 배열.
제14장 동적 메모리.
공유메모리 int shmget(key_t key, size_t size, int permflags);
연결리스트(linked list).
제 9 장 구조체와 공용체.
24 장 TCP/IP 24.1 개요 24.2 네트워크층 24.3 주소 지정 24.4 서브넷팅틍
08. 디바이스 드라이버의 읽기와 쓰기 김진홍
자료 구조: Chapter 3 (2)구조체, 포인터
윤성우의 열혈 C 프로그래밍 윤성우 저 열혈강의 C 프로그래밍 개정판 Chapter 12. 포인터의 이해.
제15장 파일 입출력 문자열을 출력하는 여러가지 방법 (15-2쪽) 문자열만 처리하는 입출력 함수
Unix Project2 <test character device 생성>
제 6장. 생성자와 소멸자 학기 프로그래밍언어및실습 (C++).
쉽게 풀어쓴 C언어 Express 제17장 동적메모리와 연결리스트 C Express Slide 1 (of 13)
UNIT 07 Memory Map 로봇 SW 교육원 조용수.
리눅스 커널의 이해 중에서 16장 스와핑 : 메모리 해제 방법 최성자 소프트웨어공학 실험실.
5장. 참조 타입.
제 3장. C보다 나은 C++ II.
07. 디바이스 드라이버의 초기화와 종료 김진홍
Dynamic Memory and Linked List
11장. 포인터 01_ 포인터의 기본 02_ 포인터와 Const.
SqlParameter 클래스 선문 비트 18기 발표자 : 박성한.
23장. 구조체와 사용자 정의 자료형 2.
DK-128 실습 EEPROM 제어 아이티즌 기술연구소
자료구조: CHAP 4 리스트 (3) 순천향대학교 컴퓨터공학과 하 상 호.
프로그래밍 랩 – 7주 리스트.
MicroC/OS-II 3. Memory Management ITISN Technical Lab.
14장. 포인터와 함수에 대한 이해.
PySpark Review 박영택.
10장. 예외처리.
모듈 초기화 module_init(hello_init); module_exit(hello_exit);
11장. 1차원 배열.
JA A V W. 03.
Cache Manager Yonghyun Kim Microsoft MVP Dev 5 team leader, ESTsoft
인터넷응용프로그래밍 JavaScript(Intro).
13. 포인터와 배열! 함께 이해하기 IT응용시스템공학과 김 형 진 교수.
UNIT 07 Memory Map 로봇 SW 교육원 조용수.
메모리 관리 & 동적 할당.
Quiz #7 다음 수들을 합병 정렬과 퀵 정렬 알고리즘을 이용하여 오름 차순으로 정렬하였을 때, 데이터 이동 회수를 각각 구하라. 여러분은 정렬 과정을 단계별로 보이면서 이동 회수를 추적해야 한다. 단, 퀵 정렬시에 피봇으로 배열의 왼쪽 첫 번째 원소를 선택한다. 5.
24장. 파일 입출력.
쉽게 풀어쓴 C언어 Express 제14장 포인터 활용 C Express Slide 1 (of 22)
Chapter6 : JVM과 메모리 6.1 JVM의 구조와 메모리 모델 6.2 프로그램 실행과 메모리 6.3 객체생성과 메모리
DK-128 실습 내부 EEPROM 제어 아이티즌 기술연구소 김태성 연구원
컴퓨터 프로그래밍 기초 - 10th : 포인터 및 구조체 -
CHAP 21. 전화, SMS, 주소록.
Canary value 스택 가드(Stack Guard).
데이터 동적 할당 Collection class.
.Net Web Application 2007 컴퓨터공학실험(Ⅰ)
3. 모듈 (5장. 모듈).
멀티미디어시스템 제 5 장. 멀티미디어 데이터베이스 개념 IT응용시스템공학과 김 형 진 교수.
발표자 : 이지연 Programming Systems Lab.
구조체(struct)와 공용체(union)
Summary of Pointers and Arrays
System Security Operating System.
AdcRead API 함수 분석 마이크로프로세서.
Static과 const 선언 조 병 규 한 국 교 통 대 학 교 SQ Lab..
바이트 순서 변환 함수 주소 변환 함수 바이트 조작 함수 원격지 호스트 정보를 얻는 함수
동적메모리와 연결 리스트 컴퓨터시뮬레이션학과 2016년 봄학기 담당교수 : 이형원 E304호,
제 4 장 Record.
06. 디바이스의 등록과 해제 김진홍
1. 지역변수와 전역변수 2. auto, register 3. static,extern 4. 도움말 사용법
29장. 템플릿과 STL 01_ 템플릿 02_ STL.
개정판 누구나 즐기는 C언어 콘서트 제13장 동적 메모리 출처: pixabay.
임시테이블과 테이블변수 SQLWorld Study Group - 최명환 -.
13. 포인터와 배열! 함께 이해하기.
6 객체.
ARP.
BoardGame 보드게임 따라가기.
Presentation transcript:

12장 Memory Management 15.06.29 CSLAB Park Se Won

Page struct page{ unsigned long flags; atomic_t _count; atomic_t _mapcount; unsigned long private; struct address_space *mapping; pgoff_t index; struct list_head lru; void *virtual; }; 모든 물리적 페이지 관리용 페이지소유자 Userspace process Dynamic data Static kernel code Page cache

Page 형 ( type ) 이름 내용 unsigned long flags 페이지의 상태를 나타내는 플래그, 플레그 배열로 페이지 프레임이 속하는 지역 번호를 가진다.  atomic_t _count 페이지의 참조 카운트.  unsigned int _mapcount  주소 공간에 매핑되고 있는 수. 페이지 프레임을 참조하는 페이지 테이블 엔트리의 수.  ( 없으면 -1 ) private  용도에 따라 제각기 다름  페이지를 사용하는 커널 구성 요소가 이용. ( ex. 버퍼 페이지의 경우 버퍼 헤드의 주소 ) 페이지가 사용하지 않는 것이라면 필드는 버디 시스템을 사용  spinlock_t u.ptl  페이지 테이블 엔트리 변경 시의 잠금용  struct address_space * mapping  파일 캐시로 사용되고 있을 때, 그 주소 영역의 구조체  pgoff_t index  페이지 단위의 파일 오프셋, 또는 스왑 영역의 인덱스 ( mapping이 스왑 캐시의 경우 ) 다른 용도와 함께 일부 커널 구성 요소가 사용한다. 예를 들어, 페이지 디스크 이미지나 익명 영역 내에서 페이지에 저장될 자료의 위치를 식별한다. 또는 스왑된 페이지 식별자를 저장.  struct list_head lru  LRU 리스트용 ( zone 구조체 헤드 )  오랫동안 사용하지 않은 페이지의 이중 연결 리스트에 대한 포인터를 담는다.  void * virtual  kmap되어 있을 때의 가상 주소 페이지의 가상 주소를 나타낸다. 보통 이 값은 단순히 가상 메모리 상의 페이지 주소.' struct page{ unsigned long flags; atomic_t _count; atomic_t _mapcount; unsigned long private; struct address_space *mapping; pgoff_t index; struct list_head lru; void *virtual; };

Page 변수 내용 flag 페이지 상태 저장 Modify, Locking 등 각 비트별로 총 32가지 상태 저장 가능 <linux/page_flags.h>에 저장되어있음 _count 페이지 사용횟수 -1: 페이지 사용 안하는 중 Page_count() 함수 이용; 0: 페이지 사용 안하는 중 virtual 가상 메모리 상의 페이지 주소 NULL: 고정된 주소가 아닐 때, 동적으로 설정됨 struct page{ unsigned long flags; atomic_t _count; atomic_t _mapcount; unsigned long private; struct address_space *mapping; pgoff_t index; struct list_head lru; void *virtual; };

Page 플래그명 의미 PG_locked 페이지에 락이 되어 있다. 예를 들어 디스크 입출력 연산과 관련된 페이지이다.  페이지에 락이 되어 있다. 예를 들어 디스크 입출력 연산과 관련된 페이지이다.  PG_error  페이지 전송 중 입출력 에러가 발생한다.  PG_referenced  이 페이지를 최근에 접근하였다.  PG_uptodate  디스크 입출력 에러가 발생하지 않고, 읽기 작업을 마친 후에 플래그를 설정한다.  PG_dirty  페이지를 수정하였다.  PG_lru  페이지가 활성 또는 비활성 페이지 리스트에 들어 있다. PG_active  active 리스트에 연결되어 있다.  PG_slab  페이지를 슬랩으로 사용한다.  PG_highmem  페이지 프래임이 슬랩에 들어 있다.  PG_checked  EX2와 EX3 파일 시스템에서 사용하는 플래그이다.  PG_arcjh_1  아키텍쳐 종속, i386에서는 미사용.   PG_reserved  커널 코드용으로 예약했거나 사용할 수 없는 페이지 프레임이다.  PG_writeback writepage 메소드에 의해 디스크에 쓰는 중이다.    PG_nosave  시스템 일시 중지/재개를 위해 사용.  PG_compound  페이지 프레임이 확장 페이징 매커니즘을 통해 처리된다.  PG_swapcache  페이지가 스왑 캐시에 속한다.  PG_mappedtodisk  페이지 내 모든 자료는 디스크에 할당된 블록에 해당한다.  PG_reclaim  메모리 해지를 위해 페이지가 디스크에 쓰여 졌다고 표시한다  PG_nosave_free 시스템 일시 중지/재개를 위해 사용된다.  PG_private 추가로 필요한 자료를 저장한다.

<linux/mmzone.h>에 정의 WHY -특정 메모리 주소로만 DMA 수행 가능 x86인 경우 ISA 장치는 메모리 앞부분 16MB만 접근 가능 PCI장치는 24bit 주소 공간에만 DMA 수행 가능 -일부 아키텍쳐에서는 가상적으로 접근할 수 있는 것보다 더 많은 양의 메모리를 물리적으로 접근할 수 있다. 따라서 일부 메모리는 커널 주소 공간에 상주할 수 없다. allocated as… Physical > Logical, 논리적주소로 물리적 주소를 매핑할 수 없다. DMA NORMAL HIGHMEM <linux/mmzone.h>에 정의 lock:구조체 스핀락  데이터 보호 O, 페이지 보호X watermark: 해당 구역 메모리 사용량 name: DMA, NORMAL, HighMem <mm/page_alloc.c>

Zone 구역 내용 물리적 메모리 ZONE_DMA DMA 가능 페이지 < 16MB ZONE_DMA32 32비트 장치들만 접근 가능 ZONE_NORMAL 일반적으로 접근 가능한 페이지 16-896MB ZONE_HIGHMEM 커널 주소 공간에 상주하지 않는 페이지;동적으로 연결되는 페이지, 상위 메모리 <896MB X86-64 와의 차이점 http://gemsres.com/story/sep07/431838/smarduch_fig1.jpg <linux/mmzone.h> 에 정의 ZONE_MOVABLE ZONE_PADDING Logical

DMA 구역 확보를 위해 ZONE_NORMAL 사용 http://gemsres.com/story/sep07/431838/smarduch_fig1.jpg Normal page DMA 구역 확보를 위해 ZONE_NORMAL 사용

Interface 페이지 할당 <linux/gfp.h> struct page * alloc_pages(gfp_t gfp_mask, unsigned int order) 1<<order 만큼 연속된 물리적 페이지를 할당 첫번째 페이지의 page 구조체 포인터 반환 오류: NULL 반환 void * page_address(struct page *page) 물리적 페이지의 논리적 주소 포인터 반환 Unsigned long __get_free_pages(gfp_t gfp_mask, unsigned int order) alloc_pages의 동작 첫 번째 페이지의 논리적 주소 반환 Unsigned long get_zeroed_page(unsigned int gfp_mask) __get_free_page()함수와 동일 할당된 페이지 내용을 0으로 채움  의도하지 않은 데이터가 있을 수 있음 order = 0  1페이지 struct page * alloc_page(gfp_t gfp_mask) Unsigned long __get_free_page(gfp_t gfp_mask)

Interface 페이지 반환 void __free_pages(struct page *page, unsigned int order) void free_pages(unsigned long addr, unsigned int order) void free_page(unsigned int addr) 할당받은 페이지만 반환 잘못사용하면 메모리 파괴됨 Ex) unsigned long page = __get_free_paes(GFP_KERNEL, 3); if(!page){ /*메모리 부족*/ return –ENOMEM; } free_pages(page, 3);

kmalloc() <linux/slab.h> void * kmalloc(size_t size, gfp_t flags) 최소 size 바이트 길이를 가진 메모리 영역의 포인터 반환;물/논리적으로 연속 오류: NULL 반환 void kfree(const void *ptr) kmalloc() 을 통한 메모리 해제 Ex) char *buf buf = kmalloc(BUF_SIZE, GFP_KERNEL); if(!buf) /*오류 처리*/ kfree(buf);

vmalloc() <linux/vmalloc.h>선언, mm/ vmalloc.c 구현 void * vmalloc(unsigned long size) 최소 size 바이트 길이를 가진 메모리 영역의 포인터 반환;논리적으로 연속 오류: NULL 반환 *페이지 테이블의 정보를 수정해서 논리적 주소를 연속적으로 만듦 *페이지 단위로 페이지 테이블에 등록 TLB를 더 사용  kmalloc에 비해 *성능 저하 void vfree(const void *addr) vmalloc() 을 통한 메모리 해제 Ex) char *buf buf = vmalloc(16 * PAGE_SIZE); /*get 16 pages*/ if(!buf) /*오류 처리*/ vfree(buf);

Free list Normal Free list free free Add deallocation free list Using object cache

Free list Normal Free list new new p = malloc() free list initialization

Free list problem Kernel Which one? free list Slab layer Memory lack Slab layer Kernel Can not control Which one? free list

Slab layer 자주 사용하는 자료구조는 캐시 *단편화 유발 방지  free list is sequential 객체, 페이지, 전체 캐시 등의 정보를 알고 있으면 정교한 처리 가능 일부 캐시가 프로세서 단위로 되어 있다면 SMP 락 없이 할당, 해제 가능 NUMA를 지원 하는 경우 메모리를 요청한 노드에 있는 메모리 할당 가능 여러 객체가 같은 캐시에 섞이지 않게, 저장되는 객체에 표시 할 수 있어야 함 *가용 메모리에서 충분한 연속된 메모리 공간을 찾을 수 없는 상황 SMP waiting 작업을 위한 데이터가 메모리의 어느 위치에 있는지 상관없이 작업할 수 있도록 프로세서에게 허용.

Slab layer Object Slab Object Object Cache Object Slab Object

Slab layer 객체 요청 부분사용 미사용 모두사용: 해제된 객체가 없음 부분사용: 할당, 해제된 객체 mm/slab.c kmem_list3 미사용 slabs_full 모두사용: 해제된 객체가 없음 slabs_patritial kmem_getpages() 부분사용: 할당, 해제된 객체 slabs_empty 미사용: 할당된 객체가 없음 새로운 Slab

Slab layer Struct slab{ struct list_headlist; unsigned long colouroff; void *s_mem; unsigned int inuse; kmem_bufctl_t free; }; static inline void * kmem_getpages(struct kmem_cache *cachep, gfp_t flags){ void *addr; flags |= cachep->gfpflags; adr = (void*) __get_free_pages(flags, cachep->gfporder); return addr; }

Slab layer Struct kmem_cache * kmem_cache_create(const char *name, size_t size, size_t align, unsigned long flags, void (*ctor) (void*)); 휴면 상태로 전환 될 수 있기 때문에 인터럽트 컨텍스트에서는 호출하면안됨 해제: int kmem_cache_destroy(struct kmem_cache *cachep) 모든 슬랩이 비어 있어야 함 호출하는 동안 캐시에 접근하면 안됨 name: 캐시 이름 size: 캐시에 들어갈 항목의 크기 align,: 슬랩 내부의 첫 번째 객체의 오프셋 default 0 flags: 캐시 동작 제어 default 0 ctor: 캐시 생성자 FLAGS 내용 SLAB_HWCACHE_ALIGN 캐시 라인에 맞춰 정렬, 잘못된 공유 현상 방지, 메모리 사용량 증가, 성능우선 SLAB_POISON a5a5a5a5 로 슬랩을 채움 (poisoning) 초기화 하지 않은 메모리 탐지 SLAB_RED_ZONE 버퍼 경계 넘침 현상 감지, 할당된 메모리 양측에 red zone 을 끼워 넣음 SLAB_PANIC 오류 시 panic 발생, VMA 할당 처럼 할당 작업이 절대로 실패해서는 안 될 때 사용 SLAB_CACHE_DMA DMA 처리 가능한 메모리에 슬랩을 할당, ZONE_DMA에 있어야 하는 경우 필요

Slab layer void * kmem_cache_alloc(struct kmem_cache *cachep, gfp_t flags) 캐시에 들어있는 객체의 포인터 반환 내부 슬랩에 해제된 객체가 없으면 kmem_getpages() 호출  flags 인자가 __get_free_pages() 함수로 전달 void kmem_cache_free(struct kmem_cache *cachep, void *objp) 객체 해제 후 슬랩에 반환 cachep에 있는 objp 에 해제 표시

Stack – 단일 페이지 커널 스택 프로세스별 메모리 사용량 최소 단편화: 메모리 할당 작업이 어려워짐 인터럽트 핸들러: 프로세스의 커널 스택 사용  커널 스택 사용량 증가 Interrupt Stack 한 페이지 인터럽트 핸들러가 사용하는 각 프로세서 별로 존재 중단된 프로세스의 커널 스택 공유 안함자체스택

상위 메모리 연결 고정연결 임시연결 <linux/highmem.h> 상위 메모리에 있는 페이지는 고정된 커널 주소 공간 값이 없을 수 있다; 논리적 주소가 없을 수 있다 고정연결 임시연결 <linux/highmem.h> void *kmap(struct page *page) 휴면상태로 전환 될 수 있음 페이지 위치가 하위메모리: 페이지의 가상 주소 반환 상위메모리: 고정 연결  주소 반환 void kunmap(struct page *page) 고정연결 개수 제한  연결 해제 temporary, atomic mapping 컨텍스트가 휴면이 불가능한 상황일 때 void *kmap_atomic(struct page *page, enum km_type type) type: 연결의 목적 <asm-generic/kmap_types.h>에 정의 메모리 연결은 프로세서별로 고유 커널 선점 비활성 void kunmap_atomic(void *kvaddr, 연결 해제, 잊어버리기만 함(덮어 씌워짐)

unsigned long my_percpu[NR_CPUS]; int cpu; cpu = get_cpu(); my_percpu[cpu]++; printk(“my_percpu on cpu=%d is %lu\n”, cpu, my_percpu[cpu]); put_cpu(); Index data 1 2 … unsigned long my_percpu[NR_CPUS]; SMP

A프로세서가 B프로세서 캐시조작  A프로세서는 캐시를 비우거나 갱신 CPU별 할당 WHY -Lock이 필요 없을 수 있음 -Lock보다 비용이 적은 커널 선점 비활성화를 사용 -Cache invalidation 를 줄여줌 캐시 동기화 상태 유지  cache invalidation  thrashing the cache  성능저하 A프로세서가 B프로세서 캐시조작  A프로세서는 캐시를 비우거나 갱신

New percpu interface 컴파일 시점의 CPU별 데이터 실행 시점의 CPU별 데이터 2.6 Kernel 이전 커널에서는 호환이 안됨 컴파일 시점의 CPU별 데이터 실행 시점의 CPU별 데이터 DEFINE_PER_CPU(type, name); 프로세스 별로 type name변수 생성 DECLARE_PER_CPU(type, name); 위 변수를 다른 곳에서 사용 하는 경우 get_cpu_var(name)++; 현재 프로세서의 name값 증가 put_cpu_var(name)++; 커널 선점 활성화 per_cpu(name, cpu)++; 지정한 프로세서의 name값 증가 선점 비활성화, Locking 없음 현재 프로세서 조작만 원자적 실행 보장 <linux/percpu.h> void *alloc_percpu(type); //매크로 void *__alloc_percpu(size_t size, size_t align); void free_percpu(const void*); get_cpu_var(ptr); 현재 프로세서의 해당 데이터를 가리키는 void 포인터 반환 put_cpu_var(ptr); 작업 마치고 커널 선점 활성화 void *percpu_ptr; unsigned long *foo; percpu_ptr = alloc_percpu(unsigned long); if(!ptr) //오류 처리 foo = get_cpu_var(percpu_ptr); put_cpu_var(percpu_ptr);

Summrary 메모리 할당: 일반적으로 kmalloc() 함수 이용 (1)GFP_ATOMIC, (2)GFP_KERNEL 플래그 이용 Case (1): 휴면상태 전환X, 우선순위가 높은 할당 작업 진행 Case (2): 휴면 상태 전환O like process context code without spinlock 상위메모리할당: alloc_pages() 함수 이용 가상적으로 연결필요: vmalloc() 함수 이용, 성능은 kmalloc()보다 낮음 큰 자료구조 생성 및 해제: 슬랩 캐시 사용 고려, freelist 제공