Я недавно читаю Разработка ядра Linux, и у меня есть несколько вопросов, связанных с отключением вытеснения.
- # P2 #
# P3 #
# P4 ## P5 #
# P6 # - # P7 # # P8 #
# P9 #
# P10 #
Я недавно читаю Разработка ядра Linux, и у меня есть несколько вопросов, связанных с отключением вытеснения.
# P3 ## P4 #
# P5 ## P6 #
# P9 ## P10 #
Я не гуру планировщика, но я хотел бы объяснить, как я это вижу. Вот несколько вещей.
thread_info->preempt_count
переменную.Вы можете увидеть, что такое preempt_disable (). Попробуйте следующее: 1. Получите спин-блокировку. 2. Расписание звонков ()
В dmesg вы увидите что-то вроде «ОШИБКА: планирование при атомарном режиме». Это происходит, когда планировщик обнаруживает, что ваш процесс находится в атомарном (не вытесняющем) контексте, но планирует сам.
Удачи.
В тестовом модуле ядра я написал для мониторинга / профилирования задачи, я попытался отключить прерывания:
1 - Использование local_irq_save ()
2 - Использование spin_lock_irqsave ()
3 - Вручную disable_irq () для всех IRQ в / proc / interrupts
Во всех трех случаях я все еще мог использовать hrtimer для измерения времени, даже если IRQ были отключены (и задача, которую я отслеживал, также была прервана).
Мне это кажется странным ... Я лично ожидал того, на что указал Себастьян Маунтаниол -> Никаких прерываний - никаких часов. Нет часов - нет таймеров ...
Ядро Linux 2.6.32 на одном ядре, одном процессоре ... Может у кого-нибудь есть лучшее объяснение?
preempt_disable()
не отключает прерывания. Однако он увеличивает счетчик вытеснения. Допустим, вы вызываете preempt_disable()
n раз в пути кода, приоритетное прерывание будет разрешено только на n-м preempt_enable()
.scheduler_tick()
не будет вызываться при системном тике (не вызывается обработчик прерывания). Однако, если программа запускает функцию расписания, приоритетное обслуживание произойдет, если preempt_disable()
не был вызван.raw_spin_lock()
не отключает локальные прерывания, которые могут привести к тупиковой ситуации. Например, если вызывается обработчик прерывания, который пытается заблокировать уже удерживаемую блокировку спина, он не сможет этого сделать, если сам процесс не освободит его, что невозможно, поскольку не произойдет возврата из прерывания. Так что лучше использовать raw_spin_lock_irq()
, который отключает прерывания.Отключение прерывания отключает некоторые формы вытеснения ядра, но есть и другие способы вытеснения ядра. По этой причине отключение прерываний не считается безопасным способом предотвращения вытеснения ядра.
Например, с отключенными прерываниями cond_resched () все равно будет вызывать приоритетное прерывание, но не будет, если прерывание было явно отключено.
Вот почему, что касается вашего второго вопроса, спин-блокировки не используют отключение прерывания для отключения вытеснения. Они явно вызывают preempt_disable (), которая увеличивает preempt_count и отключает все возможные способы вытеснения, за исключением явных вызовов schedule ().