aboutsummaryrefslogtreecommitdiff
path: root/sys/sys/bio.h
diff options
context:
space:
mode:
authorJustin T. Gibbs <gibbs@FreeBSD.org>2010-09-02 19:40:28 +0000
committerJustin T. Gibbs <gibbs@FreeBSD.org>2010-09-02 19:40:28 +0000
commitf03f7a0ca36bf5c6acb0c3a9a91dc7ded0ab009f (patch)
tree0925e11852d21e96ea5401b9798cc7d6a1135e93 /sys/sys/bio.h
parentf0092b8fc81776d5fe0c74d7637db17cffcd1eb9 (diff)
downloadsrc-f03f7a0ca36bf5c6acb0c3a9a91dc7ded0ab009f.tar.gz
src-f03f7a0ca36bf5c6acb0c3a9a91dc7ded0ab009f.zip
Correct bioq_disksort so that bioq_insert_tail() offers barrier semantic.
Add the BIO_ORDERED flag for struct bio and update bio clients to use it. The barrier semantics of bioq_insert_tail() were broken in two ways: o In bioq_disksort(), an added bio could be inserted at the head of the queue, even when a barrier was present, if the sort key for the new entry was less than that of the last queued barrier bio. o The last_offset used to generate the sort key for newly queued bios did not stay at the position of the barrier until either the barrier was de-queued, or a new barrier (which updates last_offset) was queued. When a barrier is in effect, we know that the disk will pass through the barrier position just before the "blocked bios" are released, so using the barrier's offset for last_offset is the optimal choice. sys/geom/sched/subr_disk.c: sys/kern/subr_disk.c: o Update last_offset in bioq_insert_tail(). o Only update last_offset in bioq_remove() if the removed bio is at the head of the queue (typically due to a call via bioq_takefirst()) and no barrier is active. o In bioq_disksort(), if we have a barrier (insert_point is non-NULL), set prev to the barrier and cur to it's next element. Now that last_offset is kept at the barrier position, this change isn't strictly necessary, but since we have to take a decision branch anyway, it does avoid one, no-op, loop iteration in the while loop that immediately follows. o In bioq_disksort(), bypass the normal sort for bios with the BIO_ORDERED attribute and instead insert them into the queue with bioq_insert_tail(). bioq_insert_tail() not only gives the desired command order during insertion, but also provides barrier semantics so that commands disksorted in the future cannot pass the just enqueued transaction. sys/sys/bio.h: Add BIO_ORDERED as bit 4 of the bio_flags field in struct bio. sys/cam/ata/ata_da.c: sys/cam/scsi/scsi_da.c Use an ordered command for SCSI/ATA-NCQ commands issued in response to bios with the BIO_ORDERED flag set. sys/cam/scsi/scsi_da.c Use an ordered tag when issuing a synchronize cache command. Wrap some lines to 80 columns. sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c sys/geom/geom_io.c Mark bios with the BIO_FLUSH command as BIO_ORDERED. Sponsored by: Spectra Logic Corporation MFC after: 1 month
Notes
Notes: svn path=/head/; revision=212160
Diffstat (limited to 'sys/sys/bio.h')
-rw-r--r--sys/sys/bio.h1
1 files changed, 1 insertions, 0 deletions
diff --git a/sys/sys/bio.h b/sys/sys/bio.h
index 8b6ff0ec696a..c016ee67b904 100644
--- a/sys/sys/bio.h
+++ b/sys/sys/bio.h
@@ -54,6 +54,7 @@
#define BIO_ERROR 0x01
#define BIO_DONE 0x02
#define BIO_ONQUEUE 0x04
+#define BIO_ORDERED 0x08
#ifdef _KERNEL
struct disk;