]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
block: rename and simplify disk_get_and_lock_zone_wplug()
authorDamien Le Moal <dlemoal@kernel.org>
Fri, 27 Feb 2026 13:19:46 +0000 (22:19 +0900)
committerJens Axboe <axboe@kernel.dk>
Mon, 9 Mar 2026 20:30:00 +0000 (14:30 -0600)
disk_get_and_lock_zone_wplug() always returns a zone write plug with the
plug lock held. This is unnecessary since this function does not look at
the fields of existing plugs, and new plugs need to be locked only after
their insertion in the disk hash table, when they are being used.

Remove the zone write plug locking from disk_get_and_lock_zone_wplug()
and rename this function disk_get_or_alloc_zone_wplug().
blk_zone_wplug_handle_write() is modified to add locking of the zone
write plug after calling disk_get_or_alloc_zone_wplug() and before
starting to use the plug. This change also simplifies
blk_revalidate_seq_zone() as unlocking the plug becomes unnecessary.

Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
block/blk-zoned.c

index 7aae3c236cad667aedaacf8a52bd71d13a43ea5d..185651a0d6173a8b8108f6623a7d144f90a0ed91 100644 (file)
@@ -631,23 +631,20 @@ static void disk_mark_zone_wplug_dead(struct blk_zone_wplug *zwplug)
 static void blk_zone_wplug_bio_work(struct work_struct *work);
 
 /*
- * Get a reference on the write plug for the zone containing @sector.
- * If the plug does not exist, it is allocated and hashed.
- * Return a pointer to the zone write plug with the plug spinlock held.
+ * Get a zone write plug for the zone containing @sector.
+ * If the plug does not exist, it is allocated and inserted in the disk hash
+ * table.
  */
-static struct blk_zone_wplug *disk_get_and_lock_zone_wplug(struct gendisk *disk,
-                                       sector_t sector, gfp_t gfp_mask,
-                                       unsigned long *flags)
+static struct blk_zone_wplug *disk_get_or_alloc_zone_wplug(struct gendisk *disk,
+                                       sector_t sector, gfp_t gfp_mask)
 {
        unsigned int zno = disk_zone_no(disk, sector);
        struct blk_zone_wplug *zwplug;
 
 again:
        zwplug = disk_get_zone_wplug(disk, sector);
-       if (zwplug) {
-               spin_lock_irqsave(&zwplug->lock, *flags);
+       if (zwplug)
                return zwplug;
-       }
 
        /*
         * Allocate and initialize a zone write plug with an extra reference
@@ -668,15 +665,12 @@ again:
        INIT_WORK(&zwplug->bio_work, blk_zone_wplug_bio_work);
        zwplug->disk = disk;
 
-       spin_lock_irqsave(&zwplug->lock, *flags);
-
        /*
         * Insert the new zone write plug in the hash table. This can fail only
         * if another context already inserted a plug. Retry from the beginning
         * in such case.
         */
        if (!disk_insert_zone_wplug(disk, zwplug)) {
-               spin_unlock_irqrestore(&zwplug->lock, *flags);
                mempool_free(zwplug, disk->zone_wplugs_pool);
                goto again;
        }
@@ -1398,7 +1392,7 @@ static bool blk_zone_wplug_handle_write(struct bio *bio, unsigned int nr_segs)
        if (bio->bi_opf & REQ_NOWAIT)
                gfp_mask = GFP_NOWAIT;
 
-       zwplug = disk_get_and_lock_zone_wplug(disk, sector, gfp_mask, &flags);
+       zwplug = disk_get_or_alloc_zone_wplug(disk, sector, gfp_mask);
        if (!zwplug) {
                if (bio->bi_opf & REQ_NOWAIT)
                        bio_wouldblock_error(bio);
@@ -1407,6 +1401,8 @@ static bool blk_zone_wplug_handle_write(struct bio *bio, unsigned int nr_segs)
                return true;
        }
 
+       spin_lock_irqsave(&zwplug->lock, flags);
+
        /*
         * If we got a zone write plug marked as dead, then the user is issuing
         * writes to a full zone, or without synchronizing with zone reset or
@@ -2045,7 +2041,6 @@ static int blk_revalidate_seq_zone(struct blk_zone *zone, unsigned int idx,
        struct gendisk *disk = args->disk;
        struct blk_zone_wplug *zwplug;
        unsigned int wp_offset;
-       unsigned long flags;
 
        /*
         * Remember the capacity of the first sequential zone and check
@@ -2075,10 +2070,9 @@ static int blk_revalidate_seq_zone(struct blk_zone *zone, unsigned int idx,
        if (!wp_offset || wp_offset >= zone->capacity)
                return 0;
 
-       zwplug = disk_get_and_lock_zone_wplug(disk, zone->wp, GFP_NOIO, &flags);
+       zwplug = disk_get_or_alloc_zone_wplug(disk, zone->wp, GFP_NOIO);
        if (!zwplug)
                return -ENOMEM;
-       spin_unlock_irqrestore(&zwplug->lock, flags);
        disk_put_zone_wplug(zwplug);
 
        return 0;