Skip to content

Commit e93a9a8

Browse files
tiwaiairlied
authored andcommitted
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: Takashi Iwai <[email protected]> Cc: Alan Cox <[email protected]> Cc: Florian Tobias Schandinat <[email protected]> Cc: Jiri Kosina <[email protected]> Cc: stable <[email protected]> Tested-by: Sedat Dilek <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Dave Airlie <[email protected]>
1 parent 50e244c commit e93a9a8

File tree

5 files changed

+37
-17
lines changed

5 files changed

+37
-17
lines changed

drivers/tty/vt/vt.c

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3134,6 +3134,18 @@ static int con_is_graphics(const struct consw *csw, int first, int last)
31343134
* or 0 on success.
31353135
*/
31363136
int unbind_con_driver(const struct consw *csw, int first, int last, int deflt)
3137+
{
3138+
int retval;
3139+
3140+
console_lock();
3141+
retval = do_unbind_con_driver(csw, first, last, deflt);
3142+
console_unlock();
3143+
return retval;
3144+
}
3145+
EXPORT_SYMBOL(unbind_con_driver);
3146+
3147+
/* unlocked version of unbind_con_driver() */
3148+
int do_unbind_con_driver(const struct consw *csw, int first, int last, int deflt)
31373149
{
31383150
struct module *owner = csw->owner;
31393151
const struct consw *defcsw = NULL;
@@ -3143,7 +3155,7 @@ int unbind_con_driver(const struct consw *csw, int first, int last, int deflt)
31433155
if (!try_module_get(owner))
31443156
return -ENODEV;
31453157

3146-
console_lock();
3158+
WARN_CONSOLE_UNLOCKED();
31473159

31483160
/* check if driver is registered and if it is unbindable */
31493161
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)
31563168
}
31573169
}
31583170

3159-
if (retval) {
3160-
console_unlock();
3171+
if (retval)
31613172
goto err;
3162-
}
31633173

31643174
retval = -ENODEV;
31653175

@@ -3175,15 +3185,11 @@ int unbind_con_driver(const struct consw *csw, int first, int last, int deflt)
31753185
}
31763186
}
31773187

3178-
if (retval) {
3179-
console_unlock();
3188+
if (retval)
31803189
goto err;
3181-
}
31823190

3183-
if (!con_is_bound(csw)) {
3184-
console_unlock();
3191+
if (!con_is_bound(csw))
31853192
goto err;
3186-
}
31873193

31883194
first = max(first, con_driver->first);
31893195
last = min(last, con_driver->last);
@@ -3212,13 +3218,12 @@ int unbind_con_driver(const struct consw *csw, int first, int last, int deflt)
32123218

32133219
/* ignore return value, binding should not fail */
32143220
do_bind_con_driver(defcsw, first, last, deflt);
3215-
console_unlock();
32163221
err:
32173222
module_put(owner);
32183223
return retval;
32193224

32203225
}
3221-
EXPORT_SYMBOL(unbind_con_driver);
3226+
EXPORT_SYMBOL_GPL(do_unbind_con_driver);
32223227

32233228
static int vt_bind(struct con_driver *con)
32243229
{
@@ -3605,9 +3610,18 @@ EXPORT_SYMBOL(register_con_driver);
36053610
*/
36063611
int unregister_con_driver(const struct consw *csw)
36073612
{
3608-
int i, retval = -ENODEV;
3613+
int retval;
36093614

36103615
console_lock();
3616+
retval = do_unregister_con_driver(csw);
3617+
console_unlock();
3618+
return retval;
3619+
}
3620+
EXPORT_SYMBOL(unregister_con_driver);
3621+
3622+
int do_unregister_con_driver(const struct consw *csw)
3623+
{
3624+
int i, retval = -ENODEV;
36113625

36123626
/* cannot unregister a bound driver */
36133627
if (con_is_bound(csw))
@@ -3633,10 +3647,9 @@ int unregister_con_driver(const struct consw *csw)
36333647
}
36343648
}
36353649
err:
3636-
console_unlock();
36373650
return retval;
36383651
}
3639-
EXPORT_SYMBOL(unregister_con_driver);
3652+
EXPORT_SYMBOL_GPL(do_unregister_con_driver);
36403653

36413654
/*
36423655
* If we support more console drivers, this function is used

drivers/video/console/fbcon.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3004,7 +3004,7 @@ static int fbcon_unbind(void)
30043004
{
30053005
int ret;
30063006

3007-
ret = unbind_con_driver(&fb_con, first_fb_vc, last_fb_vc,
3007+
ret = do_unbind_con_driver(&fb_con, first_fb_vc, last_fb_vc,
30083008
fbcon_is_default);
30093009

30103010
if (!ret)
@@ -3077,7 +3077,7 @@ static int fbcon_fb_unregistered(struct fb_info *info)
30773077
primary_device = -1;
30783078

30793079
if (!num_registered_fb)
3080-
unregister_con_driver(&fb_con);
3080+
do_unregister_con_driver(&fb_con);
30813081

30823082
return 0;
30833083
}

drivers/video/fbmem.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1668,8 +1668,10 @@ static int do_unregister_framebuffer(struct fb_info *fb_info)
16681668

16691669
if (!lock_fb_info(fb_info))
16701670
return -ENODEV;
1671+
console_lock();
16711672
event.info = fb_info;
16721673
ret = fb_notifier_call_chain(FB_EVENT_FB_UNBIND, &event);
1674+
console_unlock();
16731675
unlock_fb_info(fb_info);
16741676

16751677
if (ret)
@@ -1684,7 +1686,9 @@ static int do_unregister_framebuffer(struct fb_info *fb_info)
16841686
num_registered_fb--;
16851687
fb_cleanup_device(fb_info);
16861688
event.info = fb_info;
1689+
console_lock();
16871690
fb_notifier_call_chain(FB_EVENT_FB_UNREGISTERED, &event);
1691+
console_unlock();
16881692

16891693
/* this may free fb info */
16901694
put_fb_info(fb_info);

include/linux/console.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ extern const struct consw prom_con; /* SPARC PROM console */
7777
int con_is_bound(const struct consw *csw);
7878
int register_con_driver(const struct consw *csw, int first, int last);
7979
int unregister_con_driver(const struct consw *csw);
80+
int do_unregister_con_driver(const struct consw *csw);
8081
int take_over_console(const struct consw *sw, int first, int last, int deflt);
8182
int do_take_over_console(const struct consw *sw, int first, int last, int deflt);
8283
void give_up_console(const struct consw *sw);

include/linux/vt_kern.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,8 @@ void vt_event_post(unsigned int event, unsigned int old, unsigned int new);
130130
int vt_waitactive(int n);
131131
void change_console(struct vc_data *new_vc);
132132
void reset_vc(struct vc_data *vc);
133+
extern int do_unbind_con_driver(const struct consw *csw, int first, int last,
134+
int deflt);
133135
extern int unbind_con_driver(const struct consw *csw, int first, int last,
134136
int deflt);
135137
int vty_init(const struct file_operations *console_fops);

0 commit comments

Comments
 (0)