PERFORCE change 116764 for review
Scott Long
scottl at FreeBSD.org
Wed Mar 28 18:55:51 UTC 2007
http://perforce.freebsd.org/chv.cgi?CH=116764
Change 116764 by scottl at scottl-x64 on 2007/03/28 18:55:25
Lock the xpt_rescan functions.
Affected files ...
.. //depot/projects/scottl-camlock/src/sys/cam/cam_xpt.c#51 edit
Differences ...
==== //depot/projects/scottl-camlock/src/sys/cam/cam_xpt.c#51 (text+ko) ====
@@ -247,6 +247,9 @@
STAILQ_HEAD(highpowerlist, ccb_hdr) highpowerq;
int num_highpower;
+ /* queue for handling async rescan requests. */
+ TAILQ_HEAD(, ccb_hdr) ccb_scanq;
+
/* Registered busses */
TAILQ_HEAD(,cam_eb) xpt_busses;
u_int bus_generation;
@@ -1405,22 +1408,40 @@
}
/* thread to handle bus rescans */
-static TAILQ_HEAD(, ccb_hdr) ccb_scanq;
static void
xpt_scanner_thread(void *dummy)
{
- mtx_lock(&Giant);
+ cam_isrq_t queue;
+ union ccb *ccb;
+ struct cam_sim *sim;
+
for (;;) {
- union ccb *ccb;
- tsleep(&ccb_scanq, PRIBIO, "ccb_scanq", 0);
- while ((ccb = (union ccb *)TAILQ_FIRST(&ccb_scanq)) != NULL) {
- TAILQ_REMOVE(&ccb_scanq, &ccb->ccb_h, sim_links.tqe);
+ /*
+ * Wait for a rescan request to come in. When it does, splice
+ * it onto a queue from local storage so that the xpt lock
+ * doesn't need to be held while the requests are being
+ * processed.
+ */
+ xpt_lock_buses();
+ msleep(&xsoftc.ccb_scanq, &xsoftc.xpt_lock, PRIBIO,
+ "ccb_scanq", 0);
+ TAILQ_INIT(&queue);
+ TAILQ_CONCAT(&queue, &xsoftc.ccb_scanq, sim_links.tqe);
+ xpt_unlock_buses();
+
+ while ((ccb = (union ccb *)TAILQ_FIRST(&queue)) != NULL) {
+ TAILQ_REMOVE(&queue, &ccb->ccb_h, sim_links.tqe);
+
+ sim = ccb->ccb_h.path->bus->sim;
+ mtx_lock(sim->mtx);
+
ccb->ccb_h.func_code = XPT_SCAN_BUS;
ccb->ccb_h.cbfcnp = xptdone;
xpt_setup_ccb(&ccb->ccb_h, ccb->ccb_h.path, 5);
cam_periph_runccb(ccb, NULL, 0, 0, NULL);
xpt_free_path(ccb->ccb_h.path);
xpt_free_ccb(ccb);
+ mtx_unlock(sim->mtx);
}
}
}
@@ -1429,20 +1450,23 @@
xpt_rescan(union ccb *ccb)
{
struct ccb_hdr *hdr;
- GIANT_REQUIRED;
+
/*
* Don't make duplicate entries for the same paths.
*/
- TAILQ_FOREACH(hdr, &ccb_scanq, sim_links.tqe) {
+ xpt_lock_buses();
+ TAILQ_FOREACH(hdr, &xsoftc.ccb_scanq, sim_links.tqe) {
if (xpt_path_comp(hdr->path, ccb->ccb_h.path) == 0) {
+ xpt_unlock_buses();
xpt_print(ccb->ccb_h.path, "rescan already queued\n");
xpt_free_path(ccb->ccb_h.path);
xpt_free_ccb(ccb);
return;
}
}
- TAILQ_INSERT_TAIL(&ccb_scanq, &ccb->ccb_h, sim_links.tqe);
- wakeup(&ccb_scanq);
+ TAILQ_INSERT_TAIL(&xsoftc.ccb_scanq, &ccb->ccb_h, sim_links.tqe);
+ wakeup(&xsoftc.ccb_scanq);
+ xpt_unlock_buses();
}
/* Functions accessed by the peripheral drivers */
@@ -1456,7 +1480,7 @@
TAILQ_INIT(&xsoftc.xpt_busses);
TAILQ_INIT(&cam_bioq);
- TAILQ_INIT(&ccb_scanq);
+ TAILQ_INIT(&xsoftc.ccb_scanq);
STAILQ_INIT(&xsoftc.highpowerq);
xsoftc.num_highpower = CAM_MAX_HIGHPOWER;
More information about the p4-projects
mailing list