1. 24 Jul, 2013 32 commits
    • Aldo Iljazi's avatar
      Drivers: tty: n_gsm.c: fixed 7 errors & 6 warnings that checkpatch complained · f3c909b4
      Aldo Iljazi authored
      Specifically:
      n_gsm.c:810: ERROR: space required before the open parenthesis '('
      n_gsm.c:830: WARNING: line over 80 characters
      n_gsm.c:971: ERROR: trailing whitespace
      n_gsm.c:984: ERROR: code indent should use tabs where possible
      n_gsm.c:984: WARNING: please, no space before tabs
      n_gsm.c:984: WARNING: please, no spaces at the start of a line
      n_gsm.c:1141: WARNING: space prohibited before semicolon
      n_gsm.c:1743: ERROR: space required before the open brace '{'
      n_gsm.c:1744: WARNING: line over 80 characters
      n_gsm.c:1745: ERROR: code indent should use tabs where possible
      n_gsm.c:1746: ERROR: code indent should use tabs where possible
      n_gsm.c:2908: WARNING: line over 80 characters
      n_gsm.c:2912: ERROR: trailing whitespace
      Signed-off-by: default avatarAldo Iljazi <neonsync1@gmail.com>
      Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      f3c909b4
    • Peter Hurley's avatar
      tty: Fix lock order in tty_do_resize() · dee4a0be
      Peter Hurley authored
      Commits 6a1c0680 and
      9356b535, respectively
        'tty: Convert termios_mutex to termios_rwsem' and
        'n_tty: Access termios values safely'
      introduced a circular lock dependency with console_lock and
      termios_rwsem.
      
      The lockdep report [1] shows that n_tty_write() will attempt
      to claim console_lock while holding the termios_rwsem, whereas
      tty_do_resize() may already hold the console_lock while
      claiming the termios_rwsem.
      
      Since n_tty_write() and tty_do_resize() do not contend
      over the same data -- the tty->winsize structure -- correct
      the lock dependency by introducing a new lock which
      specifically serializes access to tty->winsize only.
      
      [1] Lockdep report
      
      ======================================================
      [ INFO: possible circular locking dependency detected ]
      3.10.0-0+tip-xeon+lockdep #0+tip Not tainted
      -------------------------------------------------------
      modprobe/277 is trying to acquire lock:
       (&tty->termios_rwsem){++++..}, at: [<ffffffff81452656>] tty_do_resize+0x36/0xe0
      
      but task is already holding lock:
       ((fb_notifier_list).rwsem){.+.+.+}, at: [<ffffffff8107aac6>] __blocking_notifier_call_chain+0x56/0xc0
      
      which lock already depends on the new lock.
      
      the existing dependency chain (in reverse order) is:
      
      -> #2 ((fb_notifier_list).rwsem){.+.+.+}:
             [<ffffffff810b6d62>] lock_acquire+0x92/0x1f0
             [<ffffffff8175b797>] down_read+0x47/0x5c
             [<ffffffff8107aac6>] __blocking_notifier_call_chain+0x56/0xc0
             [<ffffffff8107ab46>] blocking_notifier_call_chain+0x16/0x20
             [<ffffffff813d7c0b>] fb_notifier_call_chain+0x1b/0x20
             [<ffffffff813d95b2>] register_framebuffer+0x1e2/0x320
             [<ffffffffa01043e1>] drm_fb_helper_initial_config+0x371/0x540 [drm_kms_helper]
             [<ffffffffa01bcb05>] nouveau_fbcon_init+0x105/0x140 [nouveau]
             [<ffffffffa01ad0af>] nouveau_drm_load+0x43f/0x610 [nouveau]
             [<ffffffffa008a79e>] drm_get_pci_dev+0x17e/0x2a0 [drm]
             [<ffffffffa01ad4da>] nouveau_drm_probe+0x25a/0x2a0 [nouveau]
             [<ffffffff813b13db>] local_pci_probe+0x4b/0x80
             [<ffffffff813b1701>] pci_device_probe+0x111/0x120
             [<ffffffff814977eb>] driver_probe_device+0x8b/0x3a0
             [<ffffffff81497bab>] __driver_attach+0xab/0xb0
             [<ffffffff814956ad>] bus_for_each_dev+0x5d/0xa0
             [<ffffffff814971fe>] driver_attach+0x1e/0x20
             [<ffffffff81496cc1>] bus_add_driver+0x111/0x290
             [<ffffffff814982b7>] driver_register+0x77/0x170
             [<ffffffff813b0454>] __pci_register_driver+0x64/0x70
             [<ffffffffa008a9da>] drm_pci_init+0x11a/0x130 [drm]
             [<ffffffffa022a04d>] nouveau_drm_init+0x4d/0x1000 [nouveau]
             [<ffffffff810002ea>] do_one_initcall+0xea/0x1a0
             [<ffffffff810c54cb>] load_module+0x123b/0x1bf0
             [<ffffffff810c5f57>] SyS_init_module+0xd7/0x120
             [<ffffffff817677c2>] system_call_fastpath+0x16/0x1b
      
      -> #1 (console_lock){+.+.+.}:
             [<ffffffff810b6d62>] lock_acquire+0x92/0x1f0
             [<ffffffff810430a7>] console_lock+0x77/0x80
             [<ffffffff8146b2a1>] con_flush_chars+0x31/0x50
             [<ffffffff8145780c>] n_tty_write+0x1ec/0x4d0
             [<ffffffff814541b9>] tty_write+0x159/0x2e0
             [<ffffffff814543f5>] redirected_tty_write+0xb5/0xc0
             [<ffffffff811ab9d5>] vfs_write+0xc5/0x1f0
             [<ffffffff811abec5>] SyS_write+0x55/0xa0
             [<ffffffff817677c2>] system_call_fastpath+0x16/0x1b
      
      -> #0 (&tty->termios_rwsem){++++..}:
             [<ffffffff810b65c3>] __lock_acquire+0x1c43/0x1d30
             [<ffffffff810b6d62>] lock_acquire+0x92/0x1f0
             [<ffffffff8175b724>] down_write+0x44/0x70
             [<ffffffff81452656>] tty_do_resize+0x36/0xe0
             [<ffffffff8146c841>] vc_do_resize+0x3e1/0x4c0
             [<ffffffff8146c99f>] vc_resize+0x1f/0x30
             [<ffffffff813e4535>] fbcon_init+0x385/0x5a0
             [<ffffffff8146a4bc>] visual_init+0xbc/0x120
             [<ffffffff8146cd13>] do_bind_con_driver+0x163/0x320
             [<ffffffff8146cfa1>] do_take_over_console+0x61/0x70
             [<ffffffff813e2b93>] do_fbcon_takeover+0x63/0xc0
             [<ffffffff813e67a5>] fbcon_event_notify+0x715/0x820
             [<ffffffff81762f9d>] notifier_call_chain+0x5d/0x110
             [<ffffffff8107aadc>] __blocking_notifier_call_chain+0x6c/0xc0
             [<ffffffff8107ab46>] blocking_notifier_call_chain+0x16/0x20
             [<ffffffff813d7c0b>] fb_notifier_call_chain+0x1b/0x20
             [<ffffffff813d95b2>] register_framebuffer+0x1e2/0x320
             [<ffffffffa01043e1>] drm_fb_helper_initial_config+0x371/0x540 [drm_kms_helper]
             [<ffffffffa01bcb05>] nouveau_fbcon_init+0x105/0x140 [nouveau]
             [<ffffffffa01ad0af>] nouveau_drm_load+0x43f/0x610 [nouveau]
             [<ffffffffa008a79e>] drm_get_pci_dev+0x17e/0x2a0 [drm]
             [<ffffffffa01ad4da>] nouveau_drm_probe+0x25a/0x2a0 [nouveau]
             [<ffffffff813b13db>] local_pci_probe+0x4b/0x80
             [<ffffffff813b1701>] pci_device_probe+0x111/0x120
             [<ffffffff814977eb>] driver_probe_device+0x8b/0x3a0
             [<ffffffff81497bab>] __driver_attach+0xab/0xb0
             [<ffffffff814956ad>] bus_for_each_dev+0x5d/0xa0
             [<ffffffff814971fe>] driver_attach+0x1e/0x20
             [<ffffffff81496cc1>] bus_add_driver+0x111/0x290
             [<ffffffff814982b7>] driver_register+0x77/0x170
             [<ffffffff813b0454>] __pci_register_driver+0x64/0x70
             [<ffffffffa008a9da>] drm_pci_init+0x11a/0x130 [drm]
             [<ffffffffa022a04d>] nouveau_drm_init+0x4d/0x1000 [nouveau]
             [<ffffffff810002ea>] do_one_initcall+0xea/0x1a0
             [<ffffffff810c54cb>] load_module+0x123b/0x1bf0
             [<ffffffff810c5f57>] SyS_init_module+0xd7/0x120
             [<ffffffff817677c2>] system_call_fastpath+0x16/0x1b
      
      other info that might help us debug this:
      
      Chain exists of:
        &tty->termios_rwsem --> console_lock --> (fb_notifier_list).rwsem
      
       Possible unsafe locking scenario:
      
             CPU0                    CPU1
             ----                    ----
        lock((fb_notifier_list).rwsem);
                                     lock(console_lock);
                                     lock((fb_notifier_list).rwsem);
        lock(&tty->termios_rwsem);
      
       *** DEADLOCK ***
      
      7 locks held by modprobe/277:
       #0:  (&__lockdep_no_validate__){......}, at: [<ffffffff81497b5b>] __driver_attach+0x5b/0xb0
       #1:  (&__lockdep_no_validate__){......}, at: [<ffffffff81497b69>] __driver_attach+0x69/0xb0
       #2:  (drm_global_mutex){+.+.+.}, at: [<ffffffffa008a6dd>] drm_get_pci_dev+0xbd/0x2a0 [drm]
       #3:  (registration_lock){+.+.+.}, at: [<ffffffff813d93f5>] register_framebuffer+0x25/0x320
       #4:  (&fb_info->lock){+.+.+.}, at: [<ffffffff813d8116>] lock_fb_info+0x26/0x60
       #5:  (console_lock){+.+.+.}, at: [<ffffffff813d95a4>] register_framebuffer+0x1d4/0x320
       #6:  ((fb_notifier_list).rwsem){.+.+.+}, at: [<ffffffff8107aac6>] __blocking_notifier_call_chain+0x56/0xc0
      
      stack backtrace:
      CPU: 0 PID: 277 Comm: modprobe Not tainted 3.10.0-0+tip-xeon+lockdep #0+tip
      Hardware name: Dell Inc. Precision WorkStation T5400  /0RW203, BIOS A11 04/30/2012
       ffffffff8213e5e0 ffff8802aa2fb298 ffffffff81755f19 ffff8802aa2fb2e8
       ffffffff8174f506 ffff8802aa2fa000 ffff8802aa2fb378 ffff8802aa2ea8e8
       ffff8802aa2ea910 ffff8802aa2ea8e8 0000000000000006 0000000000000007
      Call Trace:
       [<ffffffff81755f19>] dump_stack+0x19/0x1b
       [<ffffffff8174f506>] print_circular_bug+0x1fb/0x20c
       [<ffffffff810b65c3>] __lock_acquire+0x1c43/0x1d30
       [<ffffffff810b775e>] ? mark_held_locks+0xae/0x120
       [<ffffffff810b78d5>] ? trace_hardirqs_on_caller+0x105/0x1d0
       [<ffffffff810b6d62>] lock_acquire+0x92/0x1f0
       [<ffffffff81452656>] ? tty_do_resize+0x36/0xe0
       [<ffffffff8175b724>] down_write+0x44/0x70
       [<ffffffff81452656>] ? tty_do_resize+0x36/0xe0
       [<ffffffff81452656>] tty_do_resize+0x36/0xe0
       [<ffffffff8146c841>] vc_do_resize+0x3e1/0x4c0
       [<ffffffff8146c99f>] vc_resize+0x1f/0x30
       [<ffffffff813e4535>] fbcon_init+0x385/0x5a0
       [<ffffffff8146a4bc>] visual_init+0xbc/0x120
       [<ffffffff8146cd13>] do_bind_con_driver+0x163/0x320
       [<ffffffff8146cfa1>] do_take_over_console+0x61/0x70
       [<ffffffff813e2b93>] do_fbcon_takeover+0x63/0xc0
       [<ffffffff813e67a5>] fbcon_event_notify+0x715/0x820
       [<ffffffff81762f9d>] notifier_call_chain+0x5d/0x110
       [<ffffffff8107aadc>] __blocking_notifier_call_chain+0x6c/0xc0
       [<ffffffff8107ab46>] blocking_notifier_call_chain+0x16/0x20
       [<ffffffff813d7c0b>] fb_notifier_call_chain+0x1b/0x20
       [<ffffffff813d95b2>] register_framebuffer+0x1e2/0x320
       [<ffffffffa01043e1>] drm_fb_helper_initial_config+0x371/0x540 [drm_kms_helper]
       [<ffffffff8173cbcb>] ? kmemleak_alloc+0x5b/0xc0
       [<ffffffff81198874>] ? kmem_cache_alloc_trace+0x104/0x290
       [<ffffffffa01035e1>] ? drm_fb_helper_single_add_all_connectors+0x81/0xf0 [drm_kms_helper]
       [<ffffffffa01bcb05>] nouveau_fbcon_init+0x105/0x140 [nouveau]
       [<ffffffffa01ad0af>] nouveau_drm_load+0x43f/0x610 [nouveau]
       [<ffffffffa008a79e>] drm_get_pci_dev+0x17e/0x2a0 [drm]
       [<ffffffffa01ad4da>] nouveau_drm_probe+0x25a/0x2a0 [nouveau]
       [<ffffffff8175f162>] ? _raw_spin_unlock_irqrestore+0x42/0x80
       [<ffffffff813b13db>] local_pci_probe+0x4b/0x80
       [<ffffffff813b1701>] pci_device_probe+0x111/0x120
       [<ffffffff814977eb>] driver_probe_device+0x8b/0x3a0
       [<ffffffff81497bab>] __driver_attach+0xab/0xb0
       [<ffffffff81497b00>] ? driver_probe_device+0x3a0/0x3a0
       [<ffffffff814956ad>] bus_for_each_dev+0x5d/0xa0
       [<ffffffff814971fe>] driver_attach+0x1e/0x20
       [<ffffffff81496cc1>] bus_add_driver+0x111/0x290
       [<ffffffffa022a000>] ? 0xffffffffa0229fff
       [<ffffffff814982b7>] driver_register+0x77/0x170
       [<ffffffffa022a000>] ? 0xffffffffa0229fff
       [<ffffffff813b0454>] __pci_register_driver+0x64/0x70
       [<ffffffffa008a9da>] drm_pci_init+0x11a/0x130 [drm]
       [<ffffffffa022a000>] ? 0xffffffffa0229fff
       [<ffffffffa022a000>] ? 0xffffffffa0229fff
       [<ffffffffa022a04d>] nouveau_drm_init+0x4d/0x1000 [nouveau]
       [<ffffffff810002ea>] do_one_initcall+0xea/0x1a0
       [<ffffffff810c54cb>] load_module+0x123b/0x1bf0
       [<ffffffff81399a50>] ? ddebug_proc_open+0xb0/0xb0
       [<ffffffff813855ae>] ? trace_hardirqs_on_thunk+0x3a/0x3f
       [<ffffffff810c5f57>] SyS_init_module+0xd7/0x120
       [<ffffffff817677c2>] system_call_fastpath+0x16/0x1b
      Signed-off-by: default avatarPeter Hurley <peter@hurleysoftware.com>
      Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      dee4a0be
    • Peter Hurley's avatar
      tty: Remove extra wakeup from pty write() path · 5ede5253
      Peter Hurley authored
      Acquiring the write_wait queue spin lock now accounts for the largest
      slice of cpu time on the tty write path. Two factors contribute to
      this situation; a overly-pessimistic line discipline write loop which
      _always_ sets up a wait loop even if i/o will immediately succeed, and
      on ptys, a wakeup storm from reads and writes.
      
      Writer wakeup does not need to be performed by the pty driver.
      Firstly, since the actual i/o is performed within the write, the
      line discipline write loop will continue while space remains in
      the flip buffers. Secondly, when space becomes avail in the
      line discipline receive buffer (and thus also in the flip buffers),
      the pty unthrottle re-wakes the writer (non-flow-controlled line
      disciplines unconditionally unthrottle the driver when data is
      received). Thus, existing in-kernel i/o is guaranteed to advance.
      Finally, writer wakeup occurs at the conclusion of the line discipline
      write (in tty_write_unlock()). This guarantees that any user-space write
      waiters are woken to continue additional i/o.
      Signed-off-by: default avatarPeter Hurley <peter@hurleysoftware.com>
      Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      5ede5253
    • Peter Hurley's avatar
      n_tty: Factor LNEXT processing from per-char i/o path · e60d27c4
      Peter Hurley authored
      LNEXT processing accounts for ~15% of total cpu time in end-to-end
      tty i/o; factor the lnext test/clear from the per-char i/o path.
      
      Instead, attempt to immediately handle the literal next char if not
      at the end of this received buffer; otherwise, handle the first char
      of the next received buffer as the literal next char, then continue
      with normal i/o.
      Signed-off-by: default avatarPeter Hurley <peter@hurleysoftware.com>
      Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      e60d27c4
    • Peter Hurley's avatar
      n_tty: Un-inline single-use functions · 4b293492
      Peter Hurley authored
      gcc will likely inline these single-use functions anyway; remove
      inline modifier.
      Signed-off-by: default avatarPeter Hurley <peter@hurleysoftware.com>
      Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      4b293492
    • Peter Hurley's avatar
      n_tty: Remove overflow tests from receive_buf() path · 19e2ad6a
      Peter Hurley authored
      Always pre-figure the space available in the read_buf and limit
      the inbound receive request to that amount.
      
      For compatibility reasons with the non-flow-controlled interface,
      n_tty_receive_buf() will continue filling read_buf until all data
      has been received or receive_room() returns 0.
      Signed-off-by: default avatarPeter Hurley <peter@hurleysoftware.com>
      Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      19e2ad6a
    • Peter Hurley's avatar
      n_tty: Factor PARMRK from normal per-char i/o · 7de971b0
      Peter Hurley authored
      Handle PARMRK processing on the slow per-char i/o path.
      Signed-off-by: default avatarPeter Hurley <peter@hurleysoftware.com>
      Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      7de971b0
    • Peter Hurley's avatar
      n_tty: Factor ISTRIP and IUCLC receive_buf into separate fn · 6baad008
      Peter Hurley authored
      Convert to modal receive_buf processing; factor char receive
      processing for unusual termios settings out of normal per-char
      i/o path.
      Signed-off-by: default avatarPeter Hurley <peter@hurleysoftware.com>
      Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      6baad008
    • Peter Hurley's avatar
      n_tty: Split n_tty_receive_char() · 4b1f79c2
      Peter Hurley authored
      Factor 'special' per-char processing into standalone fn,
      n_tty_receive_char_special(), which handles processing for chars
      marked in the char_map.
      Signed-off-by: default avatarPeter Hurley <peter@hurleysoftware.com>
      Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      4b1f79c2
    • Peter Hurley's avatar
      n_tty: Eliminate char tests from IXANY restart test · 855df3c0
      Peter Hurley authored
      Relocate the IXANY restart tty test to code paths where the
      the received char is not START_CHAR, STOP_CHAR, INTR_CHAR,
      QUIT_CHAR or SUSP_CHAR.
      
      Fixes the condition when ISIG if off and one of INTR_CHAR,
      QUIT_CHAR or SUSP_CHAR does not restart i/o.
      Signed-off-by: default avatarPeter Hurley <peter@hurleysoftware.com>
      Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      855df3c0
    • Peter Hurley's avatar
      n_tty: Factor standard per-char i/o into separate fn · 7d88d637
      Peter Hurley authored
      Simplify __receive_buf() into a dispatch function; perform per-char
      processing for all other modes not already handled.
      Signed-off-by: default avatarPeter Hurley <peter@hurleysoftware.com>
      Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      7d88d637
    • Peter Hurley's avatar
      n_tty: Fix build breakage on ppc64 · 86e35aea
      Peter Hurley authored
      Commit 20bafb3d
        'n_tty: Move buffers into n_tty_data'
      broke the ppc64 build.
      
      Include vmalloc.h for the required function declarations.
      Reported-by: default avatarStephen Rothwell <sfr@canb.auug.org.au>
      Signed-off-by: default avatarPeter Hurley <peter@hurleysoftware.com>
      Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      86e35aea
    • Peter Hurley's avatar
      n_tty: Factor tty->closing receive_buf() into separate fn · ad0cc7ba
      Peter Hurley authored
      Convert to modal receive_buf() processing; factor receive char
      processing when tty->closing into n_tty_receive_buf_closing().
      
      Note that EXTPROC when ISTRIP or IUCLC is set continues to be
      handled by n_tty_receive_char().
      Signed-off-by: default avatarPeter Hurley <peter@hurleysoftware.com>
      Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      ad0cc7ba
    • Peter Hurley's avatar
      n_tty: Special case EXTPROC receive_buf() as raw mode · a1dd30e9
      Peter Hurley authored
      When EXTPROC is set without ISTRIP or IUCLC, processing is
      identical to raw mode; handle this receiving mode as a special-case
      of raw mode.
      Signed-off-by: default avatarPeter Hurley <peter@hurleysoftware.com>
      Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      a1dd30e9
    • Peter Hurley's avatar
      n_tty: Factor raw mode receive_buf() into separate fn · 554117bd
      Peter Hurley authored
      Convert to modal receive_buf() processing; factor raw mode
      per-char i/o into n_tty_receive_buf_raw().
      Signed-off-by: default avatarPeter Hurley <peter@hurleysoftware.com>
      Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      554117bd
    • Peter Hurley's avatar
      n_tty: Factor flagged char handling into separate fn · d2f8d7ab
      Peter Hurley authored
      Prepare for modal receive_buf() handling; factor handling for
      TTY_BREAK, TTY_PARITY, TTY_FRAME and TTY_OVERRUN into
      n_tty_receive_char_flagged().
      Signed-off-by: default avatarPeter Hurley <peter@hurleysoftware.com>
      Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      d2f8d7ab
    • Peter Hurley's avatar
      n_tty: Factor signal char handling into separate fn · b0ac50be
      Peter Hurley authored
      Reduce the monolithic n_tty_receive_char() complexity; factor the
      handling of INTR_CHAR, QUIT_CHAR and SUSP_CHAR into
      n_tty_receive_signal_char().
      Signed-off-by: default avatarPeter Hurley <peter@hurleysoftware.com>
      Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      b0ac50be
    • Peter Hurley's avatar
      n_tty: Factor 'real raw' receive_buf into standalone fn · 4a23a4df
      Peter Hurley authored
      Convert to modal receive_buf() processing; factor real_raw
      receive_buf() into n_tty_receive_buf_real_raw().
      Signed-off-by: default avatarPeter Hurley <peter@hurleysoftware.com>
      Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      4a23a4df
    • Peter Hurley's avatar
    • Peter Hurley's avatar
    • Peter Hurley's avatar
      n_tty: Move buffers into n_tty_data · 20bafb3d
      Peter Hurley authored
      Reduce pointer reloading and improve locality-of-reference;
      allocate read_buf and echo_buf within struct n_tty_data.
      Signed-off-by: default avatarPeter Hurley <peter@hurleysoftware.com>
      Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      20bafb3d
    • Peter Hurley's avatar
      n_tty: Remove alias ptrs in __receive_buf() · 8cb06c98
      Peter Hurley authored
      The char and flag buffer local alias pointers, p and f, are
      unnecessary; remove them.
      Signed-off-by: default avatarPeter Hurley <peter@hurleysoftware.com>
      Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      8cb06c98
    • Peter Hurley's avatar
      n_tty: Fix EOF push handling · 40d5e090
      Peter Hurley authored
      In canonical mode, an EOF which is not the first character of the line
      causes read() to complete and return the number of characters read so
      far (commonly referred to as EOF push). However, if the previous read()
      returned because the user buffer was full _and_ the next character
      is an EOF not at the beginning of the line, read() must not return 0,
      thus mistakenly indicating the end-of-file condition.
      
      The TTY_PUSH flag is used to indicate an EOF was received which is not
      at the beginning of the line. Because the EOF push condition is
      evaluated by a thread other than the read(), multiple EOF pushes can
      cause a premature end-of-file to be indicated.
      
      Instead, discover the 'EOF push as first read character' condition
      from the read() thread itself, and restart the i/o loop if detected.
      Signed-off-by: default avatarPeter Hurley <peter@hurleysoftware.com>
      Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      40d5e090
    • Peter Hurley's avatar
      n_tty: Avoid false-sharing echo buffer indices · 9dfd16dd
      Peter Hurley authored
      Separate the head & commit indices from the tail index to avoid
      cache-line contention (so called 'false-sharing') between concurrent
      threads.
      Signed-off-by: default avatarPeter Hurley <peter@hurleysoftware.com>
      Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      9dfd16dd
    • Peter Hurley's avatar
      n_tty: Eliminate counter in __process_echoes · 29c7c5ca
      Peter Hurley authored
      Since neither echo_commit nor echo_tail can change for the duration
      of __process_echoes loop, substitute index comparison for the
      snapshot counter.
      Signed-off-by: default avatarPeter Hurley <peter@hurleysoftware.com>
      Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      29c7c5ca
    • Peter Hurley's avatar
      n_tty: Only flush echo output if actually output · bc5b1ec5
      Peter Hurley authored
      Don't have the driver flush received echoes if no echoes were
      actually output.
      Signed-off-by: default avatarPeter Hurley <peter@hurleysoftware.com>
      Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      bc5b1ec5
    • Peter Hurley's avatar
      n_tty: Process echoes in blocks · cbfd0340
      Peter Hurley authored
      Byte-by-byte echo output is painfully slow, requiring a lock/unlock
      cycle for every input byte.
      
      Instead, perform the echo output in blocks of 256 characters, and
      at least once per flip buffer receive. Enough space is reserved in
      the echo buffer to guarantee a full block can be saved without
      overrunning the echo output. Overrun is prevented by discarding
      the oldest echoes until enough space exists in the echo buffer
      to receive at least a full block of new echoes.
      Signed-off-by: default avatarPeter Hurley <peter@hurleysoftware.com>
      Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      cbfd0340
    • Peter Hurley's avatar
      n_tty: Eliminate echo_commit memory barrier · 019ebdf9
      Peter Hurley authored
      Use output_lock mutex as a memory barrier when storing echo_commit.
      Signed-off-by: default avatarPeter Hurley <peter@hurleysoftware.com>
      Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      019ebdf9
    • Peter Hurley's avatar
      n_tty: Remove echo_lock · 17bd7907
      Peter Hurley authored
      Adding data to echo_buf (via add_echo_byte()) is guaranteed to be
      single-threaded, since all callers are from the n_tty_receive_buf()
      path. Processing the echo_buf can be called from either the
      n_tty_receive_buf() path or the n_tty_write() path; however, these
      callers are already serialized by output_lock.
      
      Publish cumulative echo_head changes to echo_commit; process echo_buf
      from echo_tail to echo_commit; remove echo_lock.
      
      On echo_buf overrun, claim output_lock to serialize changes to
      echo_tail.
      Signed-off-by: default avatarPeter Hurley <peter@hurleysoftware.com>
      Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      17bd7907
    • Peter Hurley's avatar
      n_tty: Replace echo_cnt with computed value · 862eeffe
      Peter Hurley authored
      Prepare for lockless echo_buf handling; compute current byte count
      of echo_buf from head and tail indices.
      Signed-off-by: default avatarPeter Hurley <peter@hurleysoftware.com>
      Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      862eeffe
    • Peter Hurley's avatar
      n_tty: Use separate head and tail indices for echo_buf · addaebcc
      Peter Hurley authored
      Instead of using a single index to track the current echo_buf position,
      use a head index when adding to the buffer and a tail index when
      consuming from the buffer. Allow these head and tail indices to wrap
      at max representable value; perform modulo reduction via helper
      functions when accessing the buffer.
      Signed-off-by: default avatarPeter Hurley <peter@hurleysoftware.com>
      Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      addaebcc
    • Peter Hurley's avatar
      n_tty: Remove unused echo_overrun field · ae56f330
      Peter Hurley authored
      The echo_overrun field is only assigned and never tested; remove it.
      Signed-off-by: default avatarPeter Hurley <peter@hurleysoftware.com>
      Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      ae56f330
  2. 23 Jul, 2013 8 commits