From owner-cvs-all Thu Mar 8 11:27:40 2001 Delivered-To: cvs-all@freebsd.org Received: from VL-MS-MR001.sc1.videotron.ca (relais.videotron.ca [24.201.245.36]) by hub.freebsd.org (Postfix) with ESMTP id 2D9D237B718; Thu, 8 Mar 2001 11:27:33 -0800 (PST) (envelope-from bmilekic@technokratis.com) Received: from jehovah ([24.202.203.190]) by VL-MS-MR001.sc1.videotron.ca (Netscape Messaging Server 4.15) with SMTP id G9W8PQ05.JG2; Thu, 8 Mar 2001 14:27:26 -0500 Message-ID: <001601c0a806$34d972f0$becbca18@jehovah> From: "Bosko Milekic" To: , References: <200103081921.f28JLkU41476@freefall.freebsd.org> Subject: Re: cvs commit: src/sys/kern uipc_syscalls.c Date: Thu, 8 Mar 2001 14:30:17 -0500 MIME-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit X-Priority: 3 X-MSMail-Priority: Normal X-Mailer: Microsoft Outlook Express 5.00.2919.6700 X-MimeOLE: Produced By Microsoft MimeOLE V5.00.2919.6700 Sender: owner-cvs-all@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG This is pretty tough for me to explain, I'll just illustrate once and for all, for documentation purposes: ->thread A is sleeping [msleep() with mutex foo, so foo is dropped during the sleep] ->thread A gets a signal and since we're sleeping with PCATCH, we are removed from the sleep queue, and before we return from the msleep, though, we need to get foo back, but foo is owned/contested. ->thread B holds foo, it is in the wakeup code (it just freed an sf_buf). It detects that the sleep count is non-zero, so it calls wakeup_one() and decrements the sleep count. wakeup_one() turns out to not wakeup anyone (as thread A is already removed from the sleep queue and is blocking waiting for foo, which we own). ->thread B then decrements the sleep count. This is the problem. ->thread B unlocks foo ->thread A finally locks foo and returns from msleep. Since it got interrupted by a signal, error is non-zero and thread A also decrements the sleep count. This is a problem now since the sleep count got decremented twice. This can happen in any situation where we have a msleep + wakeup_one mechanism and where the msleep is interruptable or may timeout. The general rule of thumb should be to have the sleeping thread only do the incrementing/decrementing of the sleep count. That's all. *phew* -Bosko I wrote: > bmilekic 2001/03/08 11:21:46 PST > > Modified files: > sys/kern uipc_syscalls.c > Log: > Fix is a similar race condition as existed in the mbuf code. When we go > into an interruptable sleep and we increment a sleep count, we make sure > that we are the thread that will decrement the count when we wakeup. > Otherwise, what happens is that if we get interrupted (signal) and we > have to wake up, but before we get our mutex, some thread that wants > to wake us up detects that the count is non-zero and so enters wakeup_one(), > but there's nothing on the sleep queue and so we don't get woken up. The > thread will still decrement the sleep count, which is bad because we will > also decrement it again later (as we got interrupted) and are already off > the sleep queue. > > Revision Changes Path > 1.88 +8 -7 src/sys/kern/uipc_syscalls.c > To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe cvs-all" in the body of the message