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

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

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

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

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

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

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

Ответы [ 2 ]

11 голосов
/ 17 сентября 2009

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

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

8 голосов
/ 10 января 2009

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

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

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

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

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

...