svn commit: r314727 - stable/10/sys/cam/ctl
Alexander Motin
mav at FreeBSD.org
Mon Mar 6 06:19:05 UTC 2017
Author: mav
Date: Mon Mar 6 06:19:02 2017
New Revision: 314727
URL: https://svnweb.freebsd.org/changeset/base/314727
Log:
MFC r314027: Do not blindly free completed ATIOs/INOTs on invalidation.
When LUN is disabled, SIM starts returning queued ATIOs/INOTs. But at the
same time there can be some ATIOs/INOTs still carrying real new requests.
If we free those, SIM may leak some resources, forever expecting for any
response from us. So try to be careful, separating ATIOs/INOTs carrying
requests which still must be processed, from ATIOs/INOTs completed with
errors which can be freed.
Modified:
stable/10/sys/cam/ctl/scsi_ctl.c
Directory Properties:
stable/10/ (props changed)
Modified: stable/10/sys/cam/ctl/scsi_ctl.c
==============================================================================
--- stable/10/sys/cam/ctl/scsi_ctl.c Mon Mar 6 06:18:30 2017 (r314726)
+++ stable/10/sys/cam/ctl/scsi_ctl.c Mon Mar 6 06:19:02 2017 (r314727)
@@ -1102,6 +1102,7 @@ ctlfedone(struct cam_periph *periph, uni
struct ccb_accept_tio *atio = NULL;
union ctl_io *io = NULL;
struct mtx *mtx;
+ cam_status status;
KASSERT((done_ccb->ccb_h.flags & CAM_UNLOCKED) != 0,
("CCB in ctlfedone() without CAM_UNLOCKED flag"));
@@ -1128,30 +1129,15 @@ ctlfedone(struct cam_periph *periph, uni
mtx = cam_periph_mtx(periph);
mtx_lock(mtx);
- /*
- * If the peripheral is invalid, ATIOs and immediate notify CCBs
- * need to be freed. Most of the ATIOs and INOTs that come back
- * will be CCBs that are being returned from the SIM as a result of
- * our disabling the LUN.
- *
- * Other CCB types are handled in their respective cases below.
- */
- if (periph->flags & CAM_PERIPH_INVALID) {
- switch (done_ccb->ccb_h.func_code) {
- case XPT_ACCEPT_TARGET_IO:
- case XPT_IMMEDIATE_NOTIFY:
- case XPT_NOTIFY_ACKNOWLEDGE:
- ctlfe_free_ccb(periph, done_ccb);
- goto out;
- default:
- break;
- }
-
- }
switch (done_ccb->ccb_h.func_code) {
case XPT_ACCEPT_TARGET_IO: {
atio = &done_ccb->atio;
+ status = atio->ccb_h.status & CAM_STATUS_MASK;
+ if (status != CAM_CDB_RECVD) {
+ ctlfe_free_ccb(periph, done_ccb);
+ goto out;
+ }
resubmit:
/*
@@ -1430,14 +1416,9 @@ ctlfedone(struct cam_periph *periph, uni
case XPT_IMMEDIATE_NOTIFY: {
union ctl_io *io;
struct ccb_immediate_notify *inot;
- cam_status status;
int send_ctl_io;
inot = &done_ccb->cin1;
- printf("%s: got XPT_IMMEDIATE_NOTIFY status %#x tag %#x "
- "seq %#x\n", __func__, inot->ccb_h.status,
- inot->tag_id, inot->seq_id);
-
io = done_ccb->ccb_h.io_ptr;
ctl_zero_io(io);
@@ -1503,40 +1484,22 @@ ctlfedone(struct cam_periph *periph, uni
break;
default:
xpt_print(periph->path,
- "%s: unsupported message 0x%x\n",
- __func__, inot->arg);
+ "%s: unsupported INOT message 0x%x\n",
+ __func__, inot->arg);
send_ctl_io = 0;
break;
}
break;
+ default:
+ xpt_print(periph->path,
+ "%s: unsupported INOT status 0x%x\n",
+ __func__, status);
+ /* FALLTHROUGH */
case CAM_REQ_ABORTED:
- /*
- * This request was sent back by the driver.
- * XXX KDM what do we do here?
- */
- send_ctl_io = 0;
- break;
case CAM_REQ_INVALID:
+ case CAM_DEV_NOT_THERE:
case CAM_PROVIDE_FAIL:
- default:
- /*
- * We should only get here if we're talking
- * to a talking to a SIM that is target
- * capable but supports the old API. In
- * that case, we need to just free the CCB.
- * If we actually send a notify acknowledge,
- * it will send that back with an error as
- * well.
- */
-
- if ((status != CAM_REQ_INVALID)
- && (status != CAM_PROVIDE_FAIL))
- xpt_print(periph->path,
- "%s: unsupported CAM status 0x%x\n",
- __func__, status);
-
ctlfe_free_ccb(periph, done_ccb);
-
goto out;
}
if (send_ctl_io != 0) {
@@ -1549,6 +1512,11 @@ ctlfedone(struct cam_periph *periph, uni
break;
}
case XPT_NOTIFY_ACKNOWLEDGE:
+ if (periph->flags & CAM_PERIPH_INVALID) {
+ ctlfe_free_ccb(periph, done_ccb);
+ goto out;
+ }
+
/*
* Queue this back down to the SIM as an immediate notify.
*/
@@ -2029,14 +1997,6 @@ ctlfe_done(union ctl_io *io)
if (io->io_hdr.io_type == CTL_IO_TASK) {
/*
- * Task management commands don't require any further
- * communication back to the adapter. Requeue the CCB
- * to the adapter, and free the CTL I/O.
- */
- xpt_print(ccb->ccb_h.path, "%s: returning task I/O "
- "tag %#x seq %#x\n", __func__,
- ccb->cin1.tag_id, ccb->cin1.seq_id);
- /*
* Send the notify acknowledge down to the SIM, to let it
* know we processed the task management command.
*/
More information about the svn-src-stable
mailing list