Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 20 Nov 2020 19:36:34 +0000 (UTC)
From:      Alexander Motin <mav@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r367909 - head/sys/dev/isp
Message-ID:  <202011201936.0AKJaYOD090768@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mav
Date: Fri Nov 20 19:36:34 2020
New Revision: 367909
URL: https://svnweb.freebsd.org/changeset/base/367909

Log:
  Increase queue depths from 1024/256 to 8192/1024 IOCBs.
  
  Qlogic chips store S/G lists in the same queue as requests themselves.  In
  the worst case 1MB I/O may require up to 52 IOCBs, that means queue of 1024
  IOCBs can store only 19 of such requests.  The increase reduces chances of
  overflow, while we should be able to afford additional 512KB of RAM per HBA.
  The Linux driver uses comparable numbers.
  
  While there, decouple ATIO queue size from response queue size.  There is
  no reason for them to be equal.

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

Modified: head/sys/dev/isp/isp.c
==============================================================================
--- head/sys/dev/isp/isp.c	Fri Nov 20 18:52:37 2020	(r367908)
+++ head/sys/dev/isp/isp.c	Fri Nov 20 19:36:34 2020	(r367909)
@@ -98,7 +98,7 @@ static const uint8_t alpa_map[] = {
 /*
  * Local function prototypes.
  */
-static int isp_handle_other_response(ispsoftc_t *, int, isphdr_t *, uint32_t *);
+static int isp_handle_other_response(ispsoftc_t *, int, isphdr_t *, uint32_t *, uint16_t);
 static void isp_parse_status_24xx(ispsoftc_t *, isp24xx_statusreq_t *, XS_T *, uint32_t *);
 static void isp_clear_portdb(ispsoftc_t *, int);
 static void isp_mark_portdb(ispsoftc_t *, int);
@@ -912,7 +912,7 @@ isp_init(ispsoftc_t *isp)
 
 #ifdef	ISP_TARGET_MODE
 	/* unconditionally set up the ATIO queue if we support target mode */
-	icbp->icb_atioqlen = RESULT_QUEUE_LEN(isp);
+	icbp->icb_atioqlen = ATIO_QUEUE_LEN(isp);
 	if (icbp->icb_atioqlen < 8) {
 		isp_prt(isp, ISP_LOGERR, "bad ATIO queue length %d", icbp->icb_atioqlen);
 		return;
@@ -3179,14 +3179,15 @@ isp_intr_atioq(ispsoftc_t *isp)
 		case RQSTYPE_ATIO:
 		case RQSTYPE_NOTIFY_ACK:	/* Can be set to ATIO queue.*/
 		case RQSTYPE_ABTS_RCVD:		/* Can be set to ATIO queue.*/
-			(void) isp_target_notify(isp, addr, &oop);
+			(void) isp_target_notify(isp, addr, &oop,
+			    ATIO_QUEUE_LEN(isp));
 			break;
 		case RQSTYPE_RPT_ID_ACQ:	/* Can be set to ATIO queue.*/
 		default:
 			isp_print_qentry(isp, "?ATIOQ entry?", oop, addr);
 			break;
 		}
-		optr = ISP_NXT_QENTRY(oop, RESULT_QUEUE_LEN(isp));
+		optr = ISP_NXT_QENTRY(oop, ATIO_QUEUE_LEN(isp));
 	}
 	if (isp->isp_atioodx != optr) {
 		ISP_WRITE(isp, BIU2400_ATIO_RSPOUTP, optr);
@@ -3287,7 +3288,8 @@ isp_intr_respq(ispsoftc_t *isp)
 			}
 			ISP_MEMZERO(hp, QENTRY_LEN);	/* PERF */
 			continue;
-		} else if (isp_handle_other_response(isp, etype, hp, &cptr)) {
+		} else if (isp_handle_other_response(isp, etype, hp,
+		    &cptr, RESULT_QUEUE_LEN(isp))) {
 			/* More then one IOCB could be consumed. */
 			while (sptr != cptr) {
 				ISP_MEMZERO(hp, QENTRY_LEN);	/* PERF */
@@ -3729,7 +3731,7 @@ isp_intr_async(ispsoftc_t *isp, uint16_t mbox)
  */
 
 static int
-isp_handle_other_response(ispsoftc_t *isp, int type, isphdr_t *hp, uint32_t *optrp)
+isp_handle_other_response(ispsoftc_t *isp, int type, isphdr_t *hp, uint32_t *optrp, uint16_t ql)
 {
 	isp_ridacq_t rid;
 	int chan, c;
@@ -3794,7 +3796,7 @@ isp_handle_other_response(ispsoftc_t *isp, int type, i
 	case RQSTYPE_ABTS_RCVD:		/* Can be set to ATIO queue. */
 	case RQSTYPE_ABTS_RSP:
 #ifdef	ISP_TARGET_MODE
-		return (isp_target_notify(isp, hp, optrp));
+		return (isp_target_notify(isp, hp, optrp, ql));
 #endif
 		/* FALLTHROUGH */
 	default:

Modified: head/sys/dev/isp/isp_freebsd.h
==============================================================================
--- head/sys/dev/isp/isp_freebsd.h	Fri Nov 20 18:52:37 2020	(r367908)
+++ head/sys/dev/isp/isp_freebsd.h	Fri Nov 20 19:36:34 2020	(r367909)
@@ -349,8 +349,6 @@ struct isposinfo {
 #define	GET_NANOSEC(x)		((x)->tv_sec * 1000000000 + (x)->tv_nsec)
 #define	NANOTIME_SUB		isp_nanotime_sub
 
-#define	MAXISPREQUEST(isp)	1024
-
 #define	MEMORYBARRIER(isp, type, offset, size, chan)		\
 switch (type) {							\
 case SYNC_REQUEST:						\

Modified: head/sys/dev/isp/isp_pci.c
==============================================================================
--- head/sys/dev/isp/isp_pci.c	Fri Nov 20 18:52:37 2020	(r367908)
+++ head/sys/dev/isp/isp_pci.c	Fri Nov 20 19:36:34 2020	(r367909)
@@ -1009,9 +1009,9 @@ isp_pci_mbxdma(ispsoftc_t *isp)
 
 #ifdef	ISP_TARGET_MODE
 	/*
-	 * Allocate and map ATIO queue on 24xx with target mode.
+	 * Allocate and map ATIO queue.
 	 */
-	len = ISP_QUEUE_SIZE(RESULT_QUEUE_LEN(isp));
+	len = ISP_QUEUE_SIZE(ATIO_QUEUE_LEN(isp));
 	if (bus_dma_tag_create(isp->isp_osinfo.dmat, QENTRY_LEN, slim,
 	    BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL,
 	    len, 1, len, 0, NULL, NULL, &isp->isp_osinfo.atiodmat)) {

Modified: head/sys/dev/isp/isp_target.c
==============================================================================
--- head/sys/dev/isp/isp_target.c	Fri Nov 20 18:52:37 2020	(r367908)
+++ head/sys/dev/isp/isp_target.c	Fri Nov 20 19:36:34 2020	(r367909)
@@ -109,7 +109,7 @@ static void isp_handle_notify_24xx(ispsoftc_t *, in_fc
  */
 
 int
-isp_target_notify(ispsoftc_t *isp, void *vptr, uint32_t *optrp)
+isp_target_notify(ispsoftc_t *isp, void *vptr, uint32_t *optrp, uint16_t ql)
 {
 	union {
 		at7_entry_t	*at7iop;
@@ -149,7 +149,7 @@ isp_target_notify(ispsoftc_t *isp, void *vptr, uint32_
 			len -= (QENTRY_LEN - 8);
 			isp_prt(isp, ISP_LOGINFO, "long IU length (%d) ignored", len);
 			while (len > 0) {
-				*optrp =  ISP_NXT_QENTRY(*optrp, RESULT_QUEUE_LEN(isp));
+				*optrp = ISP_NXT_QENTRY(*optrp, ql);
 				len -= QENTRY_LEN;
 			}
 		}

Modified: head/sys/dev/isp/ispvar.h
==============================================================================
--- head/sys/dev/isp/ispvar.h	Fri Nov 20 18:52:37 2020	(r367908)
+++ head/sys/dev/isp/ispvar.h	Fri Nov 20 19:36:34 2020	(r367909)
@@ -128,20 +128,15 @@ struct ispmdvec {
 
 /*
  * Request/Response Queue defines and macros.
- * The maximum is defined per platform (and can be based on board type).
  */
 /* This is the size of a queue entry (request and response) */
 #define	QENTRY_LEN			64
-/* Both request and result queue length must be a power of two */
-#define	RQUEST_QUEUE_LEN(x)		MAXISPREQUEST(x)
-#ifdef	ISP_TARGET_MODE
-#define	RESULT_QUEUE_LEN(x)		MAXISPREQUEST(x)
-#else
-#define	RESULT_QUEUE_LEN(x)		\
-	(((MAXISPREQUEST(x) >> 2) < 64)? 64 : MAXISPREQUEST(x) >> 2)
-#endif
-#define	ISP_QUEUE_ENTRY(q, idx)		(((uint8_t *)q) + ((idx) * QENTRY_LEN))
-#define	ISP_QUEUE_SIZE(n)		((n) * QENTRY_LEN)
+/* Queue lengths must be a power of two and at least 8 elements. */
+#define	RQUEST_QUEUE_LEN(x)		8192
+#define	RESULT_QUEUE_LEN(x)		1024
+#define	ATIO_QUEUE_LEN(x)		1024
+#define	ISP_QUEUE_ENTRY(q, idx)		(((uint8_t *)q) + ((size_t)(idx) * QENTRY_LEN))
+#define	ISP_QUEUE_SIZE(n)		((size_t)(n) * QENTRY_LEN)
 #define	ISP_NXT_QENTRY(idx, qlen)	(((idx) + 1) & ((qlen)-1))
 #define	ISP_QFREE(in, out, qlen)	\
 	((in == out)? (qlen - 1) : ((in > out)? \
@@ -944,7 +939,7 @@ void isp_async(ispsoftc_t *, ispasync_t, ...);
 /*
  * This function handles new response queue entry appropriate for target mode.
  */
-int isp_target_notify(ispsoftc_t *, void *, uint32_t *);
+int isp_target_notify(ispsoftc_t *, void *, uint32_t *, uint16_t);
 
 /*
  * This function externalizes the ability to acknowledge an Immediate Notify request.



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202011201936.0AKJaYOD090768>