isp: Fix abort issue introduced by previous commit
Aborting ATIO while its CTIOs are in progress makes impossible to handle their completions, making them stuck forever. Detect this case by checking ctcnt counter and if so instead of aborting just mark the ATIO as dead to block any new CTIOs. It is not perfect since the task id can not be reused for some more time, but not as bad as the task stuck forever. MFC after: 1 week
This commit is contained in:
@@ -149,6 +149,8 @@
|
||||
..
|
||||
io
|
||||
..
|
||||
ixnvdimm
|
||||
..
|
||||
mfi
|
||||
..
|
||||
mlx5
|
||||
|
||||
+1
-1
@@ -50,7 +50,7 @@ LDIRS= geom net net80211 netgraph netinet netinet6 \
|
||||
|
||||
LSUBDIRS= dev/acpica dev/agp dev/ciss dev/filemon dev/firewire \
|
||||
dev/hwpmc dev/hyperv \
|
||||
dev/ic dev/iicbus dev/io dev/mfi dev/mmc \
|
||||
dev/ic dev/iicbus dev/io dev/ixnvdimm dev/mfi dev/mmc \
|
||||
dev/ofw dev/pbio dev/pci ${_dev_powermac_nvram} dev/ppbus dev/pwm \
|
||||
dev/smbus dev/speaker dev/tcp_log dev/veriexec dev/vkbd dev/wg \
|
||||
fs/devfs fs/fdescfs fs/msdosfs fs/nfs fs/nullfs \
|
||||
|
||||
@@ -235,6 +235,8 @@ dev/ixl/i40e_adminq.c optional ixl pci \
|
||||
compile-with "${NORMAL_C} -I$S/dev/ixl"
|
||||
dev/ixl/i40e_dcb.c optional ixl pci \
|
||||
compile-with "${NORMAL_C} -I$S/dev/ixl"
|
||||
dev/ixnvdimm/ixnvdimm.c optional ixnvdimm
|
||||
dev/ixnvdimm/ixnvdimm_copy.S optional ixnvdimm
|
||||
dev/ncthwm/ncthwm.c optional ncthwm superio
|
||||
dev/qlxge/qls_dbg.c optional qlxge pci
|
||||
dev/qlxge/qls_dump.c optional qlxge pci
|
||||
|
||||
@@ -986,6 +986,16 @@ isp_target_start_ctio(ispsoftc_t *isp, union ccb *ccb, enum Start_Ctio_How how)
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Is this command a dead duck?
|
||||
*/
|
||||
if (atp->dead) {
|
||||
isp_prt(isp, ISP_LOGERR, "%s: [0x%x] not sending a CTIO for a dead command", __func__, cso->tag_id);
|
||||
ccb->ccb_h.status = CAM_REQ_ABORTED;
|
||||
xpt_done(ccb);
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check to make sure we're still in target mode.
|
||||
*/
|
||||
@@ -2503,14 +2513,19 @@ isp_action(struct cam_sim *sim, union ccb *ccb)
|
||||
}
|
||||
|
||||
/*
|
||||
* Target should abort all affected CCBs before ACK-ing INOT,
|
||||
* Target should abort all affected tasks before ACK-ing INOT,
|
||||
* but if/since it doesn't, add this hack to allow tag reuse.
|
||||
* We can not do it if some CTIOs are in progress, or we won't
|
||||
* handle the completions. In such case just block new ones.
|
||||
*/
|
||||
uint32_t rsp = (ccb->ccb_h.flags & CAM_SEND_STATUS) ? ccb->cna2.arg : 0;
|
||||
if (ntp->nt.nt_ncode == NT_ABORT_TASK && (rsp & 0xff) == 0 &&
|
||||
(atp = isp_find_atpd(isp, XS_CHANNEL(ccb), ccb->cna2.seq_id)) != NULL) {
|
||||
if (isp_abort_atpd(isp, XS_CHANNEL(ccb), atp) == 0)
|
||||
if (atp->ctcnt == 0 &&
|
||||
isp_abort_atpd(isp, XS_CHANNEL(ccb), atp) == 0)
|
||||
isp_put_atpd(isp, XS_CHANNEL(ccb), atp);
|
||||
else
|
||||
atp->dead = 1;
|
||||
}
|
||||
|
||||
if (isp_handle_platform_target_notify_ack(isp, &ntp->nt, rsp)) {
|
||||
|
||||
@@ -104,8 +104,9 @@ typedef struct atio_private_data {
|
||||
uint16_t ctcnt; /* number of CTIOs currently active */
|
||||
uint8_t seqno; /* CTIO sequence number */
|
||||
uint8_t cdb0;
|
||||
uint8_t srr_notify_rcvd : 1,
|
||||
uint16_t srr_notify_rcvd : 1,
|
||||
sendst : 1,
|
||||
dead : 1,
|
||||
tattr : 3,
|
||||
state : 3;
|
||||
void * ests;
|
||||
|
||||
@@ -203,6 +203,7 @@ SUBDIR= \
|
||||
${_ix} \
|
||||
${_ixv} \
|
||||
${_ixl} \
|
||||
${_ixnvdimm} \
|
||||
jme \
|
||||
kbdmux \
|
||||
kgssapi \
|
||||
@@ -834,6 +835,7 @@ _enic= enic
|
||||
_iavf= iavf
|
||||
_ioat= ioat
|
||||
_ixl= ixl
|
||||
_ixnvdimm= ixnvdimm
|
||||
_nvdimm= nvdimm
|
||||
_pms= pms
|
||||
_qat= qat
|
||||
|
||||
@@ -34,6 +34,7 @@ SUBDIR= adduser \
|
||||
ifmcstat \
|
||||
iostat \
|
||||
iovctl \
|
||||
ixnvdimm \
|
||||
kldxref \
|
||||
mailwrapper \
|
||||
makefs \
|
||||
|
||||
Reference in New Issue
Block a user