Каковы соглашения о кодировании для использования с плавающей запятой в драйверах устройств Linux?

Это связано с этот вопрос.

Я не эксперт по драйверам устройств Linux или модулям ядра, но я читал "драйверы устройств Linux" [O'Reilly] Rubini & Corbet и ряд онлайн-источников, но я пока не смог найти ничего по этой конкретной проблеме.

когда ядру или модулю драйвера разрешено использовать регистры с плавающей запятой?
Если да, то кто отвечает за сохранение и восстановление их содержимого?
(Предположим, архитектура x86-64)

Если я правильно понимаю, всякий раз, когда км работает, он использует аппаратный контекст (или аппаратный поток или набор регистров-как вы хотите его назвать), который был вытеснен из некоторого потока приложения. Если вы пишете свой KM на c, компилятор правильно гарантирует, что регистры общего назначения будут правильно сохранены и восстановлены (как в приложении), но это не происходит автоматически с регистрами с плавающей запятой. Для дело в том, что многие KMs даже не могут предположить, что процессор имеет возможность с плавающей запятой.

правильно ли я предполагаю, что км, который хочет использовать плавающую точку, должен тщательно сохранять и восстанавливать состояние с плавающей точкой? Существуют ли стандартные функции ядра для этого?

соглашения о кодировании для этого прописаны где-нибудь?
они отличаются для SMP-non SMP драйверов?
они разные для пожилых невытесняющие ядер и новее упреждающие ядра?

2 ответов


короткий ответ: код ядра может использовать плавающую точку, если это использование окружено kernel_fpu_begin()/kernel_fpu_end(). Эти функции обрабатывают сохранение и восстановление контекста fpu. Кроме того, они называют preempt_disable()/preempt_enable(), что означает отсутствие сна, ошибок страницы и т. д. в коде между этими функциями. Погуглите имена функций для получения дополнительной информации.

если я правильно понимаю, всякий раз, когда KM работает, он использует оборудование контекст (или аппаратный поток или зарегистрировать наборе-все, что вы хотеть назовите это), который был вытеснен из некоторый поток приложений.

нет, модуль ядра может работать и в пользовательском контексте (например. когда userspace вызывает syscalls на устройстве, предоставленном KM). Однако он не имеет никакого отношения к проблеме float.

если вы пишете свой км в c, компилятор будет правильно гарантировать, что регистры общего назначения правильно сохранено и восстановлено (так же, как в приложении), но это не автоматически случается с регистры с плавающей запятой.

это не из-за компилятора, а из-за переключения контекста ядра.


ответ Лайнуса предоставляет эту довольно четкую цитату для использования в качестве руководства:

другими словами: правило состоит в том, что вы действительно не должны использовать FP в ядре.