vmalloc과 kmalloc의 차이점은 무엇입니까?


113

나는 주변을 훑어 본 결과 kmalloc, 연속적인 물리적 메모리 블록을 확보 할 수 있으므로. 그러나 원하는 kmalloc연속 물리적 블록을 찾을 수없는 경우 에도 실패 할 수있는 것처럼 보입니다 .
연속적인 메모리 블록을 사용하면 어떤 이점이 있습니까? 특히, 시스템 호출 에서 연속적인 물리적 메모리 블록 이 필요한 이유는 무엇입니까? 그냥 사용할 수없는 이유가 있나요 ? 마지막으로 시스템 호출을 처리하는 동안 메모리를 할당하려면 어떻게 지정해야 합니까? 시스템 호출이 원자 적 컨텍스트에서 실행됩니까?vmalloc
GFP_ATOMIC

GFP_ATOMIC
할당은 우선 순위가 높고 잠들지 않습니다. 이것은 인터럽트 핸들러, 하반부 및 잠을 잘 수없는 기타 상황에서 사용할 플래그입니다.

GFP_KERNEL 이것은 정상적인 할당이며 차단 될 수 있습니다. 수면에 안전 할 때 프로세스 컨텍스트 코드에서 사용할 플래그입니다.



4
이 기사는 "일반적으로 32 비트 아키텍처는 4KB 페이지 크기를 갖고 64 비트 아키텍처는 8KB 페이지 크기를 갖는다"와 같은 말도 안되는 내용을 주장합니다. 나는 그것을 완전히 읽지는 못했지만 "좋다"고 부르지도 않았고 심지어 그 단어를 신뢰하지도 않을 것입니다.
— Alexandro Sánchez

1
참고 (반 관련) : vmallocKernel 5.2 (2019 년 2 분기)에서 더 빠름
— VonC

답변:


96

물리적으로 주소가 지정된 버스 (예 : PCI)의 DMA 장치가 버퍼에 액세스 할 경우 물리적으로 인접한 메모리 사용에 대해서만 걱정하면됩니다. 문제는 많은 시스템 호출이 버퍼가 결국 DMA 장치로 전달되는지 여부를 알 수 없다는 것입니다. 버퍼를 다른 커널 하위 시스템으로 전달하면 실제로 어디로 갈지 알 수 없습니다. 커널이 현재 DMA 용 버퍼를 사용하지 않더라도 향후 개발에서는 그렇게 할 수 있습니다.

vmalloc은 버퍼 공간을 사실상 인접한 범위로 다시 매핑해야 할 수 있으므로 kmalloc보다 느린 경우가 많습니다. kmalloc은 다시 매핑되지 않지만 GFP_ATOMIC으로 호출되지 않으면 kmalloc이 차단 될 수 있습니다.

kmalloc은 제공 할 수있는 버퍼의 크기가 제한됩니다. 128KB *) . 정말 큰 버퍼가 필요한 경우 vmalloc 또는 부팅시 높은 메모리 예약과 같은 다른 메커니즘을 사용해야합니다.

*) 이것은 이전 커널에 해당됩니다. 최근 커널 (2.6.33.2에서 테스트)에서 단일 kmalloc의 최대 크기는 최대 4MB입니다! (나는 이것에 대해 상당히 상세한 글을 썼습니다 .) — kaiwan

시스템 호출의 경우 GFP_ATOMIC을 kmalloc ()에 전달할 필요가 없으며 GFP_KERNEL을 사용할 수 있습니다. 당신은 인터럽트 핸들러가 아닙니다. 어플리케이션 코드는 트랩을 통해 커널 컨텍스트에 들어갑니다. 그것은 인터럽트가 아닙니다.


1
int $ 0x80을 트리거하여 시스템 호출이 입력되었다고 생각했습니다. (즉, 인터럽트)?
— FreeMemory

2
int $ 0x80은 트랩이라고도하는 소프트웨어 인터럽트입니다. 인터럽트 핸들러가 의미하는 것은 사용자가 키를 누르거나 이동을 이동할 때와 같은 하드웨어 인터럽트입니다.
— Branan

시스템 호출은 사용자 공간에서 커널 공간으로의 전환을위한 것입니다 ... kmalloc은 커널 컨텍스트에서만 사용됩니까 ??
— AIB

3
@FreeMemory : int $ 0x80은 x86 전용이며, sysenter / syscall (x86에서)으로 대체 된 오래된 방법이기도합니다.
— jørgensen

18

간단한 대답 : Linux 장치 드라이버를 다운로드 하고 메모리 관리에 대한 장을 읽으십시오.

진지하게 이해해야 할 커널 메모리 관리와 관련된 미묘한 문제가 많이 있습니다. 문제를 디버깅하는 데 많은 시간을 할애합니다.

vmalloc ()은 커널이 가상 메모리를 거의 사용하지 않기 때문에 거의 사용되지 않습니다. kmalloc ()은 일반적으로 사용되지만 다른 플래그의 결과가 무엇인지 알아야하며 실패 할 때 발생하는 상황을 처리하기위한 전략이 필요합니다. 특히 제안한대로 인터럽트 처리기에있는 경우에는 더욱 그렇습니다.


1
"커널이 가상 메모리를 거의 사용하지 않기 때문에"왜 그렇습니까?
— Trey

당신은 일반적으로 커널 블록을 원하지 않기 때문에 그것은 ... 또는 디스크 스토리지 중 스왑 메모리에 커널을 기다리는 동안
— 마이크 하인즈

아니요, vmalloc으로 할당 된 커널 메모리는 스왑 되지 않습니다 . 사용자 공간 메모리 만 교체 할 수 있습니다. 커널 주소 공간은 스왑 할 수 없으며 vmalloc은 커널의 주소 공간에 할당됩니다.
— user2679859

13

로버트 러브 (Robert Love)의 리눅스 커널 개발 (12 장, 3 판 244 페이지)은 이에 대해 매우 분명하게 대답합니다.

예, 많은 경우에 물리적으로 연속적인 메모리가 필요하지 않습니다. 커널에서 kmalloc이 vmalloc보다 많이 사용되는 주된 이유는 성능 때문입니다. 이 책은 vmalloc을 사용하여 큰 메모리 청크를 할당 할 때 커널이 물리적으로 연속되지 않은 청크 (페이지)를 단일 연속 가상 메모리 영역에 매핑해야한다고 설명합니다. 메모리가 사실상 인접하고 물리적으로 비 연속적이기 때문에 여러 가상-물리적 주소 매핑을 페이지 테이블에 추가해야합니다. 그리고 최악의 경우 페이지 테이블에 추가되는 매핑 의 수 (버퍼 크기 / 페이지 크기)가 있습니다.

또한이 버퍼에 액세스 할 때 TLB (최근 가상 대 실제 주소 매핑을 저장하는 캐시 항목)에 대한 부담을 추가합니다. 이것은 스 래싱으로 이어질 수 있습니다 .


11

kmalloc()및 vmalloc()기능 바이트 크기의 청크 커널 메모리를 얻기위한 단순한 인터페이스이다.

  1. 이 kmalloc()기능은 페이지가 물리적으로 연속적이며 사실상 연속적임을 보장합니다.

  2. 이 vmalloc()함수는와 비슷한 방식으로 작동합니다 kmalloc(). 단, 가상적으로 만 연속적이고 물리적으로 연속적 일 필요는없는 메모리를 할당한다는 점이 다릅니다.


4

연속적인 메모리 블록을 사용하면 어떤 이점이 있습니까? 특히 시스템 호출에서 연속적인 물리적 메모리 블록이 필요한 이유는 무엇입니까? vmalloc을 사용할 수없는 이유가 있습니까?

Google의 "I 'm Feeling Lucky"에서 제공 vmalloc:

kmalloc은 매우 큰 영역이 필요하지 않는 한 선호되는 방법입니다. 문제는 일부 하드웨어 장치에서 DMA를 수행하려면 kmalloc을 사용해야하며 더 큰 청크가 필요할 수 있다는 것입니다. 해결책은 메모리가 조각화되기 전에 가능한 한 빨리 메모리를 할당하는 것입니다.


봐요, 읽어 봤는데 말이 안 돼요 큰 지역에서 kmalloc을 사용하는 것을 이해 합니다. 그러나 작은 할당의 경우 물리적 메모리 조각화를 피하기 위해 vmalloc을 사용하지 않는 이유는 무엇입니까?
— FreeMemory

커널이 최선을 다할 것을 신뢰해야하기 때문입니다. 단일 청크를 할당하는 것이 더 낫다고 생각하면 그렇게 할 것입니다. vmalloc은 연속 청크가 반드시 있어야하는 경우에만 사용됩니다 .
— Dark Shikari

말이 되겠지만 직관에 반하는 것 같습니다. kmalloc은 성능이 가장 중요 할 때 사용해야하는 것처럼 들립니다 (즉, 디스크 IO에 시달릴 수 없습니다). 또한 GFP_ATOMIC은 어떻습니까?
— FreeMemory

2

32 비트 시스템에서 kmalloc ()은 물리적 주소에 대한 직접 매핑 (실제로는 일정한 오프셋 사용)이있는 커널 논리 주소 (하지만 가상 주소)를 반환합니다. 이 직접 매핑은 연속적인 물리적 RAM 청크를 확보합니다. 초기 포인터 만 제공하고 이후에 작업을 위해 연속적인 물리적 매핑을 기대하는 DMA에 적합합니다.

vmalloc ()은 물리적 RAM에 연속적인 매핑이 없을 수도있는 커널 가상 주소를 반환합니다. 대용량 메모리 할당에 유용하며 프로세스에 할당 된 메모리가 물리적 RAM에서도 연속적이라는 점에 신경 쓰지 않는 경우에 유용합니다.


1

다른 차이점 중 하나는 kmalloc이 논리 주소를 반환한다는 것입니다 (그렇지 않으면 GPF_HIGHMEM을 지정하지 않음). 논리적 주소는 "낮은 메모리"(물리적 메모리의 첫 번째 기가 바이트)에 배치되고 물리적 주소에 직접 매핑됩니다 (__pa 매크로를 사용하여 변환). 이 속성은 kmalloced 메모리가 연속 메모리임을 의미합니다.

반면에 Vmalloc은 "높은 메모리"에서 가상 주소를 반환 할 수 있습니다. 이러한 주소는 직접적인 방식으로 물리적 주소로 변환 될 수 없습니다 (virt_to_page 함수를 사용해야 함).

당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.