Date: Sun, 24 Jul 2016 09:02:01 +1000 (EST) From: Bruce Evans <brde@optusnet.com.au> To: John Baldwin <jhb@freebsd.org> Cc: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: Re: svn commit: r303225 - head/sys/dev/fb Message-ID: <20160724032749.E841@besplex.bde.org> In-Reply-To: <201607231438.u6NEc9fG075708@repo.freebsd.org> References: <201607231438.u6NEc9fG075708@repo.freebsd.org>
next in thread | previous in thread | raw e-mail | index | archive | help
On Sat, 23 Jul 2016, John Baldwin wrote: > Log: > Use MTX_SYSINIT for the VESA lock. I wouldn't trust this either. > vesa_init_done isn't a reliable guard for the mutex init. If > vesa_configure() doesn't find valid VESA info it will not set > vesa_init_done, but the lock will remain initialized. Revert r303076 > and use MTX_SYSINIT to deterministically init the lock. I'm fixing consoles and needed very delicate modifications for the sio_inited guard that you added in sio. That basically works, but it needs complicated atomic locking. Early initialization is better, but MTX_SYSINIT()'s obfuscated order is wrong for console drivers: X enum sysinit_sub_id { X SI_SUB_DUMMY = 0x0000000, /* not executed; for linker*/ X SI_SUB_DONE = 0x0000001, /* processed*/ X SI_SUB_TUNABLES = 0x0700000, /* establish tunable values */ X SI_SUB_COPYRIGHT = 0x0800001, /* first use of console*/ X SI_SUB_VM = 0x1000000, /* virtual memory system init*/ X ... X SI_SUB_WITNESS = 0x1A80000, /* witness initialization */ X SI_SUB_MTX_POOL_DYNAMIC = 0x1AC0000, /* dynamic mutex pool */ X SI_SUB_LOCK = 0x1B00000, /* various locks */ MTX_SYSINIT() is in SI_SUB_LOCK, but console drivers want mutexes in (actually before) SI_SUB_COPYRIGHT, to avoid special cases. There are many other ordering bugs near here. The copyright never was the first use use of the console, at least on x86. kdb was. The careful ordering to get consoles initialized as early as practical so that kdb could be used is very broken now. In my i386 configuration, crashes or hangs for vm86 being used uninitialized just before kdb can be run to debug it. printf()s to consoles in getmemsize() are also broken. printf()s to the message buffer always were broken until after getmemsize(). amd64 doesn't use vm86 so it doesn't crash. The order in init386() is not as obfuscated as the above. syscons initializes its main lock (video_mtx) using mtx_init() before SI_SUB_COPYRIGHT, and that seems to work right. It guards this with 'cold' but that is bogus so I removed it. 'cold' is true until much later and is not needed early. Uninitialization is more broken for consoles than initialization, but is less of a problem since it is usually unreachable. It is only obviously reachable for dcons, and is obviously wrong there (cnremove() doesn't actually remove the console, but dcons tries it; no other driver even tries it). The SCHEDULER_STOPPED() hack caused me problems. My fixed console drivers know a little more about when it is safe to call mutex code than the mutex system does, except they don't want to know about this hack. They do a check like mtx_unowned() (but more fragile). mtx_unowned() also doesn't know about SCHEDULER_STOPPED(). mtx_unowned() works accidentally in more cases without INVARIANTS because the inlined mutex functions also don't know about SCHEDULER_STOPPED(). Usually they work normally. But when they would normally block, they call the public functions that don't block and do leave the mutex in an inconsistent state. Then without INVARIANTS, mtx_owned() in KASSERT() is annulled but direct mtx_owned() finds inconsistencies. Bruce
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20160724032749.E841>