From owner-freebsd-arch@FreeBSD.ORG Sat Aug 21 21:45:33 2010 Return-Path: Delivered-To: freebsd-arch@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 3B19F10656A4 for ; Sat, 21 Aug 2010 21:45:33 +0000 (UTC) (envelope-from ups@freebsd.org) Received: from p3plsmtpa01-05.prod.phx3.secureserver.net (p3plsmtpa01-05.prod.phx3.secureserver.net [72.167.82.85]) by mx1.freebsd.org (Postfix) with SMTP id AA1798FC15 for ; Sat, 21 Aug 2010 21:45:31 +0000 (UTC) Received: (qmail 12275 invoked from network); 21 Aug 2010 21:18:51 -0000 Received: from unknown (75.139.142.171) by p3plsmtpa01-05.prod.phx3.secureserver.net (72.167.82.85) with ESMTP; 21 Aug 2010 21:18:51 -0000 Message-ID: <4C7042BA.8000402@freebsd.org> Date: Sat, 21 Aug 2010 17:18:50 -0400 From: Stephan Uphoff User-Agent: Thunderbird 2.0.0.24 (Macintosh/20100228) MIME-Version: 1.0 To: Max Laier References: <201008160515.21412.max@love2party.net> In-Reply-To: <201008160515.21412.max@love2party.net> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Cc: freebsd-arch@freebsd.org Subject: Re: rmlock(9) two additions X-BeenThere: freebsd-arch@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Discussion related to FreeBSD architecture List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 21 Aug 2010 21:45:33 -0000 Max Laier wrote: > Hi, > > I'd like to run two additions to rmlock(9) by you: > > 1) See the attached patch. It adds rm_try_rlock() which avoids taking the > mutex if the lock is currently in a write episode. The only overhead to the > hot path is an additional argument and a return value for _rm_rlock*. If you > are worried about that, it can obviously be done in a separate code path, but > I reckon it not worth the code crunch. Finally, there is one additional > branch to check the "trylock" argument, but that's well past the hot path. > The rm_try_rlock() will never succeed when the lock was last locked as writer. Maybe add: void _rm_wunlock(struct rmlock *rm) { + rm->rm_noreadtoken = 0; mtx_unlock(&rm->rm_lock); } But then _rm_wlock(struct rmlock *rm) always needs to use IPIs - even when the lock was used last as a write lock. Alternatively something like: if (trylock) { if(mtx_trylock( &rm->rm_lock) == 0) return (0); } else { mtx_lock(&rm->rm_lock); } would work - but has a race. Two readers colliding just after a writer (with the second not succeeding in trylocking the mutex) leads to not granting the read lock (also it would be possible to do so). Let me think about it a bit. > 2) No code for this yet - testing the waters first. I'd like to add the > ability to replace the mutex for writer synchronization with a general lock - > especially to be able to use a sx(9) lock here. > > The reason for #2 is the following use case in a debugging facility: > > "reader": > if (rm_try_rlock()) { > grab_per_cpu_buffer(); > fill_per_cpu_buffer(); > rm_runlock(); > } > > "writer" - better exclusive access thread: > rm_wlock(); > collect_buffers_and_copy_out_to_userspace(); > rm_wunlock(); > > This is much cleaner and possibly cheaper than the various hand rolled > versions I've come across, that try to get the same synchronization with > atomic operations. If we could sleep with the wlock held, we can also avoid > copying the buffer contents, or swapping buffers. > > Is there any concern about either of this? Any objection? Input? > > Will take a look at your second patch soonish. Just ask per IPI for a copy of per cpu buffers (but not a copy to user space) - and delay the copy when an update is in progress? Stephan > Thanks, > Max Laier >