Сбой привязки прерывания Arm Linux

Вопрос или проблема

Я использую ядро 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 для получения более детальной и уважительной поддержки, а также изучения возможности использования патчей или специфических наработок для вашего варианта оборудования и задач.

Оцените материал
Добавить комментарий

Капча загружается...