From owner-svn-src-all@freebsd.org Mon Mar 6 06:18:32 2017 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 2C1BECFBF56; Mon, 6 Mar 2017 06:18:32 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 817D41687; Mon, 6 Mar 2017 06:18:31 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id v266IUwT090443; Mon, 6 Mar 2017 06:18:30 GMT (envelope-from mav@FreeBSD.org) Received: (from mav@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id v266IUj8090442; Mon, 6 Mar 2017 06:18:30 GMT (envelope-from mav@FreeBSD.org) Message-Id: <201703060618.v266IUj8090442@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: mav set sender to mav@FreeBSD.org using -f From: Alexander Motin Date: Mon, 6 Mar 2017 06:18:30 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org Subject: svn commit: r314726 - stable/11/sys/cam/ctl X-SVN-Group: stable-11 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 06 Mar 2017 06:18:32 -0000 Author: mav Date: Mon Mar 6 06:18:30 2017 New Revision: 314726 URL: https://svnweb.freebsd.org/changeset/base/314726 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/11/sys/cam/ctl/scsi_ctl.c Directory Properties: stable/11/ (props changed) Modified: stable/11/sys/cam/ctl/scsi_ctl.c ============================================================================== --- stable/11/sys/cam/ctl/scsi_ctl.c Mon Mar 6 06:09:33 2017 (r314725) +++ stable/11/sys/cam/ctl/scsi_ctl.c Mon Mar 6 06:18:30 2017 (r314726) @@ -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. */ @@ -2030,14 +1998,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. */