Почему один и тот же TASKLET не может выполняться одновременно на двух ядрах?
В реализации ядра Linux для платформы ARM отложенная работа в тасклете добавлена в список percpu vec|vec_hi.
- теперь, возвращаясь к выполнению ISR, он обращается к отложенной работе в softirq и тасклетах.
- теперь об этой отложенной работе можно позаботиться здесь в контексте прерывания с включенными IRQ, или есть потоки ksoftirq, которые могут обрабатывать ее в контексте процесса.
- тот же тасклет будет выполняться на том же процессоре, что и поток ksoftirq percpu.
- Я видел, что во многих книгах, например LDD, книге Роберта Лава, утверждается, что один и тот же тасклет не может быть выполнен одновременно на двух ядрах?
как? Может ли кто-нибудь помочь мне с этим... Если это так, что я пропускаю?
2 ответа
Это так. Хотя тасклет может быть запланирован (т.е. запрошено выполнение тасклета) на любом количестве процессоров, он будет выполняться только на одном.
Я полагаю, что причиной этого является упрощение модели разработки: чтобы упростить реализацию того, что по сути является обработчиком прерываний, без необходимости беспокоиться о гонках из-за одновременного выполнения на нескольких процессорах - и при этом не отключая другие прерывания. (Очевидно, есть еще много других возможностей для гонок, о которых должен знать разработчик драйверов, но они являются одними из самых трудных для решения.)
Если вы спрашиваете о реализации, это на самом деле довольно просто. В tasklet_action
, tasklet_trylock
называется. Используется функция гарантированного атома test_and_set_bit
установить TASKLET_STATE_RUN
немного. Это может быть успешным только на одном процессоре. Следовательно, все другие процессоры не могут выполнять тасклет до тех пор, пока бит не будет очищен, что выполняется только тем процессором, который установил его после завершения тасклета.
РЕДАКТИРОВАТЬ:
Уточнение: звоню tasklet_schedule
на любом количестве процессоров (до выполнения) выполнение тасклета выполняется ровно один раз: на первом процессоре, который сделал вызов. Тот же механизм (test_and_set_bit
) гарантирует, что если тасклет уже был запланирован на каком-либо другом процессоре, но еще не выполнен, он не будет добавлен в очередь запускаемых тасклетов на более позднем процессоре (и, следовательно, не будет выполняться на более позднем процессоре). совсем).
С другой стороны, если он уже начал выполняться на первом процессоре, TASKLET_STATE_SCHEDULE
бит будет очищен (и, следовательно, может быть установлен снова), и поэтому еще один вызов tasklet_schedule
обеспечивает повторное выполнение тасклета на более позднем процессоре, но только после того, как он завершится на первом процессоре.
softirq - это обработка прерываний нижней половины, основанная на механизме вызова функции на основе индекса, где функция реализует функциональность softirq.
Поддерживается массив указателей на функции. Когда softirq зарегистрирован, действительный указатель на функцию записывается в соответствующий индекс. Индекс представляет номер умножения, 0 - умножение наивысшего приоритета. Слово сохраняется в качестве маски для ожидающего softirq.
Число softirq в настоящее время 9 представлено каждым битом слова, когда sofirqs подняты, соответствующий бит в маске установлен. Далее, когда ядро хочет запустить ожидающие softirqs, оно использует замаскированное слово для идентификации ожидающих softtirq и вызовы функций вызываются с помощью массива, чей 0-й индекс отображается с 0-м битом слова маски.
Тасклеты реализованы через softirqs, индекс 0 и индекс 5 массива содержат указатели на функции, которые обрабатывают высокие и нормальные тасклеты соответственно. Тасклеты идентифицируются с помощью структуры, которая содержит указатель на функцию и флаг состояния среди других членов.
Всякий раз, когда создаются тасклеты, создается структура, заполняющая указатель функции адресом функции, реализующей тасклет. Список ссылок всех таких структур поддерживается. Когда тасклет запланирован, он (ядро) добавляет соответствующую структуру в начало списка ссылок и поднимает мягкость тасклетов, т.е. устанавливает соответствующие биты в слове маски.
Затем, когда вызывается функция для обработки тасклетов, она проверяет все элементы списка ссылок и вызывает функцию в структуре, если флаг состояния не запущен, что указывает на то, что она уже запущена в процессоре.
Таким образом, ядро должно убедиться, что 2 и более одинаковых тасклета работают в более чем одном процессоре.