From owner-p4-projects@FreeBSD.ORG Mon Dec 4 18:47:54 2006 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id E925616A4D8; Mon, 4 Dec 2006 18:47:53 +0000 (UTC) X-Original-To: perforce@freebsd.org Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id AF0D016A49E for ; Mon, 4 Dec 2006 18:47:53 +0000 (UTC) (envelope-from millert@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [69.147.83.41]) by mx1.FreeBSD.org (Postfix) with ESMTP id 2930643CA5 for ; Mon, 4 Dec 2006 18:47:19 +0000 (GMT) (envelope-from millert@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.6/8.13.6) with ESMTP id kB4Ilrrf092843 for ; Mon, 4 Dec 2006 18:47:53 GMT (envelope-from millert@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.6/8.13.4/Submit) id kB4Ilq6t092840 for perforce@freebsd.org; Mon, 4 Dec 2006 18:47:52 GMT (envelope-from millert@freebsd.org) Date: Mon, 4 Dec 2006 18:47:52 GMT Message-Id: <200612041847.kB4Ilq6t092840@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to millert@freebsd.org using -f From: Todd Miller To: Perforce Change Reviews Cc: Subject: PERFORCE change 111064 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 04 Dec 2006 18:47:54 -0000 http://perforce.freebsd.org/chv.cgi?CH=111064 Change 111064 by millert@millert_g5tower on 2006/12/04 18:47:08 Use spin locks in the avc until we have something RCU-like that does not sleep. Should fix remaining deadlock on dual CPU systems Affected files ... .. //depot/projects/trustedbsd/sedarwin8/policies/sedarwin/sedarwin/avc/avc.c#14 edit Differences ... ==== //depot/projects/trustedbsd/sedarwin8/policies/sedarwin/sedarwin/avc/avc.c#14 (text+ko) ==== @@ -109,7 +109,7 @@ struct avc_cache { LIST_HEAD(, avc_node) slots[AVC_CACHE_SLOTS]; - lck_rw_t *slots_lock[AVC_CACHE_SLOTS]; + lck_spin_t *slots_lock[AVC_CACHE_SLOTS]; atomic_t lru_hint; /* LRU hint for reclaim scan */ atomic_t active_nodes; u32 latest_notif; /* latest revocation notification */ @@ -139,14 +139,12 @@ static lck_grp_t *avc_lck_grp; -#define AVC_RDLOCK(n) lck_rw_lock_shared(avc_cache.slots_lock[n]) -#define AVC_WRLOCK(n) lck_rw_lock_exclusive(avc_cache.slots_lock[n]) -#define AVC_RDUNLOCK(n) lck_rw_unlock_shared(avc_cache.slots_lock[n]) -#define AVC_WRUNLOCK(n) lck_rw_unlock_exclusive(avc_cache.slots_lock[n]) +#define AVC_LOCK(n) lck_spin_lock(avc_cache.slots_lock[n]) +#define AVC_UNLOCK(n) lck_spin_unlock(avc_cache.slots_lock[n]) -static lck_mtx_t *notif_lock; -#define NOTIF_LOCK lck_mtx_lock(notif_lock) -#define NOTIF_UNLOCK lck_mtx_unlock(notif_lock) +static lck_spin_t *notif_lock; +#define NOTIF_LOCK lck_spin_lock(notif_lock) +#define NOTIF_UNLOCK lck_spin_unlock(notif_lock) static struct avc_cache avc_cache; static struct avc_callback_node *avc_callbacks; @@ -271,12 +269,12 @@ /* allocate avc mutexes */ avc_log_lock = lck_spin_alloc_init(avc_lck_grp, avc_lck_attr); - notif_lock = lck_mtx_alloc_init(avc_lck_grp, avc_lck_attr); + notif_lock = lck_spin_alloc_init(avc_lck_grp, avc_lck_attr); for (i = 0; i < AVC_CACHE_SLOTS; i++) { LIST_INIT(&avc_cache.slots[i]); avc_cache.slots_lock[i] = - lck_rw_alloc_init(avc_lck_grp, avc_lck_attr); + lck_spin_alloc_init(avc_lck_grp, avc_lck_attr); } avc_cache.active_nodes = 0; avc_cache.lru_hint = 0; @@ -306,7 +304,7 @@ slots_used = 0; max_chain_len = 0; for (i = 0; i < AVC_CACHE_SLOTS; i++) { - AVC_RDLOCK(i); + AVC_LOCK(i); if (!LIST_EMPTY(&avc_cache.slots[i])) { slots_used++; chain_len = 0; @@ -315,7 +313,7 @@ if (chain_len > max_chain_len) max_chain_len = chain_len; } - AVC_RDUNLOCK(i); + AVC_UNLOCK(i); } return scnprintf(page, PAGE_SIZE, "entries: %d\nbuckets used: %d/%d\n" @@ -365,7 +363,7 @@ for (try = 0, ecx = 0; try < AVC_CACHE_SLOTS; try++ ) { hvalue = atomic_inc_return(&avc_cache.lru_hint) & (AVC_CACHE_SLOTS - 1); - AVC_WRLOCK(hvalue); + AVC_LOCK(hvalue); for (node = LIST_FIRST(&avc_cache.slots[hvalue]); node != NULL; node = next) { next = LIST_NEXT(node, list); @@ -375,12 +373,12 @@ avc_cache_stats_incr(reclaims); ecx++; if (ecx >= AVC_CACHE_RECLAIM) { - AVC_WRUNLOCK(hvalue); + AVC_UNLOCK(hvalue); goto out; } } } - AVC_WRUNLOCK(hvalue); + AVC_UNLOCK(hvalue); } out: return ecx; @@ -422,7 +420,7 @@ struct avc_node *node, *ret = NULL; *hvaluep = avc_hash(ssid, tsid, tclass); - AVC_RDLOCK(*hvaluep); + AVC_LOCK(*hvaluep); LIST_FOREACH(node, &avc_cache.slots[*hvaluep], list) { if (ssid == node->ae.ssid && tclass == node->ae.tclass && @@ -471,7 +469,7 @@ goto out; } - AVC_RDUNLOCK(*hvaluep); + AVC_UNLOCK(*hvaluep); node = NULL; avc_cache_stats_incr(misses); out: @@ -528,7 +526,7 @@ *hvaluep = avc_hash(ssid, tsid, tclass); avc_node_populate(node, ssid, tsid, tclass, ae); - AVC_WRLOCK(*hvaluep); + AVC_LOCK(*hvaluep); LIST_FOREACH(pos, &avc_cache.slots[*hvaluep], list) { if (pos->ae.ssid == ssid && @@ -832,7 +830,7 @@ /* Lock the target slot */ hvalue = avc_hash(ssid, tsid, tclass); - AVC_WRLOCK(hvalue); + AVC_LOCK(hvalue); LIST_FOREACH(pos, &avc_cache.slots[hvalue], list){ if ( ssid==pos->ae.ssid && @@ -878,7 +876,7 @@ } avc_node_replace(node, orig); out_unlock: - AVC_WRUNLOCK(hvalue); + AVC_UNLOCK(hvalue); out: return rc; } @@ -895,10 +893,10 @@ for (i = 0; i < AVC_CACHE_SLOTS; i++) { - AVC_WRLOCK(i); + AVC_LOCK(i); while ((node = LIST_FIRST(&avc_cache.slots[i])) != NULL) avc_node_delete(node); - AVC_WRUNLOCK(i); + AVC_UNLOCK(i); } for (c = avc_callbacks; c; c = c->next) { @@ -961,9 +959,9 @@ denied = requested & ~(p_ae->avd.allowed); if (found) - AVC_RDUNLOCK(hvalue); /* locked by avc_lookup() */ + AVC_UNLOCK(hvalue); /* locked by avc_lookup() */ else if (node) - AVC_WRUNLOCK(hvalue); /* locked by avc_insert() */ + AVC_UNLOCK(hvalue); /* locked by avc_insert() */ if (!requested || denied) { if (selinux_enforcing)