From owner-svn-src-stable@freebsd.org Sat Nov 5 20:22:13 2016 Return-Path: Delivered-To: svn-src-stable@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 DC21AAF7D81; Sat, 5 Nov 2016 20:22:13 +0000 (UTC) (envelope-from markj@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 B58BCB3F; Sat, 5 Nov 2016 20:22:13 +0000 (UTC) (envelope-from markj@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id uA5KMCm7072300; Sat, 5 Nov 2016 20:22:12 GMT (envelope-from markj@FreeBSD.org) Received: (from markj@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id uA5KMCRY072298; Sat, 5 Nov 2016 20:22:12 GMT (envelope-from markj@FreeBSD.org) Message-Id: <201611052022.uA5KMCRY072298@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: markj set sender to markj@FreeBSD.org using -f From: Mark Johnston Date: Sat, 5 Nov 2016 20:22:12 +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: r308351 - stable/11/sys/cam X-SVN-Group: stable-11 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 05 Nov 2016 20:22:14 -0000 Author: markj Date: Sat Nov 5 20:22:12 2016 New Revision: 308351 URL: https://svnweb.freebsd.org/changeset/base/308351 Log: MFC r306529: cam_periph_ccbwait could return while ccb in progress Modified: stable/11/sys/cam/cam_periph.c stable/11/sys/cam/cam_periph.h Directory Properties: stable/11/ (props changed) Modified: stable/11/sys/cam/cam_periph.c ============================================================================== --- stable/11/sys/cam/cam_periph.c Sat Nov 5 20:15:58 2016 (r308350) +++ stable/11/sys/cam/cam_periph.c Sat Nov 5 20:22:12 2016 (r308351) @@ -975,16 +975,6 @@ cam_periph_unmapmem(union ccb *ccb, stru PRELE(curproc); } -void -cam_periph_ccbwait(union ccb *ccb) -{ - - if ((ccb->ccb_h.pinfo.index != CAM_UNQUEUED_INDEX) - || ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_INPROG)) - xpt_path_sleep(ccb->ccb_h.path, &ccb->ccb_h.cbfcnp, PRIBIO, - "cbwait", 0); -} - int cam_periph_ioctl(struct cam_periph *periph, u_long cmd, caddr_t addr, int (*error_routine)(union ccb *ccb, @@ -1048,13 +1038,38 @@ cam_periph_ioctl(struct cam_periph *peri } static void +cam_periph_done_panic(struct cam_periph *periph, union ccb *done_ccb) +{ + + panic("%s: already done with ccb %p", __func__, done_ccb); +} + +static void cam_periph_done(struct cam_periph *periph, union ccb *done_ccb) { /* Caller will release the CCB */ + xpt_path_assert(done_ccb->ccb_h.path, MA_OWNED); + done_ccb->ccb_h.cbfcnp = cam_periph_done_panic; wakeup(&done_ccb->ccb_h.cbfcnp); } +static void +cam_periph_ccbwait(union ccb *ccb) +{ + + if ((ccb->ccb_h.func_code & XPT_FC_QUEUED) != 0) { + while (ccb->ccb_h.cbfcnp != cam_periph_done_panic) + xpt_path_sleep(ccb->ccb_h.path, &ccb->ccb_h.cbfcnp, + PRIBIO, "cbwait", 0); + } + KASSERT(ccb->ccb_h.pinfo.index == CAM_UNQUEUED_INDEX && + (ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_INPROG, + ("%s: proceeding with incomplete ccb: ccb=%p, func_code=%#x, " + "status=%#x, index=%d", __func__, ccb, ccb->ccb_h.func_code, + ccb->ccb_h.status, ccb->ccb_h.pinfo.index)); +} + int cam_periph_runccb(union ccb *ccb, int (*error_routine)(union ccb *ccb, @@ -1069,6 +1084,9 @@ cam_periph_runccb(union ccb *ccb, starttime = NULL; xpt_path_assert(ccb->ccb_h.path, MA_OWNED); + KASSERT((ccb->ccb_h.flags & CAM_UNLOCKED) == 0, + ("%s: ccb=%p, func_code=%#x, flags=%#x", __func__, ccb, + ccb->ccb_h.func_code, ccb->ccb_h.flags)); /* * If the user has supplied a stats structure, and if we understand @@ -1088,9 +1106,10 @@ cam_periph_runccb(union ccb *ccb, cam_periph_ccbwait(ccb); if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) error = 0; - else if (error_routine != NULL) + else if (error_routine != NULL) { + ccb->ccb_h.cbfcnp = cam_periph_done; error = (*error_routine)(ccb, camflags, sense_flags); - else + } else error = 0; } while (error == ERESTART); Modified: stable/11/sys/cam/cam_periph.h ============================================================================== --- stable/11/sys/cam/cam_periph.h Sat Nov 5 20:15:58 2016 (r308350) +++ stable/11/sys/cam/cam_periph.h Sat Nov 5 20:22:12 2016 (r308351) @@ -166,7 +166,6 @@ void cam_periph_unmapmem(union ccb *ccb struct cam_periph_map_info *mapinfo); union ccb *cam_periph_getccb(struct cam_periph *periph, u_int32_t priority); -void cam_periph_ccbwait(union ccb *ccb); int cam_periph_runccb(union ccb *ccb, int (*error_routine)(union ccb *ccb, cam_flags camflags,