Skip to content

Commit 1796ef2

Browse files
committed
Merge branch 'block-7.1' into for-next
* block-7.1: 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
2 parents b388df3 + 19d3296 commit 1796ef2

9 files changed

Lines changed: 61 additions & 27 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: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1048,10 +1048,10 @@ int bio_add_page(struct bio *bio, struct page *page,
10481048
if (bio->bi_vcnt > 0) {
10491049
struct bio_vec *bv = &bio->bi_io_vec[bio->bi_vcnt - 1];
10501050

1051-
if (!zone_device_pages_have_same_pgmap(bv->bv_page, page))
1051+
if (!zone_device_pages_compatible(bv->bv_page, page))
10521052
return 0;
1053-
1054-
if (bvec_try_merge_page(bv, page, len, offset)) {
1053+
if (zone_device_pages_have_same_pgmap(bv->bv_page, page) &&
1054+
bvec_try_merge_page(bv, page, len, offset)) {
10551055
bio->bi_iter.bi_size += len;
10561056
return len;
10571057
}
@@ -1958,7 +1958,7 @@ int bioset_init(struct bio_set *bs,
19581958

19591959
if (flags & BIOSET_NEED_RESCUER) {
19601960
bs->rescue_workqueue = alloc_workqueue("bioset",
1961-
WQ_MEM_RECLAIM, 0);
1961+
WQ_MEM_RECLAIM | WQ_PERCPU, 0);
19621962
if (!bs->rescue_workqueue)
19631963
goto bad;
19641964
}

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

include/linux/t10-pi.h

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
#include <linux/types.h>
66
#include <linux/blk-mq.h>
7+
#include <linux/wordpart.h>
78

89
/*
910
* A T10 PI-capable target device can be formatted with different
@@ -25,6 +26,16 @@ enum t10_dif_type {
2526
T10_PI_TYPE3_PROTECTION = 0x3,
2627
};
2728

29+
static inline u64 full_pi_ref_tag(const struct request *rq)
30+
{
31+
unsigned int shift = ilog2(queue_logical_block_size(rq->q));
32+
33+
if (IS_ENABLED(CONFIG_BLK_DEV_INTEGRITY) &&
34+
rq->q->limits.integrity.interval_exp)
35+
shift = rq->q->limits.integrity.interval_exp;
36+
return blk_rq_pos(rq) >> (shift - SECTOR_SHIFT);
37+
}
38+
2839
/*
2940
* T10 Protection Information tuple.
3041
*/
@@ -39,12 +50,7 @@ struct t10_pi_tuple {
3950

4051
static inline u32 t10_pi_ref_tag(struct request *rq)
4152
{
42-
unsigned int shift = ilog2(queue_logical_block_size(rq->q));
43-
44-
if (IS_ENABLED(CONFIG_BLK_DEV_INTEGRITY) &&
45-
rq->q->limits.integrity.interval_exp)
46-
shift = rq->q->limits.integrity.interval_exp;
47-
return blk_rq_pos(rq) >> (shift - SECTOR_SHIFT) & 0xffffffff;
53+
return lower_32_bits(full_pi_ref_tag(rq));
4854
}
4955

5056
struct crc64_pi_tuple {
@@ -64,12 +70,7 @@ static inline u64 lower_48_bits(u64 n)
6470

6571
static inline u64 ext_pi_ref_tag(struct request *rq)
6672
{
67-
unsigned int shift = ilog2(queue_logical_block_size(rq->q));
68-
69-
if (IS_ENABLED(CONFIG_BLK_DEV_INTEGRITY) &&
70-
rq->q->limits.integrity.interval_exp)
71-
shift = rq->q->limits.integrity.interval_exp;
72-
return lower_48_bits(blk_rq_pos(rq) >> (shift - SECTOR_SHIFT));
73+
return lower_48_bits(full_pi_ref_tag(rq));
7374
}
7475

7576
#endif

0 commit comments

Comments
 (0)