local_bh_disable, preempt_disable, local_irq_disable

#multithreading #linux-kernel #interrupt-handling #softirq

#многопоточность #linux-ядро #обработка прерываний #softirq

Вопрос:

local_bh_disable отключает обработку нижних половин (softirqs). Запросы Softirq обрабатываются либо по пути возврата прерывания, либо потоком ksoftirqd- (для каждого процессора), который будет активирован, если система страдает от большой нагрузки softirq.

preempt_disable отключает упреждение, что означает, что пока поток выполняется внутри preempt_disable области <-> preemt_enable , он не будет переведен в спящий режим планировщиком. Это означает, что, если прерывание системного таймера происходит, когда текущий поток находится внутри этой области, это может обновить таблицы учета планировщика, но не переключит контекст на другой поток. это включает в себя softirqd.

local_irq_disable или local_irq_save отключите прерывания для локального процессора. это означает, что локальный процессор не будет реагировать ни на какие irq, поэтому он не будет запускать какие-либо пути возврата прерываний и, следовательно, не сможет запускать softirq там.

Предполагая, что мои приведенные выше утверждения верны (в чем я не уверен), тогда не было бы излишним вызывать local_bh_disable ПОСЛЕ того, как вы вызвали preempt_disable and local_irq_save (находясь в контексте процесса)?

Ответ №1:

ДА. После вызова local_irq_save / disable дополнительная защита не требуется — вы не будете прерваны (за исключением NMI или исключения в вашем коде).

Однако часто вы найдете фрагменты кода, которые предназначены для вызова из разных контекстов, поэтому они могут обеспечивать защиту для некоторой подоперации, которая в некоторых путях оказывается избыточной.

Ответ №2:

область preempt_disable / enable гарантирует, что вызов schedule внутри этой области ничего не делает (т. Е. Упреждение отключено). Однако softirq или irq могут прервать вас.

Отключение irq отключит только жесткие прерывания, так как отключение bh (softirqs) отключит только программные прерывания, но вам нужно явно указать, какое из них вы хотите отключить. Существует 4 уровня: NMI, IRQ, softirq, process. NMI (немаскируемые прерывания) может прерывать IRQ, softirq, процесс; IRQ может прерывать softirq и процесс; softirqs может прерывать процесс.

Вызов local_bh_disable() после local_irq_save() может быть избыточным (не уверен), но вызов local_bh_disable() после preempt_disable() определенно необходим, если вы хотите отключить BH.