ref: 8e2cfc0464d40972afa1f142f999e53771c34399
parent: 39c3fd117ab4988c041800490b23c2aedb1858d3
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Sat May 2 11:32:19 EDT 2020
ether82543gc, ether82557, ethervirtio: do kproc() call ouside of spinlock
--- a/sys/src/9/pc/ether82543gc.c
+++ b/sys/src/9/pc/ether82543gc.c
@@ -413,12 +413,10 @@
*/
ctlr = edev->ctlr;
lock(&ctlr->slock);
- if(ctlr->started == 0){
- ctlr->started = 1;
- snprint(name, KNAMELEN, "#l%d82543", edev->ctlrno);
- kproc(name, gc82543watchdog, edev);
+ if(ctlr->started){
+ unlock(&ctlr->slock);
+ return;
}
- unlock(&ctlr->slock);
ctl = csr32r(ctlr, Rctl)|Ren;
csr32w(ctlr, Rctl, ctl);
@@ -426,6 +424,12 @@
csr32w(ctlr, Tctl, ctl);
csr32w(ctlr, Ims, ctlr->im);
+
+ ctlr->started = 1;
+ unlock(&ctlr->slock);
+
+ snprint(name, KNAMELEN, "#l%d82543", edev->ctlrno);
+ kproc(name, gc82543watchdog, edev);
}
static char* statistics[Nstatistics] = {
--- a/sys/src/9/pc/ether82557.c
+++ b/sys/src/9/pc/ether82557.c
@@ -380,24 +380,26 @@
ctlr = ether->ctlr;
lock(&ctlr->slock);
- if(ctlr->state == 0){
- ilock(&ctlr->rlock);
- csr8w(ctlr, Interrupt, 0);
- iunlock(&ctlr->rlock);
- command(ctlr, RUstart, PADDR(ctlr->rfdhead->rp));
- ctlr->state = 1;
-
- /*
- * Start the watchdog timer for the receive lockup errata
- * unless the EEPROM compatibility word indicates it may be
- * omitted.
- */
- if((ctlr->eeprom[0x03] & 0x0003) != 0x0003){
- snprint(name, KNAMELEN, "#l%dwatchdog", ether->ctlrno);
- kproc(name, watchdog, ether);
- }
+ if(ctlr->state){
+ unlock(&ctlr->slock);
+ return;
}
+ ilock(&ctlr->rlock);
+ csr8w(ctlr, Interrupt, 0);
+ iunlock(&ctlr->rlock);
+ command(ctlr, RUstart, PADDR(ctlr->rfdhead->rp));
+ ctlr->state = 1;
unlock(&ctlr->slock);
+
+ /*
+ * Start the watchdog timer for the receive lockup errata
+ * unless the EEPROM compatibility word indicates it may be
+ * omitted.
+ */
+ if((ctlr->eeprom[0x03] & 0x0003) != 0x0003){
+ snprint(name, KNAMELEN, "#l%dwatchdog", ether->ctlrno);
+ kproc(name, watchdog, ether);
+ }
}
static long
--- a/sys/src/9/pc/ethervirtio.c
+++ b/sys/src/9/pc/ethervirtio.c
@@ -419,19 +419,21 @@
ctlr = edev->ctlr;
lock(ctlr);
- if(!ctlr->attached){
- ctlr->attached = 1;
-
- /* ready to go */
- outb(ctlr->port+Qstatus, inb(ctlr->port+Qstatus) | Sdriverok);
-
- /* start kprocs */
- snprint(name, sizeof name, "#l%drx", edev->ctlrno);
- kproc(name, rxproc, edev);
- snprint(name, sizeof name, "#l%dtx", edev->ctlrno);
- kproc(name, txproc, edev);
+ if(ctlr->attached){
+ unlock(ctlr);
+ return;
}
+ ctlr->attached = 1;
unlock(ctlr);
+
+ /* ready to go */
+ outb(ctlr->port+Qstatus, inb(ctlr->port+Qstatus) | Sdriverok);
+
+ /* start kprocs */
+ snprint(name, sizeof name, "#l%drx", edev->ctlrno);
+ kproc(name, rxproc, edev);
+ snprint(name, sizeof name, "#l%dtx", edev->ctlrno);
+ kproc(name, txproc, edev);
}
static long