All of lore.kernel.org
 help / color / mirror / Atom feed
From: Thomas Gleixner <tglx@linutronix.de>
To: Chen Gang <gang.chen@asianux.com>
Cc: "linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH] kernel/timer.c: using spin_lock_irqsave instead of spin_lock + local_irq_save, especially when CONFIG_LOCKDEP not defined
Date: Wed, 19 Jun 2013 12:49:10 +0200 (CEST)	[thread overview]
Message-ID: <alpine.DEB.2.02.1306191228030.4013@ionos.tec.linutronix.de> (raw)
In-Reply-To: <51C182EE.5070500@asianux.com>

On Wed, 19 Jun 2013, Chen Gang wrote:
> On 06/19/2013 05:59 PM, Thomas Gleixner wrote:
> > Lockdep tracks lock ordering and the context in which a lock is
> > taken. The timer base lock can be taken in interrupt context, so it
> > always needs to be taken with interrupts disabled. That's what lockdep
> > cares about.
> > 
> > And 
> > 	spin_lock_irqsave(&l1, flags);
> > 	spin_unlock(&l1);
> > 	spin_lock(&l2);
> > 	spin_unlock_irqrestore(&l2, flags);
> > 
> > fulfils that for both l1 and l2.
> > 
> > It does not matter whether the code pathes are different, what matters
> > is that they are semantically the same. And that's the case.
> 
> But I feel, they are not semantically the same.

This is not about feelings. This is about facts.
 
> if CONFIG_LOCKDEP is not defined, spin_lock_irqsave() should call
> do_raw_spin_lock_flags(), not call LOCK_CONTENDED().

That is what the code already does:

#ifdef CONFIG_LOCKDEP
        LOCK_CONTENDED(lock, do_raw_spin_trylock, do_raw_spin_lock);
#else
	do_raw_spin_lock_flags(lock, &flags);
#endif

If LOCKDEP is not defined it calls do_raw_spin_lock_flags(). Where is
your point?

And the reason why the LOCKDEP case and the !LOCKDEP case are
different is explained in the comment above that code. And both behave
the same way versus the spinlock semantics.

We must do this because some architectures implement
do_raw_spin_lock_flags() in the following way:

do_raw_spin_lock_flags(l, flags)
{
	while (!arch_spin_trylock(l)) {
	      if (!irq_disabled_flags(flags)) {
	      	      arch_irq_restore(flags);
		      cpu_relax();
		      arch_irq_disable();
	      }
	}
}

This is done to limit irq disabled time while we wait for the
lock. Though most architectures implement it as:

	while (!arch_spin_trylock(l))
	      cpu_relax();

In the lockdep case we CANNOT reenable interrupts in the spinning code
and therefor we use the 

	while (!arch_spin_trylock(l))
	      cpu_relax();

variant.

And again. Both are semantically the same.

spin_lock_irqsave() semantics are:

The function returns with the lock acquired, interrupts and preemption
disabled. Both variants do that.

The internal details whether an architecture reenables interrupts
while spinning on a contended lock or not are completely irrelevant
and do not affect the correctness of the code.

Thanks,

	tglx

  reply	other threads:[~2013-06-19 10:49 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-06-19  2:59 [PATCH] kernel/timer.c: using spin_lock_irqsave instead of spin_lock + local_irq_save, especially when CONFIG_LOCKDEP not defined Chen Gang
2013-06-19  8:41 ` Thomas Gleixner
2013-06-19  9:42   ` Chen Gang
2013-06-19  9:59     ` Thomas Gleixner
2013-06-19 10:07       ` Chen Gang
2013-06-19 10:49         ` Thomas Gleixner [this message]
2013-06-20  4:14           ` Chen Gang
2013-06-20  7:36             ` Thomas Gleixner
2013-06-20  8:42               ` Chen Gang
2013-06-20  9:02                 ` Thomas Gleixner
2013-06-20 10:31                   ` Chen Gang
2013-06-19 10:21       ` Chen Gang
2013-06-19 10:53         ` Thomas Gleixner
2013-06-20  8:37           ` Chen Gang
2013-06-20  9:07             ` Thomas Gleixner
2013-06-20  9:53               ` Chen Gang
2013-06-20 10:42                 ` Thomas Gleixner
2013-06-20 10:59                   ` Chen Gang
2013-06-20  9:12             ` Eric Dumazet

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=alpine.DEB.2.02.1306191228030.4013@ionos.tec.linutronix.de \
    --to=tglx@linutronix.de \
    --cc=gang.chen@asianux.com \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.