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

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

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

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

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

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

Прописаны ли где-нибудь правила кодирования для этого?
Различаются ли они для SMP-не SMP-драйверов?
Отличаются ли они для старых ядер без вытеснения и новых ядер с вытеснением?


person Die in Sente    schedule 10.01.2009    source источник


Ответы (2)


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

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

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

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

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

person jpalecek    schedule 10.01.2009
comment
Хотя технически это может быть правильным, на самом деле краткий ответ должен быть таким: не делайте этого. Если вам нужны числа с плавающей запятой, используйте фиксированную точку. - person Jani; 26.10.2018

Ответ Линуса содержит довольно четкую цитату, которую можно использовать в качестве руководства:

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

person tonylo    schedule 17.09.2009