Причины, по которым процедура rps использует spinlock с local_irq_disable - PullRequest
0 голосов
/ 05 октября 2018

В настоящее время я изучаю код внутренней сети ядра , особенно код RPS .Вы знаете, есть много функций об этом.Но я сосредоточусь на некоторых функциях обработки очереди SMP , таких как enqueue_to_backlog и process_backlog.

Меня интересует синхронизация между двумя ядрами (или одноядерными) с использованием двух функций - enqueue_to_backlog и process_backlog -.

В этих функциях Ядро (A) содержит spin_lock другого ядра (B) для постановки пакетов в очередь в input_pkt_queue и планирования napi ядра (B) Ядро (B) также содержит spin_lock для сращивания input_pkt_queue до process_queue ядра (B) и удаления графика напи самостоятельно. Я знаю, что spin_lock следует придерживатьсязапретить двум ядрам обращаться к одной и той же очереди друг другу во время обработки очереди.

Но я не могу понять, почему spin_lock вызывается с local_irq_disable (или local_irq_save).Я думаю, что нет доступа к очередям или rps_lock ядра (B) по контексту прерываний (TH), когда прерывания (TH) вытесняют текущий контекст (softirq, BH). - Конечно, napi struct можетбыть доступным для планирования напи через TH, но он удерживает отключение irq до тех пор, пока пакет не будет поставлен в очередь - Так что мне интересно, почему spin_lock вызывается с отключением irq.

Я думаю, что это такневозможно выгрузить текущий контекст (напи, softirq) с помощью другой ЧД, такой как тасклет.Это правда?И я хочу знать, отключает ли local_irq_disable все ядра irq или буквально irq текущего ядра? На самом деле, я читал книгу о разработке ядра, но думаю, что недостаточно разбираюсь в preemption.

Объяснит причины, по которым процедура rps использует spin_lock с local_irq_disable?

1 Ответ

0 голосов
/ 08 октября 2018

Отключение прерываний влияет на текущее ядро ​​(только).Поэтому при отключении другой код на том же ядре не сможет помешать обновлению структуры данных.Смысл спин-блокировок состоит в том, чтобы распространить «блокировку» на другие ядра (хотя это совместное, а не аппаратное обеспечение).

Опасно / безответственно брать спин-блокировку в ядре без отключение прерываний, потому что, когда затем происходит прерывание, текущий код будет приостановлен, и теперь вы препятствуете прогрессу других ядер, пока выполняется какой-либо несвязанный обработчик прерываний (даже если другой пользовательский процесс или тасклетна оригинальном ядре не смогу выгрузить).Другие ядра могут быть в контексте прерывания или BH, и теперь вы задерживаете всю систему.Предполагается, что спин-блокировки удерживаются в течение очень коротких периодов времени для критических обновлений общих структур данных.

Это также хороший способ создания взаимоблокировок.Подумайте, реплицировался ли описанный выше сценарий в другую подсистему (или, возможно, другое устройство в той же подсистеме, но я опишу первое).

Здесь ядро ​​A получает спин-блокировку в подсистеме 1 без отключения прерываний.В то же время ядро ​​B получает спин-блокировку в подсистеме 2 также без отключения прерываний.Теперь, что произойдет, если прерывание, связанное с подсистемой 2, произойдет в ядре A, и при выполнении обработчика прерываний подсистемы 2 ядру A необходимо обновить структуру, защищенную спин-блокировкой, хранящейся в ядре B. Но примерно в то же время подсистема 1прерывание происходит в ядре B, которому необходимо обновить структуру данных в этой подсистеме.Теперь оба ядра заняты ожиданием спин-блокировки, удерживаемой другим ядром, и вся система зависает, пока вы не выполните полный сброс.

...