svn commit: r239331 - head/sys/ia64/ia64

John Baldwin jhb at FreeBSD.org
Thu Aug 16 17:17:09 UTC 2012


Author: jhb
Date: Thu Aug 16 17:17:08 2012
New Revision: 239331
URL: http://svn.freebsd.org/changeset/base/239331

Log:
  Add locking for sscdisk(4) and mark it MPSAFE.  Since this driver just
  makes calls out to the emulator, the locking is fairly simple.  A global
  mutex protects the list of ssc disks, and each ssc disk has a mutex
  to protect it's bioq.
  
  Approved by:	marcel

Modified:
  head/sys/ia64/ia64/sscdisk.c

Modified: head/sys/ia64/ia64/sscdisk.c
==============================================================================
--- head/sys/ia64/ia64/sscdisk.c	Thu Aug 16 15:32:16 2012	(r239330)
+++ head/sys/ia64/ia64/sscdisk.c	Thu Aug 16 17:17:08 2012	(r239331)
@@ -77,13 +77,15 @@ static MALLOC_DEFINE(M_SSC, "ssc_disk", 
 static d_strategy_t sscstrategy;
 
 static LIST_HEAD(, ssc_s) ssc_softc_list = LIST_HEAD_INITIALIZER(ssc_softc_list);
+static struct mtx ssc_list_lock;
+MTX_SYSINIT(ssc_list, &ssc_list_lock, "ssc list", MTX_DEF);
 
 struct ssc_s {
 	int unit;
 	LIST_ENTRY(ssc_s) list;
 	struct bio_queue_head bio_queue;
 	struct disk *disk;
-	struct cdev *dev;
+	struct mtx lock;
 	int busy;
 	int fd;
 };
@@ -94,30 +96,27 @@ static void
 sscstrategy(struct bio *bp)
 {
 	struct ssc_s *sc;
-	int s;
 	struct disk_req req;
 	struct disk_stat stat;
 	u_long len, va, off;
 
 	sc = bp->bio_disk->d_drv1;
 
-	s = splbio();
-
+	mtx_lock(&sc->lock);
 	bioq_disksort(&sc->bio_queue, bp);
 
 	if (sc->busy) {
-		splx(s);
+		mtx_unlock(&sc->lock);
 		return;
 	}
-
 	sc->busy++;
-	
-	while (1) {
+
+	for (;;) {
 		bp = bioq_takefirst(&sc->bio_queue);
-		splx(s);
 		if (!bp)
 			break;
 
+		mtx_unlock(&sc->lock);
 		va = (u_long) bp->bio_data;
 		len = bp->bio_bcount;
 		off = bp->bio_pblkno << DEV_BSHIFT;
@@ -140,10 +139,11 @@ sscstrategy(struct bio *bp)
 		}
 		bp->bio_resid = 0;
 		biodone(bp);
-		s = splbio();
+		mtx_lock(&sc->lock);
 	}
 
 	sc->busy = 0;
+	mtx_unlock(&sc->lock);
 	return;
 }
 
@@ -158,17 +158,24 @@ ssccreate(int unit)
 	if (fd == -1)
 		return (NULL);
 
+	sc = malloc(sizeof(*sc), M_SSC, M_WAITOK | M_ZERO);
+
+	mtx_lock(&ssc_list_lock);
 	if (unit == -1)
 		unit = sscunits++;
 	/* Make sure this unit isn't already in action */
 	LIST_FOREACH(sc, &ssc_softc_list, list) {
-		if (sc->unit == unit)
+		if (sc->unit == unit) {
+			mtx_unlock(&ssc_list_lock);
+			free(sc, M_SSC);
 			return (NULL);
+		}
 	}
-	sc = malloc(sizeof(*sc), M_SSC, M_WAITOK | M_ZERO);
 	LIST_INSERT_HEAD(&ssc_softc_list, sc, list);
 	sc->unit = unit;
+	mtx_unlock(&ssc_list_lock);
 	bioq_init(&sc->bio_queue);
+	mtx_init(&sc->lock, "ssc", NULL, MTX_DEF);
 
 	sc->disk = disk_alloc();
 	sc->disk->d_drv1 = sc;
@@ -180,7 +187,6 @@ ssccreate(int unit)
 	sc->disk->d_sectorsize = DEV_BSIZE;
 	sc->disk->d_strategy = sscstrategy;
 	sc->disk->d_unit = sc->unit;
-	sc->disk->d_flags = DISKFLAG_NEEDSGIANT;
 	disk_create(sc->disk, DISK_VERSION);
 	sc->fd = fd;
 	if (sc->unit == 0) 


More information about the svn-src-all mailing list