2013-01-17 7 views
7

Чтобы дать вам полный контекст, мое обсуждение началось с наблюдения за тем, что я запускаю SMP linux (3.0.1-rt11) на ARM-коре Основанный на A8 SoC, который является однопроцессорным. Мне было интересно узнать, будет ли какое-либо преимущество в производительности, отключив поддержку SMP. И если да, какое влияние это окажет на мои драйверы и обработчики прерываний.Понимание связи между CONFIG_SMP, Spinlocks и CONFIG_PREEMPT в последнем (3.0.0 и выше) ядре Linux

Я прочитал несколько разных разделов: прядильные блоки и ядро. Я немного поработал в поисковых системах и читал, но на этот раз все, что у меня есть, - это несколько устаревших и противоречивых ответов. Поэтому я подумал, что позвольте мне попробовать stackoverflow.

Происхождение моих сомнений/вопросов этот пункт из драйверов устройств Linux третьей главы издания 5:

Спина-блокировка, по своей природе, предназначенной для использования на многопроцессорных системах хотя однопроцессорная рабочая станция с prefixive , как и SMP,. Если бы невосприимчивая однопроцессорная системавошла во вращение на замке, то она закрутилась бы навсегда; никакая другая нить никогда не сможет получить CPU , чтобы освободить замок. По этой причине операции спин-блокировки на однопроцессорных системах без предварительного включения оптимизированы, чтобы сделать ничего, за исключением тех, которые изменяют маскирование IRQ . Из-за предохранения, даже если вы никогда не ожидаете, что ваш код будет запущен в системе SMP, , вам все равно необходимо реализовать правильную блокировку.

Мои сомнения/вопросы:

а) Является ли Linux ядро ​​Преимущественное в пространстве ядра по умолчанию? Если да, является ли это ограничение преимуществом только процессами или обработчиками прерываний также могут быть вытеснены?

b) Поддерживает ли ядро ​​Linux (на ARM) вложенное прерывание? Если да, будет ли каждый обработчик прерывания (верхняя половина) иметь собственный стек или они будут использовать один и тот же стек режима ядра 4k/8k?

c) Если отключить SMP (Config_SMP) и preemption (Config_preempt), будут ли прядильные блокировки в моих драйверах и обработчиках прерываний иметь какой-то смысл?

d) Как прерывания дескриптора ядра возникают при выполнении верхней половины i.e будут ли они отключены или замаскированы?

Через некоторое Googling я нашел это:

Для ядер, собранных без CONFIG_SMP и без CONFIG_PREEMPT спин-блокировки не существует. Это отличное дизайнерское решение: , когда никто другой не может работать одновременно, нет причин для блокировки .

Если ядро ​​компилируется без CONFIG_SMP, но CONFIG_PREEMPT является множества, то Взаимные блокировки просто отключить упреждение, что является достаточным для предотвращения любых гонок. Для большинства целей мы можем думать о преимуществе как , эквивалентном SMP, и не беспокоиться об этом отдельно.

Но нет версии ядра или датой на source.Может ли кто-нибудь подтвердить, что он все еще действителен для последних ядер Linux?

+0

Это четыре вопроса, поэтому разделите их так, как они могут не ответить вместе. –

ответ

6

a) Является ли Linux превентивным или нет, зависит от того, сконфигурирован ли он таким образом
с CONFIG_PREEMPT. По умолчанию нет. Если вы запустите make config, вам придется выбирать.

b) Прерывания выполняются в Linux; в то время как прерывания обрабатываются, другие прерывания могут исчезнуть. Это верно для ARM и многих других архитектур. Все в одном стеке. Конечно, стек пользовательского пространства не используется для прерываний!

с) Если отключить SMP и упреждения, в спин-блокировки кода сведет к не-оп, если они являются регулярными, и спин-блокировки прерываний (spin_lock_irqsave Взаимные блокировки/spin_lock_irqrestore) превратится в прерывание отключить/включить. Поэтому последние по-прежнему необходимы; они предотвращают гонки между задачами, запускающими ваш код, и прерываниями, запускающими ваш код.

d) «Верхняя половина» традиционно относится к процедурам обслуживания прерываний. Верхний половинный код драйвера управляется прерываниями. Нижняя половина называется задачами (для чтения или записи данных или чего-то еще). Информация об обработке прерываний является специфичной для архитектуры.

Я совсем недавно очень тесно работал с прерываниями Linux на конкретной архитектуре MIPS. На этой конкретной плате было 128 прерывистых линий, маскируемых двумя 64-битными словами. Ядро реализовало схему приоритета поверх этого, поэтому перед выполнением обработчика для данного прерывания нижние были замаскированы через обновления этих 2x64-разрядных регистров. Я внедрил модификацию, чтобы приоритеты прерываний могли устанавливаться произвольно, а не по позиции аппаратного обеспечения и динамически, записывая значения в запись /proc. Более того, я вложил взломы, в результате чего часть числового приоритета IRQ перекрывалась с приоритетом задач в реальном времени. Таким образом, задачи RT (то есть потоки пользовательского пространства), назначенные определенному диапазону уровней приоритета, могли неявно подавлять определенный диапазон прерываний во время работы. Это было очень полезно для предотвращения помех, вызванных нарушениями критически важных задач (например, подпрограммы обслуживания прерываний в коде драйвера IDE, используемого для компактной вспышки, которая выполняет петли занятости из-за плохо спроектированного аппаратного интерфейса, становятся де-факто наивысшим приоритетом в системе.) Так или иначе, поведение маскировки IRQ не написано на камне, если вы контролируете ядро, используемое клиентами.

Котировочная заявления в вопросе справедливы только о регулярных (spin_lock спин-блокировок функция/макро) не IRQ (spin_lock_irqsave спин-блокировок). В привилегированном ядре на однопроцессорном сервере spin_lock просто должен отключить предварительное исправление, которого достаточно, чтобы оставить все остальные задачи вне ядра до spin_unlock. Но spin_lock_irqsave должен отключить прерывания.