irqs_disabled()가 선점을 비활성화하는 안전하지 않은 방법인 이유는 무엇입니까?

irqs_disabled()가 선점을 비활성화하는 안전하지 않은 방법인 이유는 무엇입니까?

선점형 커널에서 적절한 잠금: 커널 코드 선점을 안전하게 유지기사에 따르면,

그러나 "irqs 비활성화"는 선점을 비활성화하는 근본적으로 안전하지 않은 방법이라는 점을 명심하십시오. 선점 수를 0으로 줄이는 spin_unlock()은 일정 변경을 트리거할 수 있습니다. 간단한 printk()가 일정 변경을 유발할 수 있습니다.

IRQ가 비활성화되면 해당 CPU 코어의 타이머 인터럽트도 비활성화되어야 합니다. 당연히 스케줄러를 비활성화해야 합니다(선점). 선점을 비활성화하는 안전하지 않은 방법으로 irqsdisabled()를 호출하는 이유는 무엇입니까?

또한 printk()는 어떻게 일정 변경을 트리거합니까?

답변1

예, IRQ가 비활성화되면 타이머 인터럽트가 비활성화되고 작업 예약이 더 이상 발생하지 않습니다. 안전하지 않은 부분은 "if"입니다. 비활성화된 IRQ에 의존하는 경우 IRQ가 비활성화된 상태에서 실행되는 모든 코드가 이를 준수하는지 절대적으로 확인해야 합니다. 이는 커널에서는 매우 어려울 수 있습니다.Spinlock은 자체적으로 선점을 비활성화하고 활성화합니다.(어떤 경우에는 IRQ와 함께) 많은 코드가 잠금을 사용합니다.printk(로그 메시지가 혼동되지 않도록 하기 위해) 잠금이 해제될 때마다 IRQ가 비활성화된 경우에도 일정을 다시 잡을 위험이 있습니다(잠금을 기다리는 코드 실행).preempt_enable()명시적인 호출__preempt_schedule()카운터가 0에 도달하면 타이머 인터럽트가 필요하지 않습니다.

따라서 특히 미래 보장 측면에서 적절한 선점 지원을 사용하는 것이 더 안전합니다. 현재 작성 중인 코드의 제약 조건을 잘 알고 있을 수 있지만 다른 사람은 이를 변경할 수 없습니다(그리고 "다른 사람"에는 "6"이 포함됩니다). 몇 달 안에 당신은”).

답변2

타이머 인터럽트(또는 일반적으로 인터럽트)가 커널 선점의 유일한 원인은 아니기 때문입니다. 선점은 명시적으로 비활성화될 것으로 예상하는 일부 함수(예: cond_resched())에 의해 여전히 트리거될 수 있습니다.

관련 정보