Commit e93a9a86 authored by Takashi Iwai's avatar Takashi Iwai Committed by Dave Airlie

fb: Yet another band-aid for fixing lockdep mess

I've still got lockdep warnings even after Alan's patch, and it seems that
yet more band aids are required to paper over similar paths for
unbind_con_driver() and unregister_con_driver().  After this hack, lockdep
warnings are finally gone.
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
Cc: Alan Cox <alan@linux.intel.com>
Cc: Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
Cc: Jiri Kosina <jkosina@suse.cz>
Cc: stable <stable@vger.kernel.org>
Tested-by: default avatarSedat Dilek <sedat.dilek@gmail.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent 50e244cc
...@@ -3134,6 +3134,18 @@ static int con_is_graphics(const struct consw *csw, int first, int last) ...@@ -3134,6 +3134,18 @@ static int con_is_graphics(const struct consw *csw, int first, int last)
* or 0 on success. * or 0 on success.
*/ */
int unbind_con_driver(const struct consw *csw, int first, int last, int deflt) int unbind_con_driver(const struct consw *csw, int first, int last, int deflt)
{
int retval;
console_lock();
retval = do_unbind_con_driver(csw, first, last, deflt);
console_unlock();
return retval;
}
EXPORT_SYMBOL(unbind_con_driver);
/* unlocked version of unbind_con_driver() */
int do_unbind_con_driver(const struct consw *csw, int first, int last, int deflt)
{ {
struct module *owner = csw->owner; struct module *owner = csw->owner;
const struct consw *defcsw = NULL; const struct consw *defcsw = NULL;
...@@ -3143,7 +3155,7 @@ int unbind_con_driver(const struct consw *csw, int first, int last, int deflt) ...@@ -3143,7 +3155,7 @@ int unbind_con_driver(const struct consw *csw, int first, int last, int deflt)
if (!try_module_get(owner)) if (!try_module_get(owner))
return -ENODEV; return -ENODEV;
console_lock(); WARN_CONSOLE_UNLOCKED();
/* check if driver is registered and if it is unbindable */ /* check if driver is registered and if it is unbindable */
for (i = 0; i < MAX_NR_CON_DRIVER; i++) { for (i = 0; i < MAX_NR_CON_DRIVER; i++) {
...@@ -3156,10 +3168,8 @@ int unbind_con_driver(const struct consw *csw, int first, int last, int deflt) ...@@ -3156,10 +3168,8 @@ int unbind_con_driver(const struct consw *csw, int first, int last, int deflt)
} }
} }
if (retval) { if (retval)
console_unlock();
goto err; goto err;
}
retval = -ENODEV; retval = -ENODEV;
...@@ -3175,15 +3185,11 @@ int unbind_con_driver(const struct consw *csw, int first, int last, int deflt) ...@@ -3175,15 +3185,11 @@ int unbind_con_driver(const struct consw *csw, int first, int last, int deflt)
} }
} }
if (retval) { if (retval)
console_unlock();
goto err; goto err;
}
if (!con_is_bound(csw)) { if (!con_is_bound(csw))
console_unlock();
goto err; goto err;
}
first = max(first, con_driver->first); first = max(first, con_driver->first);
last = min(last, con_driver->last); last = min(last, con_driver->last);
...@@ -3212,13 +3218,12 @@ int unbind_con_driver(const struct consw *csw, int first, int last, int deflt) ...@@ -3212,13 +3218,12 @@ int unbind_con_driver(const struct consw *csw, int first, int last, int deflt)
/* ignore return value, binding should not fail */ /* ignore return value, binding should not fail */
do_bind_con_driver(defcsw, first, last, deflt); do_bind_con_driver(defcsw, first, last, deflt);
console_unlock();
err: err:
module_put(owner); module_put(owner);
return retval; return retval;
} }
EXPORT_SYMBOL(unbind_con_driver); EXPORT_SYMBOL_GPL(do_unbind_con_driver);
static int vt_bind(struct con_driver *con) static int vt_bind(struct con_driver *con)
{ {
...@@ -3605,9 +3610,18 @@ EXPORT_SYMBOL(register_con_driver); ...@@ -3605,9 +3610,18 @@ EXPORT_SYMBOL(register_con_driver);
*/ */
int unregister_con_driver(const struct consw *csw) int unregister_con_driver(const struct consw *csw)
{ {
int i, retval = -ENODEV; int retval;
console_lock(); console_lock();
retval = do_unregister_con_driver(csw);
console_unlock();
return retval;
}
EXPORT_SYMBOL(unregister_con_driver);
int do_unregister_con_driver(const struct consw *csw)
{
int i, retval = -ENODEV;
/* cannot unregister a bound driver */ /* cannot unregister a bound driver */
if (con_is_bound(csw)) if (con_is_bound(csw))
...@@ -3633,10 +3647,9 @@ int unregister_con_driver(const struct consw *csw) ...@@ -3633,10 +3647,9 @@ int unregister_con_driver(const struct consw *csw)
} }
} }
err: err:
console_unlock();
return retval; return retval;
} }
EXPORT_SYMBOL(unregister_con_driver); EXPORT_SYMBOL_GPL(do_unregister_con_driver);
/* /*
* If we support more console drivers, this function is used * If we support more console drivers, this function is used
......
...@@ -3004,7 +3004,7 @@ static int fbcon_unbind(void) ...@@ -3004,7 +3004,7 @@ static int fbcon_unbind(void)
{ {
int ret; int ret;
ret = unbind_con_driver(&fb_con, first_fb_vc, last_fb_vc, ret = do_unbind_con_driver(&fb_con, first_fb_vc, last_fb_vc,
fbcon_is_default); fbcon_is_default);
if (!ret) if (!ret)
...@@ -3077,7 +3077,7 @@ static int fbcon_fb_unregistered(struct fb_info *info) ...@@ -3077,7 +3077,7 @@ static int fbcon_fb_unregistered(struct fb_info *info)
primary_device = -1; primary_device = -1;
if (!num_registered_fb) if (!num_registered_fb)
unregister_con_driver(&fb_con); do_unregister_con_driver(&fb_con);
return 0; return 0;
} }
......
...@@ -1668,8 +1668,10 @@ static int do_unregister_framebuffer(struct fb_info *fb_info) ...@@ -1668,8 +1668,10 @@ static int do_unregister_framebuffer(struct fb_info *fb_info)
if (!lock_fb_info(fb_info)) if (!lock_fb_info(fb_info))
return -ENODEV; return -ENODEV;
console_lock();
event.info = fb_info; event.info = fb_info;
ret = fb_notifier_call_chain(FB_EVENT_FB_UNBIND, &event); ret = fb_notifier_call_chain(FB_EVENT_FB_UNBIND, &event);
console_unlock();
unlock_fb_info(fb_info); unlock_fb_info(fb_info);
if (ret) if (ret)
...@@ -1684,7 +1686,9 @@ static int do_unregister_framebuffer(struct fb_info *fb_info) ...@@ -1684,7 +1686,9 @@ static int do_unregister_framebuffer(struct fb_info *fb_info)
num_registered_fb--; num_registered_fb--;
fb_cleanup_device(fb_info); fb_cleanup_device(fb_info);
event.info = fb_info; event.info = fb_info;
console_lock();
fb_notifier_call_chain(FB_EVENT_FB_UNREGISTERED, &event); fb_notifier_call_chain(FB_EVENT_FB_UNREGISTERED, &event);
console_unlock();
/* this may free fb info */ /* this may free fb info */
put_fb_info(fb_info); put_fb_info(fb_info);
......
...@@ -77,6 +77,7 @@ extern const struct consw prom_con; /* SPARC PROM console */ ...@@ -77,6 +77,7 @@ extern const struct consw prom_con; /* SPARC PROM console */
int con_is_bound(const struct consw *csw); int con_is_bound(const struct consw *csw);
int register_con_driver(const struct consw *csw, int first, int last); int register_con_driver(const struct consw *csw, int first, int last);
int unregister_con_driver(const struct consw *csw); int unregister_con_driver(const struct consw *csw);
int do_unregister_con_driver(const struct consw *csw);
int take_over_console(const struct consw *sw, int first, int last, int deflt); int take_over_console(const struct consw *sw, int first, int last, int deflt);
int do_take_over_console(const struct consw *sw, int first, int last, int deflt); int do_take_over_console(const struct consw *sw, int first, int last, int deflt);
void give_up_console(const struct consw *sw); void give_up_console(const struct consw *sw);
......
...@@ -130,6 +130,8 @@ void vt_event_post(unsigned int event, unsigned int old, unsigned int new); ...@@ -130,6 +130,8 @@ void vt_event_post(unsigned int event, unsigned int old, unsigned int new);
int vt_waitactive(int n); int vt_waitactive(int n);
void change_console(struct vc_data *new_vc); void change_console(struct vc_data *new_vc);
void reset_vc(struct vc_data *vc); void reset_vc(struct vc_data *vc);
extern int do_unbind_con_driver(const struct consw *csw, int first, int last,
int deflt);
extern int unbind_con_driver(const struct consw *csw, int first, int last, extern int unbind_con_driver(const struct consw *csw, int first, int last,
int deflt); int deflt);
int vty_init(const struct file_operations *console_fops); int vty_init(const struct file_operations *console_fops);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment