Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 12 Aug 2013 10:15:09 +0000 (UTC)
From:      Alexander Motin <mav@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r254246 - projects/camlock/sys/cam
Message-ID:  <201308121015.r7CAF9KJ033143@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mav
Date: Mon Aug 12 10:15:09 2013
New Revision: 254246
URL: http://svnweb.freebsd.org/changeset/base/254246

Log:
  Revert r254226.  We can't create per-SIM threads while holding SIM lock.

Modified:
  projects/camlock/sys/cam/cam_sim.c
  projects/camlock/sys/cam/cam_sim.h
  projects/camlock/sys/cam/cam_xpt.c
  projects/camlock/sys/cam/cam_xpt.h

Modified: projects/camlock/sys/cam/cam_sim.c
==============================================================================
--- projects/camlock/sys/cam/cam_sim.c	Mon Aug 12 10:11:10 2013	(r254245)
+++ projects/camlock/sys/cam/cam_sim.c	Mon Aug 12 10:15:09 2013	(r254246)
@@ -33,7 +33,6 @@ __FBSDID("$FreeBSD$");
 #include <sys/systm.h>
 #include <sys/malloc.h>
 #include <sys/kernel.h>
-#include <sys/kthread.h>
 #include <sys/lock.h>
 #include <sys/mutex.h>
 
@@ -66,7 +65,6 @@ cam_sim_alloc(sim_action_func sim_action
 	      int max_tagged_dev_transactions, struct cam_devq *queue)
 {
 	struct cam_sim *sim;
-	int error;
 
 	if (mtx == NULL)
 		return (NULL);
@@ -99,13 +97,7 @@ cam_sim_alloc(sim_action_func sim_action
 	}
 	mtx_init(&sim->sim_doneq_mtx, "CAM doneq", NULL, MTX_DEF);
 	TAILQ_INIT(&sim->sim_doneq);
-	error = kproc_kthread_add(xpt_done_td, sim, &cam_proc, NULL, 0, 0,
-	    "cam", "%s%d", sim_name, unit);
-	if (error != 0) {
-		mtx_destroy(&sim->sim_doneq_mtx);
-		free(sim, M_CAMSIM);
-		return (NULL);
-	}
+
 	return (sim);
 }
 
@@ -122,12 +114,7 @@ cam_sim_free(struct cam_sim *sim, int fr
 	}
 
 	KASSERT(sim->refcount == 0, ("sim->refcount == 0"));
-	mtx_lock(&sim->sim_doneq_mtx);
-	sim->sim_doneq_flags |= CAM_SIM_DQ_EXIT;
-	wakeup(&sim->sim_doneq);
-	mtx_unlock(&sim->sim_doneq_mtx);
-	while (sim->sim_doneq_flags & CAM_SIM_DQ_EXIT)
-		msleep(&sim->sim_doneq_flags, sim->mtx, PRIBIO, "simfree2", 0);
+
 	if (free_devq)
 		cam_simq_free(sim->devq);
 	mtx_destroy(&sim->sim_doneq_mtx);

Modified: projects/camlock/sys/cam/cam_sim.h
==============================================================================
--- projects/camlock/sys/cam/cam_sim.h	Mon Aug 12 10:11:10 2013	(r254245)
+++ projects/camlock/sys/cam/cam_sim.h	Mon Aug 12 10:15:09 2013	(r254246)
@@ -97,7 +97,6 @@ struct cam_sim {
 	TAILQ_HEAD(, ccb_hdr)	sim_doneq;
 	struct mtx		sim_doneq_mtx;
 	int			sim_doneq_flags;
-#define	CAM_SIM_DQ_EXIT		0x01
 #define	CAM_SIM_DQ_ONQ		0x04
 #define	CAM_SIM_DQ_POLLED	0x08
 #define	CAM_SIM_DQ_BATCH	0x10

Modified: projects/camlock/sys/cam/cam_xpt.c
==============================================================================
--- projects/camlock/sys/cam/cam_xpt.c	Mon Aug 12 10:11:10 2013	(r254245)
+++ projects/camlock/sys/cam/cam_xpt.c	Mon Aug 12 10:15:09 2013	(r254246)
@@ -156,7 +156,15 @@ TUNABLE_INT("kern.cam.boot_delay", &xsof
 SYSCTL_INT(_kern_cam, OID_AUTO, boot_delay, CTLFLAG_RDTUN,
            &xsoftc.boot_delay, 0, "Bus registration wait time");
 
-struct proc *cam_proc;
+/* Queues for our software interrupt handler */
+typedef TAILQ_HEAD(cam_isrq, ccb_hdr) cam_isrq_t;
+typedef TAILQ_HEAD(cam_simq, cam_sim) cam_simq_t;
+static cam_simq_t cam_simq;
+static struct mtx cam_simq_lock;
+
+/* Pointers to software interrupt handlers */
+static void *cambio_ih;
+
 struct cam_periph *xpt_periph;
 
 static periph_init_t xpt_periph_init;
@@ -241,6 +249,7 @@ static int	 xpt_schedule_dev(struct camq
 static xpt_devicefunc_t xptpassannouncefunc;
 static void	 xptaction(struct cam_sim *sim, union ccb *work_ccb);
 static void	 xptpoll(struct cam_sim *sim);
+static void	 camisr(void *);
 static void	 camisr_runqueue(struct cam_sim *);
 static dev_match_ret	xptbusmatch(struct dev_match_pattern *patterns,
 				    u_int num_patterns, struct cam_eb *bus);
@@ -832,10 +841,12 @@ xpt_init(void *dummy)
 	cam_status status;
 
 	TAILQ_INIT(&xsoftc.xpt_busses);
+	TAILQ_INIT(&cam_simq);
 	TAILQ_INIT(&xsoftc.ccb_scanq);
 	STAILQ_INIT(&xsoftc.highpowerq);
 	xsoftc.num_highpower = CAM_MAX_HIGHPOWER;
 
+	mtx_init(&cam_simq_lock, "CAM SIMQ lock", NULL, MTX_DEF);
 	mtx_init(&xsoftc.xpt_lock, "XPT lock", NULL, MTX_DEF);
 	mtx_init(&xsoftc.xpt_topo_lock, "XPT topology lock", NULL, MTX_DEF);
 	xsoftc.xpt_taskq = taskqueue_create("CAM XPT task", M_WAITOK,
@@ -893,6 +904,8 @@ xpt_init(void *dummy)
 			 path, NULL, 0, xpt_sim);
 	xpt_free_path(path);
 	mtx_unlock(&xsoftc.xpt_lock);
+	/* Install our software interrupt handlers */
+	swi_add(NULL, "cambio", camisr, NULL, SWI_CAMBIO, INTR_MPSAFE, &cambio_ih);
 	/*
 	 * Register a callback for when interrupts are enabled.
 	 */
@@ -4284,7 +4297,7 @@ void
 xpt_done(union ccb *done_ccb)
 {
 	struct cam_sim *sim;
-	int	run;
+	int	first;
 
 	CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_TRACE, ("xpt_done\n"));
 	if ((done_ccb->ccb_h.func_code & XPT_FC_QUEUED) != 0) {
@@ -4299,13 +4312,16 @@ xpt_done(union ccb *done_ccb)
 		done_ccb->ccb_h.pinfo.index = CAM_DONEQ_INDEX;
 		if ((sim->sim_doneq_flags & (CAM_SIM_DQ_ONQ |
 		    CAM_SIM_DQ_POLLED | CAM_SIM_DQ_BATCH)) == 0) {
+			mtx_lock(&cam_simq_lock);
+			first = TAILQ_EMPTY(&cam_simq);
+			TAILQ_INSERT_TAIL(&cam_simq, sim, links);
+			mtx_unlock(&cam_simq_lock);
 			sim->sim_doneq_flags |= CAM_SIM_DQ_ONQ;
-			run = 1;
 		} else
-			run = 0;
+			first = 0;
 		mtx_unlock(&sim->sim_doneq_mtx);
-		if (run)
-			wakeup(&sim->sim_doneq);
+		if (first)
+			swi_sched(cambio_ih, 0);
 	}
 }
 
@@ -4812,8 +4828,7 @@ xpt_config(void *arg)
 	callout_reset(&xsoftc.boot_callout, hz * xsoftc.boot_delay / 1000,
 	    xpt_boot_delay, NULL);
 	/* Fire up rescan thread. */
-	if (kproc_kthread_add(xpt_scanner_thread, NULL, &cam_proc, NULL, 0, 0,
-	    "cam", "scanner")) {
+	if (kproc_create(xpt_scanner_thread, NULL, NULL, 0, 0, "xpt_thrd")) {
 		printf("xpt_config: failed to create rescan thread.\n");
 	}
 }
@@ -5037,30 +5052,25 @@ xpt_path_mtx(struct cam_path *path)
 	return (&path->device->device_mtx);
 }
 
-void
-xpt_done_td(void *arg)
+static void
+camisr(void *dummy)
 {
-	struct cam_sim *sim = arg;
+	cam_simq_t queue;
+	struct cam_sim *sim;
 
-	mtx_lock(&sim->sim_doneq_mtx);
-	while (1) {
-		if (TAILQ_EMPTY(&sim->sim_doneq)) {
-			if (sim->sim_doneq_flags & CAM_SIM_DQ_EXIT) {
-				mtx_unlock(&sim->sim_doneq_mtx);
-				CAM_SIM_LOCK(sim);
-				sim->sim_doneq_flags &= ~CAM_SIM_DQ_EXIT;
-				wakeup(&sim->sim_doneq_flags);
-				CAM_SIM_UNLOCK(sim);
-				kthread_exit();
-			}
-			msleep(&sim->sim_doneq, &sim->sim_doneq_mtx, PRIBIO,
-			    "-", 0);
-			continue;
+	mtx_lock(&cam_simq_lock);
+	TAILQ_INIT(&queue);
+	while (!TAILQ_EMPTY(&cam_simq)) {
+		TAILQ_CONCAT(&queue, &cam_simq, links);
+		mtx_unlock(&cam_simq_lock);
+
+		while ((sim = TAILQ_FIRST(&queue)) != NULL) {
+			TAILQ_REMOVE(&queue, sim, links);
+			camisr_runqueue(sim);
 		}
-		mtx_unlock(&sim->sim_doneq_mtx);
-		camisr_runqueue(sim);
-		mtx_lock(&sim->sim_doneq_mtx);
+		mtx_lock(&cam_simq_lock);
 	}
+	mtx_unlock(&cam_simq_lock);
 }
 
 static void

Modified: projects/camlock/sys/cam/cam_xpt.h
==============================================================================
--- projects/camlock/sys/cam/cam_xpt.h	Mon Aug 12 10:11:10 2013	(r254245)
+++ projects/camlock/sys/cam/cam_xpt.h	Mon Aug 12 10:15:09 2013	(r254246)
@@ -62,7 +62,6 @@ struct async_node {
 
 SLIST_HEAD(async_list, async_node);
 SLIST_HEAD(periph_list, cam_periph);
-extern struct proc *cam_proc;
 
 void			xpt_action(union ccb *new_ccb);
 void			xpt_action_default(union ccb *new_ccb);
@@ -124,7 +123,6 @@ void			xpt_copy_path(struct cam_path *ne
 				      struct cam_path *path);
 
 void			xpt_release_path(struct cam_path *path);
-void			xpt_done_td(void *);
 
 #endif /* _KERNEL */
 



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