disable_local_irq и таймеры ядра - PullRequest
7 голосов
/ 29 июня 2011

Привет, ребята, При выполнении SMP портирования некоторых наших драйверов (на цель powerpc) мы наблюдали какое-то поведение, на котором вы, ребята, должны пролить немного света:

  1. При выполнении local_irq_disable () в системе UP, jiffies имеют тенденцию к замораживание, то есть счет перестает увеличиваться. Это ожидается? я думал что прерывание декментера является «внутренним» и не должно получаться затронуты вызовом вида local_irq_disable, так как я ожидал отключить локальную обработку прерываний IRQ (внешнее прерывание). Система, конечно же, зависает и после выполнения local_irq_enable () Jiffies считает прыжки, и это, кажется, компенсирует 'время lapse 'между вызовом local_irq_disable () и enable ().

  2. То же самое в системе SMP (P2020 с 2 ядрами e500) результаты удивительны. Во-первых, модуль, который вставляется в делать это тестирование всегда выполняется на ядре 1. Далее иногда не вижу замораживания счетчика 'jiffies', а иногда мы видим, что это действительно замерзает. Снова в случае замораживания счета это имеет тенденцию прыгать после выполнения local_irq_enable (). Я понятия не имею, почему это может быть происходит. Знаем ли мы, что в случае SMP оба ядра запускают таймер расписания, поэтому что в некоторых случаях мы не видим замораживание отсчетов или это только на ядре 0?

Кроме того, поскольку таймеры ядра полагаются на «jiffies» - это будет означать, что ни один из наших таймеров ядра не сработает, если local_irq_disable () был сделанный ? В таком случае это делается на одном из ядер в SMP система?

Есть много других вопросов, но я думаю, их будет достаточно, чтобы начнем общую дискуссию о том же:)

ТИА

NS

Еще несколько комментариев из проведенного эксперимента.

На данный момент я понимаю, что, поскольку таймеры ядра зависят от запуска jiffies, они фактически не запускаются в системе UP, когда я запускаю local_irq_save (). Фактически, некоторые из нашего кода основаны на предположении, что когда я запускаю local_irq_save (), это гарантирует защиту от прерываний на локальном процессоре и таймерах ядра.

Однако, выполняя тот же эксперимент на SMP-системе, даже если оба ядра выполняют local_irq_save (), jiffies не прекращают увеличиваться, и система не останавливается. Как это возможно ? Использует ли LINUX какой-либо другой механизм для запуска прерываний по таймеру в системе SMP или, возможно, использует IPI? Это также нарушает наше предположение, что local_irq_disable защитит систему от таймеров ядра, работающих на том же ядре, по крайней мере.

Как нам написать код, который защищен от асинхронных событий, то есть прерываний и таймеров ядра, и действителен как для UP, так и для SMP.

Ответы [ 2 ]

4 голосов
/ 29 января 2014

Есть несколько аспектов этой проблемы.Давайте возьмем их 1 на 1.

1.

a)

local_irq_save () просто очищает флаг IF регистра eflags.Обработчики IRQ могут одновременно работать на других ядрах.

global_irq_save () недоступен, потому что для этого требуется межпроцессорное взаимодействие, и оно в действительности не требуется, так как локальное отключение irq предназначено только для очень короткого периода времени.

b)

современные APIC позволяют динамическое распределение IRQ между существующими ядрами, и, за редким исключением, ядро ​​по существу программирует необходимые регистры для получения циклического распределения IRQ.

Следствием этого является то, что если IRQ достаточно локально отключены, когда APIC доставляет IRQ ядру, для которого они отключены, конечным результатом будет то, что система глобально прекратит получать этот конкретный IRQ доТочка, в которой IRQ, наконец, включается локально на ядре, которое получило последний IRQ этого типа.

2.

Что касается различных результатов, касающихся обновлений jiffies и отключения irq, то это зависит отвыбранныйclocksource.

Вы можете выяснить, какой из них выбран, посоветовавшись:

$ cat / sys / devices / system / clocksource / clocksource0 / current_clocksource

, если у вас есть tsc какClocksource, то все ядра имеют его локально.Однако, если ваш источник синхронизации - это что-то другое, например: HPET - внешнее устройство, то jiffies будет зависать по причинам, описанным в пункте # 1.

4 голосов
/ 29 июня 2011

local_irq_disable отключает только прерывания на текущем ядре, поэтому, когда вы используете одно ядро, все отключено (включая прерывания по таймеру), и поэтому jiffies не обновляются.При работе по SMP иногда вы отключаете прерывания в ядре, которое обновляет jiffies, иногда нет.Обычно это не проблема, потому что прерывания должны быть отключены только на очень короткие периоды, и все запланированные таймеры сработают после того, как прерывания снова будут включены.

Как вы знаете, что ваш модуль всегда работает на ядре1?В текущих версиях ядра оно может даже работать на нескольких ядрах одновременно (то есть, если вы не заставляли его этого не делать).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...