projects/linux·commit 582cd91f

Merge tag 'for-5.12/block-2021-02-17' of git://git.kernel.dk/linux-block

582cd91f · Linus Torvalds <[email protected]> · 2021-02-21 11:02:48 -08:00

Pull core block updates from Jens Axboe:
 "Another nice round of removing more code than what is added, mostly
  due to Christoph's relentless pursuit of tech debt removal/cleanups.
  This pull request contains:

   - Two series of BFQ improvements (Paolo, Jan, Jia)

   - Block iov_iter improvements (Pavel)

   - bsg error path fix (Pan)

   - blk-mq scheduler improvements (Jan)

   - -EBUSY discard fix (Jan)

   - bvec allocation improvements (Ming, Christoph)

   - bio allocation and init improvements (Christoph)

   - Store bdev pointer in bio instead of gendisk + partno (Christoph)

   - Block trace point cleanups (Christoph)

   - hard read-only vs read-only split (Christoph)

   - Block based swap cleanups (Christoph)

   - Zoned write granularity support (Damien)

   - Various fixes/tweaks (Chunguang, Guoqing, Lei, Lukas, Huhai)"

* tag 'for-5.12/block-2021-02-17' of git://git.kernel.dk/linux-block: (104 commits)
  mm: simplify swapdev_block
  sd_zbc: clear zone resources for non-zoned case
  block: introduce blk_queue_clear_zone_settings()
  zonefs: use zone write granularity as block size
  block: introduce zone_write_granularity limit
  block: use blk_queue_set_zoned in add_partition()
  nullb: use blk_queue_set_zoned() to setup zoned devices
  nvme: cleanup zone information initialization
  block: document zone_append_max_bytes attribute
  block: use bi_max_vecs to find the bvec pool
  md/raid10: remove dead code in reshape_request
  block: mark the bio as cloned in bio_iov_bvec_set
  block: set BIO_NO_PAGE_REF in bio_iov_bvec_set
  block: remove a layer of indentation in bio_iov_iter_get_pages
  block: turn the nr_iovecs argument to bio_alloc* into an unsigned short
  block: remove the 1 and 4 vec bvec_slabs entries
  block: streamline bvec_alloc
  block: factor out a bvec_alloc_gfp helper
  block: move struct biovec_slab to bio.c
  block: reuse BIO_INLINE_VECS for integrity bvecs
  ...
Commit
582cd91f69de8e44857cb610ebca661dac8656b7
Parents
bd018bba · f885056a

Merge commit. Changes below are compared with the first parent: bd018bba.

Changes

148 files changed · +1343 −1608

FileStatusAddDelContent
Documentation/block/biovecs.rstmodified+2−0View file
Documentation/block/queue-sysfs.rstmodified+13−0View file
Documentation/filesystems/f2fs.rstmodified+0−1View file
Documentation/filesystems/porting.rstmodified+16−0View file
arch/m68k/emu/nfblock.cmodified+1−1View file
arch/xtensa/platforms/iss/simdisk.cmodified+1−1View file
block/bfq-iosched.cmodified+276−169View file
block/bfq-iosched.hmodified+19−10View file
block/bfq-wf2q.cmodified+0−3View file
block/bio-integrity.cmodified+15−20View file
block/bio.cmodified+253−318View file
block/blk-cgroup.cmodified+12−10View file
block/blk-core.cmodified+46−53View file
block/blk-crypto-fallback.cmodified+4−2View file
block/blk-crypto.cmodified+1−1View file
block/blk-exec.cmodified+5−9View file
block/blk-flush.cmodified+6−11View file
block/blk-merge.cmodified+8−9View file
block/blk-mq.cmodified+61−8View file
block/blk-settings.cmodified+39−2View file
block/blk-sysfs.cmodified+8−0View file
block/blk-throttle.cmodified+1−1View file
block/blk-wbt.cmodified+2−2View file
block/blk-zoned.cmodified+17−0View file
block/blk.hmodified+7−5View file
block/bounce.cmodified+3−1View file
block/bsg.cmodified+4−2View file
block/genhd.cmodified+49−257View file
block/kyber-iosched.cmodified+1−0View file
block/mq-deadline.cmodified+0−6View file
block/partitions/core.cmodified+8−28View file
block/scsi_ioctl.cmodified+3−3View file
drivers/block/brd.cmodified+2−6View file
drivers/block/drbd/drbd_actlog.cmodified+1−1View file
drivers/block/drbd/drbd_bitmap.cmodified+1−1View file
drivers/block/drbd/drbd_int.hmodified+2−4View file
drivers/block/drbd/drbd_main.cmodified+0−13View file
drivers/block/drbd/drbd_req.cmodified+5−2View file
drivers/block/drbd/drbd_req.hmodified+0−12View file
drivers/block/drbd/drbd_worker.cmodified+4−1View file
drivers/block/mtip32xx/mtip32xx.cmodified+1−1View file
drivers/block/null_blk/main.cmodified+1−1View file
drivers/block/null_blk/zoned.cmodified+4−4View file
drivers/block/paride/pd.cmodified+1−1View file
drivers/block/pktcdvd.cmodified+3−3View file
drivers/block/ps3vram.cmodified+1−1View file
drivers/block/rbd.cmodified+0−19View file
drivers/block/rsxx/dev.cmodified+1−1View file
drivers/block/sx8.cmodified+2−2View file
drivers/block/umem.cmodified+1−1View file
drivers/block/virtio_blk.cmodified+1−1View file
drivers/block/zram/zram_drv.cmodified+1−1View file
drivers/cdrom/cdrom.cmodified+1−1View file
drivers/ide/ide-atapi.cmodified+1−1View file
drivers/ide/ide-cd.cmodified+1−1View file
drivers/ide/ide-cd_ioctl.cmodified+1−1View file
drivers/ide/ide-devsets.cmodified+1−1View file
drivers/ide/ide-disk.cmodified+1−1View file
drivers/ide/ide-ioctls.cmodified+2−2View file
drivers/ide/ide-park.cmodified+1−1View file
drivers/ide/ide-pm.cmodified+2−2View file
drivers/ide/ide-tape.cmodified+1−1View file
drivers/ide/ide-taskfile.cmodified+1−1View file
drivers/lightnvm/pblk-init.cmodified+1−1View file
drivers/md/bcache/debug.cmodified+1−1View file
drivers/md/bcache/request.cmodified+24−15View file
drivers/md/bcache/super.cmodified+1−1View file
drivers/md/dm-bio-record.hmodified+3−6View file
drivers/md/dm-cache-metadata.cmodified+1−1View file
drivers/md/dm-clone-target.cmodified+1−13View file
drivers/md/dm-raid1.cmodified+5−5View file
drivers/md/dm-thin-metadata.cmodified+1−1View file
drivers/md/dm-zoned-metadata.cmodified+3−3View file
drivers/md/dm.cmodified+7−7View file
drivers/md/md-linear.cmodified+1−1View file
drivers/md/md.cmodified+29−44View file
drivers/md/md.hmodified+3−5View file
drivers/md/raid1.cmodified+4−4View file
drivers/md/raid10.cmodified+7−11View file
drivers/md/raid5-ppl.cmodified+1−1View file
drivers/md/raid5.cmodified+46−64View file
drivers/mmc/core/block.cmodified+5−5View file
drivers/nvdimm/blk.cmodified+2−2View file
drivers/nvdimm/btt.cmodified+2−2View file
drivers/nvdimm/pmem.cmodified+2−2View file
drivers/nvme/host/core.cmodified+16−15View file
drivers/nvme/host/lightnvm.cmodified+3−4View file
drivers/nvme/host/multipath.cmodified+3−3View file
drivers/nvme/host/pci.cmodified+2−2View file
drivers/nvme/host/rdma.cmodified+1−1View file
drivers/nvme/host/zns.cmodified+3−8View file
drivers/nvme/target/io-cmd-bdev.cmodified+1−1View file
drivers/nvme/target/passthru.cmodified+1−1View file
drivers/s390/block/dasd.cmodified+5−21View file
drivers/s390/block/dcssblk.cmodified+1−5View file
drivers/s390/block/xpram.cmodified+1−1View file
drivers/scsi/scsi_error.cmodified+1−1View file
drivers/scsi/scsi_lib.cmodified+1−1View file
drivers/scsi/sd_zbc.cmodified+39−4View file
drivers/scsi/sg.cmodified+1−2View file
drivers/scsi/st.cmodified+1−1View file
drivers/target/target_core_file.cmodified+6−14View file
drivers/target/target_core_pscsi.cmodified+1−2View file
fs/block_dev.cmodified+9−11View file
fs/btrfs/check-integrity.cmodified+5−5View file
fs/btrfs/raid56.cmodified+2−5View file
fs/btrfs/scrub.cmodified+1−1View file
fs/btrfs/volumes.cmodified+1−1View file
fs/btrfs/zoned.cmodified+2−2View file
fs/direct-io.cmodified+3−1View file
fs/exfat/file.cmodified+1−1View file
fs/ext4/fast_commit.cmodified+2−2View file
fs/ext4/fsync.cmodified+1−1View file
fs/ext4/ialloc.cmodified+1−1View file
fs/ext4/super.cmodified+1−1View file
fs/f2fs/data.cmodified+5−35View file
fs/f2fs/f2fs.hmodified+0−2View file
fs/f2fs/segment.cmodified+1−11View file
fs/f2fs/super.cmodified+0−1View file
fs/fat/file.cmodified+1−1View file
fs/hfsplus/inode.cmodified+1−1View file
fs/hfsplus/super.cmodified+1−1View file
fs/iomap/direct-io.cmodified+4−5View file
fs/jbd2/checkpoint.cmodified+1−1View file
fs/jbd2/commit.cmodified+2−2View file
fs/jbd2/recovery.cmodified+1−1View file
fs/libfs.cmodified+1−1View file
fs/nfs/blocklayout/blocklayout.cmodified+0−5View file
fs/nfsd/blocklayout.cmodified+1−1View file
fs/nilfs2/segbuf.cmodified+0−4View file
fs/nilfs2/the_nilfs.hmodified+1−1View file
fs/ocfs2/file.cmodified+1−1View file
fs/reiserfs/file.cmodified+1−1View file
fs/splice.cmodified+6−3View file
fs/super.cmodified+2−1View file
fs/xfs/xfs_super.cmodified+1−1View file
fs/zonefs/super.cmodified+6−7View file
include/linux/bio.hmodified+28−27View file
include/linux/blk-mq.hmodified+2−6View file
include/linux/blk_types.hmodified+3−30View file
include/linux/blkdev.hmodified+25−28View file
include/linux/elevator.hmodified+2−0View file
include/linux/genhd.hmodified+9−18View file
include/linux/swap.hmodified+0−1View file
kernel/trace/blktrace.cmodified+9−7View file
lib/iov_iter.cmodified+19−2View file
mm/page_io.cmodified+14−33View file
mm/swapfile.cmodified+3−33View file

Only the first 600 diff lines are shown. Download the complete patch.

Documentation/block/biovecs.rst

View file
diff --git a/Documentation/block/biovecs.rst b/Documentation/block/biovecs.rst
index 36771a1..ddb867e 100644
--- a/Documentation/block/biovecs.rst
+++ b/Documentation/block/biovecs.rst
@@ -40,6 +40,8 @@ normal code doesn't have to deal with bi_bvec_done.
There is a lower level advance function - bvec_iter_advance() - which takes
a pointer to a biovec, not a bio; this is used by the bio integrity code.
+As of 5.12 bvec segments with zero bv_len are not supported.
+
What's all this get us?
=======================

Documentation/block/queue-sysfs.rst

View file
diff --git a/Documentation/block/queue-sysfs.rst b/Documentation/block/queue-sysfs.rst
index 2638d34..4dc7f0d 100644
--- a/Documentation/block/queue-sysfs.rst
+++ b/Documentation/block/queue-sysfs.rst
@@ -261,6 +261,12 @@ For block drivers that support REQ_OP_WRITE_ZEROES, the maximum number of
bytes that can be zeroed at once. The value 0 means that REQ_OP_WRITE_ZEROES
is not supported.
+zone_append_max_bytes (RO)
+--------------------------
+This is the maximum number of bytes that can be written to a sequential
+zone of a zoned block device using a zone append write operation
+(REQ_OP_ZONE_APPEND). This value is always 0 for regular block devices.
+
zoned (RO)
----------
This indicates if the device is a zoned block device and the zone model of the
@@ -273,4 +279,11 @@ devices are described in the ZBC (Zoned Block Commands) and ZAC
do not support zone commands, they will be treated as regular block devices
and zoned will report "none".
+zone_write_granularity (RO)
+---------------------------
+This indicates the alignment constraint, in bytes, for write operations in
+sequential zones of zoned block devices (devices with a zoned attributed
+that reports "host-managed" or "host-aware"). This value is always 0 for
+regular block devices.
+
Jens Axboe <[email protected]>, February 2009

Documentation/filesystems/f2fs.rst

View file
diff --git a/Documentation/filesystems/f2fs.rst b/Documentation/filesystems/f2fs.rst
index 81c05ba..35ed01a 100644
--- a/Documentation/filesystems/f2fs.rst
+++ b/Documentation/filesystems/f2fs.rst
@@ -179,7 +179,6 @@ fault_type=%d Support configuring fault injection type, should be
FAULT_KVMALLOC 0x000000002
FAULT_PAGE_ALLOC 0x000000004
FAULT_PAGE_GET 0x000000008
- FAULT_ALLOC_BIO 0x000000010
FAULT_ALLOC_NID 0x000000020
FAULT_ORPHAN 0x000000040
FAULT_BLOCK 0x000000080

Documentation/filesystems/porting.rst

View file
diff --git a/Documentation/filesystems/porting.rst b/Documentation/filesystems/porting.rst
index 867036a..1f8cf8e 100644
--- a/Documentation/filesystems/porting.rst
+++ b/Documentation/filesystems/porting.rst
@@ -865,3 +865,19 @@ no matter what. Everything is handled by the caller.
clone_private_mount() returns a longterm mount now, so the proper destructor of
its result is kern_unmount() or kern_unmount_array().
+
+---
+
+**mandatory**
+
+zero-length bvec segments are disallowed, they must be filtered out before
+passed on to an iterator.
+
+---
+
+**mandatory**
+
+For bvec based itererators bio_iov_iter_get_pages() now doesn't copy bvecs but
+uses the one provided. Anyone issuing kiocb-I/O should ensure that the bvec and
+page references stay until I/O has completed, i.e. until ->ki_complete() has
+been called or returned with non -EIOCBQUEUED code.

arch/m68k/emu/nfblock.c

View file
diff --git a/arch/m68k/emu/nfblock.c b/arch/m68k/emu/nfblock.c
index 92d26c8..ba80854 100644
--- a/arch/m68k/emu/nfblock.c
+++ b/arch/m68k/emu/nfblock.c
@@ -61,7 +61,7 @@ struct nfhd_device {
static blk_qc_t nfhd_submit_bio(struct bio *bio)
{
- struct nfhd_device *dev = bio->bi_disk->private_data;
+ struct nfhd_device *dev = bio->bi_bdev->bd_disk->private_data;
struct bio_vec bvec;
struct bvec_iter iter;
int dir, len, shift;

arch/xtensa/platforms/iss/simdisk.c

View file
diff --git a/arch/xtensa/platforms/iss/simdisk.c b/arch/xtensa/platforms/iss/simdisk.c
index 3447556..fc09be7 100644
--- a/arch/xtensa/platforms/iss/simdisk.c
+++ b/arch/xtensa/platforms/iss/simdisk.c
@@ -103,7 +103,7 @@ static void simdisk_transfer(struct simdisk *dev, unsigned long sector,
static blk_qc_t simdisk_submit_bio(struct bio *bio)
{
- struct simdisk *dev = bio->bi_disk->private_data;
+ struct simdisk *dev = bio->bi_bdev->bd_disk->private_data;
struct bio_vec bvec;
struct bvec_iter iter;
sector_t sector = bio->bi_iter.bi_sector;

block/bfq-iosched.c

View file
diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c
index 9e81d10..b398dde 100644
--- a/block/bfq-iosched.c
+++ b/block/bfq-iosched.c
@@ -158,7 +158,6 @@ BFQ_BFQQ_FNS(in_large_burst);
BFQ_BFQQ_FNS(coop);
BFQ_BFQQ_FNS(split_coop);
BFQ_BFQQ_FNS(softrt_update);
-BFQ_BFQQ_FNS(has_waker);
#undef BFQ_BFQQ_FNS \
/* Expiration time of sync (0) and async (1) requests, in ns. */
@@ -1024,9 +1023,16 @@ bfq_bfqq_resume_state(struct bfq_queue *bfqq, struct bfq_data *bfqd,
else
bfq_clear_bfqq_IO_bound(bfqq);
+ bfqq->last_serv_time_ns = bic->saved_last_serv_time_ns;
+ bfqq->inject_limit = bic->saved_inject_limit;
+ bfqq->decrease_time_jif = bic->saved_decrease_time_jif;
+
bfqq->entity.new_weight = bic->saved_weight;
bfqq->ttime = bic->saved_ttime;
+ bfqq->io_start_time = bic->saved_io_start_time;
+ bfqq->tot_idle_time = bic->saved_tot_idle_time;
bfqq->wr_coeff = bic->saved_wr_coeff;
+ bfqq->service_from_wr = bic->saved_service_from_wr;
bfqq->wr_start_at_switch_to_srt = bic->saved_wr_start_at_switch_to_srt;
bfqq->last_wr_start_finish = bic->saved_last_wr_start_finish;
bfqq->wr_cur_max_time = bic->saved_wr_cur_max_time;
@@ -1647,6 +1653,8 @@ static bool bfq_bfqq_higher_class_or_weight(struct bfq_queue *bfqq,
return bfqq_weight > in_serv_weight;
}
+static bool bfq_better_to_idle(struct bfq_queue *bfqq);
+
static void bfq_bfqq_handle_idle_busy_switch(struct bfq_data *bfqd,
struct bfq_queue *bfqq,
int old_wr_coeff,
@@ -1671,15 +1679,19 @@ static void bfq_bfqq_handle_idle_busy_switch(struct bfq_data *bfqd,
* - it is sync,
* - it does not belong to a large burst,
* - it has been idle for enough time or is soft real-time,
- * - is linked to a bfq_io_cq (it is not shared in any sense).
+ * - is linked to a bfq_io_cq (it is not shared in any sense),
+ * - has a default weight (otherwise we assume the user wanted
+ * to control its weight explicitly)
*/
in_burst = bfq_bfqq_in_large_burst(bfqq);
soft_rt = bfqd->bfq_wr_max_softrt_rate > 0 &&
!BFQQ_TOTALLY_SEEKY(bfqq) &&
!in_burst &&
time_is_before_jiffies(bfqq->soft_rt_next_start) &&
- bfqq->dispatched == 0;
- *interactive = !in_burst && idle_for_long_time;
+ bfqq->dispatched == 0 &&
+ bfqq->entity.new_weight == 40;
+ *interactive = !in_burst && idle_for_long_time &&
+ bfqq->entity.new_weight == 40;
wr_or_deserves_wr = bfqd->low_latency &&
(bfqq->wr_coeff > 1 ||
(bfq_bfqq_sync(bfqq) &&
@@ -1717,17 +1729,6 @@ static void bfq_bfqq_handle_idle_busy_switch(struct bfq_data *bfqd,
bfq_clear_bfqq_just_created(bfqq);
-
- if (!bfq_bfqq_IO_bound(bfqq)) {
- if (arrived_in_time) {
- bfqq->requests_within_timer++;
- if (bfqq->requests_within_timer >=
- bfqd->bfq_requests_within_timer)
- bfq_mark_bfqq_IO_bound(bfqq);
- } else
- bfqq->requests_within_timer = 0;
- }
-
if (bfqd->low_latency) {
if (unlikely(time_is_after_jiffies(bfqq->split_time)))
/* wraparound */
@@ -1755,10 +1756,10 @@ static void bfq_bfqq_handle_idle_busy_switch(struct bfq_data *bfqd,
bfq_add_bfqq_busy(bfqd, bfqq);
/*
- * Expire in-service queue only if preemption may be needed
- * for guarantees. In particular, we care only about two
- * cases. The first is that bfqq has to recover a service
- * hole, as explained in the comments on
+ * Expire in-service queue if preemption may be needed for
+ * guarantees or throughput. As for guarantees, we care
+ * explicitly about two cases. The first is that bfqq has to
+ * recover a service hole, as explained in the comments on
* bfq_bfqq_update_budg_for_activation(), i.e., that
* bfqq_wants_to_preempt is true. However, if bfqq does not
* carry time-critical I/O, then bfqq's bandwidth is less
@@ -1785,11 +1786,23 @@ static void bfq_bfqq_handle_idle_busy_switch(struct bfq_data *bfqd,
* timestamps of the in-service queue would need to be
* updated, and this operation is quite costly (see the
* comments on bfq_bfqq_update_budg_for_activation()).
+ *
+ * As for throughput, we ask bfq_better_to_idle() whether we
+ * still need to plug I/O dispatching. If bfq_better_to_idle()
+ * says no, then plugging is not needed any longer, either to
+ * boost throughput or to perserve service guarantees. Then
+ * the best option is to stop plugging I/O, as not doing so
+ * would certainly lower throughput. We may end up in this
+ * case if: (1) upon a dispatch attempt, we detected that it
+ * was better to plug I/O dispatch, and to wait for a new
+ * request to arrive for the currently in-service queue, but
+ * (2) this switch of bfqq to busy changes the scenario.
*/
if (bfqd->in_service_queue &&
((bfqq_wants_to_preempt &&
bfqq->wr_coeff >= bfqd->in_service_queue->wr_coeff) ||
- bfq_bfqq_higher_class_or_weight(bfqq, bfqd->in_service_queue)) &&
+ bfq_bfqq_higher_class_or_weight(bfqq, bfqd->in_service_queue) ||
+ !bfq_better_to_idle(bfqd->in_service_queue)) &&
next_queue_may_preempt(bfqd))
bfq_bfqq_expire(bfqd, bfqd->in_service_queue,
false, BFQQE_PREEMPTED);
@@ -1861,6 +1874,138 @@ static void bfq_reset_inject_limit(struct bfq_data *bfqd,
bfqq->decrease_time_jif = jiffies;
}
+static void bfq_update_io_intensity(struct bfq_queue *bfqq, u64 now_ns)
+{
+ u64 tot_io_time = now_ns - bfqq->io_start_time;
+
+ if (RB_EMPTY_ROOT(&bfqq->sort_list) && bfqq->dispatched == 0)
+ bfqq->tot_idle_time +=
+ now_ns - bfqq->ttime.last_end_request;
+
+ if (unlikely(bfq_bfqq_just_created(bfqq)))
+ return;
+
+ /*
+ * Must be busy for at least about 80% of the time to be
+ * considered I/O bound.
+ */
+ if (bfqq->tot_idle_time * 5 > tot_io_time)
+ bfq_clear_bfqq_IO_bound(bfqq);
+ else
+ bfq_mark_bfqq_IO_bound(bfqq);
+
+ /*
+ * Keep an observation window of at most 200 ms in the past
+ * from now.
+ */
+ if (tot_io_time > 200 * NSEC_PER_MSEC) {
+ bfqq->io_start_time = now_ns - (tot_io_time>>1);
+ bfqq->tot_idle_time >>= 1;
+ }
+}
+
+/*
+ * Detect whether bfqq's I/O seems synchronized with that of some
+ * other queue, i.e., whether bfqq, after remaining empty, happens to
+ * receive new I/O only right after some I/O request of the other
+ * queue has been completed. We call waker queue the other queue, and
+ * we assume, for simplicity, that bfqq may have at most one waker
+ * queue.
+ *
+ * A remarkable throughput boost can be reached by unconditionally
+ * injecting the I/O of the waker queue, every time a new
+ * bfq_dispatch_request happens to be invoked while I/O is being
+ * plugged for bfqq. In addition to boosting throughput, this
+ * unblocks bfqq's I/O, thereby improving bandwidth and latency for
+ * bfqq. Note that these same results may be achieved with the general
+ * injection mechanism, but less effectively. For details on this
+ * aspect, see the comments on the choice of the queue for injection
+ * in bfq_select_queue().
+ *
+ * Turning back to the detection of a waker queue, a queue Q is deemed
+ * as a waker queue for bfqq if, for three consecutive times, bfqq
+ * happens to become non empty right after a request of Q has been
+ * completed. In particular, on the first time, Q is tentatively set
+ * as a candidate waker queue, while on the third consecutive time
+ * that Q is detected, the field waker_bfqq is set to Q, to confirm
+ * that Q is a waker queue for bfqq. These detection steps are
+ * performed only if bfqq has a long think time, so as to make it more
+ * likely that bfqq's I/O is actually being blocked by a
+ * synchronization. This last filter, plus the above three-times
+ * requirement, make false positives less likely.
+ *
+ * NOTE
+ *
+ * The sooner a waker queue is detected, the sooner throughput can be
+ * boosted by injecting I/O from the waker queue. Fortunately,
+ * detection is likely to be actually fast, for the following
+ * reasons. While blocked by synchronization, bfqq has a long think
+ * time. This implies that bfqq's inject limit is at least equal to 1
+ * (see the comments in bfq_update_inject_limit()). So, thanks to
+ * injection, the waker queue is likely to be served during the very
+ * first I/O-plugging time interval for bfqq. This triggers the first
+ * step of the detection mechanism. Thanks again to injection, the
+ * candidate waker queue is then likely to be confirmed no later than
+ * during the next I/O-plugging interval for bfqq.
+ *
+ * ISSUE
+ *
+ * On queue merging all waker information is lost.
+ */
+static void bfq_check_waker(struct bfq_data *bfqd, struct bfq_queue *bfqq,
+ u64 now_ns)
+{
+ if (!bfqd->last_completed_rq_bfqq ||
+ bfqd->last_completed_rq_bfqq == bfqq ||
+ bfq_bfqq_has_short_ttime(bfqq) ||
+ now_ns - bfqd->last_completion >= 4 * NSEC_PER_MSEC ||
+ bfqd->last_completed_rq_bfqq == bfqq->waker_bfqq)
+ return;
+
+ if (bfqd->last_completed_rq_bfqq !=
+ bfqq->tentative_waker_bfqq) {
+ /*
+ * First synchronization detected with a
+ * candidate waker queue, or with a different
+ * candidate waker queue from the current one.
+ */
+ bfqq->tentative_waker_bfqq =
+ bfqd->last_completed_rq_bfqq;
+ bfqq->num_waker_detections = 1;
+ } else /* Same tentative waker queue detected again */
+ bfqq->num_waker_detections++;
+
+ if (bfqq->num_waker_detections == 3) {
+ bfqq->waker_bfqq = bfqd->last_completed_rq_bfqq;
+ bfqq->tentative_waker_bfqq = NULL;
+
+ /*
+ * If the waker queue disappears, then
+ * bfqq->waker_bfqq must be reset. To
+ * this goal, we maintain in each
+ * waker queue a list, woken_list, of
+ * all the queues that reference the
+ * waker queue through their
+ * waker_bfqq pointer. When the waker
+ * queue exits, the waker_bfqq pointer
+ * of all the queues in the woken_list
+ * is reset.
+ *
+ * In addition, if bfqq is already in
+ * the woken_list of a waker queue,
+ * then, before being inserted into
+ * the woken_list of a new waker
+ * queue, bfqq must be removed from
+ * the woken_list of the old waker
+ * queue.
+ */
+ if (!hlist_unhashed(&bfqq->woken_list_node))
+ hlist_del_init(&bfqq->woken_list_node);
+ hlist_add_head(&bfqq->woken_list_node,
+ &bfqd->last_completed_rq_bfqq->woken_list);
+ }
+}
+
static void bfq_add_request(struct request *rq)
{
struct bfq_queue *bfqq = RQ_BFQQ(rq);
@@ -1868,117 +2013,14 @@ static void bfq_add_request(struct request *rq)
struct request *next_rq, *prev;
unsigned int old_wr_coeff = bfqq->wr_coeff;
bool interactive = false;
+ u64 now_ns = ktime_get_ns();
bfq_log_bfqq(bfqd, bfqq, "add_request %d", rq_is_sync(rq));
bfqq->queued[rq_is_sync(rq)]++;
bfqd->queued++;
if (RB_EMPTY_ROOT(&bfqq->sort_list) && bfq_bfqq_sync(bfqq)) {
- /*
- * Detect whether bfqq's I/O seems synchronized with
- * that of some other queue, i.e., whether bfqq, after
- * remaining empty, happens to receive new I/O only
- * right after some I/O request of the other queue has
- * been completed. We call waker queue the other
- * queue, and we assume, for simplicity, that bfqq may
- * have at most one waker queue.
- *
- * A remarkable throughput boost can be reached by
- * unconditionally injecting the I/O of the waker
- * queue, every time a new bfq_dispatch_request
- * happens to be invoked while I/O is being plugged
- * for bfqq. In addition to boosting throughput, this
- * unblocks bfqq's I/O, thereby improving bandwidth
- * and latency for bfqq. Note that these same results
- * may be achieved with the general injection
- * mechanism, but less effectively. For details on
- * this aspect, see the comments on the choice of the
- * queue for injection in bfq_select_queue().
- *
- * Turning back to the detection of a waker queue, a
- * queue Q is deemed as a waker queue for bfqq if, for
- * two consecutive times, bfqq happens to become non
- * empty right after a request of Q has been
- * completed. In particular, on the first time, Q is
- * tentatively set as a candidate waker queue, while
- * on the second time, the flag
- * bfq_bfqq_has_waker(bfqq) is set to confirm that Q
- * is a waker queue for bfqq. These detection steps
- * are performed only if bfqq has a long think time,
- * so as to make it more likely that bfqq's I/O is
- * actually being blocked by a synchronization. This
- * last filter, plus the above two-times requirement,
- * make false positives less likely.
- *
- * NOTE
- *
- * The sooner a waker queue is detected, the sooner
- * throughput can be boosted by injecting I/O from the
- * waker queue. Fortunately, detection is likely to be
- * actually fast, for the following reasons. While
- * blocked by synchronization, bfqq has a long think
- * time. This implies that bfqq's inject limit is at
- * least equal to 1 (see the comments in
- * bfq_update_inject_limit()). So, thanks to
- * injection, the waker queue is likely to be served
- * during the very first I/O-plugging time interval
- * for bfqq. This triggers the first step of the
- * detection mechanism. Thanks again to injection, the
- * candidate waker queue is then likely to be
- * confirmed no later than during the next
- * I/O-plugging interval for bfqq.
- */
- if (bfqd->last_completed_rq_bfqq &&
- !bfq_bfqq_has_short_ttime(bfqq) &&
- ktime_get_ns() - bfqd->last_completion <
- 200 * NSEC_PER_USEC) {
- if (bfqd->last_completed_rq_bfqq != bfqq &&
- bfqd->last_completed_rq_bfqq !=
- bfqq->waker_bfqq) {
- /*
- * First synchronization detected with
- * a candidate waker queue, or with a
- * different candidate waker queue
- * from the current one.
- */
- bfqq->waker_bfqq = bfqd->last_completed_rq_bfqq;
-
- /*
- * If the waker queue disappears, then
- * bfqq->waker_bfqq must be reset. To
- * this goal, we maintain in each
- * waker queue a list, woken_list, of
- * all the queues that reference the
- * waker queue through their
- * waker_bfqq pointer. When the waker
- * queue exits, the waker_bfqq pointer
- * of all the queues in the woken_list
- * is reset.
- *
- * In addition, if bfqq is already in
- * the woken_list of a waker queue,
- * then, before being inserted into
- * the woken_list of a new waker
- * queue, bfqq must be removed from
- * the woken_list of the old waker
- * queue.
- */
- if (!hlist_unhashed(&bfqq->woken_list_node))
- hlist_del_init(&bfqq->woken_list_node);
- hlist_add_head(&bfqq->woken_list_node,
- &bfqd->last_completed_rq_bfqq->woken_list);
-
- bfq_clear_bfqq_has_waker(bfqq);
- } else if (bfqd->last_completed_rq_bfqq ==
- bfqq->waker_bfqq &&
- !bfq_bfqq_has_waker(bfqq)) {
- /*
- * synchronization with waker_bfqq
- * seen for the second time
- */
- bfq_mark_bfqq_has_waker(bfqq);
- }
- }
+ bfq_check_waker(bfqd, bfqq, now_ns);
/*
* Periodically reset inject limit, to make sure that
@@ -2047,6 +2089,9 @@ static void bfq_add_request(struct request *rq)
}
}
+ if (bfq_bfqq_sync(bfqq))
+ bfq_update_io_intensity(bfqq, now_ns);
+
elv_rb_add(&bfqq->sort_list, rq);
/*
@@ -2352,6 +2397,24 @@ static void bfq_requests_merged(struct request_queue *q, struct request *rq,
/* Must be called with bfqq != NULL */
static void bfq_bfqq_end_wr(struct bfq_queue *bfqq)
{
+ /*
+ * If bfqq has been enjoying interactive weight-raising, then
+ * reset soft_rt_next_start. We do it for the following
+ * reason. bfqq may have been conveying the I/O needed to load
+ * a soft real-time application. Such an application actually
+ * exhibits a soft real-time I/O pattern after it finishes
+ * loading, and finally starts doing its job. But, if bfqq has
+ * been receiving a lot of bandwidth so far (likely to happen
+ * on a fast device), then soft_rt_next_start now contains a
+ * high value that. So, without this reset, bfqq would be
+ * prevented from being possibly considered as soft_rt for a
+ * very long time.
+ */
+
+ if (bfqq->wr_cur_max_time !=
+ bfqq->bfqd->bfq_wr_rt_max_time)
+ bfqq->soft_rt_next_start = jiffies;
+
if (bfq_bfqq_busy(bfqq))
bfqq->bfqd->wr_busy_queues--;
bfqq->wr_coeff = 1;
@@ -2686,10 +2749,16 @@ static void bfq_bfqq_save_state(struct bfq_queue *bfqq)
if (!bic)
return;
+ bic->saved_last_serv_time_ns = bfqq->last_serv_time_ns;
+ bic->saved_inject_limit = bfqq->inject_limit;
+ bic->saved_decrease_time_jif = bfqq->decrease_time_jif;
+
bic->saved_weight = bfqq->entity.orig_weight;
bic->saved_ttime = bfqq->ttime;
bic->saved_has_short_ttime = bfq_bfqq_has_short_ttime(bfqq);
bic->saved_IO_bound = bfq_bfqq_IO_bound(bfqq);
+ bic->saved_io_start_time = bfqq->io_start_time;
+ bic->saved_tot_idle_time = bfqq->tot_idle_time;
bic->saved_in_large_burst = bfq_bfqq_in_large_burst(bfqq);
bic->was_in_burst_list = !hlist_unhashed(&bfqq->burst_list_node);
if (unlikely(bfq_bfqq_just_created(bfqq) &&
@@ -2712,6 +2781,7 @@ static void bfq_bfqq_save_state(struct bfq_queue *bfqq)
bic->saved_wr_coeff = bfqq->wr_coeff;
bic->saved_wr_start_at_switch_to_srt =
bfqq->wr_start_at_switch_to_srt;
+ bic->saved_service_from_wr = bfqq->service_from_wr;
bic->saved_last_wr_start_finish = bfqq->last_wr_start_finish;
bic->saved_wr_cur_max_time = bfqq->wr_cur_max_time;
}
@@ -2937,6 +3007,7 @@ static void __bfq_set_in_service_queue(struct bfq_data *bfqd,
}
bfqd->in_service_queue = bfqq;
+ bfqd->in_serv_last_pos = 0;
}
/*
@@ -3442,20 +3513,38 @@ static void bfq_dispatch_remove(struct request_queue *q, struct request *rq)
* order until all the requests already queued in the device have been
* served. The last sub-condition commented above somewhat mitigates
* this problem for weight-raised queues.
+ *
+ * However, as an additional mitigation for this problem, we preserve
+ * plugging for a special symmetric case that may suddenly turn into
+ * asymmetric: the case where only bfqq is busy. In this case, not
+ * expiring bfqq does not cause any harm to any other queues in terms
+ * of service guarantees. In contrast, it avoids the following unlucky
+ * sequence of events: (1) bfqq is expired, (2) a new queue with a
+ * lower weight than bfqq becomes busy (or more queues), (3) the new
+ * queue is served until a new request arrives for bfqq, (4) when bfqq
+ * is finally served, there are so many requests of the new queue in
+ * the drive that the pending requests for bfqq take a lot of time to
+ * be served. In particular, event (2) may case even already
+ * dispatched requests of bfqq to be delayed, inside the drive. So, to
+ * avoid this series of events, the scenario is preventively declared
+ * as asymmetric also if bfqq is the only busy queues
*/
static bool idling_needed_for_service_guarantees(struct bfq_data *bfqd,
struct bfq_queue *bfqq)
{
+ int tot_busy_queues = bfq_tot_busy_queues(bfqd);
+
/* No point in idling for bfqq if it won't get requests any longer */
if (unlikely(!bfqq_process_refs(bfqq)))
return false;
return (bfqq->wr_coeff > 1 &&
(bfqd->wr_busy_queues <
- bfq_tot_busy_queues(bfqd) ||
+ tot_busy_queues ||
bfqd->rq_in_driver >=
bfqq->dispatched + 4)) ||
- bfq_asymmetric_scenario(bfqd, bfqq);
+ bfq_asymmetric_scenario(bfqd, bfqq) ||
+ tot_busy_queues == 1;
}
static bool __bfq_bfqq_expire(struct bfq_data *bfqd, struct bfq_queue *bfqq,
@@ -3939,10 +4028,6 @@ void bfq_bfqq_expire(struct bfq_data *bfqd,
bfq_bfqq_budget_left(bfqq) >= entity->budget / 3)))
bfq_bfqq_charge_time(bfqd, bfqq, delta);
- if (reason == BFQQE_TOO_IDLE &&
- entity->service <= 2 * entity->budget / 10)
- bfq_clear_bfqq_IO_bound(bfqq);
-
if (bfqd->low_latency && bfqq->wr_coeff == 1)

This diff is incomplete. Download the complete patch.

block/bfq-iosched.h

View file

This diff is incomplete. Download the complete patch.

block/bfq-wf2q.c

View file

This diff is incomplete. Download the complete patch.

block/bio-integrity.c

View file

This diff is incomplete. Download the complete patch.

block/bio.c

View file

This diff is incomplete. Download the complete patch.

block/blk-cgroup.c

View file

This diff is incomplete. Download the complete patch.

block/blk-core.c

View file

This diff is incomplete. Download the complete patch.

block/blk-crypto-fallback.c

View file

This diff is incomplete. Download the complete patch.

block/blk-crypto.c

View file

This diff is incomplete. Download the complete patch.

block/blk-exec.c

View file

This diff is incomplete. Download the complete patch.

block/blk-flush.c

View file

This diff is incomplete. Download the complete patch.

block/blk-merge.c

View file

This diff is incomplete. Download the complete patch.

block/blk-mq.c

View file

This diff is incomplete. Download the complete patch.

block/blk-settings.c

View file

This diff is incomplete. Download the complete patch.

block/blk-sysfs.c

View file

This diff is incomplete. Download the complete patch.

block/blk-throttle.c

View file

This diff is incomplete. Download the complete patch.

block/blk-wbt.c

View file

This diff is incomplete. Download the complete patch.

block/blk-zoned.c

View file

This diff is incomplete. Download the complete patch.

block/blk.h

View file

This diff is incomplete. Download the complete patch.

block/bounce.c

View file

This diff is incomplete. Download the complete patch.

block/bsg.c

View file

This diff is incomplete. Download the complete patch.

block/genhd.c

View file

This diff is incomplete. Download the complete patch.

block/kyber-iosched.c

View file

This diff is incomplete. Download the complete patch.

block/mq-deadline.c

View file

This diff is incomplete. Download the complete patch.

block/partitions/core.c

View file

This diff is incomplete. Download the complete patch.

block/scsi_ioctl.c

View file

This diff is incomplete. Download the complete patch.

drivers/block/brd.c

View file

This diff is incomplete. Download the complete patch.

drivers/block/drbd/drbd_actlog.c

View file

This diff is incomplete. Download the complete patch.

drivers/block/drbd/drbd_bitmap.c

View file

This diff is incomplete. Download the complete patch.

drivers/block/drbd/drbd_int.h

View file

This diff is incomplete. Download the complete patch.

drivers/block/drbd/drbd_main.c

View file

This diff is incomplete. Download the complete patch.

drivers/block/drbd/drbd_req.c

View file

This diff is incomplete. Download the complete patch.

drivers/block/drbd/drbd_req.h

View file

This diff is incomplete. Download the complete patch.

drivers/block/drbd/drbd_worker.c

View file

This diff is incomplete. Download the complete patch.

drivers/block/mtip32xx/mtip32xx.c

View file

This diff is incomplete. Download the complete patch.

drivers/block/null_blk/main.c

View file

This diff is incomplete. Download the complete patch.

drivers/block/null_blk/zoned.c

View file

This diff is incomplete. Download the complete patch.

drivers/block/paride/pd.c

View file

This diff is incomplete. Download the complete patch.

drivers/block/pktcdvd.c

View file

This diff is incomplete. Download the complete patch.

drivers/block/ps3vram.c

View file

This diff is incomplete. Download the complete patch.

drivers/block/rbd.c

View file

This diff is incomplete. Download the complete patch.

drivers/block/rsxx/dev.c

View file

This diff is incomplete. Download the complete patch.

drivers/block/sx8.c

View file

This diff is incomplete. Download the complete patch.

drivers/block/umem.c

View file

This diff is incomplete. Download the complete patch.

drivers/block/virtio_blk.c

View file

This diff is incomplete. Download the complete patch.

drivers/block/zram/zram_drv.c

View file

This diff is incomplete. Download the complete patch.

drivers/cdrom/cdrom.c

View file

This diff is incomplete. Download the complete patch.

drivers/ide/ide-atapi.c

View file

This diff is incomplete. Download the complete patch.

drivers/ide/ide-cd.c

View file

This diff is incomplete. Download the complete patch.

drivers/ide/ide-cd_ioctl.c

View file

This diff is incomplete. Download the complete patch.

drivers/ide/ide-devsets.c

View file

This diff is incomplete. Download the complete patch.

drivers/ide/ide-disk.c

View file

This diff is incomplete. Download the complete patch.

drivers/ide/ide-ioctls.c

View file

This diff is incomplete. Download the complete patch.

drivers/ide/ide-park.c

View file

This diff is incomplete. Download the complete patch.

drivers/ide/ide-pm.c

View file

This diff is incomplete. Download the complete patch.

drivers/ide/ide-tape.c

View file

This diff is incomplete. Download the complete patch.

drivers/ide/ide-taskfile.c

View file

This diff is incomplete. Download the complete patch.

drivers/lightnvm/pblk-init.c

View file

This diff is incomplete. Download the complete patch.

drivers/md/bcache/debug.c

View file

This diff is incomplete. Download the complete patch.

drivers/md/bcache/request.c

View file

This diff is incomplete. Download the complete patch.

drivers/md/bcache/super.c

View file

This diff is incomplete. Download the complete patch.

drivers/md/dm-bio-record.h

View file

This diff is incomplete. Download the complete patch.

drivers/md/dm-cache-metadata.c

View file

This diff is incomplete. Download the complete patch.

drivers/md/dm-clone-target.c

View file

This diff is incomplete. Download the complete patch.

drivers/md/dm-raid1.c

View file

This diff is incomplete. Download the complete patch.

drivers/md/dm-thin-metadata.c

View file

This diff is incomplete. Download the complete patch.

drivers/md/dm-zoned-metadata.c

View file

This diff is incomplete. Download the complete patch.

drivers/md/dm.c

View file

This diff is incomplete. Download the complete patch.

drivers/md/md-linear.c

View file

This diff is incomplete. Download the complete patch.

drivers/md/md.c

View file

This diff is incomplete. Download the complete patch.

drivers/md/md.h

View file

This diff is incomplete. Download the complete patch.

drivers/md/raid1.c

View file

This diff is incomplete. Download the complete patch.

drivers/md/raid10.c

View file

This diff is incomplete. Download the complete patch.

drivers/md/raid5-ppl.c

View file

This diff is incomplete. Download the complete patch.

drivers/md/raid5.c

View file

This diff is incomplete. Download the complete patch.

drivers/mmc/core/block.c

View file

This diff is incomplete. Download the complete patch.

drivers/nvdimm/blk.c

View file

This diff is incomplete. Download the complete patch.

drivers/nvdimm/btt.c

View file

This diff is incomplete. Download the complete patch.

drivers/nvdimm/pmem.c

View file

This diff is incomplete. Download the complete patch.

drivers/nvme/host/core.c

View file

This diff is incomplete. Download the complete patch.

drivers/nvme/host/lightnvm.c

View file

This diff is incomplete. Download the complete patch.

drivers/nvme/host/multipath.c

View file

This diff is incomplete. Download the complete patch.

drivers/nvme/host/pci.c

View file

This diff is incomplete. Download the complete patch.

drivers/nvme/host/rdma.c

View file

This diff is incomplete. Download the complete patch.

drivers/nvme/host/zns.c

View file

This diff is incomplete. Download the complete patch.

drivers/nvme/target/io-cmd-bdev.c

View file

This diff is incomplete. Download the complete patch.

drivers/nvme/target/passthru.c

View file

This diff is incomplete. Download the complete patch.

drivers/s390/block/dasd.c

View file

This diff is incomplete. Download the complete patch.

drivers/s390/block/dcssblk.c

View file

This diff is incomplete. Download the complete patch.

drivers/s390/block/xpram.c

View file

This diff is incomplete. Download the complete patch.

drivers/scsi/scsi_error.c

View file

This diff is incomplete. Download the complete patch.

drivers/scsi/scsi_lib.c

View file

This diff is incomplete. Download the complete patch.

drivers/scsi/sd_zbc.c

View file

This diff is incomplete. Download the complete patch.

drivers/scsi/sg.c

View file

This diff is incomplete. Download the complete patch.

drivers/scsi/st.c

View file

This diff is incomplete. Download the complete patch.

drivers/target/target_core_file.c

View file

This diff is incomplete. Download the complete patch.

drivers/target/target_core_pscsi.c

View file

This diff is incomplete. Download the complete patch.

fs/block_dev.c

View file

This diff is incomplete. Download the complete patch.

fs/btrfs/check-integrity.c

View file

This diff is incomplete. Download the complete patch.

fs/btrfs/raid56.c

View file

This diff is incomplete. Download the complete patch.

fs/btrfs/scrub.c

View file

This diff is incomplete. Download the complete patch.

fs/btrfs/volumes.c

View file

This diff is incomplete. Download the complete patch.

fs/btrfs/zoned.c

View file

This diff is incomplete. Download the complete patch.

fs/direct-io.c

View file

This diff is incomplete. Download the complete patch.

fs/exfat/file.c

View file

This diff is incomplete. Download the complete patch.

fs/ext4/fast_commit.c

View file

This diff is incomplete. Download the complete patch.

fs/ext4/fsync.c

View file

This diff is incomplete. Download the complete patch.

fs/ext4/ialloc.c

View file

This diff is incomplete. Download the complete patch.

fs/ext4/super.c

View file

This diff is incomplete. Download the complete patch.

fs/f2fs/data.c

View file

This diff is incomplete. Download the complete patch.

fs/f2fs/f2fs.h

View file

This diff is incomplete. Download the complete patch.

fs/f2fs/segment.c

View file

This diff is incomplete. Download the complete patch.

fs/f2fs/super.c

View file

This diff is incomplete. Download the complete patch.

fs/fat/file.c

View file

This diff is incomplete. Download the complete patch.

fs/hfsplus/inode.c

View file

This diff is incomplete. Download the complete patch.

fs/hfsplus/super.c

View file

This diff is incomplete. Download the complete patch.

fs/iomap/direct-io.c

View file

This diff is incomplete. Download the complete patch.

fs/jbd2/checkpoint.c

View file

This diff is incomplete. Download the complete patch.

fs/jbd2/commit.c

View file

This diff is incomplete. Download the complete patch.

fs/jbd2/recovery.c

View file

This diff is incomplete. Download the complete patch.

fs/libfs.c

View file

This diff is incomplete. Download the complete patch.

fs/nfs/blocklayout/blocklayout.c

View file

This diff is incomplete. Download the complete patch.

fs/nfsd/blocklayout.c

View file

This diff is incomplete. Download the complete patch.

fs/nilfs2/segbuf.c

View file

This diff is incomplete. Download the complete patch.

fs/nilfs2/the_nilfs.h

View file

This diff is incomplete. Download the complete patch.

fs/ocfs2/file.c

View file

This diff is incomplete. Download the complete patch.

fs/reiserfs/file.c

View file

This diff is incomplete. Download the complete patch.

fs/splice.c

View file

This diff is incomplete. Download the complete patch.

fs/super.c

View file

This diff is incomplete. Download the complete patch.

fs/xfs/xfs_super.c

View file

This diff is incomplete. Download the complete patch.

fs/zonefs/super.c

View file

This diff is incomplete. Download the complete patch.

include/linux/bio.h

View file

This diff is incomplete. Download the complete patch.

include/linux/blk-mq.h

View file

This diff is incomplete. Download the complete patch.

include/linux/blk_types.h

View file

This diff is incomplete. Download the complete patch.

include/linux/blkdev.h

View file

This diff is incomplete. Download the complete patch.

include/linux/elevator.h

View file

This diff is incomplete. Download the complete patch.

include/linux/genhd.h

View file

This diff is incomplete. Download the complete patch.

include/linux/swap.h

View file

This diff is incomplete. Download the complete patch.

kernel/trace/blktrace.c

View file

This diff is incomplete. Download the complete patch.

lib/iov_iter.c

View file

This diff is incomplete. Download the complete patch.

mm/page_io.c

View file

This diff is incomplete. Download the complete patch.

mm/swapfile.c

View file

This diff is incomplete. Download the complete patch.