hulk inclusion category: feature bugzilla: https://atomgit.com/openeuler/kernel/issues/10302 --------------------------------- Reject PCI P2PDMA on dm and md when any lower device has a block integrity profile. A mixed dm table may omit that profile on its top disk, so the P2PDMA client cannot detect the CPU integrity path there. This is the 6.6 queue-flag adaptation of the integrity withhold: dm_table_supports_pci_p2pdma() checks the underlying device integrity profile, and disk_stack_limits() clears QUEUE_FLAG_PCI_P2PDMA for integrity-bearing members so md personalities do not advertise P2P. The integrity profile is read through a local helper instead of including <linux/blk-integrity.h>: completing struct blk_integrity_profile in this translation unit would change the genksyms CRC of all exported symbols in blk-settings.c that refer to request_queue, gendisk or block_device. Signed-off-by: Zizhi Wo <wozizhi@huawei.com> --- block/blk-settings.c | 19 ++++++++++++++++++- drivers/md/dm-table.c | 3 ++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/block/blk-settings.c b/block/blk-settings.c index 23e3b6b0c266..f2a0e08cadb0 100644 --- a/block/blk-settings.c +++ b/block/blk-settings.c @@ -779,10 +779,26 @@ int blk_stack_limits(struct queue_limits *t, struct queue_limits *b, } return ret; } EXPORT_SYMBOL(blk_stack_limits); +/* + * Do not use bdev_get_integrity() here: including <linux/blk-integrity.h> + * completes struct blk_integrity_profile in this translation unit, which + * changes the genksyms CRC of every exported symbol below that refers to a + * request_queue, gendisk or block_device. struct request_queue embeds + * struct blk_integrity, whose profile pointer would then be expanded. + */ +static bool bdev_has_integrity(struct block_device *bdev) +{ +#ifdef CONFIG_BLK_DEV_INTEGRITY + return bdev->bd_disk->queue->integrity.profile != NULL; +#else + return false; +#endif +} + /** * disk_stack_limits - adjust queue limits for stacked drivers * @disk: MD/DM gendisk (top) * @bdev: the underlying block device (bottom) * @offset: offset to beginning of data within component device @@ -799,11 +815,12 @@ void disk_stack_limits(struct gendisk *disk, struct block_device *bdev, if (blk_stack_limits(&t->limits, &bdev_get_queue(bdev)->limits, get_start_sect(bdev) + (offset >> 9)) < 0) pr_notice("%s: Warning: Device %pg is misaligned\n", disk->disk_name, bdev); - if (!blk_queue_pci_p2pdma(bdev_get_queue(bdev))) + if (!blk_queue_pci_p2pdma(bdev_get_queue(bdev)) || + bdev_has_integrity(bdev)) blk_queue_flag_clear(QUEUE_FLAG_PCI_P2PDMA, t); disk_update_readahead(disk); } EXPORT_SYMBOL(disk_stack_limits); diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c index 6dfe6ec08133..2197e6da2148 100644 --- a/drivers/md/dm-table.c +++ b/drivers/md/dm-table.c @@ -1567,11 +1567,12 @@ static bool dm_table_supports_poll(struct dm_table *t) } static int device_not_pci_p2pdma_capable(struct dm_target *ti, struct dm_dev *dev, sector_t start, sector_t len, void *data) { - return !blk_queue_pci_p2pdma(bdev_get_queue(dev->bdev)); + return !blk_queue_pci_p2pdma(bdev_get_queue(dev->bdev)) || + bdev_get_integrity(dev->bdev); } static bool dm_table_supports_pci_p2pdma(struct dm_table *t) { for (unsigned int i = 0; i < t->num_targets; i++) { -- 2.52.0