summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormav <mav@FreeBSD.org>2014-09-14 11:59:49 +0000
committermav <mav@FreeBSD.org>2014-09-14 11:59:49 +0000
commitb2cfbc4e0b52141ee58095a937470e16d117d2eb (patch)
tree3f0b0e7bce731f1cb0ecedd9f972dbaea5aa95dd
parent60440293773e9af3886aaab92d13d54304b91b64 (diff)
downloadFreeBSD-src-b2cfbc4e0b52141ee58095a937470e16d117d2eb.zip
FreeBSD-src-b2cfbc4e0b52141ee58095a937470e16d117d2eb.tar.gz
Update CAM CCB accounting for the new status quo.
devq_openings counter lost its meaning after allocation queues has gone. held counter is still meaningful, but problematic to update due to separate locking of CCB allocation and queuing. To fix that replace devq_openings counter with allocated counter. held is now calculated on request as difference between number of allocated, queued and active CCBs. MFC after: 1 month
-rw-r--r--sbin/camcontrol/camcontrol.c4
-rw-r--r--sys/cam/cam_ccb.h4
-rw-r--r--sys/cam/cam_queue.c2
-rw-r--r--sys/cam/cam_queue.h18
-rw-r--r--sys/cam/cam_xpt.c13
5 files changed, 19 insertions, 22 deletions
diff --git a/sbin/camcontrol/camcontrol.c b/sbin/camcontrol/camcontrol.c
index 12a0e5c..4129cf4 100644
--- a/sbin/camcontrol/camcontrol.c
+++ b/sbin/camcontrol/camcontrol.c
@@ -4469,9 +4469,9 @@ tagcontrol(struct cam_device *device, int argc, char **argv,
fprintf(stdout, "%s", pathstr);
fprintf(stdout, "dev_active %d\n", ccb->cgds.dev_active);
fprintf(stdout, "%s", pathstr);
- fprintf(stdout, "devq_openings %d\n", ccb->cgds.devq_openings);
+ fprintf(stdout, "allocated %d\n", ccb->cgds.allocated);
fprintf(stdout, "%s", pathstr);
- fprintf(stdout, "devq_queued %d\n", ccb->cgds.devq_queued);
+ fprintf(stdout, "queued %d\n", ccb->cgds.queued);
fprintf(stdout, "%s", pathstr);
fprintf(stdout, "held %d\n", ccb->cgds.held);
fprintf(stdout, "%s", pathstr);
diff --git a/sys/cam/cam_ccb.h b/sys/cam/cam_ccb.h
index 87553c6..7ee7d79 100644
--- a/sys/cam/cam_ccb.h
+++ b/sys/cam/cam_ccb.h
@@ -347,8 +347,8 @@ struct ccb_getdevstats {
struct ccb_hdr ccb_h;
int dev_openings; /* Space left for more work on device*/
int dev_active; /* Transactions running on the device */
- int devq_openings; /* Space left for more queued work */
- int devq_queued; /* Transactions queued to be sent */
+ int allocated; /* CCBs allocated for the device */
+ int queued; /* CCBs queued to be sent to the device */
int held; /*
* CCBs held by peripheral drivers
* for this device
diff --git a/sys/cam/cam_queue.c b/sys/cam/cam_queue.c
index f6624f3..b67f687 100644
--- a/sys/cam/cam_queue.c
+++ b/sys/cam/cam_queue.c
@@ -290,7 +290,6 @@ cam_ccbq_resize(struct cam_ccbq *ccbq, int new_size)
delta = new_size - (ccbq->dev_active + ccbq->dev_openings);
ccbq->total_openings += delta;
- ccbq->devq_openings += delta;
ccbq->dev_openings += delta;
new_size = imax(64, 1 << fls(new_size + new_size / 2));
@@ -308,7 +307,6 @@ cam_ccbq_init(struct cam_ccbq *ccbq, int openings)
imax(64, 1 << fls(openings + openings / 2))) != 0)
return (1);
ccbq->total_openings = openings;
- ccbq->devq_openings = openings;
ccbq->dev_openings = openings;
return (0);
}
diff --git a/sys/cam/cam_queue.h b/sys/cam/cam_queue.h
index 0f74e82..33f6b1d 100644
--- a/sys/cam/cam_queue.h
+++ b/sys/cam/cam_queue.h
@@ -62,10 +62,9 @@ struct cam_ccbq {
struct ccb_hdr_tailq queue_extra_head;
int queue_extra_entries;
int total_openings;
- int devq_openings;
+ int allocated;
int dev_openings;
int dev_active;
- int held;
};
struct cam_ed;
@@ -188,8 +187,8 @@ cam_ccbq_pending_ccb_count(struct cam_ccbq *ccbq)
static __inline void
cam_ccbq_take_opening(struct cam_ccbq *ccbq)
{
- ccbq->devq_openings--;
- ccbq->held++;
+
+ ccbq->allocated++;
}
static __inline void
@@ -198,8 +197,6 @@ cam_ccbq_insert_ccb(struct cam_ccbq *ccbq, union ccb *new_ccb)
struct ccb_hdr *old_ccb;
struct camq *queue = &ccbq->queue;
- ccbq->held--;
-
/*
* If queue is already full, try to resize.
* If resize fail, push CCB with lowest priority out to the TAILQ.
@@ -264,7 +261,7 @@ cam_ccbq_send_ccb(struct cam_ccbq *ccbq, union ccb *send_ccb)
send_ccb->ccb_h.pinfo.index = CAM_ACTIVE_INDEX;
ccbq->dev_active++;
- ccbq->dev_openings--;
+ ccbq->dev_openings--;
}
static __inline void
@@ -272,15 +269,14 @@ cam_ccbq_ccb_done(struct cam_ccbq *ccbq, union ccb *done_ccb)
{
ccbq->dev_active--;
- ccbq->dev_openings++;
- ccbq->held++;
+ ccbq->dev_openings++;
}
static __inline void
cam_ccbq_release_opening(struct cam_ccbq *ccbq)
{
- ccbq->held--;
- ccbq->devq_openings++;
+
+ ccbq->allocated--;
}
#endif /* _KERNEL */
diff --git a/sys/cam/cam_xpt.c b/sys/cam/cam_xpt.c
index 4a8f14b..aa2ea65 100644
--- a/sys/cam/cam_xpt.c
+++ b/sys/cam/cam_xpt.c
@@ -2648,20 +2648,25 @@ call_sim:
struct ccb_getdevstats *cgds;
struct cam_eb *bus;
struct cam_et *tar;
+ struct cam_devq *devq;
cgds = &start_ccb->cgds;
bus = path->bus;
tar = path->target;
+ devq = bus->sim->devq;
+ mtx_lock(&devq->send_mtx);
cgds->dev_openings = dev->ccbq.dev_openings;
cgds->dev_active = dev->ccbq.dev_active;
- cgds->devq_openings = dev->ccbq.devq_openings;
- cgds->devq_queued = cam_ccbq_pending_ccb_count(&dev->ccbq);
- cgds->held = dev->ccbq.held;
+ cgds->allocated = dev->ccbq.allocated;
+ cgds->queued = cam_ccbq_pending_ccb_count(&dev->ccbq);
+ cgds->held = cgds->allocated - cgds->dev_active -
+ cgds->queued;
cgds->last_reset = tar->last_reset;
cgds->maxtags = dev->maxtags;
cgds->mintags = dev->mintags;
if (timevalcmp(&tar->last_reset, &bus->last_reset, <))
cgds->last_reset = bus->last_reset;
+ mtx_unlock(&devq->send_mtx);
cgds->ccb_h.status = CAM_REQ_CMP;
}
break;
@@ -3004,7 +3009,6 @@ xpt_polled_action(union ccb *start_ccb)
* can get it before us while we simulate interrupts.
*/
mtx_lock(&devq->send_mtx);
- dev->ccbq.devq_openings--;
dev->ccbq.dev_openings--;
while((devq->send_openings <= 0 || dev->ccbq.dev_openings < 0) &&
(--timeout > 0)) {
@@ -3016,7 +3020,6 @@ xpt_polled_action(union ccb *start_ccb)
camisr_runqueue();
mtx_lock(&devq->send_mtx);
}
- dev->ccbq.devq_openings++;
dev->ccbq.dev_openings++;
mtx_unlock(&devq->send_mtx);
OpenPOWER on IntegriCloud