From owner-freebsd-hackers@freebsd.org Mon Apr 10 14:44:36 2017 Return-Path: Delivered-To: freebsd-hackers@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 4D249D37745 for ; Mon, 10 Apr 2017 14:44:36 +0000 (UTC) (envelope-from julian@freebsd.org) Received: from vps1.elischer.org (vps1.elischer.org [204.109.63.16]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "vps1.elischer.org", Issuer "CA Cert Signing Authority" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 34579B6 for ; Mon, 10 Apr 2017 14:44:35 +0000 (UTC) (envelope-from julian@freebsd.org) Received: from Julian-MBP3.local (106-68-100-234.dyn.iinet.net.au [106.68.100.234]) (authenticated bits=0) by vps1.elischer.org (8.15.2/8.15.2) with ESMTPSA id v3AEiTSw050386 (version=TLSv1.2 cipher=DHE-RSA-AES128-SHA bits=128 verify=NO); Mon, 10 Apr 2017 07:44:32 -0700 (PDT) (envelope-from julian@freebsd.org) Subject: Re: Understanding the FreeBSD locking mechanism To: Yubin Ruan , Ed Schouten References: Cc: freebsd-hackers@freebsd.org From: Julian Elischer Message-ID: <56c36e41-e1cb-6e87-dc6e-922dd5abbccc@freebsd.org> Date: Mon, 10 Apr 2017 22:44:23 +0800 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:45.0) Gecko/20100101 Thunderbird/45.8.0 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: 7bit X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 10 Apr 2017 14:44:36 -0000 On 9/4/17 6:13 pm, Yubin Ruan wrote: > On 2017/4/6 17:31, Ed Schouten wrote: >> Hi Yubin, >> >> 2017-04-06 11:16 GMT+02:00 Yubin Ruan : >>> Does this function provides the ordinary "spinlock" functionality? >>> There >>> is no special "test-and-set" instruction, and neither any extra >>> locking >>> to protect internal data structure manipulation. Isn't this >>> subjected to >>> race condition? >> >> Locking a spinlock is done through macro mtx_lock_spin(), which >> expands to __mtx_lock_spin() in sys/sys/mutex.h. That macro first >> calls into the function you looked at, spinlock_enter(), to disable >> interrupts. It then calls into the _mtx_obtain_lock_fetch() to do the >> test-and-set operation you were looking for. > > Thanks for replying. I have read some of those codes. just in case it somehow slipped your attention or has not yet been brought up there is the following overview: https://www.freebsd.org/cgi/man.cgi?locking(9) > > Just a few more questions, if you don't mind: > > (1) why are spinlocks forced to disable interrupt in FreeBSD? > > From the book "The design and implementation of the FreeBSD Operating > System", the authors say "spinning can result in deadlock if a > thread interrupted the thread that held a mutex and then tried to > acquire the mutex"...(section 4.3, Mutex Synchronization, paragraph 4) > > I don't get the point why a spinlock(or *spin mutex* in the FreeBSD > world) has to disable interrupt. Being interrupted does not necessarily > mean a deadlock. Assume that thread A holding a lock T gets interrupted > by another thread B(context switch here) and thread B try to acquire > the lock T. After finding out that lock T has already been acquired, > thread B will just spin until it gets preempted, after which thread A > gets waken up and run and release the lock T. So, you see there is not > necessarily any deadlock even if thread A get interrupted. > > I can only remember two conditions where using spinlock without > disabling interrupts will cause deadlock: > > #######1, spinlock used in an interrupt handler > If a thread A holding a spinlock T get interrupted and the interrupt > handler responsible for this interrupt try to acquire T, then we have > deadlock, because A would never have a chance to run before the > interrupt handler return, and the interrupt handler, unfortunately, > will continue to spin ... so in this situation, one has to disable > interrupt before spinning. > > As far as I know, in Linux, they provide two kinds of spinlocks: > > spin_lock(..); /* spinlock that does not disable interrupts */ > spin_lock_irqsave(...); /* spinlock that disable local interrupt */ > > > #######2, priority inversion problem > If thread B with a higher priority get in and try to acquire the lock > that thread A currently holds, then thread B would spin, while at the > same time thread A has no chance to run because it has lower priority, > thus not being able to release the lock. > (I haven't investigate enough into the source code, so I don't know > how FreeBSD and Linux handle this priority inversion problem. Maybe > they use priority inheritance or random boosting?) > > thanks, > Yubin Ruan > _______________________________________________ > freebsd-hackers@freebsd.org mailing list > https://lists.freebsd.org/mailman/listinfo/freebsd-hackers > To unsubscribe, send any mail to > "freebsd-hackers-unsubscribe@freebsd.org" >