요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.
1. 요약·해설
원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.
2. 영어 원문 전체
번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.
원문 전체 펼치기
===========
DWC3 driver
===========
TODO
~~~~
Please pick something while reading :)
- Convert interrupt handler to per-ep-thread-irq
As it turns out some DWC3-commands ~1ms to complete. Currently we spin
until the command completes which is bad.
Implementation idea:
- dwc core implements a demultiplexing irq chip for interrupts per
endpoint. The interrupt numbers are allocated during probe and belong
to the device. If MSI provides per-endpoint interrupt this dummy
interrupt chip can be replaced with "real" interrupts.
- interrupts are requested / allocated on usb_ep_enable() and removed on
usb_ep_disable(). Worst case are 32 interrupts, the lower limit is two
for ep0/1.
- dwc3_send_gadget_ep_cmd() will sleep in wait_for_completion_timeout()
until the command completes.
- the interrupt handler is split into the following pieces:
- primary handler of the device
goes through every event and calls generic_handle_irq() for event
it. On return from generic_handle_irq() in acknowledges the event
counter so interrupt goes away (eventually).
- threaded handler of the device
none
- primary handler of the EP-interrupt
reads the event and tries to process it. Everything that requires
sleeping is handed over to the Thread. The event is saved in an
per-endpoint data-structure.
We probably have to pay attention not to process events once we
handed something to thread so we don't process event X prio Y
where X > Y.
- threaded handler of the EP-interrupt
handles the remaining EP work which might sleep such as waiting
for command completion.
Latency:
There should be no increase in latency since the interrupt-thread has a
high priority and will be run before an average task in user land
(except the user changed priorities).
3. 한국어 전문 번역
영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.
제목
1-5이 문서는 DWC3 driver의 미완료 개선 과제를 기록합니다.
===========
DWC3 driver
===========
TODO 안내
6-10읽는 동안 관심 있는 항목을 하나 골라 구현해 달라는 안내입니다.
TODO
~~~~
Please pick something while reading :)
Per-endpoint threaded IRQ가 필요한 이유
11-15Interrupt handler를 `per-endpoint threaded IRQ` 구조, 즉 endpoint별 threaded IRQ로 변환하는 것이 과제입니다.
일부 DWC3 command는 완료까지 약 1ms가 걸립니다. 현재 구현은 command가 끝날 때까지 spin하므로 CPU 시간을 낭비하고 interrupt context를 오래 점유하는 문제가 있습니다.
- Convert interrupt handler to per-ep-thread-irq
As it turns out some DWC3-commands ~1ms to complete. Currently we spin
until the command completes which is bad.
Demultiplexing IRQ chip과 interrupt 할당
16-24DWC core는 endpoint별 interrupt를 나누는 demultiplexing IRQ chip을 구현합니다. Interrupt number는 probe 중 할당되어 해당 device에 속합니다.
MSI가 endpoint별 interrupt를 제공한다면 이 dummy interrupt chip을 실제 hardware interrupt로 교체할 수 있습니다.
Interrupt는 `usb_ep_enable()`에서 요청·할당하고 `usb_ep_disable()`에서 제거합니다. 최악의 경우 32개가 필요하며, `ep0/1`용 최소 두 개가 하한입니다.
공유 device interrupt에서 endpoint별 IRQ 처리로 이어지는 제안 구조입니다.
Implementation idea:
- dwc core implements a demultiplexing irq chip for interrupts per
endpoint. The interrupt numbers are allocated during probe and belong
to the device. If MSI provides per-endpoint interrupt this dummy
interrupt chip can be replaced with "real" interrupts.
- interrupts are requested / allocated on usb_ep_enable() and removed on
usb_ep_disable(). Worst case are 32 interrupts, the lower limit is two
for ep0/1.
Command 완료 대기
25-26`dwc3_send_gadget_ep_cmd()`는 command가 완료될 때까지 `wait_for_completion_timeout()`에서 sleep합니다. 이는 현재의 spin 대기를 sleep 가능한 completion 대기로 바꾸는 핵심입니다.
- dwc3_send_gadget_ep_cmd() will sleep in wait_for_completion_timeout()
until the command completes.
Device interrupt handler 분리
27-35Device primary handler는 모든 event를 순회하며 각 event에 대해 `generic_handle_irq()`를 호출합니다. 호출에서 돌아오면 event counter를 acknowledge해 해당 interrupt가 최종적으로 사라지게 합니다.
Device 자체의 threaded handler는 두지 않습니다. 수면 가능한 처리는 endpoint별 thread가 담당합니다.
- the interrupt handler is split into the following pieces:
- primary handler of the device
goes through every event and calls generic_handle_irq() for event
it. On return from generic_handle_irq() in acknowledges the event
counter so interrupt goes away (eventually).
- threaded handler of the device
none
Endpoint primary handler
36-43EP interrupt의 primary handler는 event를 읽고 즉시 처리할 수 있는 부분을 수행합니다. Sleep이 필요한 모든 작업은 thread로 넘기고 event는 endpoint별 data structure에 저장합니다.
작업을 thread로 넘긴 뒤에는 event 처리 순서를 주의해야 합니다. 문서의 `X > Y` 예처럼 우선순위 관계가 있는 event를 잘못된 순서로 처리하지 않도록 후속 event 처리를 제어해야 합니다.
- primary handler of the EP-interrupt
reads the event and tries to process it. Everything that requires
sleeping is handed over to the Thread. The event is saved in an
per-endpoint data-structure.
We probably have to pay attention not to process events once we
handed something to thread so we don't process event X prio Y
where X > Y.
Endpoint threaded handler
44-47EP interrupt의 threaded handler는 command 완료 대기처럼 sleep할 수 있는 나머지 endpoint 작업을 처리합니다.
Device와 endpoint의 primary/threaded handler 책임을 구분합니다.
- threaded handler of the EP-interrupt
handles the remaining EP work which might sleep such as waiting
for command completion.
Latency 예상
48-53Interrupt thread는 높은 priority로 실행되어 일반적인 user-space task보다 먼저 scheduling되므로 latency가 늘지 않아야 합니다.
다만 사용자가 task priority를 변경한 경우에는 이 전제가 성립하지 않을 수 있습니다.
Latency:
There should be no increase in latency since the interrupt-thread has a
high priority and will be run before an average task in user land
(except the user changed priorities).
요약·해설
dwc3.rst:1-53제안의 핵심은 shared device IRQ에서 endpoint event를 분배하고, primary handler에는 즉시 가능한 처리만 남기며 약 1ms command 대기처럼 sleep 가능한 작업을 endpoint thread로 옮기는 것입니다. `usb_ep_enable()`/`usb_ep_disable()` 수명 주기, event acknowledge 시점, endpoint별 ordering을 함께 지켜야 합니다.