public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Linus Torvalds <torvalds@linux-foundation.org>
To: Sergey Senozhatsky <sergey.senozhatsky@mail.by>
Cc: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>,
	Linux Kernel Mailing List <linux-kernel@vger.kernel.org>,
	Greg KH <greg@kroah.com>
Subject: Re: WARNING at: drivers/char/tty_ldisc.c
Date: Sun, 2 Aug 2009 10:16:44 -0700 (PDT)	[thread overview]
Message-ID: <alpine.LFD.2.01.0908020940530.3352@localhost.localdomain> (raw)
In-Reply-To: <20090802120120.GA3097@localdomain.by>



On Sun, 2 Aug 2009, Sergey Senozhatsky wrote:
>
> Looks like we have one more bug in tty code:
> 'shutdown -r now' in 'single' user mode gives following trace:
> 
> WARNING at: drivers/char/tty_ldisc.c:209 tty_ldisc_put+0x95/0xa0
> ---
> warn_slowpath_common+0x78/0xa0
> warn_slowpath_null+0x21/0x40
> tty_ldisc_put+0x95/0xa0
> tty_ldisc_hangup+0xfc/0x1f0
> do_tty_hangup+0x131/0x380
> disassociate_ctty+0x50/0x210
> do_exit+0x6b8/0x700
> do_group_exit+0x45/0xb0
> get_signal_to_deliver+0x226/0x410
> do_notify_resume+0xc1+0xa90
> work_notifysig+0x13/0x19
> 
> //There is no trace in syslog, so given one is 'copy-paste' from the paper.

We have that 'refcount' counter for the ldisc, but we don't actually use 
it for memory management like we should (ie "free the ldisc when count 
goes to zero"), we just decrement it and free the thing.

And it's quite possible that another CPU is doing some tty read thing or 
other that does

	tty_ldisc_try(..) // increments ld->refcount
	...
	tty_ldisc_deref(..) // decrements it.

at the same time. 

The ldisc refcounts are simply done wrong. They are more debugging aids 
(for the case where no races occur), than actual memory management 
refcounts.

Now, when you do refcounts wrong like that, the "fix" for it is to wait 
for the count to go to zero before releasing things (the problem with that 
fix is that it tends to be complicated and prone to deadlocks etc).

And the tty layer really does try to handle this with that 

	tty_ldisc_halt() - clear TTY_LDISC so that no new refs are taken
	tty_ldisc_wait_idle()  - wait for all old refs to go away

which it did just before the call to 'tty_ldisc_reinit()' (which is 
apparently inlined) that will then call 'tty_ldisc_put()', which is what 
complains.

So we've actually just waited for the count to go down to zero, and now 
it's not zero again. Which _should_ be impossible since the TTY_LDISC bit 
is clear, of course.

But there are things that enable TTY_LDISC, like a 'tty_set_ldisc()' done 
on another CPU. Which does try to protect things with 'tty->ldisc_mutex', 
but in the case of pty's in particular, there are _two_ tty's involved, 
and it does things like

	if (o_tty)
		tty_ldisc_enable(o_tty);

to re-enable the "other" tty, without holding the lock for that tty. 

And I don't think we can just take the lock either, because that's an ABBA 
deadlock when you do it trivially.

I dunno. It might not be the above, there might be something else going 
on, I'll have to think about/look at it a bit more. 

		Linus

  parent reply	other threads:[~2009-08-02 17:16 UTC|newest]

Thread overview: 39+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-08-02 12:01 WARNING at: drivers/char/tty_ldisc.c Sergey Senozhatsky
2009-08-02 16:05 ` Greg KH
2009-08-02 17:01   ` Sergey Senozhatsky
2009-08-02 17:07   ` Sergey Senozhatsky
2009-08-02 17:16 ` Linus Torvalds [this message]
2009-08-02 19:05   ` Sergey Senozhatsky
2009-08-02 20:20     ` Linus Torvalds
2009-08-02 21:17       ` OGAWA Hirofumi
2009-08-02 21:33         ` Linus Torvalds
2009-08-02 22:46           ` Sergey Senozhatsky
2009-08-02 22:48           ` Alan Cox
2009-08-03  0:40             ` Linus Torvalds
2009-08-03  1:44               ` Linus Torvalds
2009-08-03  9:37               ` Alan Cox
2009-08-03 16:26                 ` OGAWA Hirofumi
2009-08-03 16:59                   ` Alan Cox
2009-08-03 17:55               ` [PATCH 0/2] proper tty-ldisc refcounting (was Re: WARNING at: drivers/char/tty_ldisc.c) Linus Torvalds
2009-08-03 17:58                 ` [PATCH 1/2] tty-ldisc: make refcount be atomic_t 'users' count Linus Torvalds
2009-08-03 18:11                   ` [PATCH 2/2] tty-ldisc: turn ldisc user count into a proper refcount Linus Torvalds
2009-08-03 18:39                     ` Alan Cox
2009-08-03 20:00                     ` OGAWA Hirofumi
2009-08-03 18:18                 ` [PATCH 0/2] proper tty-ldisc refcounting (was Re: WARNING at: drivers/char/tty_ldisc.c) Greg KH
2009-08-03 18:53                   ` Linus Torvalds
2009-08-03 22:16                   ` Sergey Senozhatsky
2009-08-03 22:25                     ` Linus Torvalds
2009-08-03 22:58                       ` [PATCH 3/2] tty-ldisc: be more careful in 'put_ldisc' locking Linus Torvalds
2009-08-03 23:00                         ` [PATCH 4/2] tty-ldisc: make /proc/tty/ldiscs use ldisc_ops instead of ldiscs Linus Torvalds
2009-08-03 23:01                           ` [PATCH 5/2] tty-ldisc: get rid of tty_ldisc_try_get() helper function Linus Torvalds
2009-08-04  0:30                   ` proper tty-ldisc refcounting (was Re: WARNING at: drivers/char/tty_ldisc.c) Sergey Senozhatsky
2009-08-04  0:56                     ` Linus Torvalds
2009-08-04  3:53                       ` Greg KH
2009-08-04  4:08                         ` Greg KH
2009-08-04  6:19                           ` Linus Torvalds
2009-08-04  7:23                             ` Greg KH
2009-08-04  9:12                               ` Sergey Senozhatsky
2009-08-04 14:53                                 ` Greg KH
2009-08-04 15:40                               ` Linus Torvalds
2009-08-04 16:00                                 ` Greg KH
2009-08-02 22:15       ` WARNING at: drivers/char/tty_ldisc.c Sergey Senozhatsky

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=alpine.LFD.2.01.0908020940530.3352@localhost.localdomain \
    --to=torvalds@linux-foundation.org \
    --cc=greg@kroah.com \
    --cc=hirofumi@mail.parknet.co.jp \
    --cc=linux-kernel@vger.kernel.org \
    --cc=sergey.senozhatsky@mail.by \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox