Skip to content

Commit b6a5f0b

Browse files
committed
Merge branch 'block-7.1' into for-next
* block-7.1: block: only restrict bio allocation gfp mask asked to block block/blk-throttle: Add WQ_PERCPU to alloc_workqueue users block: Add WQ_PERCPU to alloc_workqueue users block: relax pgmap check in bio_add_page for compatible zone device pages block: add pgmap check to biovec_phys_mergeable floppy: fix reference leak on platform_device_register() failure ublk: use unchecked copy helpers for bio page data t10-pi: reduce ref tag code duplication zloop: remove irq-safe locking zloop: factor out zloop_mark_{full,empty} helpers zloop: set RQF_QUIET when completing requests on deleted devices zloop: improve the unaligned write pointer warning zloop: use vfs_truncate zloop: fix write pointer calculation in zloop_forget_cache
2 parents 6596a02 + b5129bd commit b6a5f0b

10 files changed

Lines changed: 122 additions & 92 deletions

File tree

block/bio-integrity-auto.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ static int __init blk_integrity_auto_init(void)
125125
* Make it highpri CPU intensive wq with max concurrency of 1.
126126
*/
127127
kintegrityd_wq = alloc_workqueue("kintegrityd", WQ_MEM_RECLAIM |
128-
WQ_HIGHPRI | WQ_CPU_INTENSIVE, 1);
128+
WQ_HIGHPRI | WQ_CPU_INTENSIVE | WQ_PERCPU, 1);
129129
if (!kintegrityd_wq)
130130
panic("Failed to create kintegrityd\n");
131131
return 0;

block/bio-integrity.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -231,10 +231,10 @@ int bio_integrity_add_page(struct bio *bio, struct page *page,
231231
if (bip->bip_vcnt > 0) {
232232
struct bio_vec *bv = &bip->bip_vec[bip->bip_vcnt - 1];
233233

234-
if (!zone_device_pages_have_same_pgmap(bv->bv_page, page))
234+
if (!zone_device_pages_compatible(bv->bv_page, page))
235235
return 0;
236-
237-
if (bvec_try_merge_hw_page(q, bv, page, len, offset)) {
236+
if (zone_device_pages_have_same_pgmap(bv->bv_page, page) &&
237+
bvec_try_merge_hw_page(q, bv, page, len, offset)) {
238238
bip->bip_iter.bi_size += len;
239239
return len;
240240
}

block/bio.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -544,7 +544,8 @@ struct bio *bio_alloc_bioset(struct block_device *bdev, unsigned short nr_vecs,
544544
if (WARN_ON_ONCE(!mempool_initialized(&bs->bvec_pool) && nr_vecs > 0))
545545
return NULL;
546546

547-
gfp = try_alloc_gfp(gfp);
547+
if (saved_gfp & __GFP_DIRECT_RECLAIM)
548+
gfp = try_alloc_gfp(gfp);
548549
if (bs->cache && nr_vecs <= BIO_INLINE_VECS) {
549550
/*
550551
* Set REQ_ALLOC_CACHE even if no cached bio is available to
@@ -1048,10 +1049,10 @@ int bio_add_page(struct bio *bio, struct page *page,
10481049
if (bio->bi_vcnt > 0) {
10491050
struct bio_vec *bv = &bio->bi_io_vec[bio->bi_vcnt - 1];
10501051

1051-
if (!zone_device_pages_have_same_pgmap(bv->bv_page, page))
1052+
if (!zone_device_pages_compatible(bv->bv_page, page))
10521053
return 0;
1053-
1054-
if (bvec_try_merge_page(bv, page, len, offset)) {
1054+
if (zone_device_pages_have_same_pgmap(bv->bv_page, page) &&
1055+
bvec_try_merge_page(bv, page, len, offset)) {
10551056
bio->bi_iter.bi_size += len;
10561057
return len;
10571058
}
@@ -1958,7 +1959,7 @@ int bioset_init(struct bio_set *bs,
19581959

19591960
if (flags & BIOSET_NEED_RESCUER) {
19601961
bs->rescue_workqueue = alloc_workqueue("bioset",
1961-
WQ_MEM_RECLAIM, 0);
1962+
WQ_MEM_RECLAIM | WQ_PERCPU, 0);
19621963
if (!bs->rescue_workqueue)
19631964
goto bad;
19641965
}

block/blk-core.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1282,7 +1282,7 @@ int __init blk_dev_init(void)
12821282

12831283
/* used for unplugging and affects IO latency/throughput - HIGHPRI */
12841284
kblockd_workqueue = alloc_workqueue("kblockd",
1285-
WQ_MEM_RECLAIM | WQ_HIGHPRI, 0);
1285+
WQ_MEM_RECLAIM | WQ_HIGHPRI | WQ_PERCPU, 0);
12861286
if (!kblockd_workqueue)
12871287
panic("Failed to create kblockd\n");
12881288

block/blk-throttle.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1839,7 +1839,7 @@ void blk_throtl_exit(struct gendisk *disk)
18391839

18401840
static int __init throtl_init(void)
18411841
{
1842-
kthrotld_workqueue = alloc_workqueue("kthrotld", WQ_MEM_RECLAIM, 0);
1842+
kthrotld_workqueue = alloc_workqueue("kthrotld", WQ_MEM_RECLAIM | WQ_PERCPU, 0);
18431843
if (!kthrotld_workqueue)
18441844
panic("Failed to create kthrotld\n");
18451845

block/blk.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,13 +127,34 @@ static inline bool biovec_phys_mergeable(struct request_queue *q,
127127

128128
if (addr1 + vec1->bv_len != addr2)
129129
return false;
130+
if (!zone_device_pages_have_same_pgmap(vec1->bv_page, vec2->bv_page))
131+
return false;
130132
if (xen_domain() && !xen_biovec_phys_mergeable(vec1, vec2->bv_page))
131133
return false;
132134
if ((addr1 | mask) != ((addr2 + vec2->bv_len - 1) | mask))
133135
return false;
134136
return true;
135137
}
136138

139+
/*
140+
* Check if two pages from potentially different zone device pgmaps can
141+
* coexist as separate bvec entries in the same bio.
142+
*
143+
* The block DMA iterator (blk_dma_map_iter_start) caches the P2PDMA mapping
144+
* state from the first segment and applies it to all subsequent segments, so
145+
* P2PDMA pages from different pgmaps must not be mixed in the same bio.
146+
*
147+
* Other zone device types (FS_DAX, GENERIC) use the same dma_map_phys() path
148+
* as normal RAM. PRIVATE and COHERENT pages never appear in bios.
149+
*/
150+
static inline bool zone_device_pages_compatible(const struct page *a,
151+
const struct page *b)
152+
{
153+
if (is_pci_p2pdma_page(a) || is_pci_p2pdma_page(b))
154+
return zone_device_pages_have_same_pgmap(a, b);
155+
return true;
156+
}
157+
137158
static inline bool __bvec_gap_to_prev(const struct queue_limits *lim,
138159
struct bio_vec *bprv, unsigned int offset)
139160
{

drivers/block/floppy.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4722,15 +4722,19 @@ static int __init do_floppy_init(void)
47224722
floppy_device[drive].dev.groups = floppy_dev_groups;
47234723

47244724
err = platform_device_register(&floppy_device[drive]);
4725-
if (err)
4725+
if (err) {
4726+
platform_device_put(&floppy_device[drive]);
47264727
goto out_remove_drives;
4727-
4728+
}
47284729
registered[drive] = true;
47294730

47304731
err = device_add_disk(&floppy_device[drive].dev,
47314732
disks[drive][0], NULL);
4732-
if (err)
4733+
if (err) {
4734+
platform_device_unregister(&floppy_device[drive]);
4735+
registered[drive] = false;
47334736
goto out_remove_drives;
4737+
}
47344738
}
47354739

47364740
return 0;

drivers/block/ublk_drv.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1319,10 +1319,18 @@ static bool ublk_copy_user_bvec(const struct bio_vec *bv, unsigned *offset,
13191319

13201320
len = bv->bv_len - *offset;
13211321
bv_buf = kmap_local_page(bv->bv_page) + bv->bv_offset + *offset;
1322+
/*
1323+
* Bio pages may originate from slab caches without a usercopy region
1324+
* (e.g. jbd2 frozen metadata buffers). This is the same data that
1325+
* the loop driver writes to its backing file — no exposure risk.
1326+
* The bvec length is always trusted, so the size check in
1327+
* check_copy_size() is not needed either. Use the unchecked
1328+
* helpers to avoid false positives on slab pages.
1329+
*/
13221330
if (dir == ITER_DEST)
1323-
copied = copy_to_iter(bv_buf, len, uiter);
1331+
copied = _copy_to_iter(bv_buf, len, uiter);
13241332
else
1325-
copied = copy_from_iter(bv_buf, len, uiter);
1333+
copied = _copy_from_iter(bv_buf, len, uiter);
13261334

13271335
kunmap_local(bv_buf);
13281336

0 commit comments

Comments
 (0)