162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci/* bounce buffer handling for block devices 362306a36Sopenharmony_ci * 462306a36Sopenharmony_ci * - Split from highmem.c 562306a36Sopenharmony_ci */ 662306a36Sopenharmony_ci 762306a36Sopenharmony_ci#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 862306a36Sopenharmony_ci 962306a36Sopenharmony_ci#include <linux/mm.h> 1062306a36Sopenharmony_ci#include <linux/export.h> 1162306a36Sopenharmony_ci#include <linux/swap.h> 1262306a36Sopenharmony_ci#include <linux/gfp.h> 1362306a36Sopenharmony_ci#include <linux/bio.h> 1462306a36Sopenharmony_ci#include <linux/pagemap.h> 1562306a36Sopenharmony_ci#include <linux/mempool.h> 1662306a36Sopenharmony_ci#include <linux/blkdev.h> 1762306a36Sopenharmony_ci#include <linux/backing-dev.h> 1862306a36Sopenharmony_ci#include <linux/init.h> 1962306a36Sopenharmony_ci#include <linux/hash.h> 2062306a36Sopenharmony_ci#include <linux/highmem.h> 2162306a36Sopenharmony_ci#include <linux/printk.h> 2262306a36Sopenharmony_ci#include <asm/tlbflush.h> 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_ci#include <trace/events/block.h> 2562306a36Sopenharmony_ci#include "blk.h" 2662306a36Sopenharmony_ci#include "blk-cgroup.h" 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_ci#define POOL_SIZE 64 2962306a36Sopenharmony_ci#define ISA_POOL_SIZE 16 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_cistatic struct bio_set bounce_bio_set, bounce_bio_split; 3262306a36Sopenharmony_cistatic mempool_t page_pool; 3362306a36Sopenharmony_ci 3462306a36Sopenharmony_cistatic void init_bounce_bioset(void) 3562306a36Sopenharmony_ci{ 3662306a36Sopenharmony_ci static bool bounce_bs_setup; 3762306a36Sopenharmony_ci int ret; 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_ci if (bounce_bs_setup) 4062306a36Sopenharmony_ci return; 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_ci ret = bioset_init(&bounce_bio_set, BIO_POOL_SIZE, 0, BIOSET_NEED_BVECS); 4362306a36Sopenharmony_ci BUG_ON(ret); 4462306a36Sopenharmony_ci if (bioset_integrity_create(&bounce_bio_set, BIO_POOL_SIZE)) 4562306a36Sopenharmony_ci BUG_ON(1); 4662306a36Sopenharmony_ci 4762306a36Sopenharmony_ci ret = bioset_init(&bounce_bio_split, BIO_POOL_SIZE, 0, 0); 4862306a36Sopenharmony_ci BUG_ON(ret); 4962306a36Sopenharmony_ci bounce_bs_setup = true; 5062306a36Sopenharmony_ci} 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_cistatic __init int init_emergency_pool(void) 5362306a36Sopenharmony_ci{ 5462306a36Sopenharmony_ci int ret; 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_ci#ifndef CONFIG_MEMORY_HOTPLUG 5762306a36Sopenharmony_ci if (max_pfn <= max_low_pfn) 5862306a36Sopenharmony_ci return 0; 5962306a36Sopenharmony_ci#endif 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_ci ret = mempool_init_page_pool(&page_pool, POOL_SIZE, 0); 6262306a36Sopenharmony_ci BUG_ON(ret); 6362306a36Sopenharmony_ci pr_info("pool size: %d pages\n", POOL_SIZE); 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_ci init_bounce_bioset(); 6662306a36Sopenharmony_ci return 0; 6762306a36Sopenharmony_ci} 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_ci__initcall(init_emergency_pool); 7062306a36Sopenharmony_ci 7162306a36Sopenharmony_ci/* 7262306a36Sopenharmony_ci * Simple bounce buffer support for highmem pages. Depending on the 7362306a36Sopenharmony_ci * queue gfp mask set, *to may or may not be a highmem page. kmap it 7462306a36Sopenharmony_ci * always, it will do the Right Thing 7562306a36Sopenharmony_ci */ 7662306a36Sopenharmony_cistatic void copy_to_high_bio_irq(struct bio *to, struct bio *from) 7762306a36Sopenharmony_ci{ 7862306a36Sopenharmony_ci struct bio_vec tovec, fromvec; 7962306a36Sopenharmony_ci struct bvec_iter iter; 8062306a36Sopenharmony_ci /* 8162306a36Sopenharmony_ci * The bio of @from is created by bounce, so we can iterate 8262306a36Sopenharmony_ci * its bvec from start to end, but the @from->bi_iter can't be 8362306a36Sopenharmony_ci * trusted because it might be changed by splitting. 8462306a36Sopenharmony_ci */ 8562306a36Sopenharmony_ci struct bvec_iter from_iter = BVEC_ITER_ALL_INIT; 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_ci bio_for_each_segment(tovec, to, iter) { 8862306a36Sopenharmony_ci fromvec = bio_iter_iovec(from, from_iter); 8962306a36Sopenharmony_ci if (tovec.bv_page != fromvec.bv_page) { 9062306a36Sopenharmony_ci /* 9162306a36Sopenharmony_ci * fromvec->bv_offset and fromvec->bv_len might have 9262306a36Sopenharmony_ci * been modified by the block layer, so use the original 9362306a36Sopenharmony_ci * copy, bounce_copy_vec already uses tovec->bv_len 9462306a36Sopenharmony_ci */ 9562306a36Sopenharmony_ci memcpy_to_bvec(&tovec, page_address(fromvec.bv_page) + 9662306a36Sopenharmony_ci tovec.bv_offset); 9762306a36Sopenharmony_ci } 9862306a36Sopenharmony_ci bio_advance_iter(from, &from_iter, tovec.bv_len); 9962306a36Sopenharmony_ci } 10062306a36Sopenharmony_ci} 10162306a36Sopenharmony_ci 10262306a36Sopenharmony_cistatic void bounce_end_io(struct bio *bio) 10362306a36Sopenharmony_ci{ 10462306a36Sopenharmony_ci struct bio *bio_orig = bio->bi_private; 10562306a36Sopenharmony_ci struct bio_vec *bvec, orig_vec; 10662306a36Sopenharmony_ci struct bvec_iter orig_iter = bio_orig->bi_iter; 10762306a36Sopenharmony_ci struct bvec_iter_all iter_all; 10862306a36Sopenharmony_ci 10962306a36Sopenharmony_ci /* 11062306a36Sopenharmony_ci * free up bounce indirect pages used 11162306a36Sopenharmony_ci */ 11262306a36Sopenharmony_ci bio_for_each_segment_all(bvec, bio, iter_all) { 11362306a36Sopenharmony_ci orig_vec = bio_iter_iovec(bio_orig, orig_iter); 11462306a36Sopenharmony_ci if (bvec->bv_page != orig_vec.bv_page) { 11562306a36Sopenharmony_ci dec_zone_page_state(bvec->bv_page, NR_BOUNCE); 11662306a36Sopenharmony_ci mempool_free(bvec->bv_page, &page_pool); 11762306a36Sopenharmony_ci } 11862306a36Sopenharmony_ci bio_advance_iter(bio_orig, &orig_iter, orig_vec.bv_len); 11962306a36Sopenharmony_ci } 12062306a36Sopenharmony_ci 12162306a36Sopenharmony_ci bio_orig->bi_status = bio->bi_status; 12262306a36Sopenharmony_ci bio_endio(bio_orig); 12362306a36Sopenharmony_ci bio_put(bio); 12462306a36Sopenharmony_ci} 12562306a36Sopenharmony_ci 12662306a36Sopenharmony_cistatic void bounce_end_io_write(struct bio *bio) 12762306a36Sopenharmony_ci{ 12862306a36Sopenharmony_ci bounce_end_io(bio); 12962306a36Sopenharmony_ci} 13062306a36Sopenharmony_ci 13162306a36Sopenharmony_cistatic void bounce_end_io_read(struct bio *bio) 13262306a36Sopenharmony_ci{ 13362306a36Sopenharmony_ci struct bio *bio_orig = bio->bi_private; 13462306a36Sopenharmony_ci 13562306a36Sopenharmony_ci if (!bio->bi_status) 13662306a36Sopenharmony_ci copy_to_high_bio_irq(bio_orig, bio); 13762306a36Sopenharmony_ci 13862306a36Sopenharmony_ci bounce_end_io(bio); 13962306a36Sopenharmony_ci} 14062306a36Sopenharmony_ci 14162306a36Sopenharmony_cistatic struct bio *bounce_clone_bio(struct bio *bio_src) 14262306a36Sopenharmony_ci{ 14362306a36Sopenharmony_ci struct bvec_iter iter; 14462306a36Sopenharmony_ci struct bio_vec bv; 14562306a36Sopenharmony_ci struct bio *bio; 14662306a36Sopenharmony_ci 14762306a36Sopenharmony_ci /* 14862306a36Sopenharmony_ci * Pre immutable biovecs, __bio_clone() used to just do a memcpy from 14962306a36Sopenharmony_ci * bio_src->bi_io_vec to bio->bi_io_vec. 15062306a36Sopenharmony_ci * 15162306a36Sopenharmony_ci * We can't do that anymore, because: 15262306a36Sopenharmony_ci * 15362306a36Sopenharmony_ci * - The point of cloning the biovec is to produce a bio with a biovec 15462306a36Sopenharmony_ci * the caller can modify: bi_idx and bi_bvec_done should be 0. 15562306a36Sopenharmony_ci * 15662306a36Sopenharmony_ci * - The original bio could've had more than BIO_MAX_VECS biovecs; if 15762306a36Sopenharmony_ci * we tried to clone the whole thing bio_alloc_bioset() would fail. 15862306a36Sopenharmony_ci * But the clone should succeed as long as the number of biovecs we 15962306a36Sopenharmony_ci * actually need to allocate is fewer than BIO_MAX_VECS. 16062306a36Sopenharmony_ci * 16162306a36Sopenharmony_ci * - Lastly, bi_vcnt should not be looked at or relied upon by code 16262306a36Sopenharmony_ci * that does not own the bio - reason being drivers don't use it for 16362306a36Sopenharmony_ci * iterating over the biovec anymore, so expecting it to be kept up 16462306a36Sopenharmony_ci * to date (i.e. for clones that share the parent biovec) is just 16562306a36Sopenharmony_ci * asking for trouble and would force extra work. 16662306a36Sopenharmony_ci */ 16762306a36Sopenharmony_ci bio = bio_alloc_bioset(bio_src->bi_bdev, bio_segments(bio_src), 16862306a36Sopenharmony_ci bio_src->bi_opf, GFP_NOIO, &bounce_bio_set); 16962306a36Sopenharmony_ci if (bio_flagged(bio_src, BIO_REMAPPED)) 17062306a36Sopenharmony_ci bio_set_flag(bio, BIO_REMAPPED); 17162306a36Sopenharmony_ci bio->bi_ioprio = bio_src->bi_ioprio; 17262306a36Sopenharmony_ci bio->bi_iter.bi_sector = bio_src->bi_iter.bi_sector; 17362306a36Sopenharmony_ci bio->bi_iter.bi_size = bio_src->bi_iter.bi_size; 17462306a36Sopenharmony_ci 17562306a36Sopenharmony_ci switch (bio_op(bio)) { 17662306a36Sopenharmony_ci case REQ_OP_DISCARD: 17762306a36Sopenharmony_ci case REQ_OP_SECURE_ERASE: 17862306a36Sopenharmony_ci case REQ_OP_WRITE_ZEROES: 17962306a36Sopenharmony_ci break; 18062306a36Sopenharmony_ci default: 18162306a36Sopenharmony_ci bio_for_each_segment(bv, bio_src, iter) 18262306a36Sopenharmony_ci bio->bi_io_vec[bio->bi_vcnt++] = bv; 18362306a36Sopenharmony_ci break; 18462306a36Sopenharmony_ci } 18562306a36Sopenharmony_ci 18662306a36Sopenharmony_ci if (bio_crypt_clone(bio, bio_src, GFP_NOIO) < 0) 18762306a36Sopenharmony_ci goto err_put; 18862306a36Sopenharmony_ci 18962306a36Sopenharmony_ci if (bio_integrity(bio_src) && 19062306a36Sopenharmony_ci bio_integrity_clone(bio, bio_src, GFP_NOIO) < 0) 19162306a36Sopenharmony_ci goto err_put; 19262306a36Sopenharmony_ci 19362306a36Sopenharmony_ci bio_clone_blkg_association(bio, bio_src); 19462306a36Sopenharmony_ci 19562306a36Sopenharmony_ci return bio; 19662306a36Sopenharmony_ci 19762306a36Sopenharmony_cierr_put: 19862306a36Sopenharmony_ci bio_put(bio); 19962306a36Sopenharmony_ci return NULL; 20062306a36Sopenharmony_ci} 20162306a36Sopenharmony_ci 20262306a36Sopenharmony_cistruct bio *__blk_queue_bounce(struct bio *bio_orig, struct request_queue *q) 20362306a36Sopenharmony_ci{ 20462306a36Sopenharmony_ci struct bio *bio; 20562306a36Sopenharmony_ci int rw = bio_data_dir(bio_orig); 20662306a36Sopenharmony_ci struct bio_vec *to, from; 20762306a36Sopenharmony_ci struct bvec_iter iter; 20862306a36Sopenharmony_ci unsigned i = 0, bytes = 0; 20962306a36Sopenharmony_ci bool bounce = false; 21062306a36Sopenharmony_ci int sectors; 21162306a36Sopenharmony_ci 21262306a36Sopenharmony_ci bio_for_each_segment(from, bio_orig, iter) { 21362306a36Sopenharmony_ci if (i++ < BIO_MAX_VECS) 21462306a36Sopenharmony_ci bytes += from.bv_len; 21562306a36Sopenharmony_ci if (PageHighMem(from.bv_page)) 21662306a36Sopenharmony_ci bounce = true; 21762306a36Sopenharmony_ci } 21862306a36Sopenharmony_ci if (!bounce) 21962306a36Sopenharmony_ci return bio_orig; 22062306a36Sopenharmony_ci 22162306a36Sopenharmony_ci /* 22262306a36Sopenharmony_ci * Individual bvecs might not be logical block aligned. Round down 22362306a36Sopenharmony_ci * the split size so that each bio is properly block size aligned, 22462306a36Sopenharmony_ci * even if we do not use the full hardware limits. 22562306a36Sopenharmony_ci */ 22662306a36Sopenharmony_ci sectors = ALIGN_DOWN(bytes, queue_logical_block_size(q)) >> 22762306a36Sopenharmony_ci SECTOR_SHIFT; 22862306a36Sopenharmony_ci if (sectors < bio_sectors(bio_orig)) { 22962306a36Sopenharmony_ci bio = bio_split(bio_orig, sectors, GFP_NOIO, &bounce_bio_split); 23062306a36Sopenharmony_ci bio_chain(bio, bio_orig); 23162306a36Sopenharmony_ci submit_bio_noacct(bio_orig); 23262306a36Sopenharmony_ci bio_orig = bio; 23362306a36Sopenharmony_ci } 23462306a36Sopenharmony_ci bio = bounce_clone_bio(bio_orig); 23562306a36Sopenharmony_ci 23662306a36Sopenharmony_ci /* 23762306a36Sopenharmony_ci * Bvec table can't be updated by bio_for_each_segment_all(), 23862306a36Sopenharmony_ci * so retrieve bvec from the table directly. This way is safe 23962306a36Sopenharmony_ci * because the 'bio' is single-page bvec. 24062306a36Sopenharmony_ci */ 24162306a36Sopenharmony_ci for (i = 0, to = bio->bi_io_vec; i < bio->bi_vcnt; to++, i++) { 24262306a36Sopenharmony_ci struct page *bounce_page; 24362306a36Sopenharmony_ci 24462306a36Sopenharmony_ci if (!PageHighMem(to->bv_page)) 24562306a36Sopenharmony_ci continue; 24662306a36Sopenharmony_ci 24762306a36Sopenharmony_ci bounce_page = mempool_alloc(&page_pool, GFP_NOIO); 24862306a36Sopenharmony_ci inc_zone_page_state(bounce_page, NR_BOUNCE); 24962306a36Sopenharmony_ci 25062306a36Sopenharmony_ci if (rw == WRITE) { 25162306a36Sopenharmony_ci flush_dcache_page(to->bv_page); 25262306a36Sopenharmony_ci memcpy_from_bvec(page_address(bounce_page), to); 25362306a36Sopenharmony_ci } 25462306a36Sopenharmony_ci to->bv_page = bounce_page; 25562306a36Sopenharmony_ci } 25662306a36Sopenharmony_ci 25762306a36Sopenharmony_ci trace_block_bio_bounce(bio_orig); 25862306a36Sopenharmony_ci 25962306a36Sopenharmony_ci bio->bi_flags |= (1 << BIO_BOUNCED); 26062306a36Sopenharmony_ci 26162306a36Sopenharmony_ci if (rw == READ) 26262306a36Sopenharmony_ci bio->bi_end_io = bounce_end_io_read; 26362306a36Sopenharmony_ci else 26462306a36Sopenharmony_ci bio->bi_end_io = bounce_end_io_write; 26562306a36Sopenharmony_ci 26662306a36Sopenharmony_ci bio->bi_private = bio_orig; 26762306a36Sopenharmony_ci return bio; 26862306a36Sopenharmony_ci} 269