사용자 프로그램이동시 DMA 사용자 메모리
스레드 1을 고려
buf = malloc(9000);
memset(buf, 0xee, 9000);
read(buf, 9000); //for example gives pages [part of 7, 8, 9, part of 10]
스레드 2 사용자 프로그램 :
buf = malloc(9000); //for example gives pages [part of 4, 6, 5, part of 7]
memset(buf, 0xee, 9000);
read(buf, 9000);
드라이버 읽어
get_user_pages();
//build dma sg list from pages
//...
//the platform demands a cachesync
for(all pages) {
dma_cache_wback_inv();
}
//start dma and wait for it to be done
//...
wait_event_interruptible_timeout(); //blocks calling thread until dma done
for(all pages) {
if(read) SetPageDirty();
page_cache_release();
}
페이지 7은 두 가지 모두에서 사용된다는 점에 유의하십시오. 전송, 그리고 때로는 큰 문제가 나쁜 데이터 (0xee는 한 buf의 끝에 발견)입니다. 그냥 두 개의 읽기가 서로 다른 DMA 채널에서 실행되므로 동시에 실행할 수 있습니다.
내 해결책은 사용자 드라이버에서 페이지를 정렬하여 2 개의 드라이버 DMA가 같은 페이지의 부분을 절대 공유하지 않도록하는 것이 었습니다.
다른 해결책이 있습니까? 나는 이것이 왜 큰 문제 인지도 궁금합니다.
이것은 플랫폼에 따라 달라질 수 있습니다. 캐시를 무효화해야한다는 요구 사항은 임베디드 시스템에서 실행 중임을 나타냅니다. 두 개의 버퍼가 캐시 라인을 공유 할만큼 충분히 가까웠습니까? 아니면 플랫폼 정오표에 다른 제한 사항이 있습니까? –
예, ppc440ep이며 버퍼가 충분히 근접합니다. 캐시 라인은 32 바이트이며, 4-12 바이트가 깨 졌거나 변경되지 않은 것으로 나타났습니다. 캐시에 동일한 실제 메모리의 두 가지 버전이 존재할 수 있습니까? 그리고 한 스레드에서 wback을 할 때, 다른 스레드의 데이터를 파괴 할 수 있습니까? 내가 아는 한 고려하지 않은 erratas는 없습니다. 그러나 get_user_pages는 어떻습니까? 동일한 페이지의 2 가지 다른 버전을 반환하면 어떻게됩니까? 다른 thread로부터의 get_user_pages 및 page_cache_release가 인터리브되는 경우. – Ronnie
페이지에 실제 주소를주는 것 외에는 get_user_pages/page_cache_release가하는 일을 완전히 명확히 알 수는 없습니다. 이 시스템에는 디스크 캐시가 없으며 메모리 및 CPU 캐시 만 있습니다. – Ronnie