From owner-cvs-all@FreeBSD.ORG Thu Jul 17 04:06:41 2003 Return-Path: Delivered-To: cvs-all@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 7F4FA37B401; Thu, 17 Jul 2003 04:06:41 -0700 (PDT) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id 28E5143F75; Thu, 17 Jul 2003 04:06:41 -0700 (PDT) (envelope-from mtm@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.12.6/8.12.6) with ESMTP id h6HB6e0U076863; Thu, 17 Jul 2003 04:06:40 -0700 (PDT) (envelope-from mtm@repoman.freebsd.org) Received: (from mtm@localhost) by repoman.freebsd.org (8.12.6/8.12.6/Submit) id h6HB6emd076862; Thu, 17 Jul 2003 04:06:40 -0700 (PDT) Message-Id: <200307171106.h6HB6emd076862@repoman.freebsd.org> From: Mike Makonnen Date: Thu, 17 Jul 2003 04:06:40 -0700 (PDT) To: src-committers@FreeBSD.org, cvs-src@FreeBSD.org, cvs-all@FreeBSD.org X-FreeBSD-CVS-Branch: HEAD Subject: cvs commit: src/sys/kern kern_umtx.c src/sys/sys proc.h X-BeenThere: cvs-all@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: CVS commit messages for the entire tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 17 Jul 2003 11:06:42 -0000 mtm 2003/07/17 04:06:40 PDT FreeBSD src repository Modified files: sys/kern kern_umtx.c sys/sys proc.h Log: Fix umtx locking, for libthr, in the kernel. 1. There was a race condition between a thread unlocking a umtx and the thread contesting it. If the unlocking thread won the race it may try to wakeup a thread that was not yet in msleep(). The contesting thread would then go to sleep to await a wakeup that would never come. It's not possible to close the race by using a lock because calls to casuptr() may have to fault a page in from swap. Instead, the race was closed by introducing a flag that the unlocking thread will set when waking up a thread. The contesting thread will check for this flag before going to sleep. For now the flag is kept in td_flags, but it may be better to use some other member or create a new one because of the possible performance/contention issues of having to own sched_lock. Thanks to jhb for pointing me in the right direction on this one. 2. Once a umtx was contested all future locks and unlocks were happening in the kernel, regardless of whether it was contested or not. To prevent this from happening, when a thread locks a umtx it checks the queue for that umtx and unsets the contested bit if there are no other threads waiting on it. Again, this is slightly more complicated than it needs to be because we can't hold a lock across casuptr(). So, the thread has to check the queue again after unseting the bit, and reset the contested bit if it finds that another thread has put itself on the queue in the mean time. 3. Remove the if... block for unlocking an uncontested umtx, and replace it with a KASSERT. The _only_ time a thread should be unlocking a umtx in the kernel is if it is contested. Revision Changes Path 1.8 +47 -24 src/sys/kern/kern_umtx.c 1.341 +1 -0 src/sys/sys/proc.h