lkml.org 
[lkml]   [2020]   [Mar]   [18]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[patch V2 13/15] lockdep: Add hrtimer context tracing bits
    From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>

    Set current->irq_config = 1 for hrtimers which are not marked to expire in
    hard interrupt context during hrtimer_init(). These timers will expire in
    softirq context on PREEMPT_RT.

    Setting this allows lockdep to differentiate these timers. If a timer is
    marked to expire in hard interrupt context then the timer callback is not
    supposed to acquire a regular spinlock instead of a raw_spinlock in the
    expiry callback.

    Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
    Signed-off-by: Thomas Gleixner <tglx@linutronix.de>

    ---
    include/linux/irqflags.h | 15 +++++++++++++++
    include/linux/sched.h | 1 +
    kernel/locking/lockdep.c | 2 +-
    kernel/time/hrtimer.c | 6 +++++-
    4 files changed, 22 insertions(+), 2 deletions(-)

    --- a/include/linux/irqflags.h
    +++ b/include/linux/irqflags.h
    @@ -56,6 +56,19 @@ do { \
    do { \
    current->softirq_context--; \
    } while (0)
    +
    +# define lockdep_hrtimer_enter(__hrtimer) \
    + do { \
    + if (!__hrtimer->is_hard) \
    + current->irq_config = 1; \
    + } while (0)
    +
    +# define lockdep_hrtimer_exit(__hrtimer) \
    + do { \
    + if (!__hrtimer->is_hard) \
    + current->irq_config = 0; \
    + } while (0)
    +
    #else
    # define trace_hardirqs_on() do { } while (0)
    # define trace_hardirqs_off() do { } while (0)
    @@ -68,6 +81,8 @@ do { \
    # define trace_hardirq_exit() do { } while (0)
    # define lockdep_softirq_enter() do { } while (0)
    # define lockdep_softirq_exit() do { } while (0)
    +# define lockdep_hrtimer_enter(__hrtimer) do { } while (0)
    +# define lockdep_hrtimer_exit(__hrtimer) do { } while (0)
    #endif

    #if defined(CONFIG_IRQSOFF_TRACER) || \
    --- a/include/linux/sched.h
    +++ b/include/linux/sched.h
    @@ -983,6 +983,7 @@ struct task_struct {
    unsigned int softirq_enable_event;
    int softirqs_enabled;
    int softirq_context;
    + int irq_config;
    #endif

    #ifdef CONFIG_LOCKDEP
    --- a/kernel/locking/lockdep.c
    +++ b/kernel/locking/lockdep.c
    @@ -3759,7 +3759,7 @@ static int check_wait_context(struct tas
    /*
    * Check if force_irqthreads will run us threaded.
    */
    - if (curr->hardirq_threaded)
    + if (curr->hardirq_threaded || curr->irq_config)
    curr_inner = LD_WAIT_CONFIG;
    else
    curr_inner = LD_WAIT_SPIN;
    --- a/kernel/time/hrtimer.c
    +++ b/kernel/time/hrtimer.c
    @@ -1404,7 +1404,7 @@ static void __hrtimer_init(struct hrtime
    base = softtimer ? HRTIMER_MAX_CLOCK_BASES / 2 : 0;
    base += hrtimer_clockid_to_base(clock_id);
    timer->is_soft = softtimer;
    - timer->is_hard = !softtimer;
    + timer->is_hard = !!(mode & HRTIMER_MODE_HARD);
    timer->base = &cpu_base->clock_base[base];
    timerqueue_init(&timer->node);
    }
    @@ -1514,7 +1514,11 @@ static void __run_hrtimer(struct hrtimer
    */
    raw_spin_unlock_irqrestore(&cpu_base->lock, flags);
    trace_hrtimer_expire_entry(timer, now);
    + lockdep_hrtimer_enter(timer);
    +
    restart = fn(timer);
    +
    + lockdep_hrtimer_exit(timer);
    trace_hrtimer_expire_exit(timer);
    raw_spin_lock_irq(&cpu_base->lock);

    \
     
     \ /
      Last update: 2020-03-18 21:58    [W:4.094 / U:2.148 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site