2017-01-25 3 views
1

다행히도 표준 커널 소스의 일부인 usb_skeleton 예제 드라이버의 usb 장치와 동일한 Linux 드라이버를 사용하고 있습니다. 4.4 커널의 경우 간단했습니다. VID와 PID 및 몇 개의 문자열을 변경하고 드라이버를 컴파일하고 x64 및 ARM 커널에서 완벽하게 작동 시켰습니다.리눅스 장치 드라이버가 첫 번째 액세스에서 진행중인 읽기로 인해 스핀 잠금 상태로 고정됨

하지만 3.2 커널로이 작업을해야한다는 것이 밝혀졌습니다. 나는 이것에 선택의 여지가 없다. 나는 3.2 소스에서 뼈대 드라이버를 똑같이 수정했다. 다시 말하지만, 실제 코드, VID, PID 및 일부 문자열 만 변경할 필요가 없었습니다. 컴파일되고 잘로드되지만 (/ dev에 표시됩니다.)/dev/myusbdev0에서 읽기를 수행하는 첫 번째 시도에서 영구적으로 중단됩니다.

다음 코드는 대량 종료점에서 읽어야하는 read 함수의 코드입니다. 장치를 읽으려고하면 진행중인 io로 인해 차단 될 첫 번째 메시지가 표시됩니다. 그럼 아무것도. 이것을 읽으려는 사용자 프로그램이 멈추어 kill -9로 죽일 수 없다. 리눅스 머신도 재부팅 할 수 없다. 나는 파워 사이클을해야한다. 예외 메시지 나 예외 메시지는 없습니다. 그것은 'IO May Take Take Forever'라고 언급 된 부분에 매달려 있음을 확신합니다.

내 질문은 : 아직 어떤 IO가 드라이버와 IO를 수행하지 않았습니까? 드라이버 코드에서이 문제를 해결할 수 있습니까? 아니면 사용자 프로그램이/dev/myusbdev0에서 읽기를 시작하기 전에 뭔가해야합니까?

이 경우 대상 기계는 Beaglebone Black과 유사한 임베디드 ARM 장치입니다. 부수적으로이 드라이버의 4.4 커널 버전은 동일한 사용자 모드 테스트 프로그램을 사용하여 Beaglebone에서 완벽하게 작동합니다.

/* if IO is under way, we must not touch things */ 
retry: 
    spin_lock_irq(&dev->err_lock); 
    ongoing_io = dev->ongoing_read; 
    spin_unlock_irq(&dev->err_lock); 

    if (ongoing_io) { 
    dev_info(&interface->dev, 
      "USB PureView Pulser Receiver device blocking due to ongoing io -%d", 
      interface->minor); 
      /* nonblocking IO shall not wait */ 
      if (file->f_flags & O_NONBLOCK) { 
        rv = -EAGAIN; 
        goto exit; 
      } 
      /* 
      * IO may take forever 
      * hence wait in an interruptible state 
      */ 
      rv = wait_for_completion_interruptible(&dev->bulk_in_completion); 
    dev_info(&interface->dev, 
      "USB PureView Pulser Receiver device completion wait done io -%d", 
      interface->minor); 
      if (rv < 0) 
        goto exit; 
      /* 
      * by waiting we also semiprocessed the urb 
      * we must finish now 
      */ 
      dev->bulk_in_copied = 0; 
      dev->processed_urb = 1; 
    } 
+0

로버트 러브 (Robert Love)가 로킹 (locking)에 대해 쓴 책을 읽는 것이 좋습니다. – 0andriy

+0

이 커널 커밋을 살펴보십시오. - https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=c79041a44045a40329d9ada3f8679c4b30c5b76b - "USB : usb-skeleton.c : skel_read에서 영원히 차단 된 픽스 "- 내가 필요한 것일 수도 있습니다. 나는 그것을 지금 당장 자세히 볼 시간이 없으며, 나는 나중에 오늘 내가 대답 할 수 있기를 희망한다. – michaeljt

+0

코드를 자세히 살펴보고 인터럽트 가능 대기가 중단되지 않는 이유 또는 두 번째 메시지가 표시되지 않는 이유에 대해 알아보기가 어려웠습니다. 다른 경로에 메시지를 더 추가, 특히 완료 및 무정전 대기 경로는 몇 가지 단서를 제공 할 수 있습니다. – michaeljt

답변

0

내 의견에 대한 응답이 없으므로 답변을 작성하십시오. 3.10에서 추가 된 커널 커밋 c79041a4 [1]은 "skel_read에서 영구 차단됨"을 수정합니다. 위의 코드를 보면 장치 파일에 O_NONBLOCK 플래그가 설정되어 있으면 첫 번째 메시지가 두 번째 메시지없이 표시 될 수 있음을 알 수 있습니다. 커밋 메시지에 설명 된대로 read() 호출간에 완료가 발생하면 다음 read() 호출은 이미 완료된 완료를 기다리는 무중단 대기 상태로 종료됩니다.

[1]

https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=c79041a4은 분명히 나는 ​​이것이 당신이 무엇을보고 있는지 모르겠지만, 나는 좋은 기회가 생각합니다. 올바른 경우 드라이버에 변경 사항을 적용 할 수 있으며 문제가 해결됩니다.