diff options
| author | Paul Fulghum <paulkf@microgate.com> | 2006-06-28 07:26:47 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-06-28 17:59:05 -0400 |
| commit | 817d6d3bceaf34c99f5343820f9b9e6021f0655c (patch) | |
| tree | 651104833124262db46c2a372b7adb55289cd8dd | |
| parent | e0ac4761fa52acda90f9f53819c81474b511e3af (diff) | |
[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: Paul Fulghum <paulkf@microgate.com>
Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
Cc: Theodore Ts'o <tytso@mit.edu>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
| -rw-r--r-- | drivers/char/mxser.c | 1 | ||||
| -rw-r--r-- | drivers/char/n_tty.c | 6 | ||||
| -rw-r--r-- | drivers/char/pty.c | 2 | ||||
| -rw-r--r-- | drivers/char/tty_io.c | 15 | ||||
| -rw-r--r-- | drivers/serial/crisv10.c | 6 | ||||
| -rw-r--r-- | drivers/serial/jsm/jsm_tty.c | 7 | ||||
| -rw-r--r-- | drivers/usb/serial/ir-usb.c | 3 | ||||
| -rw-r--r-- | include/linux/tty.h | 1 | ||||
| -rw-r--r-- | net/bluetooth/rfcomm/tty.c | 8 |
9 files changed, 7 insertions, 42 deletions
diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c index 645d9d713ae..72cfd09091e 100644 --- a/drivers/char/mxser.c +++ b/drivers/char/mxser.c | |||
| @@ -996,7 +996,6 @@ static int mxser_open(struct tty_struct *tty, struct file *filp) | |||
| 996 | 996 | ||
| 997 | info->session = current->signal->session; | 997 | info->session = current->signal->session; |
| 998 | info->pgrp = process_group(current); | 998 | info->pgrp = process_group(current); |
| 999 | clear_bit(TTY_DONT_FLIP, &tty->flags); | ||
| 1000 | 999 | ||
| 1001 | /* | 1000 | /* |
| 1002 | status = mxser_get_msr(info->base, 0, info->port); | 1001 | status = mxser_get_msr(info->base, 0, info->port); |
diff --git a/drivers/char/n_tty.c b/drivers/char/n_tty.c index b9371d5bf79..603b9ade5eb 100644 --- a/drivers/char/n_tty.c +++ b/drivers/char/n_tty.c | |||
| @@ -1132,7 +1132,7 @@ static inline int input_available_p(struct tty_struct *tty, int amt) | |||
| 1132 | * buffer, and once to drain the space from the (physical) beginning of | 1132 | * buffer, and once to drain the space from the (physical) beginning of |
| 1133 | * the buffer to head pointer. | 1133 | * the buffer to head pointer. |
| 1134 | * | 1134 | * |
| 1135 | * Called under the tty->atomic_read_lock sem and with TTY_DONT_FLIP set | 1135 | * Called under the tty->atomic_read_lock sem |
| 1136 | * | 1136 | * |
| 1137 | */ | 1137 | */ |
| 1138 | 1138 | ||
| @@ -1271,7 +1271,6 @@ do_it_again: | |||
| 1271 | } | 1271 | } |
| 1272 | 1272 | ||
| 1273 | add_wait_queue(&tty->read_wait, &wait); | 1273 | add_wait_queue(&tty->read_wait, &wait); |
| 1274 | set_bit(TTY_DONT_FLIP, &tty->flags); | ||
| 1275 | while (nr) { | 1274 | while (nr) { |
| 1276 | /* First test for status change. */ | 1275 | /* First test for status change. */ |
| 1277 | if (tty->packet && tty->link->ctrl_status) { | 1276 | if (tty->packet && tty->link->ctrl_status) { |
| @@ -1315,9 +1314,7 @@ do_it_again: | |||
| 1315 | break; | 1314 | break; |
| 1316 | } | 1315 | } |
| 1317 | n_tty_set_room(tty); | 1316 | n_tty_set_room(tty); |
| 1318 | clear_bit(TTY_DONT_FLIP, &tty->flags); | ||
| 1319 | timeout = schedule_timeout(timeout); | 1317 | timeout = schedule_timeout(timeout); |
| 1320 | set_bit(TTY_DONT_FLIP, &tty->flags); | ||
| 1321 | continue; | 1318 | continue; |
| 1322 | } | 1319 | } |
| 1323 | __set_current_state(TASK_RUNNING); | 1320 | __set_current_state(TASK_RUNNING); |
| @@ -1394,7 +1391,6 @@ do_it_again: | |||
| 1394 | if (time) | 1391 | if (time) |
| 1395 | timeout = time; | 1392 | timeout = time; |
| 1396 | } | 1393 | } |
| 1397 | clear_bit(TTY_DONT_FLIP, &tty->flags); | ||
| 1398 | mutex_unlock(&tty->atomic_read_lock); | 1394 | mutex_unlock(&tty->atomic_read_lock); |
| 1399 | remove_wait_queue(&tty->read_wait, &wait); | 1395 | remove_wait_queue(&tty->read_wait, &wait); |
| 1400 | 1396 | ||
diff --git a/drivers/char/pty.c b/drivers/char/pty.c index 9b5a2c0e700..0c17f61549b 100644 --- a/drivers/char/pty.c +++ b/drivers/char/pty.c | |||
| @@ -101,7 +101,7 @@ static void pty_unthrottle(struct tty_struct * tty) | |||
| 101 | * | 101 | * |
| 102 | * FIXME: Our pty_write method is called with our ldisc lock held but | 102 | * FIXME: Our pty_write method is called with our ldisc lock held but |
| 103 | * not our partners. We can't just take the other one blindly without | 103 | * not our partners. We can't just take the other one blindly without |
| 104 | * risking deadlocks. There is also the small matter of TTY_DONT_FLIP | 104 | * risking deadlocks. |
| 105 | */ | 105 | */ |
| 106 | static int pty_write(struct tty_struct * tty, const unsigned char *buf, int count) | 106 | static int pty_write(struct tty_struct * tty, const unsigned char *buf, int count) |
| 107 | { | 107 | { |
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index bd74e82d8a7..b846d87f2b5 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c | |||
| @@ -784,11 +784,8 @@ restart: | |||
| 784 | } | 784 | } |
| 785 | 785 | ||
| 786 | clear_bit(TTY_LDISC, &tty->flags); | 786 | clear_bit(TTY_LDISC, &tty->flags); |
| 787 | clear_bit(TTY_DONT_FLIP, &tty->flags); | 787 | if (o_tty) |
| 788 | if (o_tty) { | ||
| 789 | clear_bit(TTY_LDISC, &o_tty->flags); | 788 | clear_bit(TTY_LDISC, &o_tty->flags); |
| 790 | clear_bit(TTY_DONT_FLIP, &o_tty->flags); | ||
| 791 | } | ||
| 792 | spin_unlock_irqrestore(&tty_ldisc_lock, flags); | 789 | spin_unlock_irqrestore(&tty_ldisc_lock, flags); |
| 793 | 790 | ||
| 794 | /* | 791 | /* |
| @@ -1955,7 +1952,6 @@ static void release_dev(struct file * filp) | |||
| 1955 | * race with the set_ldisc code path. | 1952 | * race with the set_ldisc code path. |
| 1956 | */ | 1953 | */ |
| 1957 | clear_bit(TTY_LDISC, &tty->flags); | 1954 | clear_bit(TTY_LDISC, &tty->flags); |
| 1958 | clear_bit(TTY_DONT_FLIP, &tty->flags); | ||
| 1959 | cancel_delayed_work(&tty->buf.work); | 1955 | cancel_delayed_work(&tty->buf.work); |
| 1960 | 1956 | ||
| 1961 | /* | 1957 | /* |
| @@ -2784,13 +2780,6 @@ static void flush_to_ldisc(void *private_) | |||
| 2784 | if (disc == NULL) /* !TTY_LDISC */ | 2780 | if (disc == NULL) /* !TTY_LDISC */ |
| 2785 | return; | 2781 | return; |
| 2786 | 2782 | ||
| 2787 | if (test_bit(TTY_DONT_FLIP, &tty->flags)) { | ||
| 2788 | /* | ||
| 2789 | * Do it after the next timer tick: | ||
| 2790 | */ | ||
| 2791 | schedule_delayed_work(&tty->buf.work, 1); | ||
| 2792 | goto out; | ||
| 2793 | } | ||
| 2794 | spin_lock_irqsave(&tty->buf.lock, flags); | 2783 | spin_lock_irqsave(&tty->buf.lock, flags); |
| 2795 | while((tbuf = tty->buf.head) != NULL) { | 2784 | while((tbuf = tty->buf.head) != NULL) { |
| 2796 | while ((count = tbuf->commit - tbuf->read) != 0) { | 2785 | while ((count = tbuf->commit - tbuf->read) != 0) { |
| @@ -2809,7 +2798,7 @@ static void flush_to_ldisc(void *private_) | |||
| 2809 | tty_buffer_free(tty, tbuf); | 2798 | tty_buffer_free(tty, tbuf); |
| 2810 | } | 2799 | } |
| 2811 | spin_unlock_irqrestore(&tty->buf.lock, flags); | 2800 | spin_unlock_irqrestore(&tty->buf.lock, flags); |
| 2812 | out: | 2801 | |
| 2813 | tty_ldisc_deref(disc); | 2802 | tty_ldisc_deref(disc); |
| 2814 | } | 2803 | } |
| 2815 | 2804 | ||
diff --git a/drivers/serial/crisv10.c b/drivers/serial/crisv10.c index 89700141f87..5cacc5e74a9 100644 --- a/drivers/serial/crisv10.c +++ b/drivers/serial/crisv10.c | |||
| @@ -2573,12 +2573,6 @@ static void flush_to_flip_buffer(struct e100_serial *info) | |||
| 2573 | 2573 | ||
| 2574 | DFLIP( | 2574 | DFLIP( |
| 2575 | if (1) { | 2575 | if (1) { |
| 2576 | |||
| 2577 | if (test_bit(TTY_DONT_FLIP, &tty->flags)) { | ||
| 2578 | DEBUG_LOG(info->line, "*** TTY_DONT_FLIP set flip.count %i ***\n", tty->flip.count); | ||
| 2579 | DEBUG_LOG(info->line, "*** recv_cnt %i\n", info->recv_cnt); | ||
| 2580 | } else { | ||
| 2581 | } | ||
| 2582 | DEBUG_LOG(info->line, "*** rxtot %i\n", info->icount.rx); | 2576 | DEBUG_LOG(info->line, "*** rxtot %i\n", info->icount.rx); |
| 2583 | DEBUG_LOG(info->line, "ldisc %lu\n", tty->ldisc.chars_in_buffer(tty)); | 2577 | DEBUG_LOG(info->line, "ldisc %lu\n", tty->ldisc.chars_in_buffer(tty)); |
| 2584 | DEBUG_LOG(info->line, "room %lu\n", tty->ldisc.receive_room(tty)); | 2578 | DEBUG_LOG(info->line, "room %lu\n", tty->ldisc.receive_room(tty)); |
diff --git a/drivers/serial/jsm/jsm_tty.c b/drivers/serial/jsm/jsm_tty.c index 7d823705193..f8262e6ad8d 100644 --- a/drivers/serial/jsm/jsm_tty.c +++ b/drivers/serial/jsm/jsm_tty.c | |||
| @@ -589,13 +589,6 @@ void jsm_input(struct jsm_channel *ch) | |||
| 589 | ld = tty_ldisc_ref(tp); | 589 | ld = tty_ldisc_ref(tp); |
| 590 | 590 | ||
| 591 | /* | 591 | /* |
| 592 | * If the DONT_FLIP flag is on, don't flush our buffer, and act | ||
| 593 | * like the ld doesn't have any space to put the data right now. | ||
| 594 | */ | ||
| 595 | if (test_bit(TTY_DONT_FLIP, &tp->flags)) | ||
| 596 | len = 0; | ||
| 597 | |||
| 598 | /* | ||
| 599 | * If we were unable to get a reference to the ld, | 592 | * If we were unable to get a reference to the ld, |
| 600 | * don't flush our buffer, and act like the ld doesn't | 593 | * don't flush our buffer, and act like the ld doesn't |
| 601 | * have any space to put the data right now. | 594 | * have any space to put the data right now. |
diff --git a/drivers/usb/serial/ir-usb.c b/drivers/usb/serial/ir-usb.c index 9432c730227..d7f3f736a69 100644 --- a/drivers/usb/serial/ir-usb.c +++ b/drivers/usb/serial/ir-usb.c | |||
| @@ -453,8 +453,7 @@ static void ir_read_bulk_callback (struct urb *urb, struct pt_regs *regs) | |||
| 453 | tty = port->tty; | 453 | tty = port->tty; |
| 454 | 454 | ||
| 455 | /* | 455 | /* |
| 456 | * FIXME: must not do this in IRQ context, | 456 | * FIXME: must not do this in IRQ context |
| 457 | * must honour TTY_DONT_FLIP | ||
| 458 | */ | 457 | */ |
| 459 | tty->ldisc.receive_buf( | 458 | tty->ldisc.receive_buf( |
| 460 | tty, | 459 | tty, |
diff --git a/include/linux/tty.h b/include/linux/tty.h index cb35ca50a0a..341cc4552c0 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h | |||
| @@ -259,7 +259,6 @@ struct tty_struct { | |||
| 259 | #define TTY_DO_WRITE_WAKEUP 5 /* Call write_wakeup after queuing new */ | 259 | #define TTY_DO_WRITE_WAKEUP 5 /* Call write_wakeup after queuing new */ |
| 260 | #define TTY_PUSH 6 /* n_tty private */ | 260 | #define TTY_PUSH 6 /* n_tty private */ |
| 261 | #define TTY_CLOSING 7 /* ->close() in progress */ | 261 | #define TTY_CLOSING 7 /* ->close() in progress */ |
| 262 | #define TTY_DONT_FLIP 8 /* Defer buffer flip */ | ||
| 263 | #define TTY_LDISC 9 /* Line discipline attached */ | 262 | #define TTY_LDISC 9 /* Line discipline attached */ |
| 264 | #define TTY_HW_COOK_OUT 14 /* Hardware can do output cooking */ | 263 | #define TTY_HW_COOK_OUT 14 /* Hardware can do output cooking */ |
| 265 | #define TTY_HW_COOK_IN 15 /* Hardware can do input cooking */ | 264 | #define TTY_HW_COOK_IN 15 /* Hardware can do input cooking */ |
diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c index 74368f79ee5..b81fad89332 100644 --- a/net/bluetooth/rfcomm/tty.c +++ b/net/bluetooth/rfcomm/tty.c | |||
| @@ -480,12 +480,8 @@ static void rfcomm_dev_data_ready(struct rfcomm_dlc *dlc, struct sk_buff *skb) | |||
| 480 | 480 | ||
| 481 | BT_DBG("dlc %p tty %p len %d", dlc, tty, skb->len); | 481 | BT_DBG("dlc %p tty %p len %d", dlc, tty, skb->len); |
| 482 | 482 | ||
| 483 | if (test_bit(TTY_DONT_FLIP, &tty->flags)) { | 483 | tty_insert_flip_string(tty, skb->data, skb->len); |
| 484 | tty_buffer_request_room(tty, skb->len); | 484 | tty_flip_buffer_push(tty); |
| 485 | tty_insert_flip_string(tty, skb->data, skb->len); | ||
| 486 | tty_flip_buffer_push(tty); | ||
| 487 | } else | ||
| 488 | tty->ldisc.receive_buf(tty, skb->data, NULL, skb->len); | ||
| 489 | 485 | ||
| 490 | kfree_skb(skb); | 486 | kfree_skb(skb); |
| 491 | } | 487 | } |
