On Tue, May 28, 2019 at 05:16:23PM +0200, Daniel Bristot de Oliveira wrote: > The preempt_disable/enable tracepoint only traces in the disable <-> enable > case, which is correct. But think about this case: > > ---------------------------- %< ------------------------------ > THREAD IRQ > | | > preempt_disable() { > __preempt_count_add(1) > -------> smp_apic_timer_interrupt() { > preempt_disable() > do not trace (preempt count >= 1) > .... > preempt_enable() > do not trace (preempt count >= 1) > } > trace_preempt_disable(); > } > ---------------------------- >% ------------------------------ > > The tracepoint will be skipped.
.... for the IRQ. But IRQs are not preemptible anyway, so what the problem? > To avoid skipping the trace, the change in the counter should be "atomic" > with the start/stop, w.r.t the interrupts. > > Disable interrupts while the adding/starting stopping/subtracting. > +static inline void preempt_add_start_latency(int val) > +{ > + unsigned long flags; > + > + raw_local_irq_save(flags); > + __preempt_count_add(val); > + preempt_latency_start(val); > + raw_local_irq_restore(flags); > +} > +static inline void preempt_sub_stop_latency(int val) > +{ > + unsigned long flags; > + > + raw_local_irq_save(flags); > + preempt_latency_stop(val); > + __preempt_count_sub(val); > + raw_local_irq_restore(flags); > +} That is hideously expensive :/