From 28436ba34b7d1b6af2a898d37ee678a1eb643db4 Mon Sep 17 00:00:00 2001 From: Damien Le Moal Date: Sat, 19 Jun 2021 08:15:19 +0900 Subject: dm zone: fix dm_revalidate_zones() memory allocation Make sure that the zone write pointer offset array is allocated with a vmalloc in dm_zone_revalidate_cb() by passing GFP_KERNEL gfp flag to kvcalloc(). However, since we do not want to trigger IOs while revalidating zones, change dm_revalidate_zones() to have the zone scan done in GFP_NOIO context using memalloc_noio_save/restore calls. Reported-by: Dan Carpenter Fixes: bb37d77239af ("dm: introduce zone append emulation") Signed-off-by: Damien Le Moal Signed-off-by: Mike Snitzer --- drivers/md/dm-zone.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'drivers/md') diff --git a/drivers/md/dm-zone.c b/drivers/md/dm-zone.c index c2f26949f5ee..6d82a34438c8 100644 --- a/drivers/md/dm-zone.c +++ b/drivers/md/dm-zone.c @@ -205,7 +205,7 @@ static int dm_zone_revalidate_cb(struct blk_zone *zone, unsigned int idx, if (!md->zwp_offset) { md->zwp_offset = kvcalloc(q->nr_zones, sizeof(unsigned int), - GFP_NOIO); + GFP_KERNEL); if (!md->zwp_offset) return -ENOMEM; } @@ -230,6 +230,7 @@ static int dm_zone_revalidate_cb(struct blk_zone *zone, unsigned int idx, static int dm_revalidate_zones(struct mapped_device *md, struct dm_table *t) { struct request_queue *q = md->queue; + unsigned int noio_flag; int ret; /* @@ -241,9 +242,14 @@ static int dm_revalidate_zones(struct mapped_device *md, struct dm_table *t) if (md->nr_zones) return 0; - /* Scan all zones to initialize everything */ + /* + * Scan all zones to initialize everything. Ensure that all vmalloc + * operations in this context are done as if GFP_NOIO was specified. + */ + noio_flag = memalloc_noio_save(); ret = dm_blk_do_report_zones(md, t, 0, q->nr_zones, dm_zone_revalidate_cb, md); + memalloc_noio_restore(noio_flag); if (ret < 0) goto err; if (ret != q->nr_zones) { -- cgit v1.2.3