Author: mav
Date: Sun Nov 22 04:29:55 2020
New Revision: 367926
URL: https://svnweb.freebsd.org/changeset/base/367926

Log:
  Make handlers and atpds overflows unlikely.
  
   - Allocate 256 handlers more than payload commands for management purposes.
   - Increase maximum number of handlers from 8K to 16K by tuning the format.
   - Just to be safe limit the number of payload commands to 16K - 256.
   - Limit number of target exchanges in mixed mode to the number of atpds.
   - If we still somehow get out of atpds -- return BUSY, since we really are.

Modified:
  head/sys/dev/isp/isp.c
  head/sys/dev/isp/isp_freebsd.c
  head/sys/dev/isp/isp_library.c
  head/sys/dev/isp/isp_pci.c
  head/sys/dev/isp/ispvar.h

Modified: head/sys/dev/isp/isp.c
==============================================================================
--- head/sys/dev/isp/isp.c      Sun Nov 22 04:10:13 2020        (r367925)
+++ head/sys/dev/isp/isp.c      Sun Nov 22 04:29:55 2020        (r367926)
@@ -579,6 +579,8 @@ isp_reset(ispsoftc_t *isp, int do_load_defaults)
                return;
        }
        isp->isp_maxcmds = mbs.param[3];
+       /* Limit to the maximum of our hardcoded handle format (16K now). */
+       isp->isp_maxcmds = MIN(isp->isp_maxcmds, ISP_HANDLE_MAX - 
ISP_HANDLE_RESERVE);
        isp_prt(isp, ISP_LOGCONFIG, "%d max I/O command limit set", 
isp->isp_maxcmds);
 
        /*
@@ -744,9 +746,10 @@ isp_init(ispsoftc_t *isp)
         * Set target exchange count. Take half if we are supporting both roles.
         */
        if (icbp->icb_fwoptions1 & ICB2400_OPT1_TGT_ENABLE) {
-               icbp->icb_xchgcnt = isp->isp_maxcmds;
                if ((icbp->icb_fwoptions1 & ICB2400_OPT1_INI_DISABLE) == 0)
-                       icbp->icb_xchgcnt >>= 1;
+                       icbp->icb_xchgcnt = MIN(isp->isp_maxcmds / 2, 
ATPDPSIZE);
+               else
+                       icbp->icb_xchgcnt = isp->isp_maxcmds;
        }
 
 
@@ -3535,7 +3538,7 @@ isp_intr_async(ispsoftc_t *isp, uint16_t mbox)
                         */
                        if (topo == TOPO_NL_PORT || topo == TOPO_FL_PORT) {
                                int i, j;
-                               for (i = j = 0; i < isp->isp_maxcmds; i++) {
+                               for (i = j = 0; i < ISP_HANDLE_NUM(isp); i++) {
                                        XS_T *xs;
                                        isp_hdl_t *hdp;
 

Modified: head/sys/dev/isp/isp_freebsd.c
==============================================================================
--- head/sys/dev/isp/isp_freebsd.c      Sun Nov 22 04:10:13 2020        
(r367925)
+++ head/sys/dev/isp/isp_freebsd.c      Sun Nov 22 04:29:55 2020        
(r367926)
@@ -1408,7 +1408,9 @@ isp_handle_platform_atio7(ispsoftc_t *isp, at7_entry_t
 
        oatp = isp_find_atpd(isp, chan, aep->at_rxid);
        if (oatp) {
-               isp_prt(isp, ISP_LOGTDEBUG0, "[0x%x] tag wraparound in 
isp_handle_platforms_atio7 (N-Port Handle 0x%04x S_ID 0x%04x OX_ID 0x%04x) oatp 
state %d",
+               isp_prt(isp, oatp->state == ATPD_STATE_LAST_CTIO ? 
ISP_LOGTDEBUG0 :
+                   ISP_LOGWARN, "[0x%x] tag wraparound (N-Port Handle "
+                   "0x%04x S_ID 0x%04x OX_ID 0x%04x) oatp state %d",
                    aep->at_rxid, nphdl, sid, aep->at_hdr.ox_id, oatp->state);
                /*
                 * It's not a "no resource" condition- but we can treat it like 
one
@@ -1418,7 +1420,8 @@ isp_handle_platform_atio7(ispsoftc_t *isp, at7_entry_t
        atp = isp_get_atpd(isp, chan, aep->at_rxid);
        if (atp == NULL) {
                isp_prt(isp, ISP_LOGTDEBUG0, "[0x%x] out of atps", 
aep->at_rxid);
-               goto noresrc;
+               isp_endcmd(isp, aep, nphdl, chan, SCSI_BUSY, 0);
+               return;
        }
        atp->word3 = lp->prli_word3;
        atp->state = ATPD_STATE_ATIO;
@@ -1477,8 +1480,7 @@ isp_handle_platform_atio7(ispsoftc_t *isp, at7_entry_t
        xpt_done((union ccb *)atiop);
        return;
 noresrc:
-       if (atp)
-               isp_put_atpd(isp, chan, atp);
+       KASSERT(atp == NULL, ("%s: atp is not NULL on noresrc!\n"));
        ntp = isp_get_ntpd(isp, chan);
        if (ntp == NULL) {
                isp_endcmd(isp, aep, nphdl, chan, SCSI_STATUS_BUSY, 0);
@@ -2207,7 +2209,7 @@ isp_loop_dead(ispsoftc_t *isp, int chan)
                if (lp->state == FC_PORTDB_STATE_NIL)
                        continue;
 
-               for (i = 0; i < isp->isp_maxcmds; i++) {
+               for (i = 0; i < ISP_HANDLE_NUM(isp); i++) {
                        struct ccb_scsiio *xs;
 
                        if (ISP_H2HT(isp->isp_xflist[i].handle) != 
ISP_HANDLE_INITIATOR) {

Modified: head/sys/dev/isp/isp_library.c
==============================================================================
--- head/sys/dev/isp/isp_library.c      Sun Nov 22 04:10:13 2020        
(r367925)
+++ head/sys/dev/isp/isp_library.c      Sun Nov 22 04:29:55 2020        
(r367926)
@@ -195,7 +195,7 @@ isp_find_handle(ispsoftc_t *isp, void *xs)
        uint32_t i, foundhdl = ISP_HANDLE_FREE;
 
        if (xs != NULL) {
-               for (i = 0; i < isp->isp_maxcmds; i++) {
+               for (i = 0; i < ISP_HANDLE_NUM(isp); i++) {
                        if (isp->isp_xflist[i].cmd != xs) {
                                continue;
                        }
@@ -486,7 +486,7 @@ isp_clear_commands(ispsoftc_t *isp)
        isp_notify_t notify;
 #endif
 
-       for (tmp = 0; isp->isp_xflist && tmp < isp->isp_maxcmds; tmp++) {
+       for (tmp = 0; isp->isp_xflist && tmp < ISP_HANDLE_NUM(isp); tmp++) {
 
                hdp = &isp->isp_xflist[tmp];
                switch (ISP_H2HT(hdp->handle)) {

Modified: head/sys/dev/isp/isp_pci.c
==============================================================================
--- head/sys/dev/isp/isp_pci.c  Sun Nov 22 04:10:13 2020        (r367925)
+++ head/sys/dev/isp/isp_pci.c  Sun Nov 22 04:29:55 2020        (r367926)
@@ -1112,9 +1112,9 @@ gotmaxcmds:
        }
        isp->isp_osinfo.pcmd_free = &isp->isp_osinfo.pcmd_pool[0];
 
-       len = sizeof (isp_hdl_t) * isp->isp_maxcmds;
+       len = sizeof(isp_hdl_t) * ISP_HANDLE_NUM(isp);
        isp->isp_xflist = (isp_hdl_t *) malloc(len, M_DEVBUF, M_WAITOK | 
M_ZERO);
-       for (len = 0; len < isp->isp_maxcmds - 1; len++)
+       for (len = 0; len < ISP_HANDLE_NUM(isp) - 1; len++)
                isp->isp_xflist[len].cmd = &isp->isp_xflist[len+1];
        isp->isp_xffree = isp->isp_xflist;
 

Modified: head/sys/dev/isp/ispvar.h
==============================================================================
--- head/sys/dev/isp/ispvar.h   Sun Nov 22 04:10:13 2020        (r367925)
+++ head/sys/dev/isp/ispvar.h   Sun Nov 22 04:29:55 2020        (r367926)
@@ -221,9 +221,9 @@ typedef struct {
        uint32_t        handle; /* handle associated with this command */
 } isp_hdl_t;
 #define        ISP_HANDLE_FREE         0x00000000
-#define        ISP_HANDLE_CMD_MASK     0x00001fff
-#define        ISP_HANDLE_USAGE_MASK   0x0000e000
-#define        ISP_HANDLE_USAGE_SHIFT  13
+#define        ISP_HANDLE_CMD_MASK     0x00003fff
+#define        ISP_HANDLE_USAGE_MASK   0x0000c000
+#define        ISP_HANDLE_USAGE_SHIFT  14
 #define        ISP_H2HT(hdl)   ((hdl & ISP_HANDLE_USAGE_MASK) >> 
ISP_HANDLE_USAGE_SHIFT)
 #      define  ISP_HANDLE_NONE         0
 #      define  ISP_HANDLE_INITIATOR    1
@@ -232,13 +232,15 @@ typedef struct {
 #define        ISP_HANDLE_SEQ_MASK     0xffff0000
 #define        ISP_HANDLE_SEQ_SHIFT    16
 #define        ISP_H2SEQ(hdl)  ((hdl & ISP_HANDLE_SEQ_MASK) >> 
ISP_HANDLE_SEQ_SHIFT)
-#define        ISP_VALID_HANDLE(c, hdl)        \
+#define        ISP_HANDLE_MAX          (ISP_HANDLE_CMD_MASK + 1)
+#define        ISP_HANDLE_RESERVE      256
+#define        ISP_HANDLE_NUM(isp)     ((isp)->isp_maxcmds + 
ISP_HANDLE_RESERVE)
+#define        ISP_VALID_HANDLE(isp, hdl)      \
        ((ISP_H2HT(hdl) == ISP_HANDLE_INITIATOR || \
          ISP_H2HT(hdl) == ISP_HANDLE_TARGET || \
          ISP_H2HT(hdl) == ISP_HANDLE_CTRL) && \
-        ((hdl) & ISP_HANDLE_CMD_MASK) < (c)->isp_maxcmds && \
-        (hdl) == ((c)->isp_xflist[(hdl) & ISP_HANDLE_CMD_MASK].handle))
-#define        ISP_BAD_HANDLE_INDEX    0xffffffff
+        ((hdl) & ISP_HANDLE_CMD_MASK) < ISP_HANDLE_NUM(isp) && \
+        (hdl) == ((isp)->isp_xflist[(hdl) & ISP_HANDLE_CMD_MASK].handle))
 
 
 /*
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to