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>