aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty
diff options
context:
space:
mode:
authorAlan Cox <alan@linux.intel.com>2013-01-24 19:28:15 -0500
committerDave Airlie <airlied@redhat.com>2013-02-07 21:02:40 -0500
commit50e244cc793d511b86adea24972f3a7264cae114 (patch)
treede59e5f228a256ad09521524639e1b5b6e49b8cc /drivers/tty
parent84b603abd23300df8ee5fb1c23c83634c2aaedea (diff)
fb: rework locking to fix lock ordering on takeover
Adjust the console layer to allow a take over call where the caller already holds the locks. Make the fb layer lock in order. This is partly a band aid, the fb layer is terminally confused about the locking rules it uses for its notifiers it seems. [akpm@linux-foundation.org: remove stray non-ascii char, tidy comment] [akpm@linux-foundation.org: export do_take_over_console()] [airlied: cleanup another non-ascii char] Signed-off-by: Alan Cox <alan@linux.intel.com> Cc: Florian Tobias Schandinat <FlorianSchandinat@gmx.de> Cc: Stephen Rothwell <sfr@canb.auug.org.au> Cc: Jiri Kosina <jkosina@suse.cz> Cc: stable <stable@vger.kernel.org> Tested-by: Sedat Dilek <sedat.dilek@gmail.com> Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/tty')
-rw-r--r--drivers/tty/vt/vt.c93
1 files changed, 70 insertions, 23 deletions
diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index 8fd89687d068..c076af0b300b 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -2987,7 +2987,7 @@ int __init vty_init(const struct file_operations *console_fops)
2987 2987
2988static struct class *vtconsole_class; 2988static struct class *vtconsole_class;
2989 2989
2990static int bind_con_driver(const struct consw *csw, int first, int last, 2990static int do_bind_con_driver(const struct consw *csw, int first, int last,
2991 int deflt) 2991 int deflt)
2992{ 2992{
2993 struct module *owner = csw->owner; 2993 struct module *owner = csw->owner;
@@ -2998,7 +2998,7 @@ static int bind_con_driver(const struct consw *csw, int first, int last,
2998 if (!try_module_get(owner)) 2998 if (!try_module_get(owner))
2999 return -ENODEV; 2999 return -ENODEV;
3000 3000
3001 console_lock(); 3001 WARN_CONSOLE_UNLOCKED();
3002 3002
3003 /* check if driver is registered */ 3003 /* check if driver is registered */
3004 for (i = 0; i < MAX_NR_CON_DRIVER; i++) { 3004 for (i = 0; i < MAX_NR_CON_DRIVER; i++) {
@@ -3083,11 +3083,22 @@ static int bind_con_driver(const struct consw *csw, int first, int last,
3083 3083
3084 retval = 0; 3084 retval = 0;
3085err: 3085err:
3086 console_unlock();
3087 module_put(owner); 3086 module_put(owner);
3088 return retval; 3087 return retval;
3089}; 3088};
3090 3089
3090
3091static int bind_con_driver(const struct consw *csw, int first, int last,
3092 int deflt)
3093{
3094 int ret;
3095
3096 console_lock();
3097 ret = do_bind_con_driver(csw, first, last, deflt);
3098 console_unlock();
3099 return ret;
3100}
3101
3091#ifdef CONFIG_VT_HW_CONSOLE_BINDING 3102#ifdef CONFIG_VT_HW_CONSOLE_BINDING
3092static int con_is_graphics(const struct consw *csw, int first, int last) 3103static int con_is_graphics(const struct consw *csw, int first, int last)
3093{ 3104{
@@ -3199,9 +3210,9 @@ int unbind_con_driver(const struct consw *csw, int first, int last, int deflt)
3199 if (!con_is_bound(csw)) 3210 if (!con_is_bound(csw))
3200 con_driver->flag &= ~CON_DRIVER_FLAG_INIT; 3211 con_driver->flag &= ~CON_DRIVER_FLAG_INIT;
3201 3212
3202 console_unlock();
3203 /* ignore return value, binding should not fail */ 3213 /* ignore return value, binding should not fail */
3204 bind_con_driver(defcsw, first, last, deflt); 3214 do_bind_con_driver(defcsw, first, last, deflt);
3215 console_unlock();
3205err: 3216err:
3206 module_put(owner); 3217 module_put(owner);
3207 return retval; 3218 return retval;
@@ -3492,28 +3503,18 @@ int con_debug_leave(void)
3492} 3503}
3493EXPORT_SYMBOL_GPL(con_debug_leave); 3504EXPORT_SYMBOL_GPL(con_debug_leave);
3494 3505
3495/** 3506static int do_register_con_driver(const struct consw *csw, int first, int last)
3496 * register_con_driver - register console driver to console layer
3497 * @csw: console driver
3498 * @first: the first console to take over, minimum value is 0
3499 * @last: the last console to take over, maximum value is MAX_NR_CONSOLES -1
3500 *
3501 * DESCRIPTION: This function registers a console driver which can later
3502 * bind to a range of consoles specified by @first and @last. It will
3503 * also initialize the console driver by calling con_startup().
3504 */
3505int register_con_driver(const struct consw *csw, int first, int last)
3506{ 3507{
3507 struct module *owner = csw->owner; 3508 struct module *owner = csw->owner;
3508 struct con_driver *con_driver; 3509 struct con_driver *con_driver;
3509 const char *desc; 3510 const char *desc;
3510 int i, retval = 0; 3511 int i, retval = 0;
3511 3512
3513 WARN_CONSOLE_UNLOCKED();
3514
3512 if (!try_module_get(owner)) 3515 if (!try_module_get(owner))
3513 return -ENODEV; 3516 return -ENODEV;
3514 3517
3515 console_lock();
3516
3517 for (i = 0; i < MAX_NR_CON_DRIVER; i++) { 3518 for (i = 0; i < MAX_NR_CON_DRIVER; i++) {
3518 con_driver = &registered_con_driver[i]; 3519 con_driver = &registered_con_driver[i];
3519 3520
@@ -3566,10 +3567,29 @@ int register_con_driver(const struct consw *csw, int first, int last)
3566 } 3567 }
3567 3568
3568err: 3569err:
3569 console_unlock();
3570 module_put(owner); 3570 module_put(owner);
3571 return retval; 3571 return retval;
3572} 3572}
3573
3574/**
3575 * register_con_driver - register console driver to console layer
3576 * @csw: console driver
3577 * @first: the first console to take over, minimum value is 0
3578 * @last: the last console to take over, maximum value is MAX_NR_CONSOLES -1
3579 *
3580 * DESCRIPTION: This function registers a console driver which can later
3581 * bind to a range of consoles specified by @first and @last. It will
3582 * also initialize the console driver by calling con_startup().
3583 */
3584int register_con_driver(const struct consw *csw, int first, int last)
3585{
3586 int retval;
3587
3588 console_lock();
3589 retval = do_register_con_driver(csw, first, last);
3590 console_unlock();
3591 return retval;
3592}
3573EXPORT_SYMBOL(register_con_driver); 3593EXPORT_SYMBOL(register_con_driver);
3574 3594
3575/** 3595/**
@@ -3623,17 +3643,44 @@ EXPORT_SYMBOL(unregister_con_driver);
3623 * when a driver wants to take over some existing consoles 3643 * when a driver wants to take over some existing consoles
3624 * and become default driver for newly opened ones. 3644 * and become default driver for newly opened ones.
3625 * 3645 *
3626 * take_over_console is basically a register followed by unbind 3646 * take_over_console is basically a register followed by unbind
3647 */
3648int do_take_over_console(const struct consw *csw, int first, int last, int deflt)
3649{
3650 int err;
3651
3652 err = do_register_con_driver(csw, first, last);
3653 /*
3654 * If we get an busy error we still want to bind the console driver
3655 * and return success, as we may have unbound the console driver
3656 * but not unregistered it.
3657 */
3658 if (err == -EBUSY)
3659 err = 0;
3660 if (!err)
3661 do_bind_con_driver(csw, first, last, deflt);
3662
3663 return err;
3664}
3665EXPORT_SYMBOL_GPL(do_take_over_console);
3666
3667/*
3668 * If we support more console drivers, this function is used
3669 * when a driver wants to take over some existing consoles
3670 * and become default driver for newly opened ones.
3671 *
3672 * take_over_console is basically a register followed by unbind
3627 */ 3673 */
3628int take_over_console(const struct consw *csw, int first, int last, int deflt) 3674int take_over_console(const struct consw *csw, int first, int last, int deflt)
3629{ 3675{
3630 int err; 3676 int err;
3631 3677
3632 err = register_con_driver(csw, first, last); 3678 err = register_con_driver(csw, first, last);
3633 /* if we get an busy error we still want to bind the console driver 3679 /*
3680 * If we get an busy error we still want to bind the console driver
3634 * and return success, as we may have unbound the console driver 3681 * and return success, as we may have unbound the console driver
3635  * but not unregistered it. 3682 * but not unregistered it.
3636 */ 3683 */
3637 if (err == -EBUSY) 3684 if (err == -EBUSY)
3638 err = 0; 3685 err = 0;
3639 if (!err) 3686 if (!err)