Commit 69c34f07 authored by Jens Axboe's avatar Jens Axboe
Browse files

Merge branch 'for-6.11/block-limits' into for-6.11/block



Merge in last round of queue limits changes from Christoph.

* for-6.11/block-limits: (26 commits)
  block: move the bounce flag into the features field
  block: move the skip_tagset_quiesce flag to queue_limits
  block: move the pci_p2pdma flag to queue_limits
  block: move the zone_resetall flag to queue_limits
  block: move the zoned flag into the features field
  block: move the poll flag to queue_limits
  block: move the dax flag to queue_limits
  block: move the nowait flag to queue_limits
  block: move the synchronous flag to queue_limits
  block: move the stable_writes flag to queue_limits
  block: move the io_stat flag setting to queue_limits
  block: move the add_random flag to queue_limits
  block: move the nonrot flag to queue_limits
  block: move cache control settings out of queue->flags
  block: remove blk_flush_policy
  block: freeze the queue in queue_attr_store
  nbd: move setting the cache control flags to __nbd_set_size
  virtio_blk: remove virtblk_update_cache_mode
  loop: fold loop_update_rotational into loop_reconfigure_limits
  loop: also use the default block size from an underlying block device
  ...

Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parents 465478bb 339d3948
Loading
Loading
Loading
Loading
+38 −29
Original line number Diff line number Diff line
@@ -46,41 +46,50 @@ worry if the underlying devices need any explicit cache flushing and how
the Forced Unit Access is implemented.  The REQ_PREFLUSH and REQ_FUA flags
may both be set on a single bio.

Feature settings for block drivers
----------------------------------

Implementation details for bio based block drivers
--------------------------------------------------------------
For devices that do not support volatile write caches there is no driver
support required, the block layer completes empty REQ_PREFLUSH requests before
entering the driver and strips off the REQ_PREFLUSH and REQ_FUA bits from
requests that have a payload.

These drivers will always see the REQ_PREFLUSH and REQ_FUA bits as they sit
directly below the submit_bio interface.  For remapping drivers the REQ_FUA
bits need to be propagated to underlying devices, and a global flush needs
to be implemented for bios with the REQ_PREFLUSH bit set.  For real device
drivers that do not have a volatile cache the REQ_PREFLUSH and REQ_FUA bits
on non-empty bios can simply be ignored, and REQ_PREFLUSH requests without
data can be completed successfully without doing any work.  Drivers for
devices with volatile caches need to implement the support for these
flags themselves without any help from the block layer.
For devices with volatile write caches the driver needs to tell the block layer
that it supports flushing caches by setting the

   BLK_FEAT_WRITE_CACHE

Implementation details for request_fn based block drivers
---------------------------------------------------------
flag in the queue_limits feature field.  For devices that also support the FUA
bit the block layer needs to be told to pass on the REQ_FUA bit by also setting
the

For devices that do not support volatile write caches there is no driver
support required, the block layer completes empty REQ_PREFLUSH requests before
entering the driver and strips off the REQ_PREFLUSH and REQ_FUA bits from
requests that have a payload.  For devices with volatile write caches the
driver needs to tell the block layer that it supports flushing caches by
doing::
   BLK_FEAT_FUA

flag in the features field of the queue_limits structure.

Implementation details for bio based block drivers
--------------------------------------------------

For bio based drivers the REQ_PREFLUSH and REQ_FUA bit are simplify passed on
to the driver if the drivers sets the BLK_FEAT_WRITE_CACHE flag and the drivers
needs to handle them.

*NOTE*: The REQ_FUA bit also gets passed on when the BLK_FEAT_FUA flags is
_not_ set.  Any bio based driver that sets BLK_FEAT_WRITE_CACHE also needs to
handle REQ_FUA.

	blk_queue_write_cache(sdkp->disk->queue, true, false);
For remapping drivers the REQ_FUA bits need to be propagated to underlying
devices, and a global flush needs to be implemented for bios with the
REQ_PREFLUSH bit set.

and handle empty REQ_OP_FLUSH requests in its prep_fn/request_fn.  Note that
REQ_PREFLUSH requests with a payload are automatically turned into a sequence
of an empty REQ_OP_FLUSH request followed by the actual write by the block
layer.  For devices that also support the FUA bit the block layer needs
to be told to pass through the REQ_FUA bit using::
Implementation details for blk-mq drivers
-----------------------------------------

	blk_queue_write_cache(sdkp->disk->queue, true, true);
When the BLK_FEAT_WRITE_CACHE flag is set, REQ_OP_WRITE | REQ_PREFLUSH requests
with a payload are automatically turned into a sequence of a REQ_OP_FLUSH
request followed by the actual write by the block layer.

and the driver must handle write requests that have the REQ_FUA bit set
in prep_fn/request_fn.  If the FUA bit is not natively supported the block
layer turns it into an empty REQ_OP_FLUSH request after the actual write.
When the BLK_FEAT_FUA flags is set, the REQ_FUA bit simplify passed on for the
REQ_OP_WRITE request, else a REQ_OP_FLUSH request is sent by the block layer
after the completion of the write request for bio submissions with the REQ_FUA
bit set.
+1 −0
Original line number Diff line number Diff line
@@ -98,6 +98,7 @@ static int __init nfhd_init_one(int id, u32 blocks, u32 bsize)
{
	struct queue_limits lim = {
		.logical_block_size	= bsize,
		.features		= BLK_FEAT_ROTATIONAL,
	};
	struct nfhd_device *dev;
	int dev_id = id - NFHD_DEV_OFFSET;
+1 −2
Original line number Diff line number Diff line
@@ -835,6 +835,7 @@ static int ubd_add(int n, char **error_out)
	struct queue_limits lim = {
		.max_segments		= MAX_SG,
		.seg_boundary_mask	= PAGE_SIZE - 1,
		.features		= BLK_FEAT_WRITE_CACHE,
	};
	struct gendisk *disk;
	int err = 0;
@@ -881,8 +882,6 @@ static int ubd_add(int n, char **error_out)
		goto out_cleanup_tags;
	}

	blk_queue_flag_set(QUEUE_FLAG_NONROT, disk->queue);
	blk_queue_write_cache(disk->queue, true, false);
	disk->major = UBD_MAJOR;
	disk->first_minor = n << UBD_SHIFT;
	disk->minors = 1 << UBD_SHIFT;
+4 −1
Original line number Diff line number Diff line
@@ -263,6 +263,9 @@ static const struct proc_ops simdisk_proc_ops = {
static int __init simdisk_setup(struct simdisk *dev, int which,
		struct proc_dir_entry *procdir)
{
	struct queue_limits lim = {
		.features		= BLK_FEAT_ROTATIONAL,
	};
	char tmp[2] = { '0' + which, 0 };
	int err;

@@ -271,7 +274,7 @@ static int __init simdisk_setup(struct simdisk *dev, int which,
	spin_lock_init(&dev->lock);
	dev->users = 0;

	dev->gd = blk_alloc_disk(NULL, NUMA_NO_NODE);
	dev->gd = blk_alloc_disk(&lim, NUMA_NO_NODE);
	if (IS_ERR(dev->gd)) {
		err = PTR_ERR(dev->gd);
		goto out;
+3 −4
Original line number Diff line number Diff line
@@ -782,7 +782,7 @@ void submit_bio_noacct(struct bio *bio)
		if (WARN_ON_ONCE(bio_op(bio) != REQ_OP_WRITE &&
				 bio_op(bio) != REQ_OP_ZONE_APPEND))
			goto end_io;
		if (!test_bit(QUEUE_FLAG_WC, &q->queue_flags)) {
		if (!bdev_write_cache(bdev)) {
			bio->bi_opf &= ~(REQ_PREFLUSH | REQ_FUA);
			if (!bio_sectors(bio)) {
				status = BLK_STS_OK;
@@ -791,7 +791,7 @@ void submit_bio_noacct(struct bio *bio)
		}
	}

	if (!test_bit(QUEUE_FLAG_POLL, &q->queue_flags))
	if (!(q->limits.features & BLK_FEAT_POLL))
		bio_clear_polled(bio);

	switch (bio_op(bio)) {
@@ -915,8 +915,7 @@ int bio_poll(struct bio *bio, struct io_comp_batch *iob, unsigned int flags)
		return 0;

	q = bdev_get_queue(bdev);
	if (cookie == BLK_QC_T_NONE ||
	    !test_bit(QUEUE_FLAG_POLL, &q->queue_flags))
	if (cookie == BLK_QC_T_NONE || !(q->limits.features & BLK_FEAT_POLL))
		return 0;

	blk_flush_plug(current->plug, false);
Loading