From owner-svn-src-head@freebsd.org Sun Oct 18 16:30:50 2020 Return-Path: Delivered-To: svn-src-head@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id B2127436A49; Sun, 18 Oct 2020 16:30:50 +0000 (UTC) (envelope-from trasz@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4CDlkL3rqfz4hNv; Sun, 18 Oct 2020 16:30:50 +0000 (UTC) (envelope-from trasz@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 mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 691771568E; Sun, 18 Oct 2020 16:30:50 +0000 (UTC) (envelope-from trasz@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id 09IGUoM7037024; Sun, 18 Oct 2020 16:30:50 GMT (envelope-from trasz@FreeBSD.org) Received: (from trasz@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id 09IGUoOY037023; Sun, 18 Oct 2020 16:30:50 GMT (envelope-from trasz@FreeBSD.org) Message-Id: <202010181630.09IGUoOY037023@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: trasz set sender to trasz@FreeBSD.org using -f From: Edward Tomasz Napierala Date: Sun, 18 Oct 2020 16:30:50 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r366812 - head/sys/dev/iscsi X-SVN-Group: head X-SVN-Commit-Author: trasz X-SVN-Commit-Paths: head/sys/dev/iscsi X-SVN-Commit-Revision: 366812 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.33 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 18 Oct 2020 16:30:50 -0000 Author: trasz Date: Sun Oct 18 16:30:49 2020 New Revision: 366812 URL: https://svnweb.freebsd.org/changeset/base/366812 Log: If the SIM freezes the queue at exactly the wrong moment, after another thread has started to send in a CCB and already checked the queue wasn't frozen, we would end up with iscsi_action() being called despite the queue is now frozen. Add a check to make sure this doesn't happen . Perhaps this should be fixed at the CAM level instead, but given how the send queue and SIM are governed by two separate mutexes, it is somewhat hard to do. Reviewed by: imp, mav MFC after: 2 weeks Sponsored by: NetApp, Inc. Sponsored by: Klara, Inc. Differential Revision: https://reviews.freebsd.org/D26750 Modified: head/sys/dev/iscsi/iscsi.c Modified: head/sys/dev/iscsi/iscsi.c ============================================================================== --- head/sys/dev/iscsi/iscsi.c Sun Oct 18 16:24:08 2020 (r366811) +++ head/sys/dev/iscsi/iscsi.c Sun Oct 18 16:30:49 2020 (r366812) @@ -367,8 +367,8 @@ iscsi_session_cleanup(struct iscsi_session *is, bool d xpt_async(AC_LOST_DEVICE, is->is_path, NULL); if (is->is_simq_frozen) { - xpt_release_simq(is->is_sim, 1); is->is_simq_frozen = false; + xpt_release_simq(is->is_sim, 1); } xpt_free_path(is->is_path); @@ -1479,8 +1479,8 @@ iscsi_ioctl_daemon_handoff(struct iscsi_softc *sc, KASSERT(is->is_simq_frozen, ("reconnect without frozen simq")); ISCSI_SESSION_LOCK(is); ISCSI_SESSION_DEBUG(is, "releasing"); - xpt_release_simq(is->is_sim, 1); is->is_simq_frozen = false; + xpt_release_simq(is->is_sim, 1); ISCSI_SESSION_UNLOCK(is); } else { @@ -2351,6 +2351,17 @@ iscsi_action(struct cam_sim *sim, union ccb *ccb) if (is->is_terminating || (is->is_connected == false && fail_on_disconnection)) { ccb->ccb_h.status = CAM_DEV_NOT_THERE; + xpt_done(ccb); + return; + } + + /* + * Make sure CAM doesn't sneak in a CCB just after freezing the queue. + */ + if (is->is_simq_frozen == true) { + ccb->ccb_h.status &= ~(CAM_SIM_QUEUED | CAM_STATUS_MASK); + ccb->ccb_h.status |= CAM_REQUEUE_REQ; + /* Don't freeze the devq - the SIM queue is already frozen. */ xpt_done(ccb); return; }