Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 23 Nov 2015 17:26:20 +0000 (UTC)
From:      Jim Harris <jimharris@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org
Subject:   svn commit: r291213 - stable/10/sys/dev/nvme
Message-ID:  <201511231726.tANHQKs8048757@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jimharris
Date: Mon Nov 23 17:26:20 2015
New Revision: 291213
URL: https://svnweb.freebsd.org/changeset/base/291213

Log:
  MFC r290198:
  
    nvme: fix race condition in split bio completion path
  
  Sponsored by:	Intel

Modified:
  stable/10/sys/dev/nvme/nvme_ns.c

Modified: stable/10/sys/dev/nvme/nvme_ns.c
==============================================================================
--- stable/10/sys/dev/nvme/nvme_ns.c	Mon Nov 23 17:09:35 2015	(r291212)
+++ stable/10/sys/dev/nvme/nvme_ns.c	Mon Nov 23 17:26:20 2015	(r291213)
@@ -239,7 +239,7 @@ static void
 nvme_bio_child_inbed(struct bio *parent, int bio_error)
 {
 	struct nvme_completion	parent_cpl;
-	int			inbed;
+	int			children, inbed;
 
 	if (bio_error != 0) {
 		parent->bio_flags |= BIO_ERROR;
@@ -248,10 +248,13 @@ nvme_bio_child_inbed(struct bio *parent,
 
 	/*
 	 * atomic_fetchadd will return value before adding 1, so we still
-	 *  must add 1 to get the updated inbed number.
+	 *  must add 1 to get the updated inbed number.  Save bio_children
+	 *  before incrementing to guard against race conditions when
+	 *  two children bios complete on different queues.
 	 */
+	children = atomic_load_acq_int(&parent->bio_children);
 	inbed = atomic_fetchadd_int(&parent->bio_inbed, 1) + 1;
-	if (inbed == parent->bio_children) {
+	if (inbed == children) {
 		bzero(&parent_cpl, sizeof(parent_cpl));
 		if (parent->bio_flags & BIO_ERROR)
 			parent_cpl.status.sc = NVME_SC_DATA_TRANSFER_ERROR;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201511231726.tANHQKs8048757>