lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Thu, 21 May 2020 23:25:32 +0200
From:   Thomas Gleixner <tglx@...utronix.de>
To:     paulmck@...nel.org
Cc:     LKML <linux-kernel@...r.kernel.org>,
        Andy Lutomirski <luto@...nel.org>,
        Andrew Cooper <andrew.cooper3@...rix.com>,
        X86 ML <x86@...nel.org>,
        Alexandre Chartre <alexandre.chartre@...cle.com>,
        Frederic Weisbecker <frederic@...nel.org>,
        Paolo Bonzini <pbonzini@...hat.com>,
        Sean Christopherson <sean.j.christopherson@...el.com>,
        Masami Hiramatsu <mhiramat@...nel.org>,
        Petr Mladek <pmladek@...e.com>,
        Steven Rostedt <rostedt@...dmis.org>,
        Joel Fernandes <joel@...lfernandes.org>,
        Boris Ostrovsky <boris.ostrovsky@...cle.com>,
        Juergen Gross <jgross@...e.com>,
        Brian Gerst <brgerst@...il.com>,
        Mathieu Desnoyers <mathieu.desnoyers@...icios.com>,
        Josh Poimboeuf <jpoimboe@...hat.com>,
        Will Deacon <will@...nel.org>,
        Tom Lendacky <thomas.lendacky@....com>,
        Wei Liu <wei.liu@...nel.org>,
        Michael Kelley <mikelley@...rosoft.com>,
        Jason Chen CJ <jason.cj.chen@...el.com>,
        Zhao Yakui <yakui.zhao@...el.com>,
        "Peter Zijlstra \(Intel\)" <peterz@...radead.org>
Subject: Re: [patch V9 02/39] rcu: Abstract out rcu_irq_enter_check_tick() from rcu_nmi_enter()

"Paul E. McKenney" <paulmck@...nel.org> writes:
> On Thu, May 21, 2020 at 10:05:15PM +0200, Thomas Gleixner wrote:
>> +void __rcu_irq_enter_check_tick(void);
>> +
>> +static __always_inline void rcu_irq_enter_check_tick(void)
>> +{
>> +	if (context_tracking_enabled())
>> +		__rcu_irq_enter_check_tick();
>
> I suggest moving the WARN_ON_ONCE(in_nmi()) check here to avoid calling
> in_nmi() twice.  Because of the READ_ONCE(), the compiler cannot (had
> better not!) eliminate the double call.

Makes sense.

>> +void __rcu_irq_enter_check_tick(void)
>> +{
>> +	struct rcu_data *rdp = this_cpu_ptr(&rcu_data);
>> +
>> +	 // Enabling the tick is unsafe in NMI handlers.
>
> There is an extra space before the "//", probably the one that used to
> be after the ";" below.  ;-)

This is caused by my fundamental and not suppressible disgust of tail
comments. They really disturb the reading flow for me.

          if (foo)
          	return; // Because ...

makes my pattern recognition stop because the semicolon is usually the
end of the statement. But that's not the only reason.

         // Because ....
         if (foo)
         	return;

makes more sense to me because then the comment is explaining the
condition and not the outcome. The outcome is obvious when the condition
is well explained.

There are a few exceptions where I adjusted, e.g. in macros:

        foo();				\
        bar_or_something_else();	\

but only when the trailing backslash is properly aligned.

        foo();		\
        bar_or_something_else();	\

That stops the parser as well.

I know that this is a pet pieve but I can't help it to adjust it when I
have a chance to do so :)

>> +	if (WARN_ON_ONCE(in_nmi()))
>> +		return;
>> +
>> +	RCU_LOCKDEP_WARN(rcu_dynticks_curr_cpu_in_eqs(),
>> +			 "Illegal rcu_irq_enter_check_tick() from extended quiescent state");
>
> The instrumentation_begin() has disappeared, presumably because
> instrumentation is already enabled in the non-RCU code that directly calls
> rcu_irq_enter_check_tick().  (I do see the calls in rcu_nmi_enter()
> below.)

Yes. The intention here is to make sure that the caller does not
misplace it. So if the call is in a non-instrumentable code path then
objtool will complain and the developer will hopefully think twice
whether this is the right place to wrap the call with instrumentation_*
annotations. I know it's based on hope :)

>> +
>> +	if (!tick_nohz_full_cpu(rdp->cpu) ||
>> +	    !READ_ONCE(rdp->rcu_urgent_qs) ||
>> +	    READ_ONCE(rdp->rcu_forced_tick)) {
>> +		// RCU doesn't need nohz_full help from this CPU, or it is
>> +		// already getting that help.
>> +		return;
>> +	}
>> +
>> +	// We get here only when not in an extended quiescent state and
>> +	// from interrupts (as opposed to NMIs).  Therefore, (1) RCU is
>> +	// already watching and (2) The fact that we are in an interrupt
>> +	// handler and that the rcu_node lock is an irq-disabled lock
>> +	// prevents self-deadlock.  So we can safely recheck under the lock.
>> +	// Note that the nohz_full state currently cannot change.
>> +	raw_spin_lock_rcu_node(rdp->mynode);
>> +	if (rdp->rcu_urgent_qs && !rdp->rcu_forced_tick) {
>> +		// A nohz_full CPU is in the kernel and RCU needs a
>> +		// quiescent state.  Turn on the tick!
>> +		WRITE_ONCE(rdp->rcu_forced_tick, true);
>> +		tick_dep_set_cpu(rdp->cpu, TICK_DEP_BIT_RCU);
>> +	}
>> +	raw_spin_unlock_rcu_node(rdp->mynode);
>> +}
>>  #endif /* CONFIG_NO_HZ_FULL */
>>  
>>  /**
>> @@ -894,26 +955,7 @@ noinstr void rcu_nmi_enter(void)
>>  		incby = 1;
>>  	} else if (!in_nmi()) {
>
> This can just be "else" given the in_nmi() check in
> __rcu_irq_enter_check_tick(), right?  Ah, that check got a
> WARN_ON_ONCE(), so never mind!
>
> I guess that will discourage NMI-handler calls to
> rcu_irq_enter_check_tick().  ;-)

Exactly.

> It does mean a double call to in_nmi(), though, so should that
> WARN_ON_ONCE(in_nmi()) check go into the rcu_irq_enter_check_tick()
> wrapper?  Or do modern compilers figure this one out?  Given the
> READ_ONCE() in preempt_count(), I have to say that I hope not.
> So see my comment above on rcu_irq_enter_check_tick().

Moving it to the wrapper is the right thing to do. Will fix.

Thanks,

        tglx

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ