Author: mav
Date: Sun Feb 19 05:07:02 2017
New Revision: 313936
URL: https://svnweb.freebsd.org/changeset/base/313936

Log:
  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.
  
  MFC after:    2 weeks

Modified:
  head/sys/dev/isp/isp_freebsd.c
  head/sys/dev/isp/isp_freebsd.h

Modified: head/sys/dev/isp/isp_freebsd.c
==============================================================================
--- head/sys/dev/isp/isp_freebsd.c      Sun Feb 19 05:06:29 2017        
(r313935)
+++ head/sys/dev/isp/isp_freebsd.c      Sun Feb 19 05:07:02 2017        
(r313936)
@@ -153,6 +153,7 @@ isp_attach_chan(ispsoftc_t *isp, struct 
                struct isp_spi *spi = ISP_SPI_PC(isp, chan);
                spi->sim = sim;
                spi->path = path;
+               TAILQ_INIT(&spi->waitq);
        } else {
                fcparam *fcp = FCPARAM(isp, chan);
                struct isp_fc *fc = ISP_FC_PC(isp, chan);
@@ -168,6 +169,7 @@ 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);
+               TAILQ_INIT(&fc->waitq);
                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 +978,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 +1008,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 +1134,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 +1268,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 +1285,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 +1350,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 +1467,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 +1622,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 +1711,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 +1747,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: head/sys/dev/isp/isp_freebsd.h
==============================================================================
--- head/sys/dev/isp/isp_freebsd.h      Sun Feb 19 05:06:29 2017        
(r313935)
+++ head/sys/dev/isp/isp_freebsd.h      Sun Feb 19 05:07:02 2017        
(r313936)
@@ -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;
 };
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to