2012-05-21 2 views
0

Linux IO 성능에 문제가있는 것으로 보입니다. 프로젝트로 작업 할 때 나는 커널 공간에서 전체 파일 clear을 필요로한다. 나는 다음과 같은 코드 패턴 사용부하가 높을 때 IO 성능이 좋지 않음

for_each_mapping_page(mapping, index) { 
    page = read_mapping_page(mapping, index); 
    lock_page(page); 
    { kmap // memset // kunmap } 
    set_page_dirty(page); 
    write_one_page(page, 1); 
    page_cache_release(page); 
    cond_resched(); 
} 

모두 잘 작동하지만, 대형 파일과 (~ 나를 위해 3GB +) 나는 이상한 방식으로 내 시스템 노점 볼이 작업이 완료되지 않은 상태에서 아무것도를 실행할 수 없습니다 . 즉,이 작업을 수행하기 전에 존재하는 모든 프로세스는 정상적으로 실행되지만,이 작업 중에 뭔가를 실행하려고하면 완료 될 때까지 아무 것도 볼 수 없습니다.

커널의 IO 스케줄링 문제입니까? 아니면 놓친 것일 수 있습니까? 어떻게이 문제를 해결할 수 있습니까?

감사합니다.

UPD : 크리스토프의 제안 I에 따르면

내 코드를 재 작업 한 지금은 다음과 같습니다 : 더 나은 IO 성능을 가지고 한 결과

headIndex = soff >> PAGE_CACHE_SHIFT; 
tailIndex = eoff >> PAGE_CACHE_SHIFT; 

/** 
* doing the exact @headIndex .. @tailIndex range 
*/ 

for (index = headIndex; index < tailIndex; index += nr_pages) { 
    nr_pages = min_t(int, ARRAY_SIZE(pages), tailIndex - index); 

    for (i = 0; i < nr_pages; i++) { 
     pages[i] = read_mapping_page(mapping, index + i, NULL); 
     if (IS_ERR(pages[i])) { 
      while (i--) 
       page_cache_release(pages[i]); 
      goto return_result; 
     } 
    } 

    for (i = 0; i < nr_pages; i++) 
     zero_page_atomic(pages[i]); 

    result = filemap_write_and_wait_range(mapping, index << PAGE_CACHE_SHIFT, 
          ((index + nr_pages) << PAGE_CACHE_SHIFT) - 1); 

    for (i = 0; i < nr_pages; i++) 
     page_cache_release(pages[i]); 

    if (result) 
     goto return_result; 

    if (fatal_signal_pending(current)) 
     goto return_result; 

    cond_resched(); 
} 

,하지만 여전히 문제가 작업을 일으킨 것과 동일한 사용자 내에서 동시 디스크 액세스를 수행하는 동안 거대한 IO 활동.

어쨌든 제안 해 주셔서 감사합니다.

+0

커널 모듈에 파일 입출력을 설치 하시겠습니까? [비표준] (http://lkml.indiana.edu/hypermail/linux/kernel/0005.3/0061.html)과 [bad] (http://www.linuxjournal.com/article/8110)로 간주됩니다. . 나는 당신의 질문에 대답 할 수는 없지만, 이것을 사용자 영역 프로세스로 옮기라고 말할 수 있습니다. – Shahbaz

+0

@Shahbaz : 음, 커널에서 이것을 얻을 수있는 몇 가지 이유가 있습니다. 게다가, 왜 커널 모드 IO가 나쁜지를 보여주는 아무것도 볼 수 없습니다. –

+0

이 작업에는 분명히 시간이 걸릴 것입니다. 당신은 빨리해야 할 코드 경로에서 그것을 실행하고 있습니까? 또는 다른 작업이 성공적으로 실행되지 못하도록이 루프를 시작하기 전에 잠글 수 있습니까? – Peter

답변

3

본질적으로 커널 입출력 스케줄러를 우회하고 있습니다.

ext2 구현을 보면 결코 그렇지 않다는 것을 알게 될 것입니다. (한번도 괜찮습니다.) write_one_page()을 호출합니다. 대규모 데이터 전송의 경우 대신 mpage_writepages()을 사용합니다.

이것은 하드웨어에 즉시 액세스하는 것이 아니라 I/O 인터페이스를 사용합니다. 이는 IO 스케줄러를 통과 함을 의미합니다. 대규모 작업은 스케줄러가 자동으로 다른 작업이 큰 쓰기로 인터리브되도록 보장하므로 전체 시스템을 차단하지 않습니다.

+0

댓글 주셔서 감사합니다. IO 스케줄링에 문제가 있다고 가정합니다. 코드를 다시 작성하는 데 시간이 걸릴 것입니다. –

관련 문제