]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
fbcon: Document what I learned about fbcon locking
authorDaniel Vetter <daniel.vetter@ffwll.ch>
Tue, 28 May 2019 09:03:02 +0000 (11:03 +0200)
committerDaniel Vetter <daniel.vetter@ffwll.ch>
Thu, 13 Jun 2019 08:07:09 +0000 (10:07 +0200)
It's not pretty.

Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Reviewed-by: Sam Ravnborg <sam@ravnborg.org>
Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
Cc: Hans de Goede <hdegoede@redhat.com>
Cc: Yisheng Xie <ysxie@foxmail.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20190528090304.9388-32-daniel.vetter@ffwll.ch
drivers/video/fbdev/core/fbcon.c

index 31d6a4e54436d37bc229f6184b1cb422cad567b3..b8067e07f8a808d820826aecd63bcbade3410e90 100644 (file)
 #  define DPRINTK(fmt, args...)
 #endif
 
+/*
+ * FIXME: Locking
+ *
+ * - fbcon state itself is protected by the console_lock, and the code does a
+ *   pretty good job at making sure that lock is held everywhere it's needed.
+ *
+ * - access to the registered_fb array is entirely unprotected. This should use
+ *   proper object lifetime handling, i.e. get/put_fb_info. This also means
+ *   switching from indices to proper pointers for fb_info everywhere.
+ *
+ * - fbcon doesn't bother with fb_lock/unlock at all. This is buggy, since it
+ *   means concurrent access to the same fbdev from both fbcon and userspace
+ *   will blow up. To fix this all fbcon calls from fbmem.c need to be moved out
+ *   of fb_lock/unlock protected sections, since otherwise we'll recurse and
+ *   deadlock eventually. Aside: Due to these deadlock issues the fbdev code in
+ *   fbmem.c cannot use locking asserts, and there's lots of callers which get
+ *   the rules wrong, e.g. fbsysfs.c entirely missed fb_lock/unlock calls too.
+ */
+
 enum {
        FBCON_LOGO_CANSHOW      = -1,   /* the logo can be shown */
        FBCON_LOGO_DRAW         = -2,   /* draw the logo to a console */