Created
April 10, 2014 14:08
-
-
Save scamp/10386254 to your computer and use it in GitHub Desktop.
Fix for locking model used in netgraph. Backported for FreeBSD-8.3-STABLE from HEAD.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--- /usr/src/sys/netgraph/ng_base.c 2013/07/15 01:32:55 | |
+++ /usr/src/sys/netgraph/ng_base.c 2013/10/15 17:44:35 | |
@@ -74,7 +74,12 @@ | |
MODULE_VERSION(netgraph, NG_ABI_VERSION); | |
/* Mutex to protect topology events. */ | |
-static struct mtx ng_topo_mtx; | |
+static struct rwlock ng_topo_lock; | |
+#define TOPOLOGY_RLOCK() rw_rlock(&ng_topo_lock) | |
+#define TOPOLOGY_RUNLOCK() rw_runlock(&ng_topo_lock) | |
+#define TOPOLOGY_WLOCK() rw_wlock(&ng_topo_lock) | |
+#define TOPOLOGY_WUNLOCK() rw_wunlock(&ng_topo_lock) | |
+#define TOPOLOGY_NOTOWNED() rw_assert(&ng_topo_lock, RA_UNLOCKED) | |
#ifdef NETGRAPH_DEBUG | |
static struct mtx ng_nodelist_mtx; /* protects global node/hook lists */ | |
@@ -1162,7 +1167,7 @@ | |
* Protect divorce process with mutex, to avoid races on | |
* simultaneous disconnect. | |
*/ | |
- mtx_lock(&ng_topo_mtx); | |
+ TOPOLOGY_WLOCK(); | |
hook->hk_flags |= HK_INVALID; | |
@@ -1182,17 +1187,17 @@ | |
* If it's already divorced from a node, | |
* just free it. | |
*/ | |
- mtx_unlock(&ng_topo_mtx); | |
+ TOPOLOGY_WUNLOCK(); | |
} else { | |
- mtx_unlock(&ng_topo_mtx); | |
+ TOPOLOGY_WUNLOCK(); | |
ng_rmhook_self(peer); /* Send it a surprise */ | |
} | |
NG_HOOK_UNREF(peer); /* account for peer link */ | |
NG_HOOK_UNREF(hook); /* account for peer link */ | |
} else | |
- mtx_unlock(&ng_topo_mtx); | |
+ TOPOLOGY_WUNLOCK(); | |
- mtx_assert(&ng_topo_mtx, MA_NOTOWNED); | |
+ TOPOLOGY_NOTOWNED(); | |
/* | |
* Remove the hook from the node's list to avoid possible recursion | |
@@ -1233,9 +1238,9 @@ | |
TRAP_ERROR(); | |
return (EINVAL); | |
} | |
- mtx_lock(&ng_topo_mtx); | |
+ TOPOLOGY_WLOCK(); | |
if (NG_HOOK_NOT_VALID(hook1) || NG_HOOK_NOT_VALID(hook2)) { | |
- mtx_unlock(&ng_topo_mtx); | |
+ TOPOLOGY_WUNLOCK(); | |
return (EINVAL); | |
} | |
hook1->hk_peer->hk_peer = hook2->hk_peer; | |
@@ -1243,7 +1248,7 @@ | |
hook1->hk_peer = &ng_deadhook; | |
hook2->hk_peer = &ng_deadhook; | |
- mtx_unlock(&ng_topo_mtx); | |
+ TOPOLOGY_WUNLOCK(); | |
NG_HOOK_UNREF(hook1); | |
NG_HOOK_UNREF(hook2); | |
@@ -1440,15 +1445,15 @@ | |
/* | |
* Acquire topo mutex to avoid race with ng_destroy_hook(). | |
*/ | |
- mtx_lock(&ng_topo_mtx); | |
+ TOPOLOGY_RLOCK(); | |
peer = hook->hk_peer; | |
if (peer == &ng_deadhook) { | |
- mtx_unlock(&ng_topo_mtx); | |
+ TOPOLOGY_RUNLOCK(); | |
printf("failed in ng_con_part2(B)\n"); | |
ng_destroy_hook(hook); | |
ERROUT(ENOENT); | |
} | |
- mtx_unlock(&ng_topo_mtx); | |
+ TOPOLOGY_RUNLOCK(); | |
if ((error = ng_send_fn2(peer->hk_node, peer, item, &ng_con_part3, | |
NULL, 0, NG_REUSE_ITEM))) { | |
@@ -1793,14 +1798,14 @@ | |
/* We have a segment, so look for a hook by that name */ | |
hook = ng_findhook(node, segment); | |
- mtx_lock(&ng_topo_mtx); | |
+ TOPOLOGY_WLOCK(); | |
/* Can't get there from here... */ | |
if (hook == NULL || NG_HOOK_PEER(hook) == NULL || | |
NG_HOOK_NOT_VALID(hook) || | |
NG_HOOK_NOT_VALID(NG_HOOK_PEER(hook))) { | |
TRAP_ERROR(); | |
NG_NODE_UNREF(node); | |
- mtx_unlock(&ng_topo_mtx); | |
+ TOPOLOGY_WUNLOCK(); | |
return (ENOENT); | |
} | |
@@ -1817,7 +1822,7 @@ | |
NG_NODE_UNREF(oldnode); /* XXX another race */ | |
if (NG_NODE_NOT_VALID(node)) { | |
NG_NODE_UNREF(node); /* XXX more races */ | |
- mtx_unlock(&ng_topo_mtx); | |
+ TOPOLOGY_WUNLOCK(); | |
TRAP_ERROR(); | |
return (ENXIO); | |
} | |
@@ -1830,11 +1835,11 @@ | |
} else | |
*lasthook = NULL; | |
} | |
- mtx_unlock(&ng_topo_mtx); | |
+ TOPOLOGY_WUNLOCK(); | |
*destp = node; | |
return (0); | |
} | |
- mtx_unlock(&ng_topo_mtx); | |
+ TOPOLOGY_WUNLOCK(); | |
} | |
} | |
@@ -3202,8 +3207,7 @@ | |
rw_init(&ng_typelist_lock, "netgraph types"); | |
rw_init(&ng_idhash_lock, "netgraph idhash"); | |
rw_init(&ng_namehash_lock, "netgraph namehash"); | |
- mtx_init(&ng_topo_mtx, "netgraph topology mutex", NULL, | |
- MTX_DEF); | |
+ rw_init(&ng_topo_lock, "netgraph topology mutex"); | |
#ifdef NETGRAPH_DEBUG | |
mtx_init(&ng_nodelist_mtx, "netgraph nodelist mutex", NULL, | |
MTX_DEF); | |
@@ -3579,13 +3583,13 @@ | |
* that the peer is still connected (even if invalid,) we know | |
* that the peer node is present, though maybe invalid. | |
*/ | |
- mtx_lock(&ng_topo_mtx); | |
+ TOPOLOGY_RLOCK(); | |
if ((hook == NULL) || NG_HOOK_NOT_VALID(hook) || | |
NG_HOOK_NOT_VALID(peer = NG_HOOK_PEER(hook)) || | |
NG_NODE_NOT_VALID(peernode = NG_PEER_NODE(hook))) { | |
NG_FREE_ITEM(item); | |
TRAP_ERROR(); | |
- mtx_unlock(&ng_topo_mtx); | |
+ TOPOLOGY_RUNLOCK(); | |
return (ENETDOWN); | |
} | |
@@ -3598,7 +3602,7 @@ | |
NGI_SET_NODE(item, peernode); | |
SET_RETADDR(item, here, retaddr); | |
- mtx_unlock(&ng_topo_mtx); | |
+ TOPOLOGY_RUNLOCK(); | |
return (0); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment