3

Some of GCC's builtin functions handle floating-point values: http://gcc.gnu.org/onlinedocs/gcc-4.2.4/gcc/Other-Builtins.html

Since the Linux kernel doesn't support floating-point operations by default, would this mean I cannot use these builtin GCC functions within a Linux kernel module?

Would I be able to use them if I did something to this effect (assuming I'm on an x86 system):

kernel_fpu_begin();

float x = 3.14;
x = __builtin_ceil(x);

kernel_fpu_end();
Vilhelm Gray
  • 11,516
  • 10
  • 61
  • 114
  • 1
    Most likely these use *floating point* registers. I would also be concerned about you corrupting a **user** *floating point* register state. – artless noise Apr 05 '13 at 19:00
  • You probably could call non-floating point GCC builtin functions in the kernel (e.g. `__builtin_prefetch`...), but you want to use floating point in the kernel, and that is not possible. – Basile Starynkevitch Apr 05 '13 at 19:52
  • See also: [Use of floating point in the linux kernel](http://stackoverflow.com/questions/13886338/use-of-floating-point-in-the-linux-kernel) – artless noise Apr 08 '13 at 16:44

1 Answers1

3

The Linux kernel doesn't allow the use of floating point inside, because floating point on x86 uses a special register stack that is expensive to save/restore. The (very) few places where non-integers are needed, fixed point (i.e., integer operations with an assumed decimal or binary point) is used.

vonbrand
  • 11,412
  • 8
  • 32
  • 52
  • I knew that, but I was always wondering if enabling floating point in recent kernels for recent processors would be as costly (both in term of code patch and of runtime performance) as people say... – Basile Starynkevitch Apr 05 '13 at 19:57
  • I'd (wildly) guess it became (relatively) costlier... processors are a lot faster, memory not nearly as much. – vonbrand Apr 05 '13 at 20:03
  • But caches are really bigger (and somehow faster) – Basile Starynkevitch Apr 05 '13 at 20:12
  • +1 See: [Cygnus floating point](http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm) and [same on blog](http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm). Fixed point is almost always better if you pay the pain to code it. – artless noise Apr 05 '13 at 20:17
  • 1
    @artlessnoise, Linux doesn't save it _for the kernel_. If my process does a system call and returns, floating point state hasn't changed --> Win! – vonbrand Apr 05 '13 at 21:18
  • Yes, but what about when the **kernel** is a process. The save/restore path must be different for *kernel tasks* from *user tasks*. `[kworker]` is a kernel task, I believe (and many others you see with `ps`). That is what I wondered about. Floating point is a bad idea in general. I just wonder about this technically. – artless noise Apr 05 '13 at 21:37
  • @artlessnoise, it isn't. The kernel is _not_ a process, and kernel threads are handled mostly like user threads. Floating point registers are saved only when needed (lazily). – vonbrand Apr 05 '13 at 21:39
  • Does this mean the usual floating point GCC builtin functions use fixed point when called within the kernel; or do they just not work at all if called? – Vilhelm Gray Apr 08 '13 at 13:48
  • @VilhelmGray No, the `builtin` have no idea that you execute in the kernel. They are just a way to map tricky assembler to `C` that can not be expressed in normal `C`. See Jim McNamara's comments [in your post](http://stackoverflow.com/questions/15883947/why-am-i-able-to-perform-floating-point-operations-inside-a-linux-kernel-module) – artless noise Apr 08 '13 at 16:47
  • @VilhelmGray, you _can_ define floating point variables, and operate on them just fine. But that uses the floating point stack **without** saving it, and so you are messing up the state of whatever happless task was last running before you did this little shenanigan... good luck tracking down such type of mysterious bug. – vonbrand Apr 08 '13 at 16:53