kernel_optimize_test/block
Maurizio Lombardi 254c4407cb bio: modify __bio_add_page() to accept pages that don't start a new segment
The original behaviour is to refuse to add a new page if the maximum
number of segments has been reached, regardless of the fact the page we
are going to add can be merged into the last segment or not.

Unfortunately, when the system runs under heavy memory fragmentation
conditions, a driver may try to add multiple pages to the last segment.
The original code won't accept them and EBUSY will be reported to
userspace.

This patch modifies the function so it refuses to add a page only in case
the latter starts a new segment and the maximum number of segments has
already been reached.

The bug can be easily reproduced with the st driver:

1) set CONFIG_SCSI_MPT2SAS_MAX_SGE or CONFIG_SCSI_MPT3SAS_MAX_SGE  to 16
2) modprobe st buffer_kbs=1024
3) #dd if=/dev/zero of=/dev/st0 bs=1M count=10
   dd: error writing `/dev/st0': Device or resource busy

[ming.lei@canonical.com: update bi_iter.bi_size before recounting segments]
Signed-off-by: Maurizio Lombardi <mlombard@redhat.com>
Signed-off-by: Ming Lei <ming.lei@canonical.com>
Tested-by: Dongsu Park <dongsu.park@profitbricks.com>
Tested-by: Jet Chen <jet.chen@intel.com>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Kent Overstreet <kmo@daterainc.com>
Cc: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Jens Axboe <axboe@fb.com>
2014-07-01 10:55:15 -06:00
..
partitions block/partitions/efi.c: kerneldoc fixing 2014-07-01 10:40:05 -06:00
bio-integrity.c bio-integrity: add "bip_max_vcnt" into struct bio_integrity_payload 2014-07-01 10:36:47 -06:00
bio.c bio: modify __bio_add_page() to accept pages that don't start a new segment 2014-07-01 10:55:15 -06:00
blk-cgroup.c Revert "block: add __init to blkcg_policy_register" 2014-06-22 16:34:11 -06:00
blk-cgroup.h Revert "block: add __init to blkcg_policy_register" 2014-06-22 16:34:11 -06:00
blk-core.c blk-mq: decouble blk-mq freezing from generic bypassing 2014-07-01 10:31:13 -06:00
blk-exec.c block: blk-exec.c: Cleaning up local variable address returnd 2014-06-08 19:51:31 -06:00
blk-flush.c block: remove elv_abort_queue and blk_abort_flushes 2014-06-11 15:31:21 -06:00
blk-integrity.c bio-integrity: Convert to bvec_iter 2013-11-23 22:33:50 -08:00
blk-ioc.c block: Substitute rcu_access_pointer() for rcu_dereference_raw() 2014-02-18 12:21:26 -08:00
blk-iopoll.c Merge branch 'locking-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip into next 2014-06-03 12:57:53 -07:00
blk-lib.c block/blk-lib.c: make __blkdev_issue_zeroout static 2014-05-26 17:39:09 -06:00
blk-map.c block: remove struct request buffer member 2014-04-15 14:03:02 -06:00
blk-merge.c block: add support for limiting gaps in SG lists 2014-06-24 16:22:24 -06:00
blk-mq-cpu.c blk-mq: add file comments and update copyright notices 2014-05-28 10:15:41 -06:00
blk-mq-cpumap.c blk-mq: add file comments and update copyright notices 2014-05-28 10:15:41 -06:00
blk-mq-sysfs.c blk-mq: blk_mq_unregister_hctx() can be static 2014-05-30 10:31:13 -06:00
blk-mq-tag.c blk-mq: bitmap tag: fix races in bt_get() function 2014-06-17 22:13:08 -07:00
blk-mq-tag.h blk-mq: bitmap tag: fix races on shared ::wake_index fields 2014-06-17 22:12:35 -07:00
blk-mq.c blk-mq: use percpu_ref for mq usage count 2014-07-01 10:34:38 -06:00
blk-mq.h blk-mq: decouble blk-mq freezing from generic bypassing 2014-07-01 10:31:13 -06:00
blk-settings.c block: ensure that bio_add_page() always accepts a page for an empty bio 2014-06-10 12:53:56 -06:00
blk-softirq.c block: fix regression with block enabled tagging 2014-04-09 21:54:06 -06:00
blk-sysfs.c block, blk-mq: draining can't be skipped even if bypass_depth was non-zero 2014-07-01 10:29:17 -06:00
blk-tag.c block: Reserve only one queue tag for sync IO if only 3 tags are available 2013-06-28 21:32:27 +02:00
blk-throttle.c Merge branch 'for-3.16' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup 2014-06-09 15:03:33 -07:00
blk-timeout.c block: ensure that the timer is always added 2014-05-30 15:41:39 -06:00
blk.h block: remove elv_abort_queue and blk_abort_flushes 2014-06-11 15:31:21 -06:00
bounce.c mm: convert some level-less printks to pr_* 2014-06-06 16:08:18 -07:00
bsg-lib.c bsg: Remove unused function bsg_goose_queue() 2012-12-06 14:33:02 +01:00
bsg.c block: add blk_rq_set_block_pc() 2014-06-06 07:57:37 -06:00
cfq-iosched.c Merge branch 'for-3.16' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup 2014-06-09 15:03:33 -07:00
cmdline-parser.c block: remove unrelated header files and export symbol 2014-01-21 20:18:26 -08:00
compat_ioctl.c block: fix BLKSECTGET ioctl when max_sectors is greater than USHRT_MAX 2014-07-01 10:43:07 -06:00
deadline-iosched.c block: Stop abusing csd.list for fifo_time 2014-02-24 14:46:32 -08:00
elevator.c Revert "block: add __init to elv_register" 2014-06-22 16:34:11 -06:00
genhd.c block: Convert kmalloc_node(...GFP_ZERO...) to kzalloc_node(...) 2013-09-11 13:22:03 -06:00
ioctl.c block: fix BLKSECTGET ioctl when max_sectors is greater than USHRT_MAX 2014-07-01 10:43:07 -06:00
ioprio.c block: move ioprio.c from fs/ to block/ 2014-05-19 11:02:18 -06:00
Kconfig block: change config option name for cmdline partition parsing 2013-09-30 14:31:02 -07:00
Kconfig.iosched blkcg: make CONFIG_BLK_CGROUP bool 2012-03-06 21:27:21 +01:00
Makefile block: move mm/bounce.c to block/ 2014-05-19 20:01:52 -06:00
noop-iosched.c elevator: Fix a race in elevator switching 2013-07-03 13:25:24 +02:00
partition-generic.c Revert "loop: cleanup partitions when detaching loop device" 2013-04-08 10:12:11 +02:00
scsi_ioctl.c block: fix SG_[GS]ET_RESERVED_SIZE ioctl when max_sectors is huge 2014-07-01 10:43:09 -06:00