1. 18 10月, 2015 5 次提交
    • P
      tty: Abstract tty buffer work · e176058f
      Peter Hurley 提交于
      Introduce API functions to restart and cancel tty buffer work, rather
      than manipulate buffer work directly.
      Signed-off-by: NPeter Hurley <peter@hurleysoftware.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      e176058f
    • P
      tty: Combine SIGTTOU/SIGTTIN handling · 2812d9e9
      Peter Hurley 提交于
      The job_control() check in n_tty_read() has nearly identical purpose
      and results as tty_check_change(). Both functions' purpose is to
      determine if the current task's pgrp is the foreground pgrp for the tty,
      and if not, to signal the current pgrp.
      
      Introduce __tty_check_change() which takes the signal to send
      and performs the shared operations for job control() and
      tty_check_change().
      Signed-off-by: NPeter Hurley <peter@hurleysoftware.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      2812d9e9
    • P
      tty: Remove wait_event_interruptible_tty() · f148d6d7
      Peter Hurley 提交于
      In-tree users of wait_event_interruptible_tty() have been removed;
      remove.
      Signed-off-by: NPeter Hurley <peter@hurleysoftware.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      f148d6d7
    • P
      tty: Remove tty_port::close_wait · cc2aaabf
      Peter Hurley 提交于
      With the removal of tty_wait_until_sent_from_close(), tty drivers
      no longer wait during open for parallel closes to complete (instead,
      the tty core waits before calling the driver open() method). Thus,
      the close_wait waitqueue is no longer used for waiting.
      
      Remove struct tty_port::close_wait.
      Signed-off-by: NPeter Hurley <peter@hurleysoftware.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      cc2aaabf
    • P
      tty: Remove tty_wait_until_sent_from_close() · 79c1faa4
      Peter Hurley 提交于
      tty_wait_until_sent_from_close() drops the tty lock while waiting
      for the tty driver to finish sending previously accepted data (ie.,
      data remaining in its write buffer and transmit fifo).
      
      tty_wait_until_sent_from_close() was added by commit a57a7bf3
      ("TTY: define tty_wait_until_sent_from_close") to prevent the entire
      tty subsystem from being unable to open new ttys while waiting for
      one tty to close while output drained.
      
      However, since commit 0911261d ("tty: Don't take tty_mutex for tty
      count changes"), holding a tty lock while closing does not prevent other
      ttys from being opened/closed/hung up, but only prevents lifetime event
      changes for the tty under lock.
      
      Holding the tty lock while waiting for output to drain does prevent
      parallel non-blocking opens (O_NONBLOCK) from advancing or returning
      while the tty lock is held. However, all parallel opens _already_
      block even if the tty lock is dropped while closing and the parallel
      open advances. Blocking in open has been in mainline since at least 2.6.29
      (see tty_port_block_til_ready(); note the test for O_NONBLOCK is _after_
      the wait while ASYNC_CLOSING).
      
      IOW, before this patch a non-blocking open will sleep anyway for the
      _entire_ duration of a parallel hardware shutdown, and when it wakes, the
      error return will cause a release of its tty, and it will restart with
      a fresh attempt to open. Similarly with a blocking open that is already
      waiting; when it's woken, the hardware shutdown has already completed
      to ASYNC_INITIALIZED is not set, which forces a release and restart as
      well.
      
      So, holding the tty lock across the _entire_ close (which is what this
      patch does), even while waiting for output to drain, is equivalent to
      the current outcome wrt parallel opens.
      
      Cc: Alan Cox <alan@linux.intel.com>
      Cc: David Laight <David.Laight@aculab.com>
      CC: Arnd Bergmann <arnd@arndb.de>
      CC: Karsten Keil <isdn@linux-pingi.de>
      CC: linuxppc-dev@lists.ozlabs.org
      Signed-off-by: NPeter Hurley <peter@hurleysoftware.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      79c1faa4
  2. 24 7月, 2015 1 次提交
  3. 11 5月, 2015 1 次提交
    • P
      pty: Fix input race when closing · 1a48632f
      Peter Hurley 提交于
      A read() from a pty master may mistakenly indicate EOF (errno == -EIO)
      after the pty slave has closed, even though input data remains to be read.
      For example,
      
             pty slave       |        input worker        |    pty master
                             |                            |
                             |                            |   n_tty_read()
      pty_write()            |                            |     input avail? no
        add data             |                            |     sleep
        schedule worker  --->|                            |     .
                             |---> flush_to_ldisc()       |     .
      pty_close()            |       fill read buffer     |     .
        wait for worker      |       wakeup reader    --->|     .
                             |       read buffer full?    |---> input avail ? yes
                             |<---   yes - exit worker    |     copy 4096 bytes to user
        TTY_OTHER_CLOSED <---|                            |<--- kick worker
                             |                            |
      
      		                **** New read() before worker starts ****
      
                             |                            |   n_tty_read()
                             |                            |     input avail? no
                             |                            |     TTY_OTHER_CLOSED? yes
                             |                            |     return -EIO
      
      Several conditions are required to trigger this race:
      1. the ldisc read buffer must become full so the input worker exits
      2. the read() count parameter must be >= 4096 so the ldisc read buffer
         is empty
      3. the subsequent read() occurs before the kicked worker has processed
         more input
      
      However, the underlying cause of the race is that data is pipelined, while
      tty state is not; ie., data already written by the pty slave end is not
      yet visible to the pty master end, but state changes by the pty slave end
      are visible to the pty master end immediately.
      
      Pipeline the TTY_OTHER_CLOSED state through input worker to the reader.
      1. Introduce TTY_OTHER_DONE which is set by the input worker when
         TTY_OTHER_CLOSED is set and either the input buffers are flushed or
         input processing has completed. Readers/polls are woken when
         TTY_OTHER_DONE is set.
      2. Reader/poll checks TTY_OTHER_DONE instead of TTY_OTHER_CLOSED.
      3. A new input worker is started from pty_close() after setting
         TTY_OTHER_CLOSED, which ensures the TTY_OTHER_DONE state will be
         set if the last input worker is already finished (or just about to
         exit).
      
      Remove tty_flush_to_ldisc(); no in-tree callers.
      
      Fixes: 52bce7f8 ("pty, n_tty: Simplify input processing on final close")
      Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=96311
      BugLink: http://bugs.launchpad.net/bugs/1429756
      Cc: <stable@vger.kernel.org> # 3.19+
      Reported-by: NAndy Whitcroft <apw@canonical.com>
      Reported-by: NH.J. Lu <hjl.tools@gmail.com>
      Signed-off-by: NPeter Hurley <peter@hurleysoftware.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      1a48632f
  4. 07 5月, 2015 2 次提交
  5. 28 4月, 2015 1 次提交
  6. 03 2月, 2015 4 次提交
    • P
      tty: Remove external interface for tty_set_termios() · 632f32e2
      Peter Hurley 提交于
      tty_set_termios() is an internal helper intended for file scope use.
      
      UART drivers which are capable of driving the RTS pin must
      properly handle the tiocmset() method, regardless of termios settings.
      A failure to do so is a UART driver bug and should be fixed there.
      Do not use this interface to workaround UART driver bugs.
      
      Cc: Johan Hedberg <johan.hedberg@gmail.com>
      Cc: <linux-bluetooth@vger.kernel.org>
      Signed-off-by: NPeter Hurley <peter@hurleysoftware.com>
      Acked-by: NMarcel Holtmann <marcel@holtmann.org>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      632f32e2
    • P
      n_tty: Fix signal handling flushes · d2b6f447
      Peter Hurley 提交于
      BRKINT and ISIG requires input and output flush when a signal char
      is received. However, the order of operations is significant since
      parallel i/o may be ongoing.
      
      Merge the signal handling for BRKINT with ISIG handling.
      
      Process the signal first. This ensures any ongoing i/o is aborted;
      without this, a waiting writer may continue writing after the flush
      occurs and after the signal char has been echoed.
      
      Write lock the termios_rwsem, which excludes parallel writers from
      pushing new i/o until after the output buffers are flushed; claiming
      the write lock is necessary anyway to exclude parallel readers while
      the read buffer is flushed.
      
      Subclass the termios_rwsem for ptys since the slave pty performing
      the flush may appear to reorder the termios_rwsem->tty buffer lock
      lock order; adding annotation clarifies that
        slave tty_buffer lock-> slave termios_rwsem -> master tty_buffer lock
      is a valid lock order.
      
      Flush the echo buffer. In this context, the echo buffer is 'output'.
      Otherwise, the output will appear discontinuous because the output buffer
      was cleared which contains older output than the echo buffer.
      
      Open-code the read buffer flush since the input worker does not need
      kicking (this is the input worker).
      Signed-off-by: NPeter Hurley <peter@hurleysoftware.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      d2b6f447
    • P
      pty: Fix buffer flush deadlock · 1d1d14da
      Peter Hurley 提交于
      The pty driver does not clear its write buffer when commanded.
      This is to avoid an apparent deadlock between parallel flushes from
      both pty ends; specifically when handling either BRK or INTR input.
      However, parallel flushes from this source is not possible since
      the pty master can never be set to BRKINT or ISIG. Parallel flushes
      from other sources are possible but these do not threaten deadlocks.
      
      Annotate the tty buffer mutex for lockdep to represent the nested
      tty_buffer locking which occurs when the pty slave is processing input
      (its buffer mutex held) and receives INTR or BRK and acquires the
      linked tty buffer mutex via tty_buffer_flush().
      Signed-off-by: NPeter Hurley <peter@hurleysoftware.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      1d1d14da
    • P
      tty: Make lock subclasses available for other tty locks · 3abf87cd
      Peter Hurley 提交于
      Besides nested legacy_mutex locking which is required on pty pair
      teardown, other nested pty operations require lock subclassing.
      
      Move lock subclass definition to tty interface header, include/linux/tty.h,
      and document its use.
      Signed-off-by: NPeter Hurley <peter@hurleysoftware.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      3abf87cd
  7. 07 11月, 2014 1 次提交
  8. 06 11月, 2014 10 次提交
  9. 25 9月, 2014 1 次提交
  10. 24 9月, 2014 5 次提交
    • P
      tty: Workaround Alpha non-atomic byte storage in tty_struct · 99416322
      Peter Hurley 提交于
      The Alpha EV4/EV5 cpus can corrupt adjacent byte and short data because
      those cpus use RMW to store byte and short data. Thus, concurrent adjacent
      byte stores could become corrupted, if serialized by a different lock.
      tty_struct uses different locks to protect certain fields within the
      structure, and thus is vulnerable to byte stores which are not atomic.
      
      Merge the ->ctrl_status byte and packet mode bit, both protected by the
      ->ctrl_lock, into an unsigned long.
      
      The padding bits are necessary to force the compiler to allocate the
      type specified; otherwise, gcc will ignore the type specifier and
      allocate the minimum number of bytes required to store the bitfield.
      In turn, this would allow Alpha EV4/EV5 cpus to corrupt adjacent byte
      or short storage (because those cpus use RMW to store byte and short data).
      
      gcc versions < 4.7.2 will also corrupt storage adjacent to bitfields
      smaller than unsigned long on ia64, ppc64, hppa64, and sparc64, thus
      requiring more than unsigned int storage (which would otherwise be
      sufficient to fix the Alpha non-atomic storage problem).
      Signed-off-by: NPeter Hurley <peter@hurleysoftware.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      99416322
    • P
      tty: Move and rename send_prio_char() as tty_send_xchar() · 136d5258
      Peter Hurley 提交于
      Relocate the file-scope function, send_prio_char(), as a global
      helper tty_send_xchar(). Remove the global declarations for
      tty_write_lock()/tty_write_unlock(), as these are file-scope only now.
      Signed-off-by: NPeter Hurley <peter@hurleysoftware.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      136d5258
    • P
      tty: Serialize tcflow() with other tty flow control changes · c545b66c
      Peter Hurley 提交于
      Use newly-introduced tty->flow_lock to serialize updates to
      tty->flow_stopped (via tcflow()) and with concurrent tty flow
      control changes from other sources.
      
      Merge the storage for ->stopped and ->flow_stopped, now that both
      flags are serialized by ->flow_lock.
      
      The padding bits are necessary to force the compiler to allocate the
      type specified; otherwise, gcc will ignore the type specifier and
      allocate the minimum number of bytes necessary to store the bitfield.
      In turn, this would allow Alpha EV4 and EV5 cpus to corrupt adjacent
      byte storage because those cpus use RMW to store byte and short data.
      
      gcc versions < 4.7.2 will also corrupt storage adjacent to bitfields
      smaller than unsigned long on ia64, ppc64, hppa64 and sparc64, thus
      requiring more than unsigned int storage (which would otherwise be
      sufficient to workaround the Alpha non-atomic byte/short storage problem).
      Signed-off-by: NPeter Hurley <peter@hurleysoftware.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      c545b66c
    • P
      tty: Serialize tty flow control changes with flow_lock · f9e053dc
      Peter Hurley 提交于
      Without serialization, the flow control state can become inverted
      wrt. the actual hardware state. For example,
      
      CPU 0                          | CPU 1
      stop_tty()                     |
        lock ctrl_lock               |
        tty->stopped = 1             |
        unlock ctrl_lock             |
                                     | start_tty()
                                     |   lock ctrl_lock
                                     |   tty->stopped = 0
                                     |   unlock ctrl_lock
                                     |   driver->start()
        driver->stop()               |
      
      In this case, the flow control state now indicates the tty has
      been started, but the actual hardware state has actually been stopped.
      
      Introduce tty->flow_lock spinlock to serialize tty flow control changes.
      Split out unlocked __start_tty()/__stop_tty() flavors for use by
      ioctl(TCXONC) in follow-on patch.
      Signed-off-by: NPeter Hurley <peter@hurleysoftware.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      f9e053dc
    • P
      tty: Convert tty_struct bitfield to ints · d7a855bd
      Peter Hurley 提交于
      The stopped, hw_stopped, flow_stopped and packet bits are smp-unsafe
      and interrupt-unsafe. For example,
      
      CPU 0                         | CPU 1
                                    |
      tty->flow_stopped = 1         | tty->hw_stopped = 0
      
      One of these updates will be corrupted, as the bitwise operation
      on the bitfield is non-atomic.
      
      Ensure each flag has a separate memory location, so concurrent
      updates do not corrupt orthogonal states. Because DEC Alpha EV4 and EV5
      cpus (from 1995) perform RMW on smaller-than-machine-word storage,
      "separate memory location" must be int instead of byte.
      Signed-off-by: NPeter Hurley <peter@hurleysoftware.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      d7a855bd
  11. 12 7月, 2014 1 次提交
  12. 04 5月, 2014 1 次提交
  13. 25 4月, 2014 1 次提交
    • M
      tty: Fix race condition between __tty_buffer_request_room and flush_to_ldisc · 6a20dbd6
      Manfred Schlaegl 提交于
      The race was introduced while development of linux-3.11 by
      e8437d7e and
      e9975fde.
      Originally it was found and reproduced on linux-3.12.15 and
      linux-3.12.15-rt25, by sending 500 byte blocks with 115kbaud to the
      target uart in a loop with 100 milliseconds delay.
      
      In short:
       1. The consumer flush_to_ldisc is on to remove the head tty_buffer.
       2. The producer adds a number of bytes, so that a new tty_buffer must
      	be allocated and added by __tty_buffer_request_room.
       3. The consumer removes the head tty_buffer element, without handling
      	newly committed data.
      
      Detailed example:
       * Initial buffer:
         * Head, Tail -> 0: used=250; commit=250; read=240; next=NULL
       * Consumer: ''flush_to_ldisc''
         * consumed 10 Byte
         * buffer:
           * Head, Tail -> 0: used=250; commit=250; read=250; next=NULL
      {{{
      		count = head->commit - head->read;	// count = 0
      		if (!count) {				// enter
      			// INTERRUPTED BY PRODUCER ->
      			if (head->next == NULL)
      				break;
      			buf->head = head->next;
      			tty_buffer_free(port, head);
      			continue;
      		}
      }}}
       * Producer: tty_insert_flip_... 10 bytes + tty_flip_buffer_push
         * buffer:
           * Head, Tail -> 0: used=250; commit=250; read=250; next=NULL
         * added 6 bytes: head-element filled to maximum.
           * buffer:
             * Head, Tail -> 0: used=256; commit=250; read=250; next=NULL
         * added 4 bytes: __tty_buffer_request_room is called
           * buffer:
             * Head -> 0: used=256; commit=256; read=250; next=1
             * Tail -> 1: used=4; commit=0; read=250 next=NULL
         * push (tty_flip_buffer_push)
           * buffer:
             * Head -> 0: used=256; commit=256; read=250; next=1
             * Tail -> 1: used=4; commit=4; read=250 next=NULL
       * Consumer
      {{{
      		count = head->commit - head->read;
      		if (!count) {
      			// INTERRUPTED BY PRODUCER <-
      			if (head->next == NULL)		// -> no break
      				break;
      			buf->head = head->next;
      			tty_buffer_free(port, head);
      			// ERROR: tty_buffer head freed -> 6 bytes lost
      			continue;
      		}
      }}}
      
      This patch reintroduces a spin_lock to protect this case. Perhaps later
      a lock-less solution could be found.
      Signed-off-by: NManfred Schlaegl <manfred.schlaegl@gmx.at>
      Cc: stable <stable@vger.kernel.org> # 3.11
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      6a20dbd6
  14. 01 3月, 2014 1 次提交
    • P
      tty: Fix low_latency BUG · a9c3f68f
      Peter Hurley 提交于
      The user-settable knob, low_latency, has been the source of
      several BUG reports which stem from flush_to_ldisc() running
      in interrupt context. Since 3.12, which added several sleeping
      locks (termios_rwsem and buf->lock) to the input processing path,
      the frequency of these BUG reports has increased.
      
      Note that changes in 3.12 did not introduce this regression;
      sleeping locks were first added to the input processing path
      with the removal of the BKL from N_TTY in commit
      a88a69c9,
      'n_tty: Fix loss of echoed characters and remove bkl from n_tty'
      and later in commit 38db8979,
      'tty: throttling race fix'. Since those changes, executing
      flush_to_ldisc() in interrupt_context (ie, low_latency set), is unsafe.
      
      However, since most devices do not validate if the low_latency
      setting is appropriate for the context (process or interrupt) in
      which they receive data, some reports are due to misconfiguration.
      Further, serial dma devices for which dma fails, resort to
      interrupt receiving as a backup without resetting low_latency.
      
      Historically, low_latency was used to force wake-up the reading
      process rather than wait for the next scheduler tick. The
      effect was to trim multiple milliseconds of latency from
      when the process would receive new data.
      
      Recent tests [1] have shown that the reading process now receives
      data with only 10's of microseconds latency without low_latency set.
      
      Remove the low_latency rx steering from tty_flip_buffer_push();
      however, leave the knob as an optional hint to drivers that can
      tune their rx fifos and such like. Cleanup stale code comments
      regarding low_latency.
      
      [1] https://lkml.org/lkml/2014/2/20/434
      
      "Yay.. thats an annoying historical pain in the butt gone."
      	-- Alan Cox
      Reported-by: NBeat Bolli <bbolli@ewanet.ch>
      Reported-by: NPavel Roskin <proski@gnu.org>
      Acked-by: NDavid Sterba <dsterba@suse.cz>
      Cc: Grant Edwards <grant.b.edwards@gmail.com>
      Cc: Stanislaw Gruszka <sgruszka@redhat.com>
      Cc: Hal Murray <murray+fedora@ip-64-139-1-69.sjc.megapath.net>
      Cc: <stable@vger.kernel.org> # 3.12.x+
      Signed-off-by: NPeter Hurley <peter@hurleysoftware.com>
      Signed-off-by: NAlan Cox <alan@linux.intel.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      a9c3f68f
  15. 15 2月, 2014 1 次提交
    • P
      tty: Fix ref counting for port krefs · c0fdfb80
      Peter Hurley 提交于
      The tty core supports two models for handling tty_port lifetimes;
      the tty_port can use the kref supplied by tty_port (which will
      automatically destruct the tty_port when the ref count drops to
      zero) or it can destruct the tty_port manually.
      
      For tty drivers that choose to use the port kref to manage the
      tty_port lifetime, it is not possible to safely acquire a port
      reference conditionally. If the last reference is released after
      evaluating the condition but before acquiring the reference, a
      bogus reference will be held while the tty_port destruction
      commences.
      
      Rather, only acquire a port reference if the ref count is non-zero
      and allow the caller to distinguish if a reference has successfully
      been acquired.
      
      Cc: Jiri Slaby <jslaby@suse.cz>
      Signed-off-by: NPeter Hurley <peter@hurleysoftware.com>
      Acked-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      Tested-By: NAlexander Holler <holler@ahsoftware.de>
      Signed-off-by: NMarcel Holtmann <marcel@holtmann.org>
      c0fdfb80
  16. 04 1月, 2014 1 次提交
  17. 19 12月, 2013 1 次提交
  18. 10 12月, 2013 1 次提交
  19. 09 12月, 2013 1 次提交