PERFORCE change 111064 for review

Todd Miller millert at FreeBSD.org
Mon Dec 4 10:47:54 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 p4-projects mailing list