From 7289f371a0b113c12add274c4d4aa84d0c147dee Mon Sep 17 00:00:00 2001 From: cinap_lenrek Date: Wed, 16 Feb 2022 22:31:31 +0000 Subject: 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. --- sys/src/9/ip/ethermedium.c | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'sys/src/9/ip/ethermedium.c') diff --git a/sys/src/9/ip/ethermedium.c b/sys/src/9/ip/ethermedium.c index fb6d05279..8a2a50899 100644 --- a/sys/src/9/ip/ethermedium.c +++ b/sys/src/9/ip/ethermedium.c @@ -107,7 +107,6 @@ static char *nbmsg = "nonblocking"; /* * called to bind an IP ifc to an ethernet device - * called with ifc wlock'd */ static void etherbind(Ipifc *ifc, int argc, char **argv) @@ -200,9 +199,6 @@ etherbind(Ipifc *ifc, int argc, char **argv) kproc("recvarpproc", recvarpproc, ifc); } -/* - * called with ifc wlock'd - */ static void etherunbind(Ipifc *ifc) { @@ -210,7 +206,6 @@ etherunbind(Ipifc *ifc) while(waserror()) ; - /* wait for readers to start */ while(er->arpp == (void*)-1 || er->read4p == (void*)-1 || er->read6p == (void*)-1) tsleep(&up->sleep, return0, 0, 300); @@ -221,19 +216,14 @@ etherunbind(Ipifc *ifc) postnote(er->read6p, 1, "unbind", 0); if(er->arpp != nil) postnote(er->arpp, 1, "unbind", 0); - poperror(); - wunlock(ifc); while(waserror()) ; - /* wait for readers to die */ while(er->arpp != nil || er->read4p != nil || er->read6p != nil) tsleep(&up->sleep, return0, 0, 300); - poperror(); - wlock(ifc); if(er->mchan4 != nil) cclose(er->mchan4); -- cgit v1.2.3