shithub: riscv

Download patch

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