From owner-svn-src-all@FreeBSD.ORG Sat Sep 27 19:14:23 2014 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 27018430; Sat, 27 Sep 2014 19:14:23 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::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 E8F3B6C8; Sat, 27 Sep 2014 19:14:22 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id s8RJEMcc025487; Sat, 27 Sep 2014 19:14:22 GMT (envelope-from smh@FreeBSD.org) Received: (from smh@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id s8RJEMaE025486; Sat, 27 Sep 2014 19:14:22 GMT (envelope-from smh@FreeBSD.org) Message-Id: <201409271914.s8RJEMaE025486@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: smh set sender to smh@FreeBSD.org using -f From: Steven Hartland Date: Sat, 27 Sep 2014 19:14:22 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r272223 - head/sys/dev/ahci X-SVN-Group: head 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.18-1 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: Sat, 27 Sep 2014 19:14:23 -0000 Author: smh Date: Sat Sep 27 19:14:22 2014 New Revision: 272223 URL: http://svnweb.freebsd.org/changeset/base/272223 Log: Use a local STAILQ for unlocked done CCB processing in ahci direct mode Previously it was possible for issues e.g. use after free, to result from processing the done queue while not holding the channel lock. While this should never happen in practice, unexpected code flows which result in two threads processing from the same queue may be possible. We now use a local STAILQ to prevent this ever being an issue. Sponsored by: Multiplay Modified: head/sys/dev/ahci/ahci.c Modified: head/sys/dev/ahci/ahci.c ============================================================================== --- head/sys/dev/ahci/ahci.c Sat Sep 27 18:35:16 2014 (r272222) +++ head/sys/dev/ahci/ahci.c Sat Sep 27 19:14:22 2014 (r272223) @@ -1126,6 +1126,7 @@ ahci_ch_intr_direct(void *arg) struct ahci_channel *ch = (struct ahci_channel *)arg; struct ccb_hdr *ccb_h; uint32_t istatus; + STAILQ_HEAD(, ccb_hdr) tmp_doneq = STAILQ_HEAD_INITIALIZER(tmp_doneq); /* Read interrupt statuses. */ istatus = ATA_INL(ch->r_mem, AHCI_P_IS); @@ -1136,9 +1137,14 @@ ahci_ch_intr_direct(void *arg) ch->batch = 1; ahci_ch_intr_main(ch, istatus); ch->batch = 0; + /* + * Prevent the possibility of issues caused by processing the queue + * while unlocked below by moving the contents to a local queue. + */ + STAILQ_CONCAT(&tmp_doneq, &ch->doneq); mtx_unlock(&ch->mtx); - while ((ccb_h = STAILQ_FIRST(&ch->doneq)) != NULL) { - STAILQ_REMOVE_HEAD(&ch->doneq, sim_links.stqe); + while ((ccb_h = STAILQ_FIRST(&tmp_doneq)) != NULL) { + STAILQ_REMOVE_HEAD(&tmp_doneq, sim_links.stqe); xpt_done_direct((union ccb *)ccb_h); } }