Build failures due to missing 'posix_timer_event'

Message ID alpine.LFD.2.20.1612140949190.1657@knanqh.ubzr
State New
Headers show

Commit Message

Nicolas Pitre Dec. 14, 2016, 3:14 p.m.
On Wed, 14 Dec 2016, Guenter Roeck wrote:

> avr32:allnoconfig:

> 

> kernel/built-in.o: In function `do_adjtimex':

> (.text+0x1d748): undefined reference to `posix_timer_event'

> make[1]: *** [vmlinux] Error 1

> 

> metag:allnoconfig:

> 

> kernel/built-in.o: In function `alarm_handle_timer':

> alarmtimer.c:(.text.alarm_handle_timer+0x38): undefined reference to

> `posix_timer_event'

> 

> openrisc:allnoconfig:

> 

> kernel/built-in.o: In function `alarm_handle_timer':

> alarmtimer.c:(.text+0x3fca4): undefined reference to `posix_timer_event'

> 

> unicore32:allnoconfig:

> 

> kernel/built-in.o: In function `alarm_handle_timer':

> memremap.c:(.text+0x31c1c): undefined reference to `posix_timer_event'

> 

> Since I don't run allnoconfig builds for all architectures, I strongly suspect

> that more are affected.


This is a known problem. Oddly enough only those "less popular" 
architectures are affected.

> Looking into alarmtimer.c, with seems to call posix_timer_event() 

> unconditionally, I don't entirely understand how this can work in the 

> first place. Maybe I am missing something, though.


The magic is in alarmtimer_init():

        if (IS_ENABLED(CONFIG_POSIX_TIMERS)) {
                posix_timers_register_clock(CLOCK_REALTIME_ALARM, &alarm_clock);
                posix_timers_register_clock(CLOCK_BOOTTIME_ALARM, &alarm_clock);
        }

If CONFIG_POSIX_TIMERS is not enabled, the condition becomes a constant 
zero. The posix_timers_register_clock calls are then optimized away by 
the compiler. In turn the alarm_clock structure has no longer any 
reference to it and therefore is also optimized away, including its 
method functions such as alarm_timer_create() and finally 
alarm_handle_timer().

But for some reasons, some gcc versions (mainly for "secondary" 
architectures) fail to optimize away all that code, and a dead reference 
to posix_timer_event() remains in the compiled code.

There is a fix already queued in the mm tree. It goes like this:

    posix-timers: give lazy compilers some help optimizing code away
    
    The OpenRISC compiler (so far) fails to optimize away a large portion
    of code containing a reference to posix_timer_event in alarmtimer.c when
    CONFIG_POSIX_TIMERS is unset. Let's give it a direct clue to let the build
    succeed.
    
    This fixes
    [linux-next:master 6682/7183] alarmtimer.c:undefined reference to `posix_timer_event'
    reported by kbuild test robot.
    
    Signed-off-by: Nicolas Pitre <nico@linaro.org>

    Cc: Thomas Gleixner <tglx@linutronix.de>
    Cc: Josh Triplett <josh@joshtriplett.org>
    Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

Comments

Stafford Horne Dec. 15, 2016, 2:55 a.m. | #1
Hello,

On Wed, Dec 14, 2016 at 10:14:39AM -0500, Nicolas Pitre wrote:
> On Wed, 14 Dec 2016, Guenter Roeck wrote:

> 

> > avr32:allnoconfig:

> > 

> > kernel/built-in.o: In function `do_adjtimex':

> > (.text+0x1d748): undefined reference to `posix_timer_event'

> > make[1]: *** [vmlinux] Error 1

> > 

> > metag:allnoconfig:

> > 

> > kernel/built-in.o: In function `alarm_handle_timer':

> > alarmtimer.c:(.text.alarm_handle_timer+0x38): undefined reference to

> > `posix_timer_event'

> > 

> > openrisc:allnoconfig:

> > 

> > kernel/built-in.o: In function `alarm_handle_timer':

> > alarmtimer.c:(.text+0x3fca4): undefined reference to `posix_timer_event'

> > 

> > unicore32:allnoconfig:

> > 

> > kernel/built-in.o: In function `alarm_handle_timer':

> > memremap.c:(.text+0x31c1c): undefined reference to `posix_timer_event'

> > 

> > Since I don't run allnoconfig builds for all architectures, I strongly suspect

> > that more are affected.

> 

> This is a known problem. Oddly enough only those "less popular" 

> architectures are affected.

> 

> > Looking into alarmtimer.c, with seems to call posix_timer_event() 

> > unconditionally, I don't entirely understand how this can work in the 

> > first place. Maybe I am missing something, though.

> 

> The magic is in alarmtimer_init():

> 

>         if (IS_ENABLED(CONFIG_POSIX_TIMERS)) {

>                 posix_timers_register_clock(CLOCK_REALTIME_ALARM, &alarm_clock);

>                 posix_timers_register_clock(CLOCK_BOOTTIME_ALARM, &alarm_clock);

>         }

> 

> If CONFIG_POSIX_TIMERS is not enabled, the condition becomes a constant 

> zero. The posix_timers_register_clock calls are then optimized away by 

> the compiler. In turn the alarm_clock structure has no longer any 

> reference to it and therefore is also optimized away, including its 

> method functions such as alarm_timer_create() and finally 

> alarm_handle_timer().

> 

> But for some reasons, some gcc versions (mainly for "secondary" 

> architectures) fail to optimize away all that code, and a dead reference 

> to posix_timer_event() remains in the compiled code.

> 

> There is a fix already queued in the mm tree. It goes like this:

> 

>     posix-timers: give lazy compilers some help optimizing code away

>     

>     The OpenRISC compiler (so far) fails to optimize away a large portion

>     of code containing a reference to posix_timer_event in alarmtimer.c when

>     CONFIG_POSIX_TIMERS is unset. Let's give it a direct clue to let the build

>     succeed.


To be fair, this might be related to compiler version only.  I guess its
not an excuse, but when i compile with or1k-elf-gcc (version 5.3.0) I
dont get this issue. 

I guess other archs are not breaking because they are being tested is a
newer compiler?

Tested will allnoconfig

Compiler version:

  Using built-in specs.
  COLLECT_GCC=or1k-elf-gcc
  COLLECT_LTO_WRAPPER=/opt/shorne/software/or1k/libexec/gcc/or1k-elf/5.3.0/lto-wrapper
  Target: or1k-elf
  Configured with: ../or1k-gcc/configure --target=or1k-elf --prefix=/opt/shorne/software/or1k --enable-languages=c,c++ --disable-shared --disable-libssp --with-newlib
  Thread model: single
  gcc version 5.3.0 (GCC) 

-Stafford
  
>     This fixes

>     [linux-next:master 6682/7183] alarmtimer.c:undefined reference to `posix_timer_event'

>     reported by kbuild test robot.

>     

>     Signed-off-by: Nicolas Pitre <nico@linaro.org>

>     Cc: Thomas Gleixner <tglx@linutronix.de>

>     Cc: Josh Triplett <josh@joshtriplett.org>

>     Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

> 

> diff --git a/kernel/time/alarmtimer.c b/kernel/time/alarmtimer.c

> index 9b08ca391a..3921cf7fea 100644

> --- a/kernel/time/alarmtimer.c

> +++ b/kernel/time/alarmtimer.c

> @@ -516,7 +516,8 @@ static enum alarmtimer_restart alarm_handle_timer(struct alarm *alarm,

>  

>  	spin_lock_irqsave(&ptr->it_lock, flags);

>  	if ((ptr->it_sigev_notify & ~SIGEV_THREAD_ID) != SIGEV_NONE) {

> -		if (posix_timer_event(ptr, 0) != 0)

> +		if (IS_ENABLED(CONFIG_POSIX_TIMERS) &&

> +		    posix_timer_event(ptr, 0) != 0)

>  			ptr->it_overrun++;

>  	}

>

Patch

diff --git a/kernel/time/alarmtimer.c b/kernel/time/alarmtimer.c
index 9b08ca391a..3921cf7fea 100644
--- a/kernel/time/alarmtimer.c
+++ b/kernel/time/alarmtimer.c
@@ -516,7 +516,8 @@  static enum alarmtimer_restart alarm_handle_timer(struct alarm *alarm,
 
 	spin_lock_irqsave(&ptr->it_lock, flags);
 	if ((ptr->it_sigev_notify & ~SIGEV_THREAD_ID) != SIGEV_NONE) {
-		if (posix_timer_event(ptr, 0) != 0)
+		if (IS_ENABLED(CONFIG_POSIX_TIMERS) &&
+		    posix_timer_event(ptr, 0) != 0)
 			ptr->it_overrun++;
 	}