1. 29 1月, 2016 6 次提交
    • P
      n_tty: Remove tty count checks from unthrottle · ffb91a45
      Peter Hurley 提交于
      Since n_tty_check_unthrottle() is only called from n_tty_read()
      which only originates from a userspace read(), the tty count cannot
      be 0; the read() guarantees the file descriptor has not yet been
      released.
      Signed-off-by: NPeter Hurley <peter@hurleysoftware.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      ffb91a45
    • P
      n_tty: Fix stuck write wakeup · 7bccc365
      Peter Hurley 提交于
      If signal-driven i/o is disabled while write wakeup is pending (ie.,
      n_tty_write() has set TTY_DO_WRITE_WAKEUP but then signal-driven i/o
      is disabled), the TTY_DO_WRITE_WAKEUP bit will never be cleared and
      will cause tty_wakeup() to always call n_tty_write_wakeup.
      
      Unconditionally clear the write wakeup, and since kill_fasync()
      already checks if the fasync ptr is null, call kill_fasync()
      unconditionally as well.
      Signed-off-by: NPeter Hurley <peter@hurleysoftware.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      7bccc365
    • P
      tty: Fix ioctl(FIOASYNC) on hungup file · a8f3a297
      Peter Hurley 提交于
      A small race window exists which allows signal-driven async i/o to be
      enabled for the tty when the file ptr has already been hungup and
      signal-driven i/o has been disabled:
      
      CPU 0                                CPU 1
      -----                                ------
      ioctl_fioasync(on)
        filp->f_op->fasync(on)             __tty_hangup()
          tty_fasync(on)                     tty_lock()
            tty_lock()                       ...
              .                              filp->f_op = &hung_up_tty_fops;
            (waiting)                       __tty_fasync(off)
              .                              tty_unlock()
            /* gets tty lock  */
            /* enables FASYNC */
      
      Check the tty has not been hungup while holding tty_lock.
      Signed-off-by: NPeter Hurley <peter@hurleysoftware.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      a8f3a297
    • P
      tty: Add fasync() hung up file operation · f557474c
      Peter Hurley 提交于
      VFS uses a two-stage check-and-call method for invoking file_operations
      methods, without explicitly snapshotting either the file_operations ptr
      or the function ptr. Since the tty core is one of the few VFS users that
      changes the f_op file_operations ptr of the file descriptor (when the
      tty has been hung up), and since the likelihood of the compiler generating
      a reload of either f_op or the function ptr is basically nil, just define
      a hung up fasync() file operation that returns an error.
      Signed-off-by: NPeter Hurley <peter@hurleysoftware.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      f557474c
    • P
      tty, n_tty: Remove fasync() ldisc notification · bee6741c
      Peter Hurley 提交于
      Only the N_TTY line discipline implements the signal-driven i/o
      notification enabled/disabled by fcntl(F_SETFL, O_ASYNC). The ldisc
      fasync() notification is sent to the ldisc when the enable state has
      changed (the tty core is notified via the fasync() VFS file operation).
      
      The N_TTY line discipline used the enable state to change the wakeup
      condition (minimum_to_wake = 1) for notifying the signal handler i/o is
      available. However, just the presence of data is sufficient and necessary
      to signal i/o is available, so changing minimum_to_wake is unnecessary
      (and creates a race condition with read() and poll() which may be
      concurrently updating minimum_to_wake).
      
      Furthermore, since the kill_fasync() VFS helper performs no action if
      the fasync list is empty, calling unconditionally is preferred; if
      signal driven i/o just has been disabled, no signal will be sent by
      kill_fasync() anyway so notification of the change via the ldisc
      fasync() method is superfluous.
      Signed-off-by: NPeter Hurley <peter@hurleysoftware.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      bee6741c
    • P
      n_tty: Always wake up read()/poll() if new input · 33d71363
      Peter Hurley 提交于
      A read() in non-canonical mode when VMIN > 0 and VTIME == 0 does not
      complete until at least VMIN chars have been read (or the user buffer is
      full). In this infrequent read mode, n_tty_read() attempts to reduce
      wakeups by computing the amount of data still necessary to complete the
      read (minimum_to_wake) and only waking the read()/poll() when that much
      unread data has been processed. This is the only read mode for which
      new data does not necessarily generate a wakeup.
      
      However, this optimization is broken and commonly leads to hung reads
      even though the necessary amount of data has been received. Since the
      optimization is of marginal value anyway, just remove the whole
      thing. This also remedies a race between a concurrent poll() and
      read() in this mode, where the poll() can reset the minimum_to_wake
      of the read() (and vice versa).
      Signed-off-by: NPeter Hurley <peter@hurleysoftware.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      33d71363
  2. 28 1月, 2016 34 次提交