← Documents Documentation/core-api/floating-point.rst GitHub 원문 ↗

Linux 6.18.37 · Core API

Floating-point API

커널에서 부동소수점 코드를 별도 translation unit으로 격리하고 빌드 및 런타임 FPU 가용성을 확인한 뒤 critical section으로 실행하는 규칙을 설명합니다.

Source pathDocumentation/core-api/floating-point.rst
Source versionLinux v6.18.37
TranslationDUJINLABS 전문 번역 + 해설

요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.

1. 요약·해설

원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.

요약과 해설

floating-point.rst:1-78

일반 커널 코드는 사용자 공간의 FP register state를 불필요하게 저장하지 않도록 FPU 사용이 금지됩니다. 꼭 필요한 코드는 별도 source file로 분리해 compiler가 허용 범위 밖에서 FP register를 사용하지 못하게 해야 합니다.

빌드에서는 `ARCH_HAS_KERNEL_FPU_SUPPORT`, `CC_FLAGS_FPU`, `CC_FLAGS_NO_FPU`를 통해 FP 전용 객체만 알맞게 컴파일합니다. 런타임에서는 `kernel_fpu_available()`로 platform 지원을 한 번 확인합니다.

실제 FP 연산은 `kernel_fpu_begin()`과 `kernel_fpu_end()` 사이의 짧은 critical section에서 수행합니다. 이 구간은 process context에서만 사용하고, 중첩이 필요하면 호출자가 reference counting을 제공해야 합니다.

2. 영어 원문 전체

번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.

원문 전체 펼치기
1 .. SPDX-License-Identifier: GPL-2.0+
2
3 Floating-point API
4 ==================
5
6 Kernel code is normally prohibited from using floating-point (FP) registers or
7 instructions, including the C float and double data types. This rule reduces
8 system call overhead, because the kernel does not need to save and restore the
9 userspace floating-point register state.
10
11 However, occasionally drivers or library functions may need to include FP code.
12 This is supported by isolating the functions containing FP code to a separate
13 translation unit (a separate source file), and saving/restoring the FP register
14 state around calls to those functions. This creates "critical sections" of
15 floating-point usage.
16
17 The reason for this isolation is to prevent the compiler from generating code
18 touching the FP registers outside these critical sections. Compilers sometimes
19 use FP registers to optimize inlined ``memcpy`` or variable assignment, as
20 floating-point registers may be wider than general-purpose registers.
21
22 Usability of floating-point code within the kernel is architecture-specific.
23 Additionally, because a single kernel may be configured to support platforms
24 both with and without a floating-point unit, FPU availability must be checked
25 both at build time and at run time.
26
27 Several architectures implement the generic kernel floating-point API from
28 ``linux/fpu.h``, as described below. Some other architectures implement their
29 own unique APIs, which are documented separately.
30
31 Build-time API
32 --------------
33
34 Floating-point code may be built if the option ``ARCH_HAS_KERNEL_FPU_SUPPORT``
35 is enabled. For C code, such code must be placed in a separate file, and that
36 file must have its compilation flags adjusted using the following pattern::
37
38 CFLAGS_foo.o += $(CC_FLAGS_FPU)
39 CFLAGS_REMOVE_foo.o += $(CC_FLAGS_NO_FPU)
40
41 Architectures are expected to define one or both of these variables in their
42 top-level Makefile as needed. For example::
43
44 CC_FLAGS_FPU := -mhard-float
45
46 or::
47
48 CC_FLAGS_NO_FPU := -msoft-float
49
50 Normal kernel code is assumed to use the equivalent of ``CC_FLAGS_NO_FPU``.
51
52 Runtime API
53 -----------
54
55 The runtime API is provided in ``linux/fpu.h``. This header cannot be included
56 from files implementing FP code (those with their compilation flags adjusted as
57 above). Instead, it must be included when defining the FP critical sections.
58
59 .. c:function:: bool kernel_fpu_available( void )
60
61 This function reports if floating-point code can be used on this CPU or
62 platform. The value returned by this function is not expected to change
63 at runtime, so it only needs to be called once, not before every
64 critical section.
65
66 .. c:function:: void kernel_fpu_begin( void )
67 void kernel_fpu_end( void )
68
69 These functions create a floating-point critical section. It is only
70 valid to call ``kernel_fpu_begin()`` after a previous call to
71 ``kernel_fpu_available()`` returned ``true``. These functions are only
72 guaranteed to be callable from (preemptible or non-preemptible) process
73 context.
74
75 Preemption may be disabled inside critical sections, so their size
76 should be minimized. They are *not* required to be reentrant. If the
77 caller expects to nest critical sections, it must implement its own
78 reference counting.
79

3. 한국어 전문 번역

영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.

커널 부동소수점 사용 원칙

1-30

`SPDX-License-Identifier: GPL-2.0+`

Floating-point API (부동소수점 API)

커널 코드는 일반적으로 C의 `float`와 `double` 자료형을 포함하여 floating-point(FP) register 또는 instruction을 사용할 수 없습니다. 이 규칙 덕분에 커널이 userspace floating-point register state를 저장하고 복원할 필요가 없어 system call overhead가 줄어듭니다.

그러나 드라이버나 라이브러리 함수에 FP code가 필요한 경우가 있습니다. 이때 FP code가 들어 있는 함수를 별도의 translation unit, 즉 별도 source file로 격리하고 함수 호출 전후에 FP register state를 저장하고 복원합니다. 이 범위가 floating-point 사용의 critical section이 됩니다.

이렇게 격리하는 이유는 compiler가 critical section 밖에서 FP register를 건드리는 코드를 생성하지 못하게 하기 위해서입니다. floating-point register가 general-purpose register보다 넓을 수 있으므로 compiler는 inline `memcpy`나 variable assignment를 최적화할 때 FP register를 사용하기도 합니다.

커널 안에서 floating-point code를 사용할 수 있는지는 architecture-specific합니다. 하나의 커널이 floating-point unit이 있는 platform과 없는 platform을 모두 지원하도록 구성될 수 있으므로 FPU availability는 build time과 run time에 모두 검사해야 합니다.

여러 아키텍처는 아래 설명처럼 `linux/fpu.h`의 generic kernel floating-point API를 구현합니다. 일부 다른 아키텍처는 별도의 고유 API를 구현하며 해당 문서에서 따로 설명합니다.

빌드 시점 API와 컴파일 플래그

31-51

Build-time API

`ARCH_HAS_KERNEL_FPU_SUPPORT` 옵션이 활성화되어 있으면 floating-point code를 빌드할 수 있습니다. C code는 반드시 별도 파일에 두고 다음 pattern으로 그 파일의 compilation flags를 조정해야 합니다.

CFLAGS_foo.o += $(CC_FLAGS_FPU)
CFLAGS_REMOVE_foo.o += $(CC_FLAGS_NO_FPU)

아키텍처는 필요에 따라 top-level Makefile에서 이 두 변수 중 하나 또는 둘 다를 정의해야 합니다. 예를 들어 하드웨어 부동소수점을 활성화하려면 다음과 같이 정의합니다.

CC_FLAGS_FPU := -mhard-float

또는 소프트웨어 부동소수점을 지정하려면 다음과 같이 정의합니다.

CC_FLAGS_NO_FPU := -msoft-float

일반 커널 코드는 `CC_FLAGS_NO_FPU`와 동등한 플래그를 사용한다고 가정합니다. 즉 FP 전용 translation unit만 `CC_FLAGS_FPU`를 선택하고, 그 파일에서 기본 no-FPU 플래그를 제거합니다.

런타임 API와 FPU 가용성

52-65

Runtime API

runtime API는 `linux/fpu.h`에서 제공합니다. 위와 같이 compilation flags를 조정한 FP code 구현 파일에서는 이 header를 include할 수 없습니다. 대신 FP critical section을 정의하는 파일에서 include해야 합니다.

`bool kernel_fpu_available( void )`

이 함수는 현재 CPU 또는 platform에서 floating-point code를 사용할 수 있는지 알려줍니다. 반환값은 runtime 중 바뀌지 않는다고 가정하므로 모든 critical section 앞에서 호출할 필요 없이 한 번만 호출하면 됩니다.

FP critical section의 시작과 종료

66-78

`void kernel_fpu_begin( void )` / `void kernel_fpu_end( void )`

이 함수들은 floating-point critical section을 만듭니다. 앞서 호출한 `kernel_fpu_available()`가 `true`를 반환한 뒤에만 `kernel_fpu_begin()`을 호출할 수 있습니다. 이 함수들은 preemptible 또는 non-preemptible process context에서만 호출 가능하다고 보장됩니다.

critical section 안에서는 preemption이 비활성화될 수 있으므로 구간 크기를 최소화해야 합니다. 이 함수들은 reentrant일 필요가 없습니다. 호출자가 critical section 중첩을 예상한다면 자체 reference counting을 구현해야 합니다.