Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

block: Kill gfp_t argument of blkdev_report_zones()

Only GFP_KERNEL and GFP_NOIO are used with blkdev_report_zones(). In
preparation of using vmalloc() for large report buffer and zone array
allocations used by this function, remove its "gfp_t gfp_mask" argument
and rely on the caller context to use memalloc_noio_save/restore() where
necessary (block layer zone revalidation and dm-zoned I/O error path).

Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>

authored by

Damien Le Moal and committed by
Jens Axboe
bd976e52 b4c5875d

+46 -44
+19 -12
block/blk-zoned.c
··· 14 14 #include <linux/rbtree.h> 15 15 #include <linux/blkdev.h> 16 16 #include <linux/blk-mq.h> 17 + #include <linux/sched/mm.h> 17 18 18 19 #include "blk.h" 19 20 ··· 118 117 } 119 118 120 119 static int blk_report_zones(struct gendisk *disk, sector_t sector, 121 - struct blk_zone *zones, unsigned int *nr_zones, 122 - gfp_t gfp_mask) 120 + struct blk_zone *zones, unsigned int *nr_zones) 123 121 { 124 122 struct request_queue *q = disk->queue; 125 123 unsigned int z = 0, n, nrz = *nr_zones; ··· 127 127 128 128 while (z < nrz && sector < capacity) { 129 129 n = nrz - z; 130 - ret = disk->fops->report_zones(disk, sector, &zones[z], &n, 131 - gfp_mask); 130 + ret = disk->fops->report_zones(disk, sector, &zones[z], &n); 132 131 if (ret) 133 132 return ret; 134 133 if (!n) ··· 148 149 * @sector: Sector from which to report zones 149 150 * @zones: Array of zone structures where to return the zones information 150 151 * @nr_zones: Number of zone structures in the zone array 151 - * @gfp_mask: Memory allocation flags (for bio_alloc) 152 152 * 153 153 * Description: 154 154 * Get zone information starting from the zone containing @sector. 155 155 * The number of zone information reported may be less than the number 156 156 * requested by @nr_zones. The number of zones actually reported is 157 157 * returned in @nr_zones. 158 + * The caller must use memalloc_noXX_save/restore() calls to control 159 + * memory allocations done within this function (zone array and command 160 + * buffer allocation by the device driver). 158 161 */ 159 162 int blkdev_report_zones(struct block_device *bdev, sector_t sector, 160 - struct blk_zone *zones, unsigned int *nr_zones, 161 - gfp_t gfp_mask) 163 + struct blk_zone *zones, unsigned int *nr_zones) 162 164 { 163 165 struct request_queue *q = bdev_get_queue(bdev); 164 166 unsigned int i, nrz; ··· 184 184 nrz = min(*nr_zones, 185 185 __blkdev_nr_zones(q, bdev->bd_part->nr_sects - sector)); 186 186 ret = blk_report_zones(bdev->bd_disk, get_start_sect(bdev) + sector, 187 - zones, &nrz, gfp_mask); 187 + zones, &nrz); 188 188 if (ret) 189 189 return ret; 190 190 ··· 305 305 if (!zones) 306 306 return -ENOMEM; 307 307 308 - ret = blkdev_report_zones(bdev, rep.sector, 309 - zones, &rep.nr_zones, 310 - GFP_KERNEL); 308 + ret = blkdev_report_zones(bdev, rep.sector, zones, &rep.nr_zones); 311 309 if (ret) 312 310 goto out; 313 311 ··· 413 415 unsigned long *seq_zones_wlock = NULL, *seq_zones_bitmap = NULL; 414 416 unsigned int i, rep_nr_zones = 0, z = 0, nrz; 415 417 struct blk_zone *zones = NULL; 418 + unsigned int noio_flag; 416 419 sector_t sector = 0; 417 420 int ret = 0; 418 421 ··· 425 426 q->nr_zones = nr_zones; 426 427 return 0; 427 428 } 429 + 430 + /* 431 + * Ensure that all memory allocations in this context are done as 432 + * if GFP_NOIO was specified. 433 + */ 434 + noio_flag = memalloc_noio_save(); 428 435 429 436 if (!blk_queue_is_zoned(q) || !nr_zones) { 430 437 nr_zones = 0; ··· 454 449 455 450 while (z < nr_zones) { 456 451 nrz = min(nr_zones - z, rep_nr_zones); 457 - ret = blk_report_zones(disk, sector, zones, &nrz, GFP_NOIO); 452 + ret = blk_report_zones(disk, sector, zones, &nrz); 458 453 if (ret) 459 454 goto out; 460 455 if (!nrz) ··· 485 480 blk_mq_unfreeze_queue(q); 486 481 487 482 out: 483 + memalloc_noio_restore(noio_flag); 484 + 488 485 free_pages((unsigned long)zones, 489 486 get_order(rep_nr_zones * sizeof(struct blk_zone))); 490 487 kfree(seq_zones_wlock);
+1 -2
drivers/block/null_blk.h
··· 89 89 int null_zone_init(struct nullb_device *dev); 90 90 void null_zone_exit(struct nullb_device *dev); 91 91 int null_zone_report(struct gendisk *disk, sector_t sector, 92 - struct blk_zone *zones, unsigned int *nr_zones, 93 - gfp_t gfp_mask); 92 + struct blk_zone *zones, unsigned int *nr_zones); 94 93 void null_zone_write(struct nullb_cmd *cmd, sector_t sector, 95 94 unsigned int nr_sectors); 96 95 void null_zone_reset(struct nullb_cmd *cmd, sector_t sector);
+1 -2
drivers/block/null_blk_zoned.c
··· 67 67 } 68 68 69 69 int null_zone_report(struct gendisk *disk, sector_t sector, 70 - struct blk_zone *zones, unsigned int *nr_zones, 71 - gfp_t gfp_mask) 70 + struct blk_zone *zones, unsigned int *nr_zones) 72 71 { 73 72 struct nullb *nullb = disk->private_data; 74 73 struct nullb_device *dev = nullb->dev;
+2 -3
drivers/md/dm-flakey.c
··· 461 461 462 462 #ifdef CONFIG_BLK_DEV_ZONED 463 463 static int flakey_report_zones(struct dm_target *ti, sector_t sector, 464 - struct blk_zone *zones, unsigned int *nr_zones, 465 - gfp_t gfp_mask) 464 + struct blk_zone *zones, unsigned int *nr_zones) 466 465 { 467 466 struct flakey_c *fc = ti->private; 468 467 int ret; 469 468 470 469 /* Do report and remap it */ 471 470 ret = blkdev_report_zones(fc->dev->bdev, flakey_map_sector(ti, sector), 472 - zones, nr_zones, gfp_mask); 471 + zones, nr_zones); 473 472 if (ret != 0) 474 473 return ret; 475 474
+2 -3
drivers/md/dm-linear.c
··· 137 137 138 138 #ifdef CONFIG_BLK_DEV_ZONED 139 139 static int linear_report_zones(struct dm_target *ti, sector_t sector, 140 - struct blk_zone *zones, unsigned int *nr_zones, 141 - gfp_t gfp_mask) 140 + struct blk_zone *zones, unsigned int *nr_zones) 142 141 { 143 142 struct linear_c *lc = (struct linear_c *) ti->private; 144 143 int ret; 145 144 146 145 /* Do report and remap it */ 147 146 ret = blkdev_report_zones(lc->dev->bdev, linear_map_sector(ti, sector), 148 - zones, nr_zones, gfp_mask); 147 + zones, nr_zones); 149 148 if (ret != 0) 150 149 return ret; 151 150
+12 -4
drivers/md/dm-zoned-metadata.c
··· 8 8 9 9 #include <linux/module.h> 10 10 #include <linux/crc32.h> 11 + #include <linux/sched/mm.h> 11 12 12 13 #define DM_MSG_PREFIX "zoned metadata" 13 14 ··· 1163 1162 while (sector < dev->capacity) { 1164 1163 /* Get zone information */ 1165 1164 nr_blkz = DMZ_REPORT_NR_ZONES; 1166 - ret = blkdev_report_zones(dev->bdev, sector, blkz, 1167 - &nr_blkz, GFP_KERNEL); 1165 + ret = blkdev_report_zones(dev->bdev, sector, blkz, &nr_blkz); 1168 1166 if (ret) { 1169 1167 dmz_dev_err(dev, "Report zones failed %d", ret); 1170 1168 goto out; ··· 1201 1201 static int dmz_update_zone(struct dmz_metadata *zmd, struct dm_zone *zone) 1202 1202 { 1203 1203 unsigned int nr_blkz = 1; 1204 + unsigned int noio_flag; 1204 1205 struct blk_zone blkz; 1205 1206 int ret; 1206 1207 1207 - /* Get zone information from disk */ 1208 + /* 1209 + * Get zone information from disk. Since blkdev_report_zones() uses 1210 + * GFP_KERNEL by default for memory allocations, set the per-task 1211 + * PF_MEMALLOC_NOIO flag so that all allocations are done as if 1212 + * GFP_NOIO was specified. 1213 + */ 1214 + noio_flag = memalloc_noio_save(); 1208 1215 ret = blkdev_report_zones(zmd->dev->bdev, dmz_start_sect(zmd, zone), 1209 - &blkz, &nr_blkz, GFP_NOIO); 1216 + &blkz, &nr_blkz); 1217 + memalloc_noio_restore(noio_flag); 1210 1218 if (!nr_blkz) 1211 1219 ret = -EIO; 1212 1220 if (ret) {
+2 -4
drivers/md/dm.c
··· 441 441 } 442 442 443 443 static int dm_blk_report_zones(struct gendisk *disk, sector_t sector, 444 - struct blk_zone *zones, unsigned int *nr_zones, 445 - gfp_t gfp_mask) 444 + struct blk_zone *zones, unsigned int *nr_zones) 446 445 { 447 446 #ifdef CONFIG_BLK_DEV_ZONED 448 447 struct mapped_device *md = disk->private_data; ··· 479 480 * So there is no need to loop here trying to fill the entire array 480 481 * of zones. 481 482 */ 482 - ret = tgt->type->report_zones(tgt, sector, zones, 483 - nr_zones, gfp_mask); 483 + ret = tgt->type->report_zones(tgt, sector, zones, nr_zones); 484 484 485 485 out: 486 486 dm_put_live_table(md, srcu_idx);
+1 -2
drivers/scsi/sd.h
··· 213 213 extern void sd_zbc_complete(struct scsi_cmnd *cmd, unsigned int good_bytes, 214 214 struct scsi_sense_hdr *sshdr); 215 215 extern int sd_zbc_report_zones(struct gendisk *disk, sector_t sector, 216 - struct blk_zone *zones, unsigned int *nr_zones, 217 - gfp_t gfp_mask); 216 + struct blk_zone *zones, unsigned int *nr_zones); 218 217 219 218 #else /* CONFIG_BLK_DEV_ZONED */ 220 219
+2 -4
drivers/scsi/sd_zbc.c
··· 109 109 * @sector: Start 512B sector of the report 110 110 * @zones: Array of zone descriptors 111 111 * @nr_zones: Number of descriptors in the array 112 - * @gfp_mask: Memory allocation mask 113 112 * 114 113 * Execute a report zones command on the target disk. 115 114 */ 116 115 int sd_zbc_report_zones(struct gendisk *disk, sector_t sector, 117 - struct blk_zone *zones, unsigned int *nr_zones, 118 - gfp_t gfp_mask) 116 + struct blk_zone *zones, unsigned int *nr_zones) 119 117 { 120 118 struct scsi_disk *sdkp = scsi_disk(disk); 121 119 unsigned int i, buflen, nrz = *nr_zones; ··· 132 134 */ 133 135 buflen = min(queue_max_hw_sectors(disk->queue) << 9, 134 136 roundup((nrz + 1) * 64, 512)); 135 - buf = kmalloc(buflen, gfp_mask); 137 + buf = kmalloc(buflen, GFP_KERNEL); 136 138 if (!buf) 137 139 return -ENOMEM; 138 140
+1 -3
fs/f2fs/super.c
··· 2841 2841 while (zones && sector < nr_sectors) { 2842 2842 2843 2843 nr_zones = F2FS_REPORT_NR_ZONES; 2844 - err = blkdev_report_zones(bdev, sector, 2845 - zones, &nr_zones, 2846 - GFP_KERNEL); 2844 + err = blkdev_report_zones(bdev, sector, zones, &nr_zones); 2847 2845 if (err) 2848 2846 break; 2849 2847 if (!nr_zones) {
+2 -3
include/linux/blkdev.h
··· 347 347 extern unsigned int blkdev_nr_zones(struct block_device *bdev); 348 348 extern int blkdev_report_zones(struct block_device *bdev, 349 349 sector_t sector, struct blk_zone *zones, 350 - unsigned int *nr_zones, gfp_t gfp_mask); 350 + unsigned int *nr_zones); 351 351 extern int blkdev_reset_zones(struct block_device *bdev, sector_t sectors, 352 352 sector_t nr_sectors, gfp_t gfp_mask); 353 353 extern int blk_revalidate_disk_zones(struct gendisk *disk); ··· 1673 1673 /* this callback is with swap_lock and sometimes page table lock held */ 1674 1674 void (*swap_slot_free_notify) (struct block_device *, unsigned long); 1675 1675 int (*report_zones)(struct gendisk *, sector_t sector, 1676 - struct blk_zone *zones, unsigned int *nr_zones, 1677 - gfp_t gfp_mask); 1676 + struct blk_zone *zones, unsigned int *nr_zones); 1678 1677 struct module *owner; 1679 1678 const struct pr_ops *pr_ops; 1680 1679 };
+1 -2
include/linux/device-mapper.h
··· 95 95 96 96 typedef int (*dm_report_zones_fn) (struct dm_target *ti, sector_t sector, 97 97 struct blk_zone *zones, 98 - unsigned int *nr_zones, 99 - gfp_t gfp_mask); 98 + unsigned int *nr_zones); 100 99 101 100 /* 102 101 * These iteration functions are typically used to check (and combine)