public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Arnd Bergmann <arnd@arndb.de>
To: Nishanth Aravamudan <nacc@us.ibm.com>
Cc: Al Borchers <alborchers@steinerpoint.com>,
	david-b@pacbell.net, greg@kroah.com,
	linux-kernel@vger.kernel.org
Subject: Re: [RFC UPDATE PATCH] add wait_event_*_lock() functions and comments
Date: Sat, 12 Feb 2005 12:38:26 +0100	[thread overview]
Message-ID: <200502121238.31478.arnd@arndb.de> (raw)
In-Reply-To: <20050211195553.GE2372@us.ibm.com>

[-- Attachment #1: Type: text/plain, Size: 2906 bytes --]

On Freedag 11 Februar 2005 20:55, Nishanth Aravamudan wrote:

> + * If the macro name contains:
> + * 	lock, then @lock should be held before calling wait_event*().
> + * 		It is released before sleeping and grabbed after
> + * 		waking, saving the current IRQ mask in @flags. This lock
> + * 		should also be held when changing any variables
> + * 		affecting the condition and when waking up the process.

Hmm, I see two problems with that approach:

1. It might lead to people not thinking about their locking order
thoroughly if you introduce a sleeping function that is called with
a spinlock held. Anyone relying on that lock introduces races because
it actually is given up by the macro. I'd prefer it to be called 
without the lock and then have it acquire the lock only to check the
condition, e.g:

#define __wait_event_lock(wq, condition, lock, flags)                  \
do {                                                                   \
       DEFINE_WAIT(__wait);                                            \
                                                                       \
       for (;;) {                                                      \
               prepare_to_wait(&wq, &__wait, TASK_UNINTERRUPTIBLE);    \
               spin_lock_irqsave(lock, flags);                         \
               if (condition)                                          \
                       break;                                          \
               spin_unlock_irqrestore(lock, flags);                    \
               schedule();                                             \
       }                                                               \
       spin_unlock_irqrestore(lock, flags);                            \
       finish_wait(&wq, &__wait);                                      \
} while (0)

2. You define the macros only for using spin_lock_irqsave. To make the
API complete, you would also need
spin_lock()
spin_lock_irq()
spin_lock_bh()
read_lock()
read_lock_irq()
read_lock_bh()
read_lock_irqsave()
write_lock()
write_lock_irq()
write_lock_bh()
write_lock_irqsave()

Of course, that is complete overkill if you want to define all the 
wait_event variations for each of those locking variations, but sooner or
later someone will want another one.

One solution that might work could look like
#define __cond_spin_locked(cond, lock) \
	({ __typeof__(cond) c; spin_lock(lock); \
		c = (cond); spin_unlock(lock); c; })

#define wait_event_lock(wq, condition, lock) \
	wait_event(wq, __cond_spin_locked(condition, lock))

#define wait_event_timeout_lock(wq, condition, lock, flags, timeout) \
	wait_event_timeout(wq, __cond_spin_locked(condition, lock), timeout)

and so forth.

OTOH, that is easy enough that it can as well be encapsulated in the
places where it is needed.

	Arnd <><

[-- Attachment #2: signature --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

  reply	other threads:[~2005-02-12 11:49 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-02-11  7:07 [RFC PATCH] add wait_event_*_lock() functions Al Borchers
2005-02-11 17:31 ` Nishanth Aravamudan
2005-02-11 19:55 ` [RFC UPDATE PATCH] add wait_event_*_lock() functions and comments Nishanth Aravamudan
2005-02-12 11:38   ` Arnd Bergmann [this message]
2005-02-12 13:28     ` Sergey Vlasov
2005-02-13  2:41       ` Arnd Bergmann
2005-02-13  5:00         ` Nish Aravamudan
2005-02-15  1:04           ` Nishanth Aravamudan
2005-02-15 17:50             ` Arnd Bergmann
2005-02-15 18:19               ` Nish Aravamudan

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=200502121238.31478.arnd@arndb.de \
    --to=arnd@arndb.de \
    --cc=alborchers@steinerpoint.com \
    --cc=david-b@pacbell.net \
    --cc=greg@kroah.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=nacc@us.ibm.com \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox