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.
This commit is contained in:
parent
e63daed1b8
commit
b8e2395ec5
@ -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, isphdr_t *hp, uint32_t *opt
|
||||
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:
|
||||
|
@ -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: \
|
||||
|
@ -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)) {
|
||||
|
@ -109,7 +109,7 @@ static void isp_handle_notify_24xx(ispsoftc_t *, in_fcentry_24xx_t *);
|
||||
*/
|
||||
|
||||
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_t *optrp)
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user