Commit 817d6d3b authored by Paul Fulghum's avatar Paul Fulghum Committed by Linus Torvalds

[PATCH] remove TTY_DONT_FLIP

Remove TTY_DONT_FLIP tty flag.  This flag was introduced in 2.1.X kernels
to prevent the N_TTY line discipline functions read_chan() and
n_tty_receive_buf() from running at the same time.  2.2.15 introduced
tty->read_lock to protect access to the N_TTY read buffer, which is the
only state requiring protection between these two functions.

The current TTY_DONT_FLIP implementation is broken for SMP, and is not
universally honored by drivers that send data directly to the line
discipline receive_buf function.

Because TTY_DONT_FLIP is not necessary, is broken in implementation, and is
not universally honored, it is removed.
Signed-off-by: default avatarPaul Fulghum <paulkf@microgate.com>
Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
Cc: Theodore Ts'o <tytso@mit.edu>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent e0ac4761
...@@ -996,7 +996,6 @@ static int mxser_open(struct tty_struct *tty, struct file *filp) ...@@ -996,7 +996,6 @@ static int mxser_open(struct tty_struct *tty, struct file *filp)
info->session = current->signal->session; info->session = current->signal->session;
info->pgrp = process_group(current); info->pgrp = process_group(current);
clear_bit(TTY_DONT_FLIP, &tty->flags);
/* /*
status = mxser_get_msr(info->base, 0, info->port); status = mxser_get_msr(info->base, 0, info->port);
......
...@@ -1132,7 +1132,7 @@ static inline int input_available_p(struct tty_struct *tty, int amt) ...@@ -1132,7 +1132,7 @@ static inline int input_available_p(struct tty_struct *tty, int amt)
* buffer, and once to drain the space from the (physical) beginning of * buffer, and once to drain the space from the (physical) beginning of
* the buffer to head pointer. * the buffer to head pointer.
* *
* Called under the tty->atomic_read_lock sem and with TTY_DONT_FLIP set * Called under the tty->atomic_read_lock sem
* *
*/ */
...@@ -1271,7 +1271,6 @@ static ssize_t read_chan(struct tty_struct *tty, struct file *file, ...@@ -1271,7 +1271,6 @@ static ssize_t read_chan(struct tty_struct *tty, struct file *file,
} }
add_wait_queue(&tty->read_wait, &wait); add_wait_queue(&tty->read_wait, &wait);
set_bit(TTY_DONT_FLIP, &tty->flags);
while (nr) { while (nr) {
/* First test for status change. */ /* First test for status change. */
if (tty->packet && tty->link->ctrl_status) { if (tty->packet && tty->link->ctrl_status) {
...@@ -1315,9 +1314,7 @@ static ssize_t read_chan(struct tty_struct *tty, struct file *file, ...@@ -1315,9 +1314,7 @@ static ssize_t read_chan(struct tty_struct *tty, struct file *file,
break; break;
} }
n_tty_set_room(tty); n_tty_set_room(tty);
clear_bit(TTY_DONT_FLIP, &tty->flags);
timeout = schedule_timeout(timeout); timeout = schedule_timeout(timeout);
set_bit(TTY_DONT_FLIP, &tty->flags);
continue; continue;
} }
__set_current_state(TASK_RUNNING); __set_current_state(TASK_RUNNING);
...@@ -1394,7 +1391,6 @@ static ssize_t read_chan(struct tty_struct *tty, struct file *file, ...@@ -1394,7 +1391,6 @@ static ssize_t read_chan(struct tty_struct *tty, struct file *file,
if (time) if (time)
timeout = time; timeout = time;
} }
clear_bit(TTY_DONT_FLIP, &tty->flags);
mutex_unlock(&tty->atomic_read_lock); mutex_unlock(&tty->atomic_read_lock);
remove_wait_queue(&tty->read_wait, &wait); remove_wait_queue(&tty->read_wait, &wait);
......
...@@ -101,7 +101,7 @@ static void pty_unthrottle(struct tty_struct * tty) ...@@ -101,7 +101,7 @@ static void pty_unthrottle(struct tty_struct * tty)
* *
* FIXME: Our pty_write method is called with our ldisc lock held but * FIXME: Our pty_write method is called with our ldisc lock held but
* not our partners. We can't just take the other one blindly without * not our partners. We can't just take the other one blindly without
* risking deadlocks. There is also the small matter of TTY_DONT_FLIP * risking deadlocks.
*/ */
static int pty_write(struct tty_struct * tty, const unsigned char *buf, int count) static int pty_write(struct tty_struct * tty, const unsigned char *buf, int count)
{ {
......
...@@ -784,11 +784,8 @@ static int tty_set_ldisc(struct tty_struct *tty, int ldisc) ...@@ -784,11 +784,8 @@ static int tty_set_ldisc(struct tty_struct *tty, int ldisc)
} }
clear_bit(TTY_LDISC, &tty->flags); clear_bit(TTY_LDISC, &tty->flags);
clear_bit(TTY_DONT_FLIP, &tty->flags); if (o_tty)
if (o_tty) {
clear_bit(TTY_LDISC, &o_tty->flags); clear_bit(TTY_LDISC, &o_tty->flags);
clear_bit(TTY_DONT_FLIP, &o_tty->flags);
}
spin_unlock_irqrestore(&tty_ldisc_lock, flags); spin_unlock_irqrestore(&tty_ldisc_lock, flags);
/* /*
...@@ -1955,7 +1952,6 @@ static void release_dev(struct file * filp) ...@@ -1955,7 +1952,6 @@ static void release_dev(struct file * filp)
* race with the set_ldisc code path. * race with the set_ldisc code path.
*/ */
clear_bit(TTY_LDISC, &tty->flags); clear_bit(TTY_LDISC, &tty->flags);
clear_bit(TTY_DONT_FLIP, &tty->flags);
cancel_delayed_work(&tty->buf.work); cancel_delayed_work(&tty->buf.work);
/* /*
...@@ -2784,13 +2780,6 @@ static void flush_to_ldisc(void *private_) ...@@ -2784,13 +2780,6 @@ static void flush_to_ldisc(void *private_)
if (disc == NULL) /* !TTY_LDISC */ if (disc == NULL) /* !TTY_LDISC */
return; return;
if (test_bit(TTY_DONT_FLIP, &tty->flags)) {
/*
* Do it after the next timer tick:
*/
schedule_delayed_work(&tty->buf.work, 1);
goto out;
}
spin_lock_irqsave(&tty->buf.lock, flags); spin_lock_irqsave(&tty->buf.lock, flags);
while((tbuf = tty->buf.head) != NULL) { while((tbuf = tty->buf.head) != NULL) {
while ((count = tbuf->commit - tbuf->read) != 0) { while ((count = tbuf->commit - tbuf->read) != 0) {
...@@ -2809,7 +2798,7 @@ static void flush_to_ldisc(void *private_) ...@@ -2809,7 +2798,7 @@ static void flush_to_ldisc(void *private_)
tty_buffer_free(tty, tbuf); tty_buffer_free(tty, tbuf);
} }
spin_unlock_irqrestore(&tty->buf.lock, flags); spin_unlock_irqrestore(&tty->buf.lock, flags);
out:
tty_ldisc_deref(disc); tty_ldisc_deref(disc);
} }
......
...@@ -2573,12 +2573,6 @@ static void flush_to_flip_buffer(struct e100_serial *info) ...@@ -2573,12 +2573,6 @@ static void flush_to_flip_buffer(struct e100_serial *info)
DFLIP( DFLIP(
if (1) { if (1) {
if (test_bit(TTY_DONT_FLIP, &tty->flags)) {
DEBUG_LOG(info->line, "*** TTY_DONT_FLIP set flip.count %i ***\n", tty->flip.count);
DEBUG_LOG(info->line, "*** recv_cnt %i\n", info->recv_cnt);
} else {
}
DEBUG_LOG(info->line, "*** rxtot %i\n", info->icount.rx); DEBUG_LOG(info->line, "*** rxtot %i\n", info->icount.rx);
DEBUG_LOG(info->line, "ldisc %lu\n", tty->ldisc.chars_in_buffer(tty)); DEBUG_LOG(info->line, "ldisc %lu\n", tty->ldisc.chars_in_buffer(tty));
DEBUG_LOG(info->line, "room %lu\n", tty->ldisc.receive_room(tty)); DEBUG_LOG(info->line, "room %lu\n", tty->ldisc.receive_room(tty));
......
...@@ -588,13 +588,6 @@ void jsm_input(struct jsm_channel *ch) ...@@ -588,13 +588,6 @@ void jsm_input(struct jsm_channel *ch)
len = min(len, (N_TTY_BUF_SIZE - 1) - tp->read_cnt); len = min(len, (N_TTY_BUF_SIZE - 1) - tp->read_cnt);
ld = tty_ldisc_ref(tp); ld = tty_ldisc_ref(tp);
/*
* If the DONT_FLIP flag is on, don't flush our buffer, and act
* like the ld doesn't have any space to put the data right now.
*/
if (test_bit(TTY_DONT_FLIP, &tp->flags))
len = 0;
/* /*
* If we were unable to get a reference to the ld, * If we were unable to get a reference to the ld,
* don't flush our buffer, and act like the ld doesn't * don't flush our buffer, and act like the ld doesn't
......
...@@ -453,8 +453,7 @@ static void ir_read_bulk_callback (struct urb *urb, struct pt_regs *regs) ...@@ -453,8 +453,7 @@ static void ir_read_bulk_callback (struct urb *urb, struct pt_regs *regs)
tty = port->tty; tty = port->tty;
/* /*
* FIXME: must not do this in IRQ context, * FIXME: must not do this in IRQ context
* must honour TTY_DONT_FLIP
*/ */
tty->ldisc.receive_buf( tty->ldisc.receive_buf(
tty, tty,
......
...@@ -259,7 +259,6 @@ struct tty_struct { ...@@ -259,7 +259,6 @@ struct tty_struct {
#define TTY_DO_WRITE_WAKEUP 5 /* Call write_wakeup after queuing new */ #define TTY_DO_WRITE_WAKEUP 5 /* Call write_wakeup after queuing new */
#define TTY_PUSH 6 /* n_tty private */ #define TTY_PUSH 6 /* n_tty private */
#define TTY_CLOSING 7 /* ->close() in progress */ #define TTY_CLOSING 7 /* ->close() in progress */
#define TTY_DONT_FLIP 8 /* Defer buffer flip */
#define TTY_LDISC 9 /* Line discipline attached */ #define TTY_LDISC 9 /* Line discipline attached */
#define TTY_HW_COOK_OUT 14 /* Hardware can do output cooking */ #define TTY_HW_COOK_OUT 14 /* Hardware can do output cooking */
#define TTY_HW_COOK_IN 15 /* Hardware can do input cooking */ #define TTY_HW_COOK_IN 15 /* Hardware can do input cooking */
......
...@@ -480,12 +480,8 @@ static void rfcomm_dev_data_ready(struct rfcomm_dlc *dlc, struct sk_buff *skb) ...@@ -480,12 +480,8 @@ static void rfcomm_dev_data_ready(struct rfcomm_dlc *dlc, struct sk_buff *skb)
BT_DBG("dlc %p tty %p len %d", dlc, tty, skb->len); BT_DBG("dlc %p tty %p len %d", dlc, tty, skb->len);
if (test_bit(TTY_DONT_FLIP, &tty->flags)) { tty_insert_flip_string(tty, skb->data, skb->len);
tty_buffer_request_room(tty, skb->len); tty_flip_buffer_push(tty);
tty_insert_flip_string(tty, skb->data, skb->len);
tty_flip_buffer_push(tty);
} else
tty->ldisc.receive_buf(tty, skb->data, NULL, skb->len);
kfree_skb(skb); kfree_skb(skb);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment