I had a play with the kenel framebuffer, and managed to lock up my machine:
In one thread:
[ 701.790000] c3 [] (mutex_lock+0xc/0x24) from [] (lock_fb_info+0x14/0x38) [ 701.790000] c3 [] (lock_fb_info+0x14/0x38) from [] (fbcon_blank+0x234/0x260) [ 701.790000] c3 [] (fbcon_blank+0x234/0x260) from [] (do_blank_screen+0x1d0/0x27c) [ 701.790000] c3 [] (do_blank_screen+0x1d0/0x27c) from [] (console_callback+0x8c/0x140) [ 701.790000] c3 [] (console_callback+0x8c/0x140) from [] (process_one_work+0x12c/0x3d0) [ 701.790000] c3 [] (process_one_work+0x12c/0x3d0) from [] (worker_thread+0x190/0x3dc) [ 701.790000] c3 [] (worker_thread+0x190/0x3dc) from [] (kthread+0x90/0x94) [ 701.790000] c3 [] (kthread+0x90/0x94) from [] (kernel_thread_exit+0x0/0x8) In another thread: [ 701.790000] c3 SurfaceFlinger D 02517c7c 0 258 1 0x00000001 [ 701.790000] c3 [] (__schedule+0x214/0x6f8) from [] (schedule_timeout+0x180/0x1d0) [ 701.790000] c3 [] (schedule_timeout+0x180/0x1d0) from [] (__down+0x78/0xac) [ 701.790000] c3 [] (__down+0x78/0xac) from [] (down+0x44/0x4c) [ 701.790000] c3 [] (down+0x44/0x4c) from [] (console_lock+0x2c/0x60) [ 701.790000] c3 [] (console_lock+0x2c/0x60) from [] (do_fb_ioctl+0x394/0x450) [ 701.790000] c3 [] (do_fb_ioctl+0x394/0x450) from [] (do_vfs_ioctl+0x84/0x4ec) [ 701.790000] c3 [] (do_vfs_ioctl+0x84/0x4ec) from [] (sys_ioctl+0x38/0x60)
So in the first thread, we get console_lock (in console_callback) and then lock_fb_info.
In the second thread we get lock_fb_info (in do_fb_ioctl) and then console_lock.
I came up with a pretty trivial patch for this:
Subject: [PATCH] Fix deadlock between fb_info and console. Do not lock fb_info when calling sending the FB_EVENT_CONBLANK In fbmem.c, the semantics are that we acquire the lock_fb_info first, and then console_lock. However when fbcon.c fbcon_generic_blank() is called, the console lock could already be held. Locking fb_info can thus cause a deadlock. fbmem.c sends the FB_EVENT_BLANK without locking lock_fb_info first, so this change introduces similar behaviour. --- drivers/video/console/fbcon.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c index 6b4fb5c..8546441 100644 --- a/drivers/video/console/fbcon.c +++ b/drivers/video/console/fbcon.c @@ -2333,13 +2333,9 @@ static void fbcon_generic_blank(struct vc_data *vc, struct fb_info *info, vc->vc_video_erase_char = oldc; } - - if (!lock_fb_info(info)) - return; event.info = info; event.data = ␣ fb_notifier_call_chain(FB_EVENT_CONBLANK, &event); - unlock_fb_info(info); } static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch) -- 1.8.1.2 I passed the patch onto the framebuffer developers, but they weren't very interested because this whole code should be going away at sometime.