Shalom Craimer
Shalom Craimer

Reputation: 21449

Link error when attempting to measure time in kernel using do_gettimeofday()

I'm attempting to time some functions calls made by a driver. So I called do_gettimeofday to get the struct timeval of the time. It compiles, but the linker complains thusly:

drivers/built-in.o: In function `SPC_TIMING_add':
hid-quirks.c:(.text+0x31354): undefined reference to `__aeabi_i2d'
hid-quirks.c:(.text+0x31384): undefined reference to `__aeabi_i2d'
hid-quirks.c:(.text+0x31398): undefined reference to `__aeabi_dadd'
make: *** [.tmp_vmlinux1] Error 1

I tried reading the value of xtime directly, and got the same result.

Obviously, there's some kind of mistake in the link-order, but since I'm not sure where __aeabi_i2d and __aeabi_dadd come from, I don't know what makefile to edit.

UPDATE: Turns out that "aeabi" means "Embedded Application Binary Interface" (EABI) for the ARM Architecture. The dadd instruction is double-precision addition, and i2d is integer-to-double conversion (according to this). I guess this means that my problem isn't simply linking, but of convincing the compiler to use the right instruction, or a surrogate instruction (which seems to be what is being done in arch/arm/lib/lib1funcs.S).

UPDATE: According to a Google search, __aeabi_dadd is often aliased to be __adddf3, and __aeabi_i2d is aliased to __floatsidf.

UPDATE: After looking closely at the actual compiler's output, it turns out that the error has nothing to do with do_gettimeofday. It was merely that commenting-out the call to do_gettimeofday allowed the compiler's optimizer to remove references to a function that was performing double-precision floating point operations. Once that function was not longer being called, the error wouldn't appear. And that's why I thought it was being caused by do_gettimeofday.

Upvotes: 0

Views: 2316

Answers (1)

mpe
mpe

Reputation: 2720

If you're in the kernel you probably shouldn't be using do_gettimeofday().

I think the right way to do it is using the ktime family of functions, eg:

ktime_t start, end, delta;

start = ktime_get();
...
end = ktime_get();

delta = ktime_sub(end, start);

There are then a bunch of conversion routines in ktime.h for turning delta into milli/nano/etc seconds.

Upvotes: 2

Related Questions