10 Jul, 2009

2 commits

  • The timer migration expiry check should prevent the migration of a
    timer to another CPU when the timer expires before the next event is
    scheduled on the other CPU. Migrating the timer might delay it because
    we can not reprogram the clock event device on the other CPU. But the
    code implementing that check has two flaws:

    - for !HIGHRES the check compares the expiry value with the clock
    events device expiry value which is wrong for CLOCK_REALTIME based
    timers.

    - the check is racy. It holds the hrtimer base lock of the target CPU,
    but the clock event device expiry value can be modified
    nevertheless, e.g. by an timer interrupt firing.

    The !HIGHRES case is easy to fix as we can enqueue the timer on the
    cpu which was selected by the load balancer. It runs the idle
    balancing code once per jiffy anyway. So the maximum delay for the
    timer is the same as when we keep the tick on the current cpu going.

    In the HIGHRES case we can get the next expiry value from the hrtimer
    cpu_base of the target CPU and serialize the update with the cpu_base
    lock. This moves the lock section in hrtimer_interrupt() so we can set
    next_event to KTIME_MAX while we are handling the expired timers and
    set it to the next expiry value after we handled the timers under the
    base lock. While the expired timers are processed timer migration is
    blocked because the expiry time of the timer is always

    Thomas Gleixner
     
  • The timer migration code needs to check whether the expiry time of the
    timer is before the programmed clock event expiry time when the timer
    is enqueued on another CPU because we can not reprogram the timer
    device on the other CPU. The current logic checks the expiry time even
    if we enqueue on the current CPU when nohz_get_load_balancer() returns
    current CPU. This might lead to an endless loop in the expiry check
    code when the expiry time of the timer is before the current
    programmed next event.

    Check whether nohz_get_load_balancer() returns current CPU and skip
    the expiry check if this is the case.

    The bug was triggered from the networking code. The patch fixes the
    regression http://bugzilla.kernel.org/show_bug.cgi?id=13738
    (Soft-Lockup/Race in networking in 2.6.31-rc1+195)

    Cc: Arun Bharadwaj
    Tested-by: Andres Freund
    Signed-off-by: Thomas Gleixner

    Thomas Gleixner
     

24 Jun, 2009

1 commit

  • When the kernel is configured with CONFIG_TIMER_STATS but timer
    stats are runtime disabled we still get calls to
    __timer_stats_timer_set_start_info which initializes some
    fields in the corresponding struct timer_list.

    So add some quick checks in the the timer stats setup functions
    to avoid function calls to __timer_stats_timer_set_start_info
    when timer stats are disabled.

    In an artificial workload that does nothing but playing ping
    pong with a single tcp packet via loopback this decreases cpu
    consumption by 1 - 1.5%.

    This is part of a modified function trace output on SLES11:

    perl-2497 [00] 28630647177732388 [+ 125]: sk_reset_timer
    Cc: Andrew Morton
    Cc: Martin Schwidefsky
    Cc: Mustafa Mesanovic
    Cc: Arjan van de Ven
    LKML-Reference:
    Signed-off-by: Ingo Molnar

    Heiko Carstens
     

23 Jun, 2009

37 commits