Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 16 Apr 2013 08:49:28 +0000 (UTC)
From:      Alexander Motin <mav@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r249541 - projects/camlock/sys/cam
Message-ID:  <201304160849.r3G8nSGn073332@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mav
Date: Tue Apr 16 08:49:27 2013
New Revision: 249541
URL: http://svnweb.freebsd.org/changeset/base/249541

Log:
  Give periph validity flag own periph reference.  That slightly simplifies
  the release logic and covers hypothetical case if lock is dropped inside
  the periph_oninval() method.

Modified:
  projects/camlock/sys/cam/cam_periph.c

Modified: projects/camlock/sys/cam/cam_periph.c
==============================================================================
--- projects/camlock/sys/cam/cam_periph.c	Tue Apr 16 07:48:49 2013	(r249540)
+++ projects/camlock/sys/cam/cam_periph.c	Tue Apr 16 08:49:27 2013	(r249541)
@@ -202,7 +202,7 @@ cam_periph_alloc(periph_ctor_t *periph_c
 	periph->periph_oninval = periph_oninvalidate;
 	periph->type = type;
 	periph->periph_name = name;
-	periph->refcount = 0;
+	periph->refcount = 1;		/* Dropped by invalidation. */
 	periph->sim = sim;
 	mtx_init(&periph->periph_mtx, "CAM periph lock", NULL, MTX_DEF);
 	status = xpt_create_path(&path, periph, path_id, target_id, lun_id);
@@ -380,10 +380,8 @@ cam_periph_release_locked_buses(struct c
 
 	mtx_assert(periph->sim->mtx, MA_OWNED);
 	KASSERT(periph->refcount >= 1, ("periph->refcount >= 1"));
-	if (--periph->refcount == 0
-	    && (periph->flags & CAM_PERIPH_INVALID)) {
+	if (--periph->refcount == 0)
 		camperiphfree(periph);
-	}
 }
 
 void
@@ -578,23 +576,20 @@ void
 cam_periph_invalidate(struct cam_periph *periph)
 {
 
-	CAM_DEBUG(periph->path, CAM_DEBUG_INFO, ("Periph invalidated\n"));
 	mtx_assert(periph->sim->mtx, MA_OWNED);
 	/*
 	 * We only call this routine the first time a peripheral is
 	 * invalidated.
 	 */
-	if (((periph->flags & CAM_PERIPH_INVALID) == 0)
-	 && (periph->periph_oninval != NULL))
-		periph->periph_oninval(periph);
+	if ((periph->flags & CAM_PERIPH_INVALID) != 0)
+		return;
 
+	CAM_DEBUG(periph->path, CAM_DEBUG_INFO, ("Periph invalidated\n"));
 	periph->flags |= CAM_PERIPH_INVALID;
 	periph->flags &= ~CAM_PERIPH_NEW_DEV_FOUND;
-
-	xpt_lock_buses();
-	if (periph->refcount == 0)
-		camperiphfree(periph);
-	xpt_unlock_buses();
+	if (periph->periph_oninval != NULL)
+		periph->periph_oninval(periph);
+	cam_periph_release_locked(periph);
 }
 
 static void



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201304160849.r3G8nSGn073332>