27 Nov, 2011

1 commit


18 Nov, 2011

4 commits

  • They were cut&pasted from tty_io. Many of them are not needed in
    tty_ldisc.

    Signed-off-by: Jiri Slaby
    Cc: Alan Cox
    Signed-off-by: Greg Kroah-Hartman

    Jiri Slaby
     
  • For /dev/console case, we do not kill all ldisc users. It's due to
    redirected_tty_write test in __tty_hangup. In that case there still
    might be a process waiting e.g. in n_tty_read for input.

    We wait for such processes to disappear. The problem is that we use a
    timeout. After this timeout, we continue closing the ldisc and start
    freeing tty resources. It obviously leads to crashes when the other
    process is woken.

    So to fix this, we wait infinitely before reiniting the ldisc. (The
    tiocsetd remains untouched -- times out after 5s.)

    This is nicely reproducible with this run from shell:
    exec 0<>/dev/console 1<>/dev/console 2<>/dev/console
    and stopping a getty like:
    systemctl stop serial-getty@ttyS0.service

    The crash proper may be produced only under load or with constified
    timing the same as for 92f6fa09b.

    Signed-off-by: Jiri Slaby
    Cc: Dave Young
    Cc: Dave Jones
    Cc: Ben Hutchings
    Cc: Dmitriy Matrosov
    Cc: Alan Cox
    Cc: stable
    Signed-off-by: Greg Kroah-Hartman

    Jiri Slaby
     
  • It is the only place where reinit is called from. And we really need
    to wait for the old ldisc to go once. Actually this is the place where
    the waiting originally was (before removed and re-added later).

    This will make the fix in the following patch easier to implement.

    Signed-off-by: Jiri Slaby
    Cc: Dave Young
    Cc: Dave Jones
    Cc: Ben Hutchings
    Cc: Dmitriy Matrosov
    Cc: Alan Cox
    Cc: stable
    Signed-off-by: Greg Kroah-Hartman

    Jiri Slaby
     
  • To fix a nasty bug in ldisc hup vs. reinit we need to wait infinitely
    long for ldisc to be gone. So here we add a parameter to
    tty_ldisc_wait_idle to allow that.

    This is only a preparation for the real fix which is done in the
    following patches.

    Signed-off-by: Jiri Slaby
    Cc: Dave Young
    Cc: Dave Jones
    Cc: Ben Hutchings
    Cc: Dmitriy Matrosov
    Cc: Alan Cox
    Cc: stable
    Signed-off-by: Greg Kroah-Hartman

    Jiri Slaby
     

16 Nov, 2011

1 commit


24 Aug, 2011

1 commit

  • We used it really only serial and ami_serial. The rest of the
    callsites were BUG/WARN_ONs to check if BTM is held. Now that we
    pruned tty_locked from both of the real users, we can get rid of
    tty_lock along with __big_tty_mutex_owner.

    Signed-off-by: Jiri Slaby
    Acked-by: Arnd Bergmann
    Cc: Alan Cox
    Signed-off-by: Greg Kroah-Hartman

    Jiri Slaby
     

08 Jun, 2011

1 commit

  • We restored tty_ldisc_wait_idle in 100eeae2c5c (TTY: restore
    tty_ldisc_wait_idle). We used it in the ldisc changing path to fix the
    case where there are tasks in n_tty_read waiting for data and somebody
    tries to change ldisc.

    Similar to the case above, there may be also tasks waiting in
    n_tty_read while hangup is performed. As 65b770468e98 (tty-ldisc: turn
    ldisc user count into a proper refcount) removed the wait-until-idle
    from all paths, hangup path won't wait for them to disappear either
    now. So add it back even to the hangup path.

    There is a difference, we need uninterruptible sleep as there is
    obviously HUP signal pending. So tty_ldisc_wait_idle now sleeps
    without possibility to be interrupted. This is what original
    tty_ldisc_wait_idle did. After the wait idle reintroduction
    (100eeae2c5c), we have had interruptible sleeps for the ldisc changing
    path. But as there is a 5s timeout anyway, we don't allow it to be
    interrupted from now on. It's not worth the added complexity of
    deciding what kind of sleep we want.

    Before 65b770468e98 tty_ldisc_release was called also from
    tty_ldisc_release. It is called from tty_release, so I don't think we
    need to restore that one.

    This is nicely reproducible after constifying the timing when
    drivers/tty/n_tty.c is patched as follows ("TTY: ntty, add one more
    sanity check" patch is needed to actually see it explode):
    %% -1548,6 +1549,7 @@ static int n_tty_open(struct tty_struct *tty)

    /* These are ugly. Currently a malloc failure here can panic */
    if (!tty->read_buf) {
    + msleep(100);
    tty->read_buf = kzalloc(N_TTY_BUF_SIZE, GFP_KERNEL);
    if (!tty->read_buf)
    return -ENOMEM;
    %% -1785,6 +1788,7 @@ do_it_again:
    break;
    }
    timeout = schedule_timeout(timeout);
    + msleep(20);
    continue;
    }
    __set_current_state(TASK_RUNNING);
    ===== With a process: =====
    while (1) {
    int fd = open(argv[1], O_RDWR);
    read(fd, buf, sizeof(buf));
    close(fd);
    }
    ===== and its child: =====
    setsid();
    while (1) {
    int fd = open(tty, O_RDWR|O_NOCTTY);
    ioctl(fd, TIOCSCTTY, 1);
    vhangup();
    close(fd);
    usleep(100 * (10 + random() % 1000));
    }
    ===== EOF =====

    References: https://bugzilla.novell.com/show_bug.cgi?id=693374
    References: https://bugzilla.novell.com/show_bug.cgi?id=694509
    Signed-off-by: Jiri Slaby
    Cc: Alan Cox
    Cc: Linus Torvalds
    Cc: stable [32, 33, 34, 39]
    Signed-off-by: Greg Kroah-Hartman

    Jiri Slaby
     

20 Apr, 2011

1 commit

  • Introduce deinitialize_tty_struct which should be called after
    initialize_tty_struct and before successfull tty_ldisc_setup.

    It calls tty_ldisc_deinit which is opposite of tty_ldisc_init. It only
    puts a reference to ldisc and assigns NULL to tty->ldisc.

    It will be used to shut down ldisc when tty_release cannot be called
    yet.

    Signed-off-by: Jiri Slaby
    Cc: Alan Cox
    Cc: Julian Anastasov
    Signed-off-by: Greg Kroah-Hartman

    Jiri Slaby
     

23 Mar, 2011

1 commit

  • Using delayed-work for tty flip buffers ends up causing us to wait for
    the next tick to complete some actions. That's usually not all that
    noticeable, but for certain latency-critical workloads it ends up being
    totally unacceptable.

    As an extreme case of this, passing a token back-and-forth over a pty
    will take two ticks per iteration, so even just a thousand iterations
    will take 8 seconds assuming a common 250Hz configuration.

    Avoiding the whole delayed work issue brings that ping-pong test-case
    down to 0.009s on my machine.

    In more practical terms, this latency has been a performance problem for
    things like dive computer simulators (simulating the serial interface
    using the ptys) and for other environments (Alan mentions a CP/M emulator).

    Reported-by: Jef Driesen
    Acked-by: Greg KH
    Acked-by: Alan Cox
    Signed-off-by: Linus Torvalds

    Linus Torvalds
     

17 Mar, 2011

1 commit


02 Mar, 2011

1 commit


04 Feb, 2011

1 commit

  • flush_scheduled_work() is scheduled to be deprecated. Explicitly sync
    flush the used work items instead. Note that before this change,
    flush_scheduled_work() wouldn't have properly flushed tty->buf.work if
    it were on timer.

    Signed-off-by: Tejun Heo
    Signed-off-by: Greg Kroah-Hartman

    Tejun Heo
     

30 Nov, 2010

1 commit

  • When a concrete ldisc open fails in tty_ldisc_open, we forget to clear
    TTY_LDISC_OPEN. This causes a false warning on the next ldisc open:
    WARNING: at drivers/char/tty_ldisc.c:445 tty_ldisc_open+0x26/0x38()
    Hardware name: System Product Name
    Modules linked in: ...
    Pid: 5251, comm: a.out Tainted: G W 2.6.32-5-686 #1
    Call Trace:
    [] ? warn_slowpath_common+0x5e/0x8a
    [] ? warn_slowpath_null+0xa/0xc
    [] ? tty_ldisc_open+0x26/0x38
    [] ? tty_set_ldisc+0x218/0x304
    ...

    So clear the bit when failing...

    Introduced in c65c9bc3efa (tty: rewrite the ldisc locking) back in
    2.6.31-rc1.

    Signed-off-by: Jiri Slaby
    Cc: Alan Cox
    Reported-by: Sergey Lapin
    Tested-by: Sergey Lapin
    Cc: stable
    Signed-off-by: Greg Kroah-Hartman

    Jiri Slaby
     

10 Nov, 2010

2 commits

  • A kernel BUG when bluetooth rfcomm connection drop while the associated
    serial port is open is sometime triggered.

    It seems that the line discipline can disappear between the
    tty_ldisc_put and tty_ldisc_get. This patch fall back to the N_TTY line
    discipline if the previous discipline is not available anymore.

    Signed-off-by: Philippe Retornaz
    Acked-by: Alan Cox
    Cc: stable
    Signed-off-by: Greg Kroah-Hartman

    Philippe Rétornaz
     
  • It was removed in 65b770468e98 (tty-ldisc: turn ldisc user count into
    a proper refcount), but we need to wait for last user to quit the
    ldisc before we close it in tty_set_ldisc.

    Otherwise weird things start to happen. There might be processes
    waiting in tty_read->n_tty_read on tty->read_wait for input to appear
    and at that moment, a change of ldisc is fatal. n_tty_close is called,
    it frees read_buf and the waiting process is still in the middle of
    reading and goes nuts after it is woken.

    Previously we prevented close to happen when others are in ldisc ops
    by tty_ldisc_wait_idle in tty_set_ldisc. But the commit above removed
    that. So revoke the change and test whether there is 1 user (=we), and
    allow the close then.

    We can do that without ldisc/tty locks, because nobody else can open
    the device due to TTY_LDISC_CHANGING bit set, so we in fact wait for
    everybody to leave.

    I don't understand why tty_ldisc_lock would be needed either when the
    counter is an atomic variable, so this is a lockless
    tty_ldisc_wait_idle.

    On the other hand, if we fail to wait (timeout or signal), we have to
    reenable the halted ldiscs, so we take ldisc lock and reuse the setup
    path at the end of tty_set_ldisc.

    Signed-off-by: Jiri Slaby
    Acked-by: Linus Torvalds
    Tested-by: Sebastian Andrzej Siewior
    LKML-Reference:
    LKML-Reference:
    Cc: Alan Cox
    Cc: stable@kernel.org [32, 33, 36]
    Signed-off-by: Greg Kroah-Hartman

    Jiri Slaby
     

05 Nov, 2010

1 commit