• L
    tty-ldisc: turn ldisc user count into a proper refcount · 65b77046
    Linus Torvalds 提交于
    By using the user count for the actual lifetime rules, we can get rid of
    the silly "wait_for_idle" logic, because any busy ldisc will
    automatically stay around until the last user releases it.  This avoids
    a host of odd issues, and simplifies the code.
    
    So now, when the last ldisc reference is dropped, we just release the
    ldisc operations struct reference, and free the ldisc.
    
    It looks obvious enough, and it does work for me, but the counting
    _could_ be off. It probably isn't (bad counting in the new version would
    generally imply that the old code did something really bad, like free an
    ldisc with a non-zero count), but it does need some testing, and
    preferably somebody looking at it.
    
    With this change, both 'tty_ldisc_put()' and 'tty_ldisc_deref()' are
    just aliases for the new ref-counting 'put_ldisc()'. Both of them
    decrement the ldisc user count and free it if it goes down to zero.
    They're identical functions, in other words.
    
    But the reason they still exist as sepate functions is that one of them
    was exported (tty_ldisc_deref) and had a stupid name (so I don't want to
    use it as the main name), and the other one was used in multiple places
    (and I didn't want to make the patch larger just to rename the users).
    
    In addition to the refcounting, I did do some minimal cleanup. For
    example, now "tty_ldisc_try()" actually returns the ldisc it got under
    the lock, rather than returning true/false and then the caller would
    look up the ldisc again (now without the protection of the lock).
    
    That said, there's tons of dubious use of 'tty->ldisc' without obviously
    proper locking or refcounting left. I expressly did _not_ want to try to
    fix it all, keeping the patch minimal. There may or may not be bugs in
    that kind of code, but they wouldn't be _new_ bugs.
    
    That said, even if the bugs aren't new, the timing and lifetime will
    change. For example, some silly code may depend on the 'tty->ldisc'
    pointer not changing because they hold a refcount on the 'ldisc'. And
    that's no longer true - if you hold a ref on the ldisc, the 'ldisc'
    itself is safe, but tty->ldisc may change.
    
    So the proper locking (remains) to hold tty->ldisc_mutex if you expect
    tty->ldisc to be stable. That's not really a _new_ rule, but it's an
    example of something that the old code might have unintentionally
    depended on and hidden bugs.
    
    Whatever. The patch _looks_ sensible to me. The only users of
    ldisc->users are:
     - get_ldisc() - atomically increment the count
    
     - put_ldisc() - atomically decrements the count and releases if zero
    
     - tty_ldisc_try_get() - creates the ldisc, and sets the count to 1.
       The ldisc should then either be released, or be attached to a tty.
    Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
    Tested-by: NOGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
    Tested-by: NSergey Senozhatsky <sergey.senozhatsky@mail.by>
    Acked-by: NAlan Cox <alan@linux.intel.com>
    Signed-off-by: NGreg Kroah-Hartman <gregkh@suse.de>
    65b77046
tty_ldisc.c 20.8 KB