From: Arnd Bergmann <arnd@arndb.de>
To: Greg KH <gregkh@suse.de>
Cc: linux-kernel@vger.kernel.org, Arnd Bergmann <arnd@arndb.de>,
Alan Cox <alan@lxorguk.ukuu.org.uk>,
Frederic Weisbecker <fweisbec@gmail.com>,
John Kacur <jkacur@redhat.com>
Subject: [PATCH 25/31] tty: introduce wait_event_interruptible_tty
Date: Tue, 1 Jun 2010 22:53:05 +0200 [thread overview]
Message-ID: <1275425591-8803-26-git-send-email-arnd@arndb.de> (raw)
In-Reply-To: <1275425591-8803-1-git-send-email-arnd@arndb.de>
Calling wait_event_interruptible implicitly
releases the BKL when it sleeps, but we need
to do this explcitly when we have converted
it to a mutex.
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
drivers/char/cyclades.c | 2 +-
drivers/char/istallion.c | 12 ++++++++----
drivers/char/n_r3964.c | 2 +-
drivers/char/tty_port.c | 2 +-
drivers/char/vt_ioctl.c | 2 +-
drivers/serial/crisv10.c | 4 ++--
include/linux/tty.h | 42 ++++++++++++++++++++++++++++++++++++++++++
7 files changed, 56 insertions(+), 10 deletions(-)
diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c
index 51acfe3..27aad94 100644
--- a/drivers/char/cyclades.c
+++ b/drivers/char/cyclades.c
@@ -1607,7 +1607,7 @@ static int cy_open(struct tty_struct *tty, struct file *filp)
* If the port is the middle of closing, bail out now
*/
if (tty_hung_up_p(filp) || (info->port.flags & ASYNC_CLOSING)) {
- wait_event_interruptible(info->port.close_wait,
+ wait_event_interruptible_tty(info->port.close_wait,
!(info->port.flags & ASYNC_CLOSING));
return (info->port.flags & ASYNC_HUP_NOTIFY) ? -EAGAIN: -ERESTARTSYS;
}
diff --git a/drivers/char/istallion.c b/drivers/char/istallion.c
index 5e9a81d..be28391 100644
--- a/drivers/char/istallion.c
+++ b/drivers/char/istallion.c
@@ -954,7 +954,7 @@ static int stli_rawopen(struct stlibrd *brdp, struct stliport *portp, unsigned l
* order of opens and closes may not be preserved across shared
* memory, so we must wait until it is complete.
*/
- wait_event_interruptible(portp->raw_wait,
+ wait_event_interruptible_tty(portp->raw_wait,
!test_bit(ST_CLOSING, &portp->state));
if (signal_pending(current)) {
return -ERESTARTSYS;
@@ -989,7 +989,7 @@ static int stli_rawopen(struct stlibrd *brdp, struct stliport *portp, unsigned l
set_bit(ST_OPENING, &portp->state);
spin_unlock_irqrestore(&brd_lock, flags);
- wait_event_interruptible(portp->raw_wait,
+ wait_event_interruptible_tty(portp->raw_wait,
!test_bit(ST_OPENING, &portp->state));
if (signal_pending(current))
rc = -ERESTARTSYS;
@@ -1020,7 +1020,7 @@ static int stli_rawclose(struct stlibrd *brdp, struct stliport *portp, unsigned
* occurs on this port.
*/
if (wait) {
- wait_event_interruptible(portp->raw_wait,
+ wait_event_interruptible_tty(portp->raw_wait,
!test_bit(ST_CLOSING, &portp->state));
if (signal_pending(current)) {
return -ERESTARTSYS;
@@ -1052,7 +1052,7 @@ static int stli_rawclose(struct stlibrd *brdp, struct stliport *portp, unsigned
* to come back.
*/
rc = 0;
- wait_event_interruptible(portp->raw_wait,
+ wait_event_interruptible_tty(portp->raw_wait,
!test_bit(ST_CLOSING, &portp->state));
if (signal_pending(current))
rc = -ERESTARTSYS;
@@ -1073,6 +1073,10 @@ static int stli_rawclose(struct stlibrd *brdp, struct stliport *portp, unsigned
static int stli_cmdwait(struct stlibrd *brdp, struct stliport *portp, unsigned long cmd, void *arg, int size, int copyback)
{
+ /*
+ * no need for wait_event_tty because clearing ST_CMDING cannot block
+ * on BTM
+ */
wait_event_interruptible(portp->raw_wait,
!test_bit(ST_CMDING, &portp->state));
if (signal_pending(current))
diff --git a/drivers/char/n_r3964.c b/drivers/char/n_r3964.c
index f4bd259..a98290d 100644
--- a/drivers/char/n_r3964.c
+++ b/drivers/char/n_r3964.c
@@ -1079,7 +1079,7 @@ static ssize_t r3964_read(struct tty_struct *tty, struct file *file,
goto unlock;
}
/* block until there is a message: */
- wait_event_interruptible(pInfo->read_wait,
+ wait_event_interruptible_tty(pInfo->read_wait,
(pMsg = remove_msg(pInfo, pClient)));
}
diff --git a/drivers/char/tty_port.c b/drivers/char/tty_port.c
index a3bd1d0..35eb304 100644
--- a/drivers/char/tty_port.c
+++ b/drivers/char/tty_port.c
@@ -231,7 +231,7 @@ int tty_port_block_til_ready(struct tty_port *port,
/* block if port is in the process of being closed */
if (tty_hung_up_p(filp) || port->flags & ASYNC_CLOSING) {
- wait_event_interruptible(port->close_wait,
+ wait_event_interruptible_tty(port->close_wait,
!(port->flags & ASYNC_CLOSING));
if (port->flags & ASYNC_HUP_NOTIFY)
return -EAGAIN;
diff --git a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c
index cc07fab..c56c4f3 100644
--- a/drivers/char/vt_ioctl.c
+++ b/drivers/char/vt_ioctl.c
@@ -133,7 +133,7 @@ static void vt_event_wait(struct vt_event_wait *vw)
list_add(&vw->list, &vt_events);
spin_unlock_irqrestore(&vt_event_lock, flags);
/* Wait for it to pass */
- wait_event_interruptible(vt_event_waitqueue, vw->done);
+ wait_event_interruptible_tty(vt_event_waitqueue, vw->done);
/* Dequeue it */
spin_lock_irqsave(&vt_event_lock, flags);
list_del(&vw->list);
diff --git a/drivers/serial/crisv10.c b/drivers/serial/crisv10.c
index d11d898..e6a1cb7 100644
--- a/drivers/serial/crisv10.c
+++ b/drivers/serial/crisv10.c
@@ -3981,7 +3981,7 @@ block_til_ready(struct tty_struct *tty, struct file * filp,
*/
if (tty_hung_up_p(filp) ||
(info->flags & ASYNC_CLOSING)) {
- wait_event_interruptible(info->close_wait,
+ wait_event_interruptible_tty(info->close_wait,
!(info->flags & ASYNC_CLOSING));
#ifdef SERIAL_DO_RESTART
if (info->flags & ASYNC_HUP_NOTIFY)
@@ -4139,7 +4139,7 @@ rs_open(struct tty_struct *tty, struct file * filp)
*/
if (tty_hung_up_p(filp) ||
(info->flags & ASYNC_CLOSING)) {
- wait_event_interruptible(info->close_wait,
+ wait_event_interruptible_tty(info->close_wait,
!(info->flags & ASYNC_CLOSING));
#ifdef SERIAL_DO_RESTART
return ((info->flags & ASYNC_HUP_NOTIFY) ?
diff --git a/include/linux/tty.h b/include/linux/tty.h
index faf0bcd..18a7955 100644
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -603,5 +603,47 @@ static inline void tty_unlock(void) __releases(kernel_lock)
}
#define tty_locked() (kernel_locked())
+/*
+ * wait_event_interruptible_tty -- wait for a condition with the tty lock held
+ *
+ * The condition we are waiting for might take a long time to
+ * become true, or might depend on another thread taking the
+ * BTM. In either case, we need to drop the BTM to guarantee
+ * forward progress. This is a leftover from the conversion
+ * from the BKL and should eventually get removed as the BTM
+ * falls out of use.
+ *
+ * Do not use in new code.
+ */
+#define wait_event_interruptible_tty(wq, condition) \
+({ \
+ int __ret = 0; \
+ if (!(condition)) { \
+ __wait_event_interruptible_tty(wq, condition, __ret); \
+ } \
+ __ret; \
+})
+
+#define __wait_event_interruptible_tty(wq, condition, ret) \
+do { \
+ DEFINE_WAIT(__wait); \
+ \
+ for (;;) { \
+ prepare_to_wait(&wq, &__wait, TASK_INTERRUPTIBLE); \
+ if (condition) \
+ break; \
+ if (!signal_pending(current)) { \
+ tty_unlock(); \
+ schedule(); \
+ tty_lock(); \
+ continue; \
+ } \
+ ret = -ERESTARTSYS; \
+ break; \
+ } \
+ finish_wait(&wq, &__wait); \
+} while (0)
+
+
#endif /* __KERNEL__ */
#endif
--
1.7.0.4
next prev parent reply other threads:[~2010-06-01 20:58 UTC|newest]
Thread overview: 37+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-06-01 20:52 [PATCH 00/31] tty: BKL removal Arnd Bergmann
2010-06-01 20:52 ` [PATCH 01/31] stallion: prune lock_kernel calls Arnd Bergmann
2010-06-01 20:52 ` [PATCH 02/31] istallion: use bit ops for the board flags Arnd Bergmann
2010-06-01 20:52 ` [PATCH 03/31] riscom8: kill use of lock_kernel Arnd Bergmann
2010-06-01 20:52 ` [PATCH 04/31] isicom: kill off the BKL Arnd Bergmann
2010-06-01 20:52 ` [PATCH 05/31] rocket: kill BKL Arnd Bergmann
2010-06-01 20:52 ` [PATCH 06/31] synclink: kill the big kernel lock Arnd Bergmann
2010-06-01 20:52 ` [PATCH 07/31] cyclades: Kill off BKL usage Arnd Bergmann
2010-06-01 20:52 ` [PATCH 08/31] epca: Kill the big kernel lock Arnd Bergmann
2010-06-01 20:52 ` [PATCH 09/31] specialix; Kill the BKL Arnd Bergmann
2010-06-01 20:52 ` [PATCH 10/31] synclink: reworking locking a bit Arnd Bergmann
2010-06-01 20:52 ` [PATCH 11/31] tty: serial - fix various misuses/mishandlings of port->tty Arnd Bergmann
2010-06-01 20:52 ` [PATCH 12/31] tty: serial - fix tty back references in termios Arnd Bergmann
2010-06-17 18:50 ` Tony Luck
2010-06-17 20:21 ` Greg KH
2010-06-01 20:52 ` [PATCH 13/31] tty: serial - fix tty referencing in set_ldisc Arnd Bergmann
2010-06-01 20:52 ` [PATCH 14/31] vc: Locking clean up Arnd Bergmann
2010-06-01 20:52 ` [PATCH 15/31] tty: Make vt's have a tty_port Arnd Bergmann
2010-06-01 20:52 ` [PATCH 16/31] tty: Move the vt_tty field from the vc_data into the standard tty_port Arnd Bergmann
2010-06-01 20:52 ` [PATCH 17/31] serial: Change the wait for carrier locking Arnd Bergmann
2010-06-01 20:52 ` [PATCH 18/31] serial: add port helpers Arnd Bergmann
2010-06-01 20:52 ` [PATCH 19/31] serial: trim locking on the helpers Arnd Bergmann
2010-06-01 20:53 ` [PATCH 20/31] serial: Use block_til_ready helper Arnd Bergmann
2010-06-01 20:53 ` [PATCH 21/31] tty: replace BKL with a new tty_lock Arnd Bergmann
2010-06-01 20:53 ` [PATCH 22/31] tty: never hold BTM while getting tty_mutex Arnd Bergmann
2010-06-01 20:53 ` [PATCH 23/31] tty: fix console_sem lock order Arnd Bergmann
2010-06-01 20:53 ` [PATCH 24/31] cdc-acm: remove dead code Arnd Bergmann
2010-06-01 20:53 ` Arnd Bergmann [this message]
2010-06-01 20:53 ` [PATCH 26/31] tty: reorder ldisc locking Arnd Bergmann
2010-06-01 20:53 ` [PATCH 27/31] tty: untangle locking of wait_until_sent Arnd Bergmann
2010-06-01 20:53 ` [PATCH 28/31] tty: remove tty_lock_nested Arnd Bergmann
2010-06-01 20:53 ` [PATCH 29/31] tty: implement BTM as mutex instead of BKL Arnd Bergmann
2010-06-01 20:53 ` [PATCH 30/31] tty: release BTM while sleeping in block_til_ready Arnd Bergmann
2010-06-01 20:53 ` [PATCH 31/31] 8250: fix set_ldisc operation Arnd Bergmann
2010-06-02 22:16 ` [PATCH 00/31] tty: BKL removal Arnd Bergmann
2010-06-02 23:10 ` Greg KH
2010-06-16 20:49 ` Greg KH
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=1275425591-8803-26-git-send-email-arnd@arndb.de \
--to=arnd@arndb.de \
--cc=alan@lxorguk.ukuu.org.uk \
--cc=fweisbec@gmail.com \
--cc=gregkh@suse.de \
--cc=jkacur@redhat.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®