문제

검색해 보니 대부분의 사람들이 사용을 옹호하는 것으로 나타났습니다. kmalloc, 연속적인 물리적 메모리 블록을 얻을 수 있기 때문입니다.그러나 그것은 또한 것처럼 보인다 kmalloc 연속된 경우 실패할 수 있음 물리적 원하는 블록을 찾을 수 없습니다.
연속된 메모리 블록을 사용하면 어떤 이점이 있나요?구체적으로 왜 연속적인 물리적 메모리 블록 시스템 호출?그냥 사용하지 못하는 이유가 있나요? vmalloc?
마지막으로, 시스템 호출을 처리하는 동안 메모리를 할당하려면 다음을 지정해야 합니까? GFP_ATOMIC?시스템 호출이 원자적 컨텍스트에서 실행됩니까?

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

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

도움이 되었습니까?

해결책

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

vmalloc은 버퍼 공간을 사실상 연속적인 범위로 다시 매핑해야 할 수 있기 때문에 kmalloc보다 느린 경우가 많습니다.kmalloc은 다시 매핑하지 않지만 GFP_ATOMIC으로 호출하지 않으면 kmalloc이 차단될 수 있습니다.

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

*) 이는 이전 커널에서도 마찬가지였습니다.최근 커널(2.6.33.2에서 테스트함)에서 단일 kmalloc의 최대 크기는 최대 4MB입니다!(나는 꽤 썼다. 이에 대한 자세한 포스팅.) — 카이완

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

다른 팁

짧은 답변:다운로드 리눅스 장치 드라이버 그리고 메모리 관리에 관한 장을 읽어보세요.

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

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

Robert Love의 Linux Kernel Development(3판 12장, 244페이지)는 이에 대해 매우 명확하게 대답합니다.

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

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

그만큼 kmalloc() & vmalloc() 함수는 바이트 크기의 청크로 커널 메모리를 얻기 위한 간단한 인터페이스입니다.

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

  2. 그만큼 vmalloc() 기능은 다음과 비슷한 방식으로 작동합니다. kmalloc(), 단, 가상으로만 연속적이고 반드시 물리적으로 연속적이지는 않은 메모리를 할당하는 경우는 제외됩니다.

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

Google의 'I'm Feeling Lucky'에서 vmalloc:

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

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

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

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

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

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top