Skip to content

Commit 519121f

Browse files
committed
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 (cherry picked from commit 2c48a8f)
1 parent f81286d commit 519121f

File tree

2 files changed

+19
-3
lines changed

2 files changed

+19
-3
lines changed

sys/dev/isp/isp_freebsd.c

+17-2
Original file line numberDiff line numberDiff line change
@@ -986,6 +986,16 @@ isp_target_start_ctio(ispsoftc_t *isp, union ccb *ccb, enum Start_Ctio_How how)
986986
continue;
987987
}
988988

989+
/*
990+
* Is this command a dead duck?
991+
*/
992+
if (atp->dead) {
993+
isp_prt(isp, ISP_LOGERR, "%s: [0x%x] not sending a CTIO for a dead command", __func__, cso->tag_id);
994+
ccb->ccb_h.status = CAM_REQ_ABORTED;
995+
xpt_done(ccb);
996+
continue;
997+
}
998+
989999
/*
9901000
* Check to make sure we're still in target mode.
9911001
*/
@@ -2503,14 +2513,19 @@ isp_action(struct cam_sim *sim, union ccb *ccb)
25032513
}
25042514

25052515
/*
2506-
* Target should abort all affected CCBs before ACK-ing INOT,
2516+
* Target should abort all affected tasks before ACK-ing INOT,
25072517
* but if/since it doesn't, add this hack to allow tag reuse.
2518+
* We can not do it if some CTIOs are in progress, or we won't
2519+
* handle the completions. In such case just block new ones.
25082520
*/
25092521
uint32_t rsp = (ccb->ccb_h.flags & CAM_SEND_STATUS) ? ccb->cna2.arg : 0;
25102522
if (ntp->nt.nt_ncode == NT_ABORT_TASK && (rsp & 0xff) == 0 &&
25112523
(atp = isp_find_atpd(isp, XS_CHANNEL(ccb), ccb->cna2.seq_id)) != NULL) {
2512-
if (isp_abort_atpd(isp, XS_CHANNEL(ccb), atp) == 0)
2524+
if (atp->ctcnt == 0 &&
2525+
isp_abort_atpd(isp, XS_CHANNEL(ccb), atp) == 0)
25132526
isp_put_atpd(isp, XS_CHANNEL(ccb), atp);
2527+
else
2528+
atp->dead = 1;
25142529
}
25152530

25162531
if (isp_handle_platform_target_notify_ack(isp, &ntp->nt, rsp)) {

sys/dev/isp/isp_freebsd.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -104,8 +104,9 @@ typedef struct atio_private_data {
104104
uint16_t ctcnt; /* number of CTIOs currently active */
105105
uint8_t seqno; /* CTIO sequence number */
106106
uint8_t cdb0;
107-
uint8_t srr_notify_rcvd : 1,
107+
uint16_t srr_notify_rcvd : 1,
108108
sendst : 1,
109+
dead : 1,
109110
tattr : 3,
110111
state : 3;
111112
void * ests;

0 commit comments

Comments
 (0)