PERFORCE change 111064 for review
Todd Miller
millert at FreeBSD.org
Mon Dec 4 10:51:09 PST 2006
http://perforce.freebsd.org/chv.cgi?CH=111064
Change 111064 by millert at 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)
More information about the trustedbsd-cvs
mailing list