From 109c17807fba0a917084df9774a5c19a7baeed54 Mon Sep 17 00:00:00 2001 From: Xin Li Date: Sat, 7 Jan 2012 01:44:20 -0800 Subject: [PATCH 54/65] Incorporate mav@'s patch from: http://people.freebsd.org/~mav/cam_batch.patch This removes about 1/6 context switches for ATA SIMs. The removed context switches gave 3.8% speedup. --- sys/cam/cam_sim.h | 1 + sys/cam/cam_xpt.c | 22 +++++++++++++++++++++- sys/cam/cam_xpt_sim.h | 2 ++ sys/dev/ahci/ahci.c | 2 ++ sys/dev/ata/ata-all.c | 2 ++ sys/dev/mvs/mvs.c | 2 ++ sys/dev/siis/siis.c | 2 ++ 7 files changed, 32 insertions(+), 1 deletions(-) diff --git a/sys/cam/cam_sim.h b/sys/cam/cam_sim.h index 398d540..93e99a5 100644 --- a/sys/cam/cam_sim.h +++ b/sys/cam/cam_sim.h @@ -106,6 +106,7 @@ struct cam_sim { #define CAM_SIM_MPSAFE 0x02 #define CAM_SIM_ON_DONEQ 0x04 #define CAM_SIM_POLLED 0x08 +#define CAM_SIM_BATCH 0x10 struct callout callout; struct cam_devq *devq; /* Device Queue to use for this SIM */ int refcount; /* References to the SIM. */ diff --git a/sys/cam/cam_xpt.c b/sys/cam/cam_xpt.c index 000e48a..46d832f 100644 --- a/sys/cam/cam_xpt.c +++ b/sys/cam/cam_xpt.c @@ -4232,7 +4232,8 @@ xpt_done(union ccb *done_ccb) TAILQ_INSERT_TAIL(&sim->sim_doneq, &done_ccb->ccb_h, sim_links.tqe); done_ccb->ccb_h.pinfo.index = CAM_DONEQ_INDEX; - if ((sim->flags & (CAM_SIM_ON_DONEQ | CAM_SIM_POLLED)) == 0) { + if ((sim->flags & (CAM_SIM_ON_DONEQ | CAM_SIM_POLLED | + CAM_SIM_BATCH)) == 0) { mtx_lock(&cam_simq_lock); first = TAILQ_EMPTY(&cam_simq); TAILQ_INSERT_TAIL(&cam_simq, sim, links); @@ -4244,6 +4245,25 @@ xpt_done(union ccb *done_ccb) } } +void +xpt_batch_start(struct cam_sim *sim) +{ + + KASSERT((sim->flags & CAM_SIM_BATCH) == 0, ("Batch flag already set")); + sim->flags |= CAM_SIM_BATCH; +} + +void +xpt_batch_done(struct cam_sim *sim) +{ + + KASSERT((sim->flags & CAM_SIM_BATCH) != 0, ("Batch flag was not set")); + sim->flags &= ~CAM_SIM_BATCH; + if (!TAILQ_EMPTY(&sim->sim_doneq) && + (sim->flags & CAM_SIM_ON_DONEQ) == 0) + camisr_runqueue(&sim->sim_doneq); +} + union ccb * xpt_alloc_ccb() { diff --git a/sys/cam/cam_xpt_sim.h b/sys/cam/cam_xpt_sim.h index 323f786..67b895f 100644 --- a/sys/cam/cam_xpt_sim.h +++ b/sys/cam/cam_xpt_sim.h @@ -51,6 +51,8 @@ void xpt_release_devq_rl(struct cam_path *path, cam_rl rl, u_int count, int run_queue); int xpt_sim_opened(struct cam_sim *sim); void xpt_done(union ccb *done_ccb); +void xpt_batch_start(struct cam_sim *sim); +void xpt_batch_done(struct cam_sim *sim); #endif #endif /* _CAM_CAM_XPT_SIM_H */ diff --git a/sys/dev/ahci/ahci.c b/sys/dev/ahci/ahci.c index 2d75c0d..ef3718b 100644 --- a/sys/dev/ahci/ahci.c +++ b/sys/dev/ahci/ahci.c @@ -1456,7 +1456,9 @@ ahci_ch_intr_locked(void *data) struct ahci_channel *ch = device_get_softc(dev); mtx_lock(&ch->mtx); + xpt_batch_start(ch->sim); ahci_ch_intr(data); + xpt_batch_done(ch->sim); mtx_unlock(&ch->mtx); } diff --git a/sys/dev/ata/ata-all.c b/sys/dev/ata/ata-all.c index 9b307f8..4850298 100644 --- a/sys/dev/ata/ata-all.c +++ b/sys/dev/ata/ata-all.c @@ -532,9 +532,11 @@ ata_interrupt(void *data) struct ata_channel *ch = (struct ata_channel *)data; mtx_lock(&ch->state_mtx); + xpt_batch_start(ch->sim); #endif ata_interrupt_locked(data); #ifdef ATA_CAM + xpt_batch_done(ch->sim); mtx_unlock(&ch->state_mtx); #endif } diff --git a/sys/dev/mvs/mvs.c b/sys/dev/mvs/mvs.c index 54808c5..81dcd56 100644 --- a/sys/dev/mvs/mvs.c +++ b/sys/dev/mvs/mvs.c @@ -654,7 +654,9 @@ mvs_ch_intr_locked(void *data) struct mvs_channel *ch = device_get_softc(dev); mtx_lock(&ch->mtx); + xpt_batch_start(ch->sim); mvs_ch_intr(data); + xpt_batch_done(ch->sim); mtx_unlock(&ch->mtx); } diff --git a/sys/dev/siis/siis.c b/sys/dev/siis/siis.c index ccbe079..c33379f 100644 --- a/sys/dev/siis/siis.c +++ b/sys/dev/siis/siis.c @@ -830,7 +830,9 @@ siis_ch_intr_locked(void *data) struct siis_channel *ch = device_get_softc(dev); mtx_lock(&ch->mtx); + xpt_batch_start(ch->sim); siis_ch_intr(data); + xpt_batch_done(ch->sim); mtx_unlock(&ch->mtx); } -- 1.7.8.3