svn commit: r254363 - projects/camlock/sys/cam
Alexander Motin
mav at FreeBSD.org
Thu Aug 15 11:41:53 UTC 2013
Author: mav
Date: Thu Aug 15 11:41:53 2013
New Revision: 254363
URL: http://svnweb.freebsd.org/changeset/base/254363
Log:
Make polling work in new locking environment.
Modified:
projects/camlock/sys/cam/cam_xpt.c
Modified: projects/camlock/sys/cam/cam_xpt.c
==============================================================================
--- projects/camlock/sys/cam/cam_xpt.c Thu Aug 15 11:01:25 2013 (r254362)
+++ projects/camlock/sys/cam/cam_xpt.c Thu Aug 15 11:41:53 2013 (r254363)
@@ -2977,13 +2977,12 @@ xpt_polled_action(union ccb *start_ccb)
struct cam_devq *devq;
struct cam_ed *dev;
-
timeout = start_ccb->ccb_h.timeout * 10;
sim = start_ccb->ccb_h.path->bus->sim;
devq = sim->devq;
dev = start_ccb->ccb_h.path->device;
- mtx_assert(sim->mtx, MA_OWNED);
+ mtx_unlock(&dev->device_mtx);
/* Don't use ISR for this SIM while polling. */
mtx_lock(&sim->sim_doneq_mtx);
@@ -2994,23 +2993,29 @@ xpt_polled_action(union ccb *start_ccb)
* Steal an opening so that no other queued requests
* can get it before us while we simulate interrupts.
*/
+ mtx_lock(&devq->send_mtx);
dev->ccbq.devq_openings--;
dev->ccbq.dev_openings--;
-
- while(((devq != NULL && devq->send_openings <= 0) ||
- dev->ccbq.dev_openings < 0) && (--timeout > 0)) {
+ while((devq->send_openings <= 0 || dev->ccbq.dev_openings < 0) &&
+ (--timeout > 0)) {
+ mtx_unlock(&devq->send_mtx);
DELAY(100);
+ CAM_SIM_LOCK(sim);
(*(sim->sim_poll))(sim);
+ CAM_SIM_UNLOCK(sim);
camisr_runqueue(sim);
+ mtx_lock(&devq->send_mtx);
}
-
dev->ccbq.devq_openings++;
dev->ccbq.dev_openings++;
+ mtx_unlock(&devq->send_mtx);
if (timeout != 0) {
xpt_action(start_ccb);
while(--timeout > 0) {
+ CAM_SIM_LOCK(sim);
(*(sim->sim_poll))(sim);
+ CAM_SIM_UNLOCK(sim);
camisr_runqueue(sim);
if ((start_ccb->ccb_h.status & CAM_STATUS_MASK)
!= CAM_REQ_INPROG)
@@ -3034,6 +3039,8 @@ xpt_polled_action(union ccb *start_ccb)
mtx_lock(&sim->sim_doneq_mtx);
sim->sim_doneq_flags &= ~CAM_SIM_DQ_POLLED;
mtx_unlock(&sim->sim_doneq_mtx);
+ camisr_runqueue(sim);
+ mtx_lock(&dev->device_mtx);
}
/*
@@ -4351,15 +4358,18 @@ xpt_done(union ccb *done_ccb)
if (sim->sim_doneq_flags & CAM_SIM_DQ_BATCH) {
TAILQ_INSERT_TAIL(&sim->sim_doneq, &done_ccb->ccb_h,
sim_links.tqe);
+ done_ccb->ccb_h.pinfo.index = CAM_DONEQ_INDEX;
mtx_unlock(&sim->sim_doneq_mtx);
return;
}
+ run = ((sim->sim_doneq_flags & CAM_SIM_DQ_POLLED) == 0);
mtx_unlock(&sim->sim_doneq_mtx);
hash = (done_ccb->ccb_h.path_id + done_ccb->ccb_h.target_id +
done_ccb->ccb_h.target_lun) % cam_num_doneqs;
queue = &cam_doneqs[hash];
mtx_lock(&queue->cam_doneq_mtx);
- run = TAILQ_EMPTY(&queue->cam_doneq);
+ if (!TAILQ_EMPTY(&queue->cam_doneq))
+ run = 0;
TAILQ_INSERT_TAIL(&queue->cam_doneq, &done_ccb->ccb_h,
sim_links.tqe);
done_ccb->ccb_h.pinfo.index = CAM_DONEQ_INDEX;
@@ -4393,6 +4403,7 @@ xpt_batch_done(struct cam_sim *sim)
while ((ccb_h = TAILQ_FIRST(&sim->sim_doneq)) != NULL) {
TAILQ_REMOVE(&sim->sim_doneq, ccb_h, sim_links.tqe);
mtx_unlock(&sim->sim_doneq_mtx);
+ ccb_h->pinfo.index = CAM_UNQUEUED_INDEX;
xpt_done_process(ccb_h);
mtx_lock(&sim->sim_doneq_mtx);
}
@@ -5177,6 +5188,7 @@ xpt_done_td(void *arg)
}
TAILQ_REMOVE(&queue->cam_doneq, ccb_h, sim_links.tqe);
mtx_unlock(&queue->cam_doneq_mtx);
+ ccb_h->pinfo.index = CAM_UNQUEUED_INDEX;
xpt_done_process(ccb_h);
mtx_lock(&queue->cam_doneq_mtx);
}
@@ -5186,17 +5198,32 @@ static void
camisr_runqueue(struct cam_sim *sim)
{
struct ccb_hdr *ccb_h;
+ struct cam_doneq *queue;
+ int i;
+ /* Process per-SIM queue. */
mtx_lock(&sim->sim_doneq_mtx);
while ((ccb_h = TAILQ_FIRST(&sim->sim_doneq)) != NULL) {
TAILQ_REMOVE(&sim->sim_doneq, ccb_h, sim_links.tqe);
mtx_unlock(&sim->sim_doneq_mtx);
ccb_h->pinfo.index = CAM_UNQUEUED_INDEX;
-
xpt_done_process(ccb_h);
-
mtx_lock(&sim->sim_doneq_mtx);
}
sim->sim_doneq_flags &= ~CAM_SIM_DQ_ONQ;
mtx_unlock(&sim->sim_doneq_mtx);
+
+ /* Process global queues. */
+ for (i = 0; i < cam_num_doneqs; i++) {
+ queue = &cam_doneqs[i];
+ mtx_lock(&queue->cam_doneq_mtx);
+ while ((ccb_h = TAILQ_FIRST(&queue->cam_doneq)) != NULL) {
+ TAILQ_REMOVE(&queue->cam_doneq, ccb_h, sim_links.tqe);
+ mtx_unlock(&queue->cam_doneq_mtx);
+ ccb_h->pinfo.index = CAM_UNQUEUED_INDEX;
+ xpt_done_process(ccb_h);
+ mtx_lock(&queue->cam_doneq_mtx);
+ }
+ mtx_unlock(&queue->cam_doneq_mtx);
+ }
}
More information about the svn-src-projects
mailing list