Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

tty: rewrite the ldisc locking

There are several pretty much unfixable races in the old ldisc code, especially
with respect to pty behaviour and also to hangup. It's easier to rewrite the
code than simply try and patch it up.

This patch
- splits the ldisc from the tty (so we will be able to refcount it more cleanly
later)
- introduces a mutex lock for ldisc changing on an active device
- fixes the complete mess that hangup caused
- implements hopefully correct setldisc/close/hangup locking

There are still some problems around pty pairs that have always been there but
at least it is now possible to understand the code and fix further problems.

This fixes the following known bugs
- hang up can leak ldisc references
- hang up may not call open/close on ldisc in a matched way
- pty/tty pairs can deadlock during an ldisc change
- reading the ldisc proc files can cause every ldisc to be loaded

and probably a few other of the mysterious ldisc race reports.

I'm sure it also adds the odd new one.

Signed-off-by: Alan Cox <alan@linux.intel.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Alan Cox and committed by
Linus Torvalds
c65c9bc3 e8b70e7d

+330 -254
+2 -2
drivers/bluetooth/hci_ldisc.c
··· 277 277 /* FIXME: why is this needed. Note don't use ldisc_ref here as the 278 278 open path is before the ldisc is referencable */ 279 279 280 - if (tty->ldisc.ops->flush_buffer) 281 - tty->ldisc.ops->flush_buffer(tty); 280 + if (tty->ldisc->ops->flush_buffer) 281 + tty->ldisc->ops->flush_buffer(tty); 282 282 tty_driver_flush_buffer(tty); 283 283 284 284 return 0;
+1 -1
drivers/char/cyclades.c
··· 5200 5200 (cur_jifs - info->idle_stats.recv_idle)/ 5201 5201 HZ, info->idle_stats.overruns, 5202 5202 /* FIXME: double check locking */ 5203 - (long)info->port.tty->ldisc.ops->num); 5203 + (long)info->port.tty->ldisc->ops->num); 5204 5204 else 5205 5205 seq_printf(m, "%3d %8lu %10lu %8lu " 5206 5206 "%10lu %8lu %9lu %6ld\n",
+2 -2
drivers/char/epca.c
··· 2114 2114 tty_wait_until_sent(tty, 0); 2115 2115 } else { 2116 2116 /* ldisc lock already held in ioctl */ 2117 - if (tty->ldisc.ops->flush_buffer) 2118 - tty->ldisc.ops->flush_buffer(tty); 2117 + if (tty->ldisc->ops->flush_buffer) 2118 + tty->ldisc->ops->flush_buffer(tty); 2119 2119 } 2120 2120 unlock_kernel(); 2121 2121 /* Fall Thru */
+2 -2
drivers/char/ip2/i2lib.c
··· 868 868 amountToMove = count; 869 869 } 870 870 // Move the first block 871 - pCh->pTTY->ldisc.ops->receive_buf( pCh->pTTY, 871 + pCh->pTTY->ldisc->ops->receive_buf( pCh->pTTY, 872 872 &(pCh->Ibuf[stripIndex]), NULL, amountToMove ); 873 873 // If we needed to wrap, do the second data move 874 874 if (count > amountToMove) { 875 - pCh->pTTY->ldisc.ops->receive_buf( pCh->pTTY, 875 + pCh->pTTY->ldisc->ops->receive_buf( pCh->pTTY, 876 876 pCh->Ibuf, NULL, count - amountToMove ); 877 877 } 878 878 // Bump and wrap the stripIndex all at once by the amount of data read. This
+2 -2
drivers/char/ip2/ip2main.c
··· 1315 1315 if (tty->pgrp) 1316 1316 kill_pgrp(tty->pgrp, sig, 1); 1317 1317 if (flush || !L_NOFLSH(tty)) { 1318 - if ( tty->ldisc.ops->flush_buffer ) 1319 - tty->ldisc.ops->flush_buffer(tty); 1318 + if ( tty->ldisc->ops->flush_buffer ) 1319 + tty->ldisc->ops->flush_buffer(tty); 1320 1320 i2InputFlush( tty->driver_data ); 1321 1321 } 1322 1322 }
+2 -2
drivers/char/n_hdlc.c
··· 342 342 #endif 343 343 344 344 /* Flush any pending characters in the driver and discipline. */ 345 - if (tty->ldisc.ops->flush_buffer) 346 - tty->ldisc.ops->flush_buffer(tty); 345 + if (tty->ldisc->ops->flush_buffer) 346 + tty->ldisc->ops->flush_buffer(tty); 347 347 348 348 tty_driver_flush_buffer(tty); 349 349
+5 -5
drivers/char/pty.c
··· 110 110 c = to->receive_room; 111 111 if (c > count) 112 112 c = count; 113 - to->ldisc.ops->receive_buf(to, buf, NULL, c); 113 + to->ldisc->ops->receive_buf(to, buf, NULL, c); 114 114 115 115 return c; 116 116 } ··· 148 148 int count; 149 149 150 150 /* We should get the line discipline lock for "tty->link" */ 151 - if (!to || !to->ldisc.ops->chars_in_buffer) 151 + if (!to || !to->ldisc->ops->chars_in_buffer) 152 152 return 0; 153 153 154 154 /* The ldisc must report 0 if no characters available to be read */ 155 - count = to->ldisc.ops->chars_in_buffer(to); 155 + count = to->ldisc->ops->chars_in_buffer(to); 156 156 157 157 if (tty->driver->subtype == PTY_TYPE_SLAVE) 158 158 return count; ··· 186 186 if (!to) 187 187 return; 188 188 189 - if (to->ldisc.ops->flush_buffer) 190 - to->ldisc.ops->flush_buffer(to); 189 + if (to->ldisc->ops->flush_buffer) 190 + to->ldisc->ops->flush_buffer(to); 191 191 192 192 if (to->packet) { 193 193 spin_lock_irqsave(&tty->ctrl_lock, flags);
+1 -1
drivers/char/selection.c
··· 327 327 } 328 328 count = sel_buffer_lth - pasted; 329 329 count = min(count, tty->receive_room); 330 - tty->ldisc.ops->receive_buf(tty, sel_buffer + pasted, 330 + tty->ldisc->ops->receive_buf(tty, sel_buffer + pasted, 331 331 NULL, count); 332 332 pasted += count; 333 333 }
+8 -56
drivers/char/tty_io.c
··· 492 492 EXPORT_SYMBOL_GPL(tty_ldisc_flush); 493 493 494 494 /** 495 - * tty_reset_termios - reset terminal state 496 - * @tty: tty to reset 497 - * 498 - * Restore a terminal to the driver default state 499 - */ 500 - 501 - static void tty_reset_termios(struct tty_struct *tty) 502 - { 503 - mutex_lock(&tty->termios_mutex); 504 - *tty->termios = tty->driver->init_termios; 505 - tty->termios->c_ispeed = tty_termios_input_baud_rate(tty->termios); 506 - tty->termios->c_ospeed = tty_termios_baud_rate(tty->termios); 507 - mutex_unlock(&tty->termios_mutex); 508 - } 509 - 510 - /** 511 495 * do_tty_hangup - actual handler for hangup events 512 496 * @work: tty device 513 497 * ··· 520 536 struct file *cons_filp = NULL; 521 537 struct file *filp, *f = NULL; 522 538 struct task_struct *p; 523 - struct tty_ldisc *ld; 524 539 int closecount = 0, n; 525 540 unsigned long flags; 526 541 int refs = 0; ··· 550 567 filp->f_op = &hung_up_tty_fops; 551 568 } 552 569 file_list_unlock(); 553 - /* 554 - * FIXME! What are the locking issues here? This may me overdoing 555 - * things... This question is especially important now that we've 556 - * removed the irqlock. 557 - */ 558 - ld = tty_ldisc_ref(tty); 559 - if (ld != NULL) { 560 - /* We may have no line discipline at this point */ 561 - if (ld->ops->flush_buffer) 562 - ld->ops->flush_buffer(tty); 563 - tty_driver_flush_buffer(tty); 564 - if ((test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags)) && 565 - ld->ops->write_wakeup) 566 - ld->ops->write_wakeup(tty); 567 - if (ld->ops->hangup) 568 - ld->ops->hangup(tty); 569 - } 570 - /* 571 - * FIXME: Once we trust the LDISC code better we can wait here for 572 - * ldisc completion and fix the driver call race 573 - */ 574 - wake_up_interruptible_poll(&tty->write_wait, POLLOUT); 575 - wake_up_interruptible_poll(&tty->read_wait, POLLIN); 576 - /* 577 - * Shutdown the current line discipline, and reset it to 578 - * N_TTY. 579 - */ 580 - if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS) 581 - tty_reset_termios(tty); 582 - /* Defer ldisc switch */ 583 - /* tty_deferred_ldisc_switch(N_TTY); 584 570 585 - This should get done automatically when the port closes and 586 - tty_release is called */ 571 + tty_ldisc_hangup(tty); 587 572 588 573 read_lock(&tasklist_lock); 589 574 if (tty->session) { ··· 580 629 read_unlock(&tasklist_lock); 581 630 582 631 spin_lock_irqsave(&tty->ctrl_lock, flags); 583 - tty->flags = 0; 632 + clear_bit(TTY_THROTTLED, &tty->flags); 633 + clear_bit(TTY_PUSH, &tty->flags); 634 + clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); 584 635 put_pid(tty->session); 585 636 put_pid(tty->pgrp); 586 637 tty->session = NULL; 587 638 tty->pgrp = NULL; 588 639 tty->ctrl_status = 0; 640 + set_bit(TTY_HUPPED, &tty->flags); 589 641 spin_unlock_irqrestore(&tty->ctrl_lock, flags); 590 642 591 643 /* Account for the p->signal references we killed */ ··· 614 660 * can't yet guarantee all that. 615 661 */ 616 662 set_bit(TTY_HUPPED, &tty->flags); 617 - if (ld) { 618 - tty_ldisc_enable(tty); 619 - tty_ldisc_deref(ld); 620 - } 663 + tty_ldisc_enable(tty); 621 664 unlock_kernel(); 622 665 if (f) 623 666 fput(f); ··· 2521 2570 case TIOCGSID: 2522 2571 return tiocgsid(tty, real_tty, p); 2523 2572 case TIOCGETD: 2524 - return put_user(tty->ldisc.ops->num, (int __user *)p); 2573 + return put_user(tty->ldisc->ops->num, (int __user *)p); 2525 2574 case TIOCSETD: 2526 2575 return tiocsetd(tty, p); 2527 2576 /* ··· 2736 2785 tty->buf.head = tty->buf.tail = NULL; 2737 2786 tty_buffer_init(tty); 2738 2787 mutex_init(&tty->termios_mutex); 2788 + mutex_init(&tty->ldisc_mutex); 2739 2789 init_waitqueue_head(&tty->write_wait); 2740 2790 init_waitqueue_head(&tty->read_wait); 2741 2791 INIT_WORK(&tty->hangup_work, do_tty_hangup);
+298 -179
drivers/char/tty_ldisc.c
··· 115 115 /** 116 116 * tty_ldisc_try_get - try and reference an ldisc 117 117 * @disc: ldisc number 118 - * @ld: tty ldisc structure to complete 119 118 * 120 119 * Attempt to open and lock a line discipline into place. Return 121 - * the line discipline refcounted and assigned in ld. On an error 122 - * report the error code back 120 + * the line discipline refcounted or an error. 123 121 */ 124 122 125 - static int tty_ldisc_try_get(int disc, struct tty_ldisc *ld) 123 + static struct tty_ldisc *tty_ldisc_try_get(int disc) 126 124 { 127 125 unsigned long flags; 126 + struct tty_ldisc *ld; 128 127 struct tty_ldisc_ops *ldops; 129 128 int err = -EINVAL; 130 129 130 + ld = kmalloc(sizeof(struct tty_ldisc), GFP_KERNEL); 131 + if (ld == NULL) 132 + return ERR_PTR(-ENOMEM); 133 + 131 134 spin_lock_irqsave(&tty_ldisc_lock, flags); 132 135 ld->ops = NULL; 133 136 ldops = tty_ldiscs[disc]; ··· 143 140 /* lock it */ 144 141 ldops->refcount++; 145 142 ld->ops = ldops; 143 + ld->refcount = 0; 146 144 err = 0; 147 145 } 148 146 } 149 147 spin_unlock_irqrestore(&tty_ldisc_lock, flags); 150 - return err; 148 + if (err) 149 + return ERR_PTR(err); 150 + return ld; 151 151 } 152 152 153 153 /** 154 154 * tty_ldisc_get - take a reference to an ldisc 155 155 * @disc: ldisc number 156 - * @ld: tty line discipline structure to use 157 156 * 158 157 * Takes a reference to a line discipline. Deals with refcounts and 159 158 * module locking counts. Returns NULL if the discipline is not available. ··· 166 161 * takes tty_ldisc_lock to guard against ldisc races 167 162 */ 168 163 169 - static int tty_ldisc_get(int disc, struct tty_ldisc *ld) 164 + static struct tty_ldisc *tty_ldisc_get(int disc) 170 165 { 171 - int err; 166 + struct tty_ldisc *ld; 172 167 173 168 if (disc < N_TTY || disc >= NR_LDISCS) 174 - return -EINVAL; 175 - err = tty_ldisc_try_get(disc, ld); 176 - if (err < 0) { 169 + return ERR_PTR(-EINVAL); 170 + ld = tty_ldisc_try_get(disc); 171 + if (IS_ERR(ld)) { 177 172 request_module("tty-ldisc-%d", disc); 178 - err = tty_ldisc_try_get(disc, ld); 173 + ld = tty_ldisc_try_get(disc); 179 174 } 180 - return err; 175 + return ld; 181 176 } 182 177 183 178 /** 184 179 * tty_ldisc_put - drop ldisc reference 185 - * @disc: ldisc number 180 + * @ld: ldisc 186 181 * 187 182 * Drop a reference to a line discipline. Manage refcounts and 188 - * module usage counts 183 + * module usage counts. Free the ldisc once the recount hits zero. 189 184 * 190 185 * Locking: 191 186 * takes tty_ldisc_lock to guard against ldisc races 192 187 */ 193 188 194 - static void tty_ldisc_put(struct tty_ldisc_ops *ld) 189 + static void tty_ldisc_put(struct tty_ldisc *ld) 195 190 { 196 191 unsigned long flags; 197 - int disc = ld->num; 192 + int disc = ld->ops->num; 193 + struct tty_ldisc_ops *ldo; 198 194 199 195 BUG_ON(disc < N_TTY || disc >= NR_LDISCS); 200 196 201 197 spin_lock_irqsave(&tty_ldisc_lock, flags); 202 - ld = tty_ldiscs[disc]; 203 - BUG_ON(ld->refcount == 0); 204 - ld->refcount--; 205 - module_put(ld->owner); 198 + ldo = tty_ldiscs[disc]; 199 + BUG_ON(ldo->refcount == 0); 200 + ldo->refcount--; 201 + module_put(ldo->owner); 206 202 spin_unlock_irqrestore(&tty_ldisc_lock, flags); 203 + kfree(ld); 207 204 } 208 205 209 206 static void * tty_ldiscs_seq_start(struct seq_file *m, loff_t *pos) ··· 226 219 static int tty_ldiscs_seq_show(struct seq_file *m, void *v) 227 220 { 228 221 int i = *(loff_t *)v; 229 - struct tty_ldisc ld; 222 + struct tty_ldisc *ld; 230 223 231 - if (tty_ldisc_get(i, &ld) < 0) 224 + ld = tty_ldisc_try_get(i); 225 + if (IS_ERR(ld)) 232 226 return 0; 233 - seq_printf(m, "%-10s %2d\n", ld.ops->name ? ld.ops->name : "???", i); 234 - tty_ldisc_put(ld.ops); 227 + seq_printf(m, "%-10s %2d\n", ld->ops->name ? ld->ops->name : "???", i); 228 + tty_ldisc_put(ld); 235 229 return 0; 236 230 } 237 231 ··· 271 263 272 264 static void tty_ldisc_assign(struct tty_struct *tty, struct tty_ldisc *ld) 273 265 { 274 - ld->refcount = 0; 275 - tty->ldisc = *ld; 266 + tty->ldisc = ld; 276 267 } 277 268 278 269 /** ··· 293 286 int ret = 0; 294 287 295 288 spin_lock_irqsave(&tty_ldisc_lock, flags); 296 - ld = &tty->ldisc; 289 + ld = tty->ldisc; 297 290 if (test_bit(TTY_LDISC, &tty->flags)) { 298 291 ld->refcount++; 299 292 ret = 1; ··· 322 315 { 323 316 /* wait_event is a macro */ 324 317 wait_event(tty_ldisc_wait, tty_ldisc_try(tty)); 325 - WARN_ON(tty->ldisc.refcount == 0); 326 - return &tty->ldisc; 318 + WARN_ON(tty->ldisc->refcount == 0); 319 + return tty->ldisc; 327 320 } 328 321 329 322 EXPORT_SYMBOL_GPL(tty_ldisc_ref_wait); ··· 342 335 struct tty_ldisc *tty_ldisc_ref(struct tty_struct *tty) 343 336 { 344 337 if (tty_ldisc_try(tty)) 345 - return &tty->ldisc; 338 + return tty->ldisc; 346 339 return NULL; 347 340 } 348 341 ··· 414 407 mutex_unlock(&tty->termios_mutex); 415 408 } 416 409 410 + /** 411 + * tty_ldisc_open - open a line discipline 412 + * @tty: tty we are opening the ldisc on 413 + * @ld: discipline to open 414 + * 415 + * A helper opening method. Also a convenient debugging and check 416 + * point. 417 + */ 418 + 419 + static int tty_ldisc_open(struct tty_struct *tty, struct tty_ldisc *ld) 420 + { 421 + WARN_ON(test_and_set_bit(TTY_LDISC_OPEN, &tty->flags)); 422 + if (ld->ops->open) 423 + return ld->ops->open(tty); 424 + return 0; 425 + } 426 + 427 + /** 428 + * tty_ldisc_close - close a line discipline 429 + * @tty: tty we are opening the ldisc on 430 + * @ld: discipline to close 431 + * 432 + * A helper close method. Also a convenient debugging and check 433 + * point. 434 + */ 435 + 436 + static void tty_ldisc_close(struct tty_struct *tty, struct tty_ldisc *ld) 437 + { 438 + WARN_ON(!test_bit(TTY_LDISC_OPEN, &tty->flags)); 439 + clear_bit(TTY_LDISC_OPEN, &tty->flags); 440 + if (ld->ops->close) 441 + ld->ops->close(tty); 442 + } 417 443 418 444 /** 419 445 * tty_ldisc_restore - helper for tty ldisc change ··· 460 420 static void tty_ldisc_restore(struct tty_struct *tty, struct tty_ldisc *old) 461 421 { 462 422 char buf[64]; 463 - struct tty_ldisc new_ldisc; 423 + struct tty_ldisc *new_ldisc; 424 + int r; 464 425 465 426 /* There is an outstanding reference here so this is safe */ 466 - tty_ldisc_get(old->ops->num, old); 427 + old = tty_ldisc_get(old->ops->num); 428 + WARN_ON(IS_ERR(old)); 467 429 tty_ldisc_assign(tty, old); 468 430 tty_set_termios_ldisc(tty, old->ops->num); 469 - if (old->ops->open && (old->ops->open(tty) < 0)) { 470 - tty_ldisc_put(old->ops); 431 + if (tty_ldisc_open(tty, old) < 0) { 432 + tty_ldisc_put(old); 471 433 /* This driver is always present */ 472 - if (tty_ldisc_get(N_TTY, &new_ldisc) < 0) 434 + new_ldisc =tty_ldisc_get(N_TTY); 435 + if (IS_ERR(new_ldisc)) 473 436 panic("n_tty: get"); 474 - tty_ldisc_assign(tty, &new_ldisc); 437 + tty_ldisc_assign(tty, new_ldisc); 475 438 tty_set_termios_ldisc(tty, N_TTY); 476 - if (new_ldisc.ops->open) { 477 - int r = new_ldisc.ops->open(tty); 478 - if (r < 0) 479 - panic("Couldn't open N_TTY ldisc for " 480 - "%s --- error %d.", 481 - tty_name(tty, buf), r); 482 - } 439 + r = tty_ldisc_open(tty, new_ldisc); 440 + if (r < 0) 441 + panic("Couldn't open N_TTY ldisc for " 442 + "%s --- error %d.", 443 + tty_name(tty, buf), r); 483 444 } 484 445 } 485 446 486 447 /** 487 - * tty_ldisc_halt - shutdown the line discipline 448 + * tty_ldisc_halt - shut down the line discipline 488 449 * @tty: tty device 489 450 * 490 451 * Shut down the line discipline and work queue for this tty device. ··· 497 456 * tty_ldisc_wait_idle. 498 457 */ 499 458 500 - static void tty_ldisc_halt(struct tty_struct *tty) 459 + static int tty_ldisc_halt(struct tty_struct *tty) 501 460 { 502 461 clear_bit(TTY_LDISC, &tty->flags); 503 - cancel_delayed_work(&tty->buf.work); 504 - /* 505 - * Wait for ->hangup_work and ->buf.work handlers to terminate 506 - */ 507 - flush_scheduled_work(); 462 + return cancel_delayed_work(&tty->buf.work); 508 463 } 509 464 510 465 /** ··· 510 473 * Wait for the line discipline to become idle. The discipline must 511 474 * have been halted for this to guarantee it remains idle. 512 475 * 476 + * tty_ldisc_lock protects the ref counts currently. 513 477 */ 514 478 515 - static void tty_ldisc_wait_idle(struct tty_struct *tty) 479 + static int tty_ldisc_wait_idle(struct tty_struct *tty) 516 480 { 517 481 unsigned long flags; 518 482 spin_lock_irqsave(&tty_ldisc_lock, flags); 519 - while (tty->ldisc.refcount) { 483 + while (tty->ldisc->refcount) { 520 484 spin_unlock_irqrestore(&tty_ldisc_lock, flags); 521 - wait_event(tty_ldisc_wait, tty->ldisc.refcount == 0); 485 + if (wait_event_timeout(tty_ldisc_wait, 486 + tty->ldisc->refcount == 0, 5 * HZ) == 0) 487 + return -EBUSY; 522 488 spin_lock_irqsave(&tty_ldisc_lock, flags); 523 489 } 524 490 spin_unlock_irqrestore(&tty_ldisc_lock, flags); 491 + return 0; 525 492 } 526 493 527 494 /** ··· 534 493 * @ldisc: the line discipline 535 494 * 536 495 * Set the discipline of a tty line. Must be called from a process 537 - * context. 496 + * context. The ldisc change logic has to protect itself against any 497 + * overlapping ldisc change (including on the other end of pty pairs), 498 + * the close of one side of a tty/pty pair, and eventually hangup. 538 499 * 539 - * Locking: takes tty_ldisc_lock. 540 - * called functions take termios_mutex 500 + * Locking: takes tty_ldisc_lock, termios_mutex 541 501 */ 542 502 543 503 int tty_set_ldisc(struct tty_struct *tty, int ldisc) 544 504 { 545 505 int retval; 546 - struct tty_ldisc o_ldisc, new_ldisc; 547 - int work; 548 - unsigned long flags; 506 + struct tty_ldisc *o_ldisc, *new_ldisc; 507 + int work, o_work = 0; 549 508 struct tty_struct *o_tty; 550 509 551 - restart: 552 - /* This is a bit ugly for now but means we can break the 'ldisc 553 - is part of the tty struct' assumption later */ 554 - retval = tty_ldisc_get(ldisc, &new_ldisc); 555 - if (retval) 556 - return retval; 510 + new_ldisc = tty_ldisc_get(ldisc); 511 + if (IS_ERR(new_ldisc)) 512 + return PTR_ERR(new_ldisc); 513 + 514 + /* 515 + * We need to look at the tty locking here for pty/tty pairs 516 + * when both sides try to change in parallel. 517 + */ 518 + 519 + o_tty = tty->link; /* o_tty is the pty side or NULL */ 520 + 521 + 522 + /* 523 + * Check the no-op case 524 + */ 525 + 526 + if (tty->ldisc->ops->num == ldisc) { 527 + tty_ldisc_put(new_ldisc); 528 + return 0; 529 + } 557 530 558 531 /* 559 532 * Problem: What do we do if this blocks ? 533 + * We could deadlock here 560 534 */ 561 535 562 536 tty_wait_until_sent(tty, 0); 563 537 564 - if (tty->ldisc.ops->num == ldisc) { 565 - tty_ldisc_put(new_ldisc.ops); 566 - return 0; 567 - } 538 + mutex_lock(&tty->ldisc_mutex); 568 539 540 + /* 541 + * We could be midstream of another ldisc change which has 542 + * dropped the lock during processing. If so we need to wait. 543 + */ 544 + 545 + while (test_bit(TTY_LDISC_CHANGING, &tty->flags)) { 546 + mutex_unlock(&tty->ldisc_mutex); 547 + wait_event(tty_ldisc_wait, 548 + test_bit(TTY_LDISC_CHANGING, &tty->flags) == 0); 549 + mutex_lock(&tty->ldisc_mutex); 550 + } 551 + set_bit(TTY_LDISC_CHANGING, &tty->flags); 552 + 569 553 /* 570 554 * No more input please, we are switching. The new ldisc 571 555 * will update this value in the ldisc open function ··· 599 533 tty->receive_room = 0; 600 534 601 535 o_ldisc = tty->ldisc; 602 - o_tty = tty->link; 603 - 604 536 /* 605 537 * Make sure we don't change while someone holds a 606 538 * reference to the line discipline. The TTY_LDISC bit ··· 609 545 * with a userspace app continually trying to use the tty in 610 546 * parallel to the change and re-referencing the tty. 611 547 */ 612 - clear_bit(TTY_LDISC, &tty->flags); 613 - if (o_tty) 614 - clear_bit(TTY_LDISC, &o_tty->flags); 615 548 616 - spin_lock_irqsave(&tty_ldisc_lock, flags); 617 - if (tty->ldisc.refcount || (o_tty && o_tty->ldisc.refcount)) { 618 - if (tty->ldisc.refcount) { 619 - /* Free the new ldisc we grabbed. Must drop the lock 620 - first. */ 621 - spin_unlock_irqrestore(&tty_ldisc_lock, flags); 622 - tty_ldisc_put(o_ldisc.ops); 623 - /* 624 - * There are several reasons we may be busy, including 625 - * random momentary I/O traffic. We must therefore 626 - * retry. We could distinguish between blocking ops 627 - * and retries if we made tty_ldisc_wait() smarter. 628 - * That is up for discussion. 629 - */ 630 - if (wait_event_interruptible(tty_ldisc_wait, tty->ldisc.refcount == 0) < 0) 631 - return -ERESTARTSYS; 632 - goto restart; 633 - } 634 - if (o_tty && o_tty->ldisc.refcount) { 635 - spin_unlock_irqrestore(&tty_ldisc_lock, flags); 636 - tty_ldisc_put(o_tty->ldisc.ops); 637 - if (wait_event_interruptible(tty_ldisc_wait, o_tty->ldisc.refcount == 0) < 0) 638 - return -ERESTARTSYS; 639 - goto restart; 640 - } 641 - } 642 - /* 643 - * If the TTY_LDISC bit is set, then we are racing against 644 - * another ldisc change 645 - */ 646 - if (test_bit(TTY_LDISC_CHANGING, &tty->flags)) { 647 - struct tty_ldisc *ld; 648 - spin_unlock_irqrestore(&tty_ldisc_lock, flags); 649 - tty_ldisc_put(new_ldisc.ops); 650 - ld = tty_ldisc_ref_wait(tty); 651 - tty_ldisc_deref(ld); 652 - goto restart; 653 - } 654 - /* 655 - * This flag is used to avoid two parallel ldisc changes. Once 656 - * open and close are fine grained locked this may work better 657 - * as a mutex shared with the open/close/hup paths 658 - */ 659 - set_bit(TTY_LDISC_CHANGING, &tty->flags); 549 + work = tty_ldisc_halt(tty); 660 550 if (o_tty) 661 - set_bit(TTY_LDISC_CHANGING, &o_tty->flags); 662 - spin_unlock_irqrestore(&tty_ldisc_lock, flags); 663 - 551 + o_work = tty_ldisc_halt(o_tty); 552 + 664 553 /* 665 - * From this point on we know nobody has an ldisc 666 - * usage reference, nor can they obtain one until 667 - * we say so later on. 554 + * Wait for ->hangup_work and ->buf.work handlers to terminate. 555 + * We must drop the mutex here in case a hangup is also in process. 668 556 */ 669 557 670 - work = cancel_delayed_work(&tty->buf.work); 671 - /* 672 - * Wait for ->hangup_work and ->buf.work handlers to terminate 673 - * MUST NOT hold locks here. 674 - */ 558 + mutex_unlock(&tty->ldisc_mutex); 559 + 675 560 flush_scheduled_work(); 561 + 562 + /* Let any existing reference holders finish */ 563 + retval = tty_ldisc_wait_idle(tty); 564 + if (retval < 0) { 565 + clear_bit(TTY_LDISC_CHANGING, &tty->flags); 566 + tty_ldisc_put(new_ldisc); 567 + return retval; 568 + } 569 + 570 + mutex_lock(&tty->ldisc_mutex); 571 + if (test_bit(TTY_HUPPED, &tty->flags)) { 572 + /* We were raced by the hangup method. It will have stomped 573 + the ldisc data and closed the ldisc down */ 574 + clear_bit(TTY_LDISC_CHANGING, &tty->flags); 575 + mutex_unlock(&tty->ldisc_mutex); 576 + tty_ldisc_put(new_ldisc); 577 + return -EIO; 578 + } 579 + 676 580 /* Shutdown the current discipline. */ 677 - if (o_ldisc.ops->close) 678 - (o_ldisc.ops->close)(tty); 581 + tty_ldisc_close(tty, o_ldisc); 679 582 680 583 /* Now set up the new line discipline. */ 681 - tty_ldisc_assign(tty, &new_ldisc); 584 + tty_ldisc_assign(tty, new_ldisc); 682 585 tty_set_termios_ldisc(tty, ldisc); 683 - if (new_ldisc.ops->open) 684 - retval = (new_ldisc.ops->open)(tty); 586 + 587 + retval = tty_ldisc_open(tty, new_ldisc); 685 588 if (retval < 0) { 686 - tty_ldisc_put(new_ldisc.ops); 687 - tty_ldisc_restore(tty, &o_ldisc); 589 + /* Back to the old one or N_TTY if we can't */ 590 + tty_ldisc_put(new_ldisc); 591 + tty_ldisc_restore(tty, o_ldisc); 688 592 } 593 + 689 594 /* At this point we hold a reference to the new ldisc and a 690 595 a reference to the old ldisc. If we ended up flipping back 691 596 to the existing ldisc we have two references to it */ 692 597 693 - if (tty->ldisc.ops->num != o_ldisc.ops->num && tty->ops->set_ldisc) 598 + if (tty->ldisc->ops->num != o_ldisc->ops->num && tty->ops->set_ldisc) 694 599 tty->ops->set_ldisc(tty); 695 600 696 - tty_ldisc_put(o_ldisc.ops); 601 + tty_ldisc_put(o_ldisc); 697 602 698 603 /* 699 - * Allow ldisc referencing to occur as soon as the driver 700 - * ldisc callback completes. 604 + * Allow ldisc referencing to occur again 701 605 */ 702 606 703 607 tty_ldisc_enable(tty); 704 608 if (o_tty) 705 609 tty_ldisc_enable(o_tty); 706 610 707 - /* Restart it in case no characters kick it off. Safe if 611 + /* Restart the work queue in case no characters kick it off. Safe if 708 612 already running */ 709 613 if (work) 710 614 schedule_delayed_work(&tty->buf.work, 1); 615 + if (o_work) 616 + schedule_delayed_work(&o_tty->buf.work, 1); 617 + mutex_unlock(&tty->ldisc_mutex); 711 618 return retval; 712 619 } 713 620 621 + /** 622 + * tty_reset_termios - reset terminal state 623 + * @tty: tty to reset 624 + * 625 + * Restore a terminal to the driver default state. 626 + */ 627 + 628 + static void tty_reset_termios(struct tty_struct *tty) 629 + { 630 + mutex_lock(&tty->termios_mutex); 631 + *tty->termios = tty->driver->init_termios; 632 + tty->termios->c_ispeed = tty_termios_input_baud_rate(tty->termios); 633 + tty->termios->c_ospeed = tty_termios_baud_rate(tty->termios); 634 + mutex_unlock(&tty->termios_mutex); 635 + } 636 + 637 + 638 + /** 639 + * tty_ldisc_reinit - reinitialise the tty ldisc 640 + * @tty: tty to reinit 641 + * 642 + * Switch the tty back to N_TTY line discipline and leave the 643 + * ldisc state closed 644 + */ 645 + 646 + static void tty_ldisc_reinit(struct tty_struct *tty) 647 + { 648 + struct tty_ldisc *ld; 649 + 650 + tty_ldisc_close(tty, tty->ldisc); 651 + tty_ldisc_put(tty->ldisc); 652 + tty->ldisc = NULL; 653 + /* 654 + * Switch the line discipline back 655 + */ 656 + ld = tty_ldisc_get(N_TTY); 657 + BUG_ON(IS_ERR(ld)); 658 + tty_ldisc_assign(tty, ld); 659 + tty_set_termios_ldisc(tty, N_TTY); 660 + } 661 + 662 + /** 663 + * tty_ldisc_hangup - hangup ldisc reset 664 + * @tty: tty being hung up 665 + * 666 + * Some tty devices reset their termios when they receive a hangup 667 + * event. In that situation we must also switch back to N_TTY properly 668 + * before we reset the termios data. 669 + * 670 + * Locking: We can take the ldisc mutex as the rest of the code is 671 + * careful to allow for this. 672 + * 673 + * In the pty pair case this occurs in the close() path of the 674 + * tty itself so we must be careful about locking rules. 675 + */ 676 + 677 + void tty_ldisc_hangup(struct tty_struct *tty) 678 + { 679 + struct tty_ldisc *ld; 680 + 681 + /* 682 + * FIXME! What are the locking issues here? This may me overdoing 683 + * things... This question is especially important now that we've 684 + * removed the irqlock. 685 + */ 686 + ld = tty_ldisc_ref(tty); 687 + if (ld != NULL) { 688 + /* We may have no line discipline at this point */ 689 + if (ld->ops->flush_buffer) 690 + ld->ops->flush_buffer(tty); 691 + tty_driver_flush_buffer(tty); 692 + if ((test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags)) && 693 + ld->ops->write_wakeup) 694 + ld->ops->write_wakeup(tty); 695 + if (ld->ops->hangup) 696 + ld->ops->hangup(tty); 697 + tty_ldisc_deref(ld); 698 + } 699 + /* 700 + * FIXME: Once we trust the LDISC code better we can wait here for 701 + * ldisc completion and fix the driver call race 702 + */ 703 + wake_up_interruptible_poll(&tty->write_wait, POLLOUT); 704 + wake_up_interruptible_poll(&tty->read_wait, POLLIN); 705 + /* 706 + * Shutdown the current line discipline, and reset it to 707 + * N_TTY. 708 + */ 709 + if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS) { 710 + /* Avoid racing set_ldisc */ 711 + mutex_lock(&tty->ldisc_mutex); 712 + /* Switch back to N_TTY */ 713 + tty_ldisc_reinit(tty); 714 + /* At this point we have a closed ldisc and we want to 715 + reopen it. We could defer this to the next open but 716 + it means auditing a lot of other paths so this is a FIXME */ 717 + WARN_ON(tty_ldisc_open(tty, tty->ldisc)); 718 + tty_ldisc_enable(tty); 719 + mutex_unlock(&tty->ldisc_mutex); 720 + tty_reset_termios(tty); 721 + } 722 + } 714 723 715 724 /** 716 725 * tty_ldisc_setup - open line discipline ··· 791 654 * @o_tty: pair tty for pty/tty pairs 792 655 * 793 656 * Called during the initial open of a tty/pty pair in order to set up the 794 - * line discplines and bind them to the tty. 657 + * line disciplines and bind them to the tty. This has no locking issues 658 + * as the device isn't yet active. 795 659 */ 796 660 797 661 int tty_ldisc_setup(struct tty_struct *tty, struct tty_struct *o_tty) 798 662 { 799 - struct tty_ldisc *ld = &tty->ldisc; 663 + struct tty_ldisc *ld = tty->ldisc; 800 664 int retval; 801 665 802 - if (ld->ops->open) { 803 - retval = (ld->ops->open)(tty); 804 - if (retval) 805 - return retval; 806 - } 807 - if (o_tty && o_tty->ldisc.ops->open) { 808 - retval = (o_tty->ldisc.ops->open)(o_tty); 666 + retval = tty_ldisc_open(tty, ld); 667 + if (retval) 668 + return retval; 669 + 670 + if (o_tty) { 671 + retval = tty_ldisc_open(o_tty, o_tty->ldisc); 809 672 if (retval) { 810 - if (ld->ops->close) 811 - (ld->ops->close)(tty); 673 + tty_ldisc_close(tty, ld); 812 674 return retval; 813 675 } 814 676 tty_ldisc_enable(o_tty); ··· 815 679 tty_ldisc_enable(tty); 816 680 return 0; 817 681 } 818 - 819 - static void tty_ldisc_reinit(struct tty_struct *tty) 820 - { 821 - struct tty_ldisc ld; 822 - 823 - if (tty->ldisc.ops->close) 824 - (tty->ldisc.ops->close)(tty); 825 - tty_ldisc_put(tty->ldisc.ops); 826 - /* 827 - * Switch the line discipline back 828 - */ 829 - WARN_ON(tty_ldisc_get(N_TTY, &ld)); 830 - tty_ldisc_assign(tty, &ld); 831 - tty_set_termios_ldisc(tty, N_TTY); 832 - } 833 - 834 682 /** 835 683 * tty_ldisc_release - release line discipline 836 684 * @tty: tty being shut down 837 685 * @o_tty: pair tty for pty/tty pairs 838 686 * 839 687 * Called during the final close of a tty/pty pair in order to shut down the 840 - * line discpline layer. 688 + * line discpline layer. On exit the ldisc assigned is N_TTY and the 689 + * ldisc has not been opened. 841 690 */ 842 691 843 692 void tty_ldisc_release(struct tty_struct *tty, struct tty_struct *o_tty) 844 693 { 845 - 846 694 /* 847 695 * Prevent flush_to_ldisc() from rescheduling the work for later. Then 848 696 * kill any delayed work. As this is the final close it does not ··· 834 714 */ 835 715 836 716 tty_ldisc_halt(tty); 717 + flush_scheduled_work(); 837 718 838 719 /* 839 720 * Wait for any short term users (we know they are just driver ··· 851 730 */ 852 731 853 732 tty_ldisc_reinit(tty); 854 - if (o_tty) { 855 - /* FIXME: could o_tty be in setldisc here ? */ 856 - clear_bit(TTY_LDISC, &o_tty->flags); 857 - tty_ldisc_reinit(o_tty); 858 - } 733 + /* This will need doing differently if we need to lock */ 734 + if (o_tty) 735 + tty_ldisc_release(o_tty, NULL); 859 736 } 860 737 861 738 /** ··· 866 747 867 748 void tty_ldisc_init(struct tty_struct *tty) 868 749 { 869 - struct tty_ldisc ld; 870 - if (tty_ldisc_get(N_TTY, &ld) < 0) 750 + struct tty_ldisc *ld = tty_ldisc_get(N_TTY); 751 + if (IS_ERR(ld)) 871 752 panic("n_tty: init_tty"); 872 - tty_ldisc_assign(tty, &ld); 753 + tty_ldisc_assign(tty, ld); 873 754 } 874 755 875 756 void tty_ldisc_begin(void)
+7 -2
include/linux/tty.h
··· 226 226 struct tty_driver *driver; 227 227 const struct tty_operations *ops; 228 228 int index; 229 - /* The ldisc objects are protected by tty_ldisc_lock at the moment */ 230 - struct tty_ldisc ldisc; 229 + 230 + /* Protects ldisc changes: Lock tty not pty */ 231 + struct mutex ldisc_mutex; 232 + struct tty_ldisc *ldisc; 233 + 231 234 struct mutex termios_mutex; 232 235 spinlock_t ctrl_lock; 233 236 /* Termios values are protected by the termios mutex */ ··· 317 314 #define TTY_CLOSING 7 /* ->close() in progress */ 318 315 #define TTY_LDISC 9 /* Line discipline attached */ 319 316 #define TTY_LDISC_CHANGING 10 /* Line discipline changing */ 317 + #define TTY_LDISC_OPEN 11 /* Line discipline is open */ 320 318 #define TTY_HW_COOK_OUT 14 /* Hardware can do output cooking */ 321 319 #define TTY_HW_COOK_IN 15 /* Hardware can do input cooking */ 322 320 #define TTY_PTY_LOCK 16 /* pty private */ ··· 410 406 extern struct tty_ldisc *tty_ldisc_ref(struct tty_struct *); 411 407 extern void tty_ldisc_deref(struct tty_ldisc *); 412 408 extern struct tty_ldisc *tty_ldisc_ref_wait(struct tty_struct *); 409 + extern void tty_ldisc_hangup(struct tty_struct *tty); 413 410 extern const struct file_operations tty_ldiscs_proc_fops; 414 411 415 412 extern void tty_wakeup(struct tty_struct *tty);