diff options
author | cinap_lenrek <cinap_lenrek@felloff.net> | 2022-02-16 22:31:31 +0000 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2022-02-16 22:31:31 +0000 |
commit | 7289f371a0b113c12add274c4d4aa84d0c147dee (patch) | |
tree | caaadea3c6dff299367b9079558141efc2f1ea65 /sys/src/9/ip/netdevmedium.c | |
parent | 755880b19f365c3f98eac5c7de1d8b25f773ace3 (diff) |
devip: dont hold ifc wlock during medium bind/unbind
Wlock()'ing the ifc causes a deadlock with Medium
bind/unbind as the routine can walk /net, while
ndb/dns or ndb/cs are currently blocked enumerating
/net/ipifc/*.
The fix is to have a fake medium, called "unbound",
that is set temporarily during the call of Medium
bind and unbind.
That way, the interface rwlock can be released while
bind/unbind is in progress.
The ipifcunbind() routine will refuse to unbind a
ifc that is currently assigned to the "unbound"
medium, preventing any accidents.
Diffstat (limited to 'sys/src/9/ip/netdevmedium.c')
-rw-r--r-- | sys/src/9/ip/netdevmedium.c | 10 |
1 files changed, 0 insertions, 10 deletions
diff --git a/sys/src/9/ip/netdevmedium.c b/sys/src/9/ip/netdevmedium.c index 9e265d19b..f60d43b3a 100644 --- a/sys/src/9/ip/netdevmedium.c +++ b/sys/src/9/ip/netdevmedium.c @@ -35,7 +35,6 @@ Medium netdevmedium = /* * called to bind an IP ifc to a generic network device - * called with ifc qlock'd */ static void netdevbind(Ipifc *ifc, int argc, char **argv) @@ -58,9 +57,6 @@ netdevbind(Ipifc *ifc, int argc, char **argv) kproc("netdevread", netdevread, ifc); } -/* - * called with ifc wlock'd - */ static void netdevunbind(Ipifc *ifc) { @@ -68,26 +64,20 @@ netdevunbind(Ipifc *ifc) while(waserror()) ; - /* wait for reader to start */ while(er->readp == (void*)-1) tsleep(&up->sleep, return0, 0, 300); if(er->readp != nil) postnote(er->readp, 1, "unbind", 0); - poperror(); - wunlock(ifc); while(waserror()) ; - /* wait for reader to die */ while(er->readp != nil) tsleep(&up->sleep, return0, 0, 300); - poperror(); - wlock(ifc); if(er->mchan != nil) cclose(er->mchan); |