Каковы соглашения о кодировании для использования плавающей запятой в драйверах устройств Linux?
-
08-07-2019 - |
Вопрос
Это связано с этот вопрос .
Я не специалист по драйверам устройств Linux или модулям ядра, но я читал "Драйверы устройств Linux" [O'Reilly] Рубини Корбет и ряд интернет-источников, но я пока не смог найти ничего по этому конкретному вопросу.
Когда модулю ядра или драйвера разрешается использовать регистры с плавающей запятой?
Если да, то кто несет ответственность за сохранение и восстановление их содержимого?
(Предположим, архитектура x86-64)
Если я правильно понимаю, всякий раз, когда KM работает, он использует аппаратный контекст (или аппаратный поток или набор регистров - как вы хотите это называть), который был выгружен из некоторого потока приложения. Если вы напишите свой KM на языке c, компилятор правильно обеспечит правильное сохранение и восстановление регистров общего назначения (как в приложении), но это не происходит автоматически с регистрами с плавающей запятой. В этом отношении многие КМ даже не могут предположить, что процессор имеет какие-либо возможности с плавающей запятой.
Правильно ли я предположил, что КМ, который хочет использовать плавающую точку, должен тщательно сохранять и восстанавливать состояние с плавающей точкой? Существуют ли стандартные функции ядра для этого?
Где-нибудь прописаны соглашения о кодировании для этого?
Отличаются ли они для драйверов SMP-non-SMP?
Отличаются ли они для более старых ядер без вытеснения и более новых ядер с вытеснением?
Решение
Краткий ответ: код ядра может использовать число с плавающей запятой, если это использование окружено kernel_fpu_begin ()
/ kernel_fpu_end ()
. Эти функции обрабатывают сохранение и восстановление контекста fpu. Кроме того, они вызывают preempt_disable ()
/ preempt_enable ()
, что означает отсутствие спящего режима, сбоев страниц и т. Д. В коде между этими функциями. Google имена функций для получения дополнительной информации.
Если я правильно понимаю, всякий раз, когда КМ работает, он использует оборудование контекст (или аппаратный поток или набор регистров - все, что вы хотите называть это), который был выгружен из какая-то ветка приложения.
Нет, модуль ядра также может работать в контексте пользователя (например, когда пользовательское пространство вызывает системные вызовы на устройстве, предоставляемом КМ). Однако это не имеет отношения к проблеме с плавающей точкой.
Если вы напишите свой КМ на с, компилятор будет правильно гарантировать, что регистры общего назначения должным образом сохранены и восстановлены в приложении), но это не автоматически происходит с регистры с плавающей точкой.
Это не из-за компилятора, а из-за кода переключения контекста ядра.
Другие советы
Ответ Линуса содержит эту довольно четкую цитату, которую можно использовать как руководство:
Другими словами: правило таково, что вам не следует использовать FP в ядре.