summaryrefslogtreecommitdiffstats
path: root/sys/cam/cam_xpt.c
diff options
context:
space:
mode:
authormav <mav@FreeBSD.org>2013-08-05 11:48:40 +0000
committermav <mav@FreeBSD.org>2013-08-05 11:48:40 +0000
commitbbfed93309ad0e43fcd90d67e5ba66ff86d113ff (patch)
treead49b3f2fe36aff83e041ef6aa15d048ab38b893 /sys/cam/cam_xpt.c
parent08061c3f1e43cdc5bba4b98a08da51432d3ba18c (diff)
downloadFreeBSD-src-bbfed93309ad0e43fcd90d67e5ba66ff86d113ff.zip
FreeBSD-src-bbfed93309ad0e43fcd90d67e5ba66ff86d113ff.tar.gz
MFprojects/camlock r249505:
Change CCB queue resize logic to be able safely handle overallocations: - (re)allocate queue space in power of 2 chunks with 64 elements minimum and never shrink it; with only 4/8 bytes per element size is insignificant. - automatically reallocate the queue to double size if it is overflowed. - if queue reallocation failed, store extra CCBs in unsorted TAILQ, fetching them back as soon as some queue element is freed. To free space in CCB for TAILQ linking, change highpowerq from keeping high-power CCBs to keeping devices frozen due to high-power CCBs. This encloses all pieces of queue resize logic inside of cam_queue.[ch], removing some not obvious duties from xpt_release_ccb().
Diffstat (limited to 'sys/cam/cam_xpt.c')
-rw-r--r--sys/cam/cam_xpt.c26
1 files changed, 9 insertions, 17 deletions
diff --git a/sys/cam/cam_xpt.c b/sys/cam/cam_xpt.c
index aac1be2..8246acd 100644
--- a/sys/cam/cam_xpt.c
+++ b/sys/cam/cam_xpt.c
@@ -99,7 +99,7 @@ struct xpt_softc {
u_int32_t xpt_generation;
/* number of high powered commands that can go through right now */
- STAILQ_HEAD(highpowerlist, ccb_hdr) highpowerq;
+ STAILQ_HEAD(highpowerlist, cam_ed) highpowerq;
int num_highpower;
/* queue for handling async rescan requests. */
@@ -2684,7 +2684,7 @@ xpt_action_default(union ccb *start_ccb)
cgds->dev_openings = dev->ccbq.dev_openings;
cgds->dev_active = dev->ccbq.dev_active;
cgds->devq_openings = dev->ccbq.devq_openings;
- cgds->devq_queued = dev->ccbq.queue.entries;
+ cgds->devq_queued = cam_ccbq_pending_ccb_count(&dev->ccbq);
cgds->held = dev->ccbq.held;
cgds->last_reset = tar->last_reset;
cgds->maxtags = dev->maxtags;
@@ -3255,8 +3255,8 @@ xpt_run_devq(struct cam_devq *devq)
*/
xpt_freeze_devq(work_ccb->ccb_h.path, 1);
STAILQ_INSERT_TAIL(&xsoftc.highpowerq,
- &work_ccb->ccb_h,
- xpt_links.stqe);
+ work_ccb->ccb_h.path->device,
+ highpowerq_entry);
mtx_unlock(&xsoftc.xpt_lock);
continue;
@@ -3778,11 +3778,6 @@ xpt_release_ccb(union ccb *free_ccb)
mtx_assert(sim->mtx, MA_OWNED);
cam_ccbq_release_opening(&device->ccbq);
- if (device->flags & CAM_DEV_RESIZE_QUEUE_NEEDED) {
- device->flags &= ~CAM_DEV_RESIZE_QUEUE_NEEDED;
- cam_ccbq_resize(&device->ccbq,
- device->ccbq.dev_openings + device->ccbq.dev_active);
- }
if (sim->ccb_count > sim->max_ccbs) {
xpt_free_ccb(free_ccb);
sim->ccb_count--;
@@ -4581,9 +4576,6 @@ xpt_dev_ccbq_resize(struct cam_path *path, int newopenings)
diff = newopenings - (dev->ccbq.dev_active + dev->ccbq.dev_openings);
result = cam_ccbq_resize(&dev->ccbq, newopenings);
- if (result == CAM_REQ_CMP && (diff < 0)) {
- dev->flags |= CAM_DEV_RESIZE_QUEUE_NEEDED;
- }
if ((dev->flags & CAM_DEV_TAG_AFTER_COUNT) != 0
|| (dev->inq_flags & SID_CmdQue) != 0)
dev->tag_saved_openings = newopenings;
@@ -4965,12 +4957,12 @@ camisr_runqueue(void *V_queue)
if (ccb_h->flags & CAM_HIGH_POWER) {
struct highpowerlist *hphead;
- union ccb *send_ccb;
+ struct cam_ed *device;
mtx_lock(&xsoftc.xpt_lock);
hphead = &xsoftc.highpowerq;
- send_ccb = (union ccb *)STAILQ_FIRST(hphead);
+ device = STAILQ_FIRST(hphead);
/*
* Increment the count since this command is done.
@@ -4980,12 +4972,12 @@ camisr_runqueue(void *V_queue)
/*
* Any high powered commands queued up?
*/
- if (send_ccb != NULL) {
+ if (device != NULL) {
- STAILQ_REMOVE_HEAD(hphead, xpt_links.stqe);
+ STAILQ_REMOVE_HEAD(hphead, highpowerq_entry);
mtx_unlock(&xsoftc.xpt_lock);
- xpt_release_devq(send_ccb->ccb_h.path,
+ xpt_release_devq_device(device,
/*count*/1, /*runqueue*/TRUE);
} else
mtx_unlock(&xsoftc.xpt_lock);
OpenPOWER on IntegriCloud