Вопрос или проблема
Я использую ядро Linux 3.10 на процессоре ARM и пишу драйвер для GPIO. Система присвоила прерывание номер 182. Я использовал команду echo для привязки ядра и хотел привязать прерывание к CPU2, но это не удалось.
cat /proc/irq/182/smp_affinity
4
cat /proc/irq/182/smp_affinity_list
2
Однако я проверил следующую информацию, и проблем не было. Что происходит? Мои cpu2 и cpu3 изолированы.
cat /proc/interrupts
CPU0 CPU1 CPU2 CPU3
29: 2000407 1993990 308737 1328118 GIC arch_timer
30: 0 0 0 0 GIC arch_timer
32: 0 0 0 0 GIC axp22_irq_chip
33: 410 0 0 0 GIC uart0
39: 1090 0 0 0 GIC twi0
40: 0 0 0 0 GIC twi1
41: 48 0 0 0 GIC twi2
43: 6211 0 115847 0 GIC spi1
54: 0 0 0 0 GIC sunxi_timer
59: 0 0 0 0 GIC 1c02000.dma-controller
60: 95854 0 31972 0 GIC PIN_GRP
66: 13154 0 0 0 GIC sunxi-mmc
71: 0 0 0 0 GIC ehci_hcd:usb1
72: 0 0 0 0 GIC ohci_hcd:usb4
76: 0 0 0 0 GIC dispaly
78: 0 0 0 0 GIC 1e80000.g2d
96: 0 0 0 0 GIC ohci_hcd:usb5
97: 0 0 0 0 GIC ohci_hcd:usb6
98: 0 0 0 0 GIC mdfs
108: 0 0 0 0 GIC ehci_hcd:usb2
110: 0 0 0 0 GIC ehci_hcd:usb3
117: 3069 0 0 0 GIC 1c50000.eth
120: 0 0 0 0 GIC twi3
121: 0 0 0 0 GIC twi4
125: 0 0 0 0 GIC DE-Interlace
128: 0 0 0 0 GIC 1000000.tr
182: 52594 75232 0 0 - spiio_irq
IPI0: 0 0 0 0 CPU wakeup interrupts
IPI1: 0 0 0 0 Timer broadcast interrupts
IPI2: 460761 501962 125084 114712 Rescheduling interrupts
IPI3: 2 2 4 4 Function call interrupts
IPI4: 2 3 0 0 Single function call interrupts
IPI5: 0 0 0 0 CPU stop interrupts
IPI6: 0 0 0 0 completion interrupts
IPI7: 0 0 0 0 CPU backtrace
Err: 0
Ответ или решение
Отказ привязки прерывания в Linux на платформе ARM может вызывать значительное количество проблем, которые требуют тщательного подхода к решению. Здесь мы рассматриваем случай, связанный с попыткой привязать прерывание (IRQ) к определённому ядру процессора, CPU2, в системе, работающей под управлением ядра Linux версии 3.10.
Теория
В операционной системе Linux прерывания могут назначаться различным процессорам для равномерного распределения нагрузки и повышения эффективности обработки. Это достигается с помощью изменения маски smp_affinity. Маска smp_affinity указывает доступным системам, какое ядро необходимо использовать для обработки определённого прерывания. Прерывания, определенные в системе, хранятся в каталоге /proc/irq
, а их назначение может управляться путем изменения значения в файле smp_affinity
для каждого IRQ.
Каждому биту в маске smp_affinity
соответствует определённое ядро. Например, если в вашей системе четыре ядра (CPU0 до CPU3), то для привязки прерывания к CPU2 нужно установить маску на бит 0b0100
(или 4
в десятичном) — что соответствует CPU2
.
Пример
В вашем примере, для IRQ 182:
cat /proc/irq/182/smp_affinity
4
cat /proc/irq/182/smp_affinity_list
2
Эти команды показывают, что маска smp_affinity
уже установлена на 4
, что переводится в CPU2
, что правильно. Но в выводе из /proc/interrupts
видно, что прерывание 182
не обрабатывается на CPU2, хотя должно было бы:
182: 52594 75232 0 0 - spiio_irq
Это свидетельствует о том, что прерывание назначено, но не активно обрабатывается на CPU2. Такое поведение может быть вызвано различными факторами, которые стоит рассмотреть.
Применение
1. Изолированные ядра
Уже упомянуто, что CPU2 и CPU3 изолированы. Изоляция ядер обычно используется, чтобы резервировать их для специфических задач времени выполнения или реального времени, минимизируя вмешательство со стороны ОС. Изоляция достигается через параметр командной строки ядра isolcpus
. Если ядра изолированы, системные прерывания, такие как IRQs, по умолчанию не будут назначаться и обрабатываться теми ядрами.
Решение:
- Если требуется использовать CPU2 для данного прерывания, избавьтесь от изоляции с помощью соответствующего редактирования конфигурации загрузчика и перезапуска системы. Удалите CPU2 из параметра
isolcpus
.
2. Ограничения на уровне драйвера или устройства
Некоторые драйверы устройств имеют ограничения или допущения на то, какие процессоры могут использоваться для обработки их прерываний. Это часто связано с аппаратной архитектурой устройства и соответствующими требованиями.
Решение:
- Проверьте документацию на используемое оборудование и драйвер, чтобы подтвердить, есть ли ограничения на использование определённых процессоров.
- При необходимости обновите или пересоберите драйвер с учётом специфики архитектуры.
3. Версия ядра
Вы используете устаревшую версию ядра Linux (3.10), что создаёт определённые ограничения. Данная версия является относительно старой и может не иметь всех новых функций, улучшений или исправлений, представленных в более современных версиях ядра.
Решение:
- Рассмотрите возможность обновления на более новую версию ядра, если это совместимо с системой.
4. Неправильная конфигурация системы
- Убедитесь, что файл конфигурации ядра не содержит указаний, которые могут предотвращать обработку прерываний на некоторых ядрах или изменяют поведение прерываний (например, параметры
noirqaffinity
).
Заключая вышеописанные шаги, решите возможные проблемы, связанные с конфигурацией вашей системы и драйвера. Это поможет добиться корректной привязки и обработки прерываний для IRQ 182 на CPU2. Если после выполнения всех предложенных шагов проблема сохраняется, рекомендуется обратиться за помощью к разработчикам дистрибутива или сообществах ядра Linux для получения более детальной и уважительной поддержки, а также изучения возможности использования патчей или специфических наработок для вашего варианта оборудования и задач.