1. 19 12月, 2013 1 次提交
    • C
      TTY/n_gsm: Removing the wrong tty_unlock/lock() in gsm_dlci_release() · be706572
      Chuansheng Liu 提交于
      Commit 4d9b1090(tty: Prevent deadlock in n_gsm driver)
      tried to close all the virtual ports synchronously before closing the
      phycial ports, so the tty_vhangup() is used.
      
      But the tty_unlock/lock() is wrong:
      tty_release
       tty_ldisc_release
        tty_lock_pair(tty, o_tty)  < == Here the tty is for physical port
        tty_ldisc_kill
          gsmld_close
            gsm_cleanup_mux
              gsm_dlci_release
                tty = tty_port_tty_get(&dlci->port)
                                  < == Here the tty(s) are for virtual port
      
      They are different ttys, so before tty_vhangup(virtual tty), do not need
      to call the tty_unlock(virtual tty) at all which causes unbalanced unlock
      warning.
      
      When enabling mutex debugging option, we will hit the below warning also:
      [   99.276903] =====================================
      [   99.282172] [ BUG: bad unlock balance detected! ]
      [   99.287442] 3.10.20-261976-gaec5ba0 #44 Tainted: G           O
      [   99.293972] -------------------------------------
      [   99.299240] mmgr/152 is trying to release lock (&tty->legacy_mutex) at:
      [   99.306693] [<c1b2dcad>] mutex_unlock+0xd/0x10
      [   99.311669] but there are no more locks to release!
      [   99.317131]
      [   99.317131] other info that might help us debug this:
      [   99.324440] 3 locks held by mmgr/152:
      [   99.328542]  #0:  (&tty->legacy_mutex/1){......}, at: [<c1b30ab0>] tty_lock_nested+0x40/0x90
      [   99.338116]  #1:  (&tty->ldisc_mutex){......}, at: [<c15dbd02>] tty_ldisc_kill+0x22/0xd0
      [   99.347284]  #2:  (&gsm->mutex){......}, at: [<c15e3d83>] gsm_cleanup_mux+0x73/0x170
      [   99.356060]
      [   99.356060] stack backtrace:
      [   99.360932] CPU: 0 PID: 152 Comm: mmgr Tainted: G           O 3.10.20-261976-gaec5ba0 #44
      [   99.370086]  ef4a4de0 ef4a4de0 ef4c1d98 c1b27b91 ef4c1db8 c1292655 c1dd10f5 c1b2dcad
      [   99.378921]  c1b2dcad ef4a4de0 ef4a528c ffffffff ef4c1dfc c12930dd 00000246 00000000
      [   99.387754]  00000000 00000000 c15e1926 00000000 00000001 ddfa7530 00000003 c1b2dcad
      [   99.396588] Call Trace:
      [   99.399326]  [<c1b27b91>] dump_stack+0x16/0x18
      [   99.404307]  [<c1292655>] print_unlock_imbalance_bug+0xe5/0xf0
      [   99.410840]  [<c1b2dcad>] ? mutex_unlock+0xd/0x10
      [   99.416110]  [<c1b2dcad>] ? mutex_unlock+0xd/0x10
      [   99.421382]  [<c12930dd>] lock_release_non_nested+0x1cd/0x210
      [   99.427818]  [<c15e1926>] ? gsm_destroy_network+0x36/0x130
      [   99.433964]  [<c1b2dcad>] ? mutex_unlock+0xd/0x10
      [   99.439235]  [<c12931a2>] lock_release+0x82/0x1c0
      [   99.444505]  [<c1b2dcad>] ? mutex_unlock+0xd/0x10
      [   99.449776]  [<c1b2dcad>] ? mutex_unlock+0xd/0x10
      [   99.455047]  [<c1b2dc2f>] __mutex_unlock_slowpath+0x5f/0xd0
      [   99.461288]  [<c1b2dcad>] mutex_unlock+0xd/0x10
      [   99.466365]  [<c1b30bb1>] tty_unlock+0x21/0x50
      [   99.471345]  [<c15e3dd1>] gsm_cleanup_mux+0xc1/0x170
      [   99.476906]  [<c15e44d2>] gsmld_close+0x52/0x90
      [   99.481983]  [<c15db905>] tty_ldisc_close.isra.1+0x35/0x50
      [   99.488127]  [<c15dbd0c>] tty_ldisc_kill+0x2c/0xd0
      [   99.493494]  [<c15dc7af>] tty_ldisc_release+0x2f/0x50
      [   99.499152]  [<c15d572c>] tty_release+0x37c/0x4b0
      [   99.504424]  [<c1b2dcad>] ? mutex_unlock+0xd/0x10
      [   99.509695]  [<c1b2dcad>] ? mutex_unlock+0xd/0x10
      [   99.514967]  [<c1372f6e>] ? eventpoll_release_file+0x7e/0x90
      [   99.521307]  [<c1335849>] __fput+0xd9/0x200
      [   99.525996]  [<c133597d>] ____fput+0xd/0x10
      [   99.530685]  [<c125c731>] task_work_run+0x81/0xb0
      [   99.535957]  [<c12019e9>] do_notify_resume+0x49/0x70
      [   99.541520]  [<c1b30dc4>] work_notifysig+0x29/0x31
      [   99.546897] ------------[ cut here ]------------
      
      So here we can call tty_vhangup() directly which is for virtual port.
      Reviewed-by: NChao Bi <chao.bi@intel.com>
      Signed-off-by: NLiu, Chuansheng <chuansheng.liu@intel.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      be706572
  2. 18 12月, 2013 1 次提交
    • R
      drivers: tty: Mark the functions as static in n_gsm.c · 54af5836
      Rashika Kheria 提交于
      Marks the functions gsm_cleanup_mux(), gsm_activate_mux(),
      gsm_free_mux(), gsm_alloc_mux() and gsm_change_mtu() as static in
      n_gsm.c because they are not used outside this file.
      
      Also, drop the EXPORT_SYMBOL_GPL for the above mentioned functions
      because nothing else in the kernel calls them.
      
      This eliminates the following warnings in n_gsm.c:
      drivers/tty/n_gsm.c:2022:6: warning: no previous prototype for ‘gsm_cleanup_mux’ [-Wmissing-prototypes]
      drivers/tty/n_gsm.c:2076:5: warning: no previous prototype for ‘gsm_activate_mux’ [-Wmissing-prototypes]
      drivers/tty/n_gsm.c:2120:6: warning: no previous prototype for ‘gsm_free_mux’ [-Wmissing-prototypes]
      drivers/tty/n_gsm.c:2156:17: warning: no previous prototype for ‘gsm_alloc_mux’ [-Wmissing-prototypes]
      drivers/tty/n_gsm.c:2714:5: warning: no previous prototype for ‘gsm_change_mtu’ [-Wmissing-prototypes]
      Signed-off-by: NRashika Kheria <rashika.kheria@gmail.com>
      Reviewed-by: NJosh Triplett <josh@joshtriplett.org>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      54af5836
  3. 09 12月, 2013 2 次提交
    • C
      n_gsm: race between ld close and gsmtty open · dfabf7ff
      Chao Bi 提交于
      ttyA has ld associated to n_gsm, when ttyA is closing, it triggers
      to release gsmttyB's ld data dlci[B], then race would happen if gsmttyB
      is opening in parallel.
      
      (Note: This patch set differs from previous set in that it uses mutex
      instead of spin lock to avoid race, so that it avoids sleeping in automic
      context)
      
      Here are race cases we found recently in test:
      
      CASE #1
      ====================================================================
      releasing dlci[B] race with gsmtty_install(gsmttyB), then panic
      in gsmtty_open(gsmttyB), as below:
      
       tty_release(ttyA)                  tty_open(gsmttyB)
           |                                   |
         -----                           gsmtty_install(gsmttyB)
           |                                   |
         -----                    gsm_dlci_alloc(gsmttyB) => alloc dlci[B]
       tty_ldisc_release(ttyA)               -----
           |                                   |
       gsm_dlci_release(dlci[B])             -----
           |                                   |
       gsm_dlci_free(dlci[B])                -----
           |                                   |
         -----                           gsmtty_open(gsmttyB)
      
       gsmtty_open()
       {
           struct gsm_dlci *dlci = tty->driver_data; => here it uses dlci[B]
           ...
       }
      
       In gsmtty_open(gsmttyA), it uses dlci[B] which was release, so hit a panic.
      =====================================================================
      
      CASE #2
      =====================================================================
      releasing dlci[0] race with gsmtty_install(gsmttyB), then panic
      in gsmtty_open(), as below:
      
       tty_release(ttyA)                  tty_open(gsmttyB)
           |                                   |
         -----                           gsmtty_install(gsmttyB)
           |                                   |
         -----                    gsm_dlci_alloc(gsmttyB) => alloc dlci[B]
           |                                   |
         -----                         gsmtty_open(gsmttyB) fail
           |                                   |
         -----                           tty_release(gsmttyB)
           |                                   |
         -----                           gsmtty_close(gsmttyB)
           |                                   |
         -----                        gsmtty_detach_dlci(dlci[B])
           |                                   |
         -----                             dlci_put(dlci[B])
           |                                   |
       tty_ldisc_release(ttyA)               -----
           |                                   |
       gsm_dlci_release(dlci[0])             -----
           |                                   |
       gsm_dlci_free(dlci[0])                -----
           |                                   |
         -----                             dlci_put(dlci[0])
      
       In gsmtty_detach_dlci(dlci[B]), it tries to use dlci[0] which was released,
       then hit panic.
      =====================================================================
      
      IMHO, n_gsm tty operations would refer released ldisc,  as long as
      gsm_dlci_release() has chance to release ldisc data when some gsmtty operations
      are ongoing..
      
      This patch is try to avoid it by:
      
      1) in n_gsm driver, use a global gsm mutex lock to avoid gsm_dlci_release() run in
      parallel with gsmtty_install();
      
      2) Increase dlci's ref count in gsmtty_install() instead of in gsmtty_open(), the
      purpose is to prevent gsm_dlci_release() releasing dlci after gsmtty_install()
      allocats dlci but before gsmtty_open increases dlci's ref count;
      
      3) Decrease dlci's ref count in gsmtty_remove(), a tty framework API, this is the
      opposite process of step 2).
      Signed-off-by: NChao Bi <chao.bi@intel.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      dfabf7ff
    • P
      tty: Always handle NULL flag ptr · 82f91fe0
      Peter Hurley 提交于
      Most line disciplines already handle the undocumented NULL flag
      ptr in their .receive_buf method; however, several don't.
      
      Document the NULL flag ptr, and correct handling in the
      N_MOUSE, N_GSM0710 and N_R394 line disciplines.
      Signed-off-by: NPeter Hurley <peter@hurleysoftware.com>
      Acked-by: NDmitry Torokhov <dmitry.torokhov@gmail.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      82f91fe0
  4. 26 11月, 2013 2 次提交
    • G
      Revert "n_gsm: race between ld close and gsmtty open" · c42b4e65
      Greg Kroah-Hartman 提交于
      This reverts commit c284ee2c.  Turns out
      the locking was incorrect.
      Reported-by: NFengguang Wu <fengguang.wu@intel.com>
      Cc: Chao Bi <chao.bi@intel.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      c42b4e65
    • C
      n_gsm: race between ld close and gsmtty open · c284ee2c
      Chao Bi 提交于
      ttyA has ld associated to n_gsm, when ttyA is closing, it triggers
      to release gsmttyB's ld data dlci[B], then race would happen if gsmttyB
      is opening in parallel.
      
      Here are race cases we found recently in test:
      
      CASE #1
      ====================================================================
      releasing dlci[B] race with gsmtty_install(gsmttyB), then panic
      in gsmtty_open(gsmttyB), as below:
      
       tty_release(ttyA)                  tty_open(gsmttyB)
           |                                   |
         -----                           gsmtty_install(gsmttyB)
           |                                   |
         -----                    gsm_dlci_alloc(gsmttyB) => alloc dlci[B]
       tty_ldisc_release(ttyA)               -----
           |                                   |
       gsm_dlci_release(dlci[B])             -----
           |                                   |
       gsm_dlci_free(dlci[B])                -----
           |                                   |
         -----                           gsmtty_open(gsmttyB)
      
       gsmtty_open()
       {
           struct gsm_dlci *dlci = tty->driver_data; => here it uses dlci[B]
           ...
       }
      
       In gsmtty_open(gsmttyA), it uses dlci[B] which was release, so hit a panic.
      =====================================================================
      
      CASE #2
      =====================================================================
      releasing dlci[0] race with gsmtty_install(gsmttyB), then panic
      in gsmtty_open(), as below:
      
       tty_release(ttyA)                  tty_open(gsmttyB)
           |                                   |
         -----                           gsmtty_install(gsmttyB)
           |                                   |
         -----                    gsm_dlci_alloc(gsmttyB) => alloc dlci[B]
           |                                   |
         -----                         gsmtty_open(gsmttyB) fail
           |                                   |
         -----                           tty_release(gsmttyB)
           |                                   |
         -----                           gsmtty_close(gsmttyB)
           |                                   |
         -----                        gsmtty_detach_dlci(dlci[B])
           |                                   |
         -----                             dlci_put(dlci[B])
           |                                   |
       tty_ldisc_release(ttyA)               -----
           |                                   |
       gsm_dlci_release(dlci[0])             -----
           |                                   |
       gsm_dlci_free(dlci[0])                -----
           |                                   |
         -----                             dlci_put(dlci[0])
      
       In gsmtty_detach_dlci(dlci[B]), it tries to use dlci[0] which was released,
       then hit panic.
      =====================================================================
      
      IMHO, n_gsm tty operations would refer released ldisc,  as long as
      gsm_dlci_release() has chance to release ldisc data when some gsmtty operations
      are not completed..
      
      This patch is try to avoid it by:
      
      1) in n_gsm driver, use a global gsm spin lock to avoid gsm_dlci_release() run in
      parallel with gsmtty_install();
      
      2) Increase dlci's ref count in gsmtty_install() instead of in gsmtty_open(), the
      purpose is to prevent gsm_dlci_release() releasing dlci after gsmtty_install()
      allocats dlci but before gsmtty_open increases dlci's ref count;
      
      3) Decrease dlci's ref count in gsmtty_remove(), which is a tty framework api, and
      this is the opposite process of step 2).
      Signed-off-by: NChao Bi <chao.bi@intel.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      c284ee2c
  5. 25 7月, 2013 1 次提交
    • A
      Drivers: tty: n_gsm.c: fixed 7 errors & 6 warnings that checkpatch complained · f3c909b4
      Aldo Iljazi 提交于
      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: NAldo Iljazi <neonsync1@gmail.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      f3c909b4
  6. 19 3月, 2013 2 次提交
    • J
      TTY: fix DTR not being dropped on hang up · 957dacae
      Johan Hovold 提交于
      Move HUPCL handling to port shutdown so that DTR is dropped also on hang
      up (tty_port_close is a noop for hung-up ports).
      
      Also do not try to drop DTR for uninitialised ports where it has never
      been raised (e.g. after a failed open).
      
      Note that this is also the current behaviour of serial-core.
      
      Nine drivers currently call tty_port_close_start directly (rather than
      through tty_port_close) and seven of them lower DTR as part of their
      close (if the port has been initialised). Fixup the remaining two
      drivers so that it continues to be lowered also on normal (non-HUP)
      close. [ Note that most of those other seven drivers did not expect DTR
      to have been dropped by tty_port_close_start in the first place. ]
      Signed-off-by: NJohan Hovold <jhovold@gmail.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      957dacae
    • J
      TTY: add tty_port_tty_hangup helper · aa27a094
      Jiri Slaby 提交于
      It allows for cleaning up on a considerable amount of places. They did
      port_get, hangup, kref_put. Now the only thing needed is to call
      tty_port_tty_hangup which does exactly that. And they can also decide
      whether to consider CLOCAL or completely ignore that.
      Signed-off-by: NJiri Slaby <jslaby@suse.cz>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      aa27a094
  7. 30 1月, 2013 1 次提交
    • D
      tty: Prevent deadlock in n_gsm driver · 4d9b1090
      Dirkjan Bussink 提交于
      This change fixes a deadlock when the multiplexer is closed while there
      are still client side ports open.
      
      When the multiplexer is closed and there are active tty's it tries to
      close them with tty_vhangup. This has a problem though, because
      tty_vhangup needs the tty_lock. This patch changes it to unlock the
      tty_lock before attempting the hangup and relocks afterwards. The
      additional call to tty_port_tty_set is needed because otherwise the
      port stays active because of the reference counter.
      
      This change also exposed another problem that other code paths don't
      expect that the multiplexer could have been closed. This patch also adds
      checks for these cases in the gsmtty_ class of function that could be
      called.
      
      The documentation explicitly states that "first close all virtual ports
      before closing the physical port" but we've found this to not always
      reality in our field situations. The GPRS / UTMS modem sometimes crashes
      and needs a power cycle in that case which means cleanly shutting down
      everything is not always possible. This change makes it much more robust
      for our situation where at least the system is recoverable with this patch
      and doesn't hang in a deadlock situation inside the kernel.
      
      The patch is against the long term support kernel (3.4.27) and should
      apply cleanly to more recent branches. Tested with a Telit GE864-QUADV2
      and Telit HE910 modem.
      Signed-off-by: NDirkjan Bussink <dirkjan.bussink@nedap.com>
      Cc: stable <stable@vger.kernel.org>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      4d9b1090
  8. 16 1月, 2013 5 次提交
  9. 16 11月, 2012 1 次提交
  10. 17 9月, 2012 1 次提交
  11. 17 8月, 2012 8 次提交
  12. 11 8月, 2012 1 次提交
  13. 17 7月, 2012 1 次提交
  14. 09 3月, 2012 1 次提交
  15. 09 11月, 2011 1 次提交
    • A
      n_gsm: Fix timings · a8d12007
      Alan Cox 提交于
      Alek Du reported that the code erroneously applies time to jiffies
      conversions twice to the t1 and t2 values. In normal use on a modem link
      this cases no visible problem but on a slower link it will break as with
      HZ=1000 as is typical we are running t1/t2 ten times too fast.
      
      Alek's original patch removed the conversion from the timer setting but we
      in fact have to be more careful as the contents of t1/t2 are visible via
      the device API and we thus need to correct the constants.
      Signed-off-by: NAlan Cox <alan@linux.intel.com>
      Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
      a8d12007
  16. 27 9月, 2011 3 次提交
  17. 27 8月, 2011 2 次提交
  18. 09 7月, 2011 1 次提交
  19. 02 7月, 2011 3 次提交
    • R
      tty: n_gsm: Added refcount usage to gsm_mux and gsm_dlci structs · 6ab8fba7
      Russ Gorby 提交于
      The gsm_mux is created/destroyed when ldisc is
      opened/closed but clients of the MUX channel devices (gsmttyN)
      may access this structure as long as the TTYs are open.
      For the open, the ldisc open is guaranteed to preceed the TTY open,
      but the close has no such guaranteed ordering. As a result,
      the gsm_mux can be freed in the ldisc close before being accessed
      by one of the TTY clients. This can happen if the ldisc is removed
      while there are open, active MUX channels.
      A similar situation exists for DLCI-0, it is basically a resource
      shared by MUX and DLCI  , and should not be freed while they can
      be accessed
      
      To avoid this, gsm_mux and dlcis now have a reference counter
      ldisc open takes a reference on the mux and all the dlcis
      gsmtty_open takes a reference on the mux, dlci0 and its specific
      dlci. Dropping the last reference initiates the actual free.
      Signed-off-by: NRuss Gorby <russ.gorby@intel.com>
      Acked-by: NAlan Cox <alan@linux.intel.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@suse.de>
      6ab8fba7
    • R
      tty: n_gsm: Add raw-ip support · bcd5abe2
      Russ Gorby 提交于
      This patch adds the ability to open a network data connection over a mux
      virtual tty channel. This is for modems that support data connections
      with raw IP frames instead of PPP. On high speed data connections this
      eliminates a significant amount of PPP overhead. To use this interface,
      the application must first tell the modem to open a network connection on
      a virtual tty. Once that has been accomplished, the app will issue an
      IOCTL on that virtual tty to create the network interface. The IOCTL will
      return the index of the interface created.
      
      The two IOCTL commands are:
      
          ioctl( fd, GSMIOC_ENABLE_NET );
      
          ioctl( fd, GSMIOC_DISABLE_NET );
      Signed-off-by: NRuss Gorby <russ.gorby@intel.com>
      Acked-by: NAlan Cox <alan@linux.intel.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@suse.de>
      bcd5abe2
    • R
      tty: n_gsm: expose gsmtty device nodes at ldisc open time · d50f6dca
      Russ Gorby 提交于
      The n_gsm driver being an ldisc, does not provide a convenient method
      e.g. udev to create the tty device nodes automatically when the ldisc
      is opened.
      
      The TTY device nodes are now created via calls to tty_register_device
      from the ldisc open.
      Signed-off-by: NRuss Gorby <russ.gorby@intel.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@suse.de>
      d50f6dca
  20. 17 6月, 2011 2 次提交