svn commit: r314698 - stable/10/sys/dev/isp
Alexander Motin
mav at FreeBSD.org
Sun Mar 5 05:17:37 UTC 2017
Author: mav
Date: Sun Mar 5 05:17:36 2017
New Revision: 314698
URL: https://svnweb.freebsd.org/changeset/base/314698
Log:
MFC r313936, r313937: Move CTIO waitq from per-LUN to per-channel.
All resources lack of which may put CTIO into the queue are either
per-channel or potentially per-queue, but none of them are per-LUN.
This is a first step to fix live LUN disabling. Before this change
any CTIOs held in a queue in time of disabling were just leaked.
Modified:
stable/10/sys/dev/isp/isp_freebsd.c
stable/10/sys/dev/isp/isp_freebsd.h
Directory Properties:
stable/10/ (props changed)
Modified: stable/10/sys/dev/isp/isp_freebsd.c
==============================================================================
--- stable/10/sys/dev/isp/isp_freebsd.c Sun Mar 5 05:17:02 2017 (r314697)
+++ stable/10/sys/dev/isp/isp_freebsd.c Sun Mar 5 05:17:36 2017 (r314698)
@@ -153,6 +153,9 @@ isp_attach_chan(ispsoftc_t *isp, struct
struct isp_spi *spi = ISP_SPI_PC(isp, chan);
spi->sim = sim;
spi->path = path;
+#ifdef ISP_TARGET_MODE
+ TAILQ_INIT(&spi->waitq);
+#endif
} else {
fcparam *fcp = FCPARAM(isp, chan);
struct isp_fc *fc = ISP_FC_PC(isp, chan);
@@ -168,6 +171,9 @@ isp_attach_chan(ispsoftc_t *isp, struct
callout_init_mtx(&fc->gdt, &isp->isp_osinfo.lock, 0);
TASK_INIT(&fc->gtask, 1, isp_gdt_task, fc);
+#ifdef ISP_TARGET_MODE
+ TAILQ_INIT(&fc->waitq);
+#endif
isp_loop_changed(isp, chan);
ISP_UNLOCK(isp);
if (THREAD_CREATE(isp_kthread, fc, &fc->kproc, 0, 0, "%s: fc_thrd%d", device_get_nameunit(isp->isp_osinfo.dev), chan)) {
@@ -976,6 +982,7 @@ isp_tmcmd_restart(ispsoftc_t *isp)
tstate_t *tptr;
union ccb *ccb;
struct tslist *lhp;
+ struct isp_ccbq *waitq;
int bus, i;
for (bus = 0; bus < isp->isp_nchan; bus++) {
@@ -1005,16 +1012,18 @@ isp_tmcmd_restart(ispsoftc_t *isp)
break;
}
}
- /*
- * We only need to do this once per tptr
- */
- if (!TAILQ_EMPTY(&tptr->waitq)) {
- ccb = (union ccb *)TAILQ_LAST(&tptr->waitq, isp_ccbq);
- TAILQ_REMOVE(&tptr->waitq, &ccb->ccb_h, periph_links.tqe);
- isp_target_start_ctio(isp, ccb, FROM_TIMER);
- }
}
}
+
+ /*
+ * We only need to do this once per channel.
+ */
+ ISP_GET_PC_ADDR(isp, bus, waitq, waitq);
+ ccb = (union ccb *)TAILQ_FIRST(waitq);
+ if (ccb != NULL) {
+ TAILQ_REMOVE(waitq, &ccb->ccb_h, periph_links.tqe);
+ isp_target_start_ctio(isp, ccb, FROM_TIMER);
+ }
}
}
@@ -1129,7 +1138,6 @@ create_lun_state(ispsoftc_t *isp, int bu
}
SLIST_INIT(&tptr->atios);
SLIST_INIT(&tptr->inots);
- TAILQ_INIT(&tptr->waitq);
LIST_INIT(&tptr->atfree);
for (i = ATPDPSIZE-1; i >= 0; i--)
LIST_INSERT_HEAD(&tptr->atfree, &tptr->atpool[i], next);
@@ -1264,6 +1272,7 @@ isp_target_start_ctio(ispsoftc_t *isp, u
fcparam *fcp;
atio_private_data_t *atp;
struct ccb_scsiio *cso;
+ struct isp_ccbq *waitq;
uint32_t dmaresult, handle, xfrlen, sense_length, tmp;
uint8_t local[QENTRY_LEN];
@@ -1280,23 +1289,23 @@ isp_target_start_ctio(ispsoftc_t *isp, u
isp_prt(isp, ISP_LOGTDEBUG0, "%s: ENTRY[0x%x] how %u xfrlen %u sendstatus %d sense_len %u", __func__, ccb->csio.tag_id, how, ccb->csio.dxfer_len,
(ccb->ccb_h.flags & CAM_SEND_STATUS) != 0, ((ccb->ccb_h.flags & CAM_SEND_SENSE)? ccb->csio.sense_len : 0));
+ ISP_GET_PC_ADDR(isp, XS_CHANNEL(ccb), waitq, waitq);
switch (how) {
- case FROM_TIMER:
case FROM_CAM:
/*
* Insert at the tail of the list, if any, waiting CTIO CCBs
*/
- TAILQ_INSERT_TAIL(&tptr->waitq, &ccb->ccb_h, periph_links.tqe);
+ TAILQ_INSERT_TAIL(waitq, &ccb->ccb_h, periph_links.tqe);
break;
+ case FROM_TIMER:
case FROM_SRR:
case FROM_CTIO_DONE:
- TAILQ_INSERT_HEAD(&tptr->waitq, &ccb->ccb_h, periph_links.tqe);
+ TAILQ_INSERT_HEAD(waitq, &ccb->ccb_h, periph_links.tqe);
break;
}
- while (TAILQ_FIRST(&tptr->waitq) != NULL) {
- ccb = (union ccb *) TAILQ_FIRST(&tptr->waitq);
- TAILQ_REMOVE(&tptr->waitq, &ccb->ccb_h, periph_links.tqe);
+ while ((ccb = (union ccb *) TAILQ_FIRST(waitq)) != NULL) {
+ TAILQ_REMOVE(waitq, &ccb->ccb_h, periph_links.tqe);
cso = &ccb->csio;
xfrlen = cso->dxfer_len;
@@ -1345,7 +1354,7 @@ isp_target_start_ctio(ispsoftc_t *isp, u
*/
if (atp->ctcnt >= ATPD_CCB_OUTSTANDING) {
isp_prt(isp, ISP_LOGTINFO, "[0x%x] handling only %d CCBs at a time (flags for this ccb: 0x%x)", cso->tag_id, ATPD_CCB_OUTSTANDING, ccb->ccb_h.flags);
- TAILQ_INSERT_HEAD(&tptr->waitq, &ccb->ccb_h, periph_links.tqe);
+ TAILQ_INSERT_HEAD(waitq, &ccb->ccb_h, periph_links.tqe);
break;
}
@@ -1462,7 +1471,7 @@ isp_target_start_ctio(ispsoftc_t *isp, u
if (atp->ests == NULL) {
atp->ests = isp_get_ecmd(isp);
if (atp->ests == NULL) {
- TAILQ_INSERT_HEAD(&tptr->waitq, &ccb->ccb_h, periph_links.tqe);
+ TAILQ_INSERT_HEAD(waitq, &ccb->ccb_h, periph_links.tqe);
break;
}
}
@@ -1617,7 +1626,7 @@ isp_target_start_ctio(ispsoftc_t *isp, u
if (atp->ests == NULL) {
atp->ests = isp_get_ecmd(isp);
if (atp->ests == NULL) {
- TAILQ_INSERT_HEAD(&tptr->waitq, &ccb->ccb_h, periph_links.tqe);
+ TAILQ_INSERT_HEAD(waitq, &ccb->ccb_h, periph_links.tqe);
break;
}
}
@@ -1706,13 +1715,13 @@ isp_target_start_ctio(ispsoftc_t *isp, u
if (isp_get_pcmd(isp, ccb)) {
ISP_PATH_PRT(isp, ISP_LOGWARN, ccb->ccb_h.path, "out of PCMDs\n");
- TAILQ_INSERT_HEAD(&tptr->waitq, &ccb->ccb_h, periph_links.tqe);
+ TAILQ_INSERT_HEAD(waitq, &ccb->ccb_h, periph_links.tqe);
break;
}
handle = isp_allocate_handle(isp, ccb, ISP_HANDLE_TARGET);
if (handle == 0) {
ISP_PATH_PRT(isp, ISP_LOGWARN, ccb->ccb_h.path, "No XFLIST pointers for %s\n", __func__);
- TAILQ_INSERT_HEAD(&tptr->waitq, &ccb->ccb_h, periph_links.tqe);
+ TAILQ_INSERT_HEAD(waitq, &ccb->ccb_h, periph_links.tqe);
isp_free_pcmd(isp, ccb);
break;
}
@@ -1742,7 +1751,7 @@ isp_target_start_ctio(ispsoftc_t *isp, u
isp_destroy_handle(isp, handle);
isp_free_pcmd(isp, ccb);
if (dmaresult == CMD_EAGAIN) {
- TAILQ_INSERT_HEAD(&tptr->waitq, &ccb->ccb_h, periph_links.tqe);
+ TAILQ_INSERT_HEAD(waitq, &ccb->ccb_h, periph_links.tqe);
break;
}
ccb->ccb_h.status = CAM_REQ_CMP_ERR;
Modified: stable/10/sys/dev/isp/isp_freebsd.h
==============================================================================
--- stable/10/sys/dev/isp/isp_freebsd.h Sun Mar 5 05:17:02 2017 (r314697)
+++ stable/10/sys/dev/isp/isp_freebsd.h Sun Mar 5 05:17:36 2017 (r314698)
@@ -163,12 +163,10 @@ typedef struct isp_timed_notify_ack {
struct callout timer;
} isp_tna_t;
-TAILQ_HEAD(isp_ccbq, ccb_hdr);
typedef struct tstate {
SLIST_ENTRY(tstate) next;
lun_id_t ts_lun;
struct cam_path *owner;
- struct isp_ccbq waitq; /* waiting CCBs */
struct ccb_hdr_slist atios;
struct ccb_hdr_slist inots;
uint32_t hold;
@@ -220,6 +218,7 @@ struct isp_nexus {
* Per channel information
*/
SLIST_HEAD(tslist, tstate);
+TAILQ_HEAD(isp_ccbq, ccb_hdr);
struct isp_fc {
struct cam_sim *sim;
@@ -249,7 +248,8 @@ struct isp_fc {
struct callout gdt; /* gone device timer */
struct task gtask;
#ifdef ISP_TARGET_MODE
- struct tslist lun_hash[LUN_HASH_SIZE];
+ struct tslist lun_hash[LUN_HASH_SIZE];
+ struct isp_ccbq waitq; /* waiting CCBs */
#if defined(DEBUG)
unsigned int inject_lost_data_frame;
#endif
@@ -264,7 +264,8 @@ struct isp_spi {
simqfrozen : 3,
iid : 4;
#ifdef ISP_TARGET_MODE
- struct tslist lun_hash[LUN_HASH_SIZE];
+ struct tslist lun_hash[LUN_HASH_SIZE];
+ struct isp_ccbq waitq; /* waiting CCBs */
#endif
int num_threads;
};
More information about the svn-src-stable
mailing list