From owner-freebsd-hackers Thu Oct 30 05:01:53 1997 Return-Path: Received: (from root@localhost) by hub.freebsd.org (8.8.7/8.8.7) id FAA07071 for hackers-outgoing; Thu, 30 Oct 1997 05:01:53 -0800 (PST) (envelope-from owner-freebsd-hackers) Received: from iq.org (proff@profane.iq.org [203.4.184.222]) by hub.freebsd.org (8.8.7/8.8.7) with SMTP id FAA07063 for ; Thu, 30 Oct 1997 05:01:48 -0800 (PST) (envelope-from proff@iq.org) Received: (qmail 731 invoked by uid 110); 30 Oct 1997 13:01:07 -0000 To: freebsd-hackers@freebsd.org Subject: Re: kernel spinlocks, splbio(), MUTEX etc References: <199710301141.WAA00594@word.smith.net.au> From: Julian Assange In-Reply-To: Mike Smith's message of Thu, 30 Oct 1997 22:11:24 +1030 X-Mailer: Gnus v5.4.52/XEmacs 20.2 Date: 31 Oct 1997 00:01:07 +1100 Message-ID: Lines: 106 Sender: owner-freebsd-hackers@freebsd.org X-Loop: FreeBSD.org Precedence: bulk Mike Smith writes: > > > > I have a possible access contention between two peices of code, > > one hanging off a timeout() interrupt and the other called via > > the VFS sub-system. I don't want to lock the object they are > > accessing by using splbio() as both bits of code use around > > 32k instructions. > > > > ideas? > > Can you defer one or both of the fragments? The only real alternatives > are to redesign your code to reduce the size of the critical region(s), > and that's not always easy... > > mike I ended up using a combination of splbio(), tsleep(), wakeup() and my own locking system. maruXORkeys() is the cpu pig that we don't want to block on. Below is the locking code. I'm a bit dubious of my usage of volatile here (I want it to apply to what the pointer points to rather than the pointer itself) I don't want references to maru->mkeyLock to end up optimized into a register on the first reference, because by the time we get to the second another thread may have hit the original in-memory instance. static void maruLockKeys(volatile munit *maru) { int s; re: s = splbio(); if (maru->m_keyLock == kl_timer) { splx(s); tsleep(maru, PRIBIO, "maru", 0); goto re; } maru->m_keyLockCount++; if (maru->m_keyLock != kl_strategy) /* maybe running concurrently */ { maru->m_keyLock = kl_strategy; splx(s); if (maru->m_keyState == ks_cipher) maruXORkeys(maru); } else splx(s); } static void maruUnlockKeys(volatile munit *maru) { int s; s = splbio(); if (--maru->m_keyLockCount == 0) maru->m_keyLock = kl_none; splx(s); } static void maruKeyTimer(void *m) { volatile munit *maru = m; /* right semantics for volatile ?*/ maruInstance *i; int s; IFOPT(MARU_FOLLOW) printf ("maruXORkey(%p)\n", m); if (!munits[maru->m_unit]) return; i = maru->m_instance; if (!i) return; s = splbio(); /* where is MUTEX() when you need it */ switch (maru->m_keyLock) { case kl_none: break; case kl_timer: case kl_strategy: splx(s); goto end; default: panic("maruKeyTimer() default: wtf are we doing here?"); } maru->m_keyLock = kl_timer; maru->m_keyLockCount++; splx(s); maruXORkeys(maru); s = splbio(); if (maru->m_keyLock == kl_strategy) { splx(s); wakeup(maru); } else splx(s); end: timeout(maruKeyTimer, maru, ((maru->m_xorfreq*hz/1000)>0)? (maru->m_xorfreq*hz)/1000: 1); } -- Prof. Julian Assange |"Don't worry about people stealing your ideas. If your | Ideas are any good, you'll have to ram them down proff@iq.org | people's throats." proff@gnu.ai.mit.edu | -- Howard Aiken