2013-10-20 11 views
1

1 년 이상 상용 제품에서 작동하는 블록 장치 드라이버가 있습니다. 최근에 나는 REQ_DISCARD 플래그로 폐기를 처리하고 요청을 처리하여 씬 프로비저닝에 대한 지원을 추가하려고했습니다. 모든 컨텍스트에서 이러한 유형의 요청에 대해 blk_end_request의 변형을 호출 할 때마다 적어도 BUG() 출력을 얻는 것 같고 최악의 경우 (blk_end_request_all__ 접두사가있는 잠금 해제 된 버전이 포함됨) 중단되거나 oops가 발생합니다. 또한, 위의 파일 시스템 드라이버 (ext4)가 동일한 요청 포인터를 사용하는 경우에도 동일한 REQ_DISCARD 요청을 재발행한다는 것은 요청을 정상적으로 읽기/쓰기 요청에 대해 잘 수행하려고 시도 할 때 나타납니다. 다음은이 문제를 보여주는 간단한 요청 기능 (blk_init_queue으로 전달됨)입니다. 이것은 요청을 처리 할 수있을만큼 빠르기 때문에, 거의 모든 코드를 제거합니다. 이는 정상적인 읽기/쓰기 작업을 다시 수행합니다.Linux 블록 장치 드라이버 : REQ_DISCARD를 처리하는 방법

// This is a simplified version of the function that's passed into blk_init_queue 
static void 
my_request_fn(struct request_queue * queue) 
{ 
    struct request * req; 

    while ((req = blk_fetch_request(queue)) != NULL) { 

     if (rq_data_dir(req) && (req->cmd_flags & REQ_DISCARD)) { 
      printk(KERN_INFO "Received DISCARD request from process %d, sector=%lu, req %p\n", 
        pid_nr(task_pid(current)), 
        blk_rq_pos(req), 
        req); 
      // FIXME: this is a lie 
      __blk_end_request_all(req, 0); 
      continue; 
     } 

// ... more code hidden for brevity 
    } 
} 

근본적으로 다르게 처리해야하는 요청 사항이 있습니까? 나는 sd, md, xenblk 등과 같은 다른 드라이버를 보려고 노력했지만 근본적으로 다르므로 명확하지 않습니다. 근본적인 질문은 입니다. REQ_DISCARD 요청을 어떻게 적절히 처리하고 완료를 알리는 지 어떻게 알 수 있습니까?

는 경우 이것은 끝나면 uname -a가보고 내 커널 버전은 내 순발력 끝에 때문에 Linux mydevbox 3.2.0-54-generiC#82-Ubuntu SMP Tue Sep 10 20:08:42 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux

답변

2

내가 여기에 게시 알려진 버그입니다. 해결책은 간단했고 어쩌면 이것은 동일한 문제를 겪고있는 다른 사람을 도울 것입니다. discard 기능과 관련된 새로운 제한이 있습니다. 그 중 두 개는 아래에 있습니다.

// WARNING: these values are bad, do not use 
queue->limits.discard_zeroes_data = 1; 
queue->limits.max_discard_sectors = 1; 
queue->limits.discard_granularity = 2048; 

I 든 마지막 두 값이 매우 입도가 매우 크며, 최대 섹터 만 1 (단 힌트 것으로 예상되는) 세 번째 행을 주석 후에이었다 폐기 전치와 RHS 값을 고정했다 두 번째 줄의 모든 것이 작동합니다! 값은 아래의 값과 같습니다.

queue->limits.discard_zeroes_data = 1; 
queue->limits.max_discard_sectors = 2048 
// queue->limits.discard_granularity = 1; 

당신은 간헐적 인 충돌과 구성을 확인, 이중 REQ_DISCARDED 요청을 처리와 BUG() 스택 추적을 받고있는 경우.