summaryrefslogtreecommitdiffstats
path: root/sys/cam/cam_queue.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/cam/cam_queue.c')
-rw-r--r--sys/cam/cam_queue.c31
1 files changed, 8 insertions, 23 deletions
diff --git a/sys/cam/cam_queue.c b/sys/cam/cam_queue.c
index 41d0167..daaa9b3 100644
--- a/sys/cam/cam_queue.c
+++ b/sys/cam/cam_queue.c
@@ -284,39 +284,24 @@ u_int32_t
cam_ccbq_resize(struct cam_ccbq *ccbq, int new_size)
{
int delta;
- int space_left;
delta = new_size - (ccbq->dev_active + ccbq->dev_openings);
- space_left = new_size
- - ccbq->queue.entries
- - ccbq->held
- - ccbq->dev_active;
+ ccbq->devq_openings += delta;
+ ccbq->dev_openings += delta;
- /*
- * Only attempt to change the underlying queue size if we are
- * shrinking it and there is space for all outstanding entries
- * in the new array or we have been requested to grow the array.
- * We don't fail in the case where we can't reduce the array size,
- * but clients that care that the queue be "garbage collected"
- * should detect this condition and call us again with the
- * same size once the outstanding entries have been processed.
- */
- if (space_left < 0
- || camq_resize(&ccbq->queue, new_size + (CAM_RL_VALUES - 1)) ==
- CAM_REQ_CMP) {
- ccbq->devq_openings += delta;
- ccbq->dev_openings += delta;
+ new_size = imax(64, 1 << fls(new_size + new_size / 2));
+ if (new_size > ccbq->queue.array_size)
+ return (camq_resize(&ccbq->queue, new_size));
+ else
return (CAM_REQ_CMP);
- } else {
- return (CAM_RESRC_UNAVAIL);
- }
}
int
cam_ccbq_init(struct cam_ccbq *ccbq, int openings)
{
bzero(ccbq, sizeof(*ccbq));
- if (camq_init(&ccbq->queue, openings + (CAM_RL_VALUES - 1)) != 0)
+ if (camq_init(&ccbq->queue,
+ imax(64, 1 << fls(openings + openings / 2))) != 0)
return (1);
ccbq->devq_openings = openings;
ccbq->dev_openings = openings;
OpenPOWER on IntegriCloud