dm: switch dm_io booleans over to proper flags
authorMike Snitzer <snitzer@kernel.org>
Fri, 18 Mar 2022 04:15:28 +0000 (00:15 -0400)
committerMike Snitzer <snitzer@kernel.org>
Mon, 21 Mar 2022 18:15:34 +0000 (14:15 -0400)
Add flags to dm_io and manage them using the same pattern used for
bi_flags in struct bio.

Signed-off-by: Mike Snitzer <snitzer@kernel.org>
drivers/md/dm-core.h
drivers/md/dm.c

index 8d3d118873430e07db15f56b315b02b816db6a0d..e127cbcaf33d884f95f9008f7b89b7c926994541 100644 (file)
@@ -232,18 +232,36 @@ struct dm_io {
        struct mapped_device *md;
        struct bio *orig_bio;
        blk_status_t status;
-       bool start_io_acct:1;
-       int was_accounted;
+       unsigned short flags;
        unsigned long start_time;
        void *data;
        struct hlist_node node;
        struct task_struct *map_task;
+       spinlock_t startio_lock;
        spinlock_t endio_lock;
        struct dm_stats_aux stats_aux;
        /* last member of dm_target_io is 'struct bio' */
        struct dm_target_io tio;
 };
 
+/*
+ * dm_io flags
+ */
+enum {
+       DM_IO_START_ACCT,
+       DM_IO_ACCOUNTED
+};
+
+static inline bool dm_io_flagged(struct dm_io *io, unsigned int bit)
+{
+       return (io->flags & (1U << bit)) != 0;
+}
+
+static inline void dm_io_set_flag(struct dm_io *io, unsigned int bit)
+{
+       io->flags |= (1U << bit);
+}
+
 static inline void dm_io_inc_pending(struct dm_io *io)
 {
        atomic_inc(&io->io_count);
index df7664f3028c229711dce92fb6d4be59dc0813b4..83328f03bcb27065bda76a0d4b1bd19e39cadd0f 100644 (file)
@@ -541,11 +541,18 @@ static void dm_start_io_acct(struct dm_io *io, struct bio *clone)
         * Expect no possibility for race unless is_duplicate_bio.
         */
        if (!clone || likely(!clone_to_tio(clone)->is_duplicate_bio)) {
-               if (WARN_ON_ONCE(io->was_accounted))
+               if (WARN_ON_ONCE(dm_io_flagged(io, DM_IO_ACCOUNTED)))
                        return;
-               io->was_accounted = 1;
-       } else if (xchg(&io->was_accounted, 1) == 1)
-               return;
+               dm_io_set_flag(io, DM_IO_ACCOUNTED);
+       } else {
+               unsigned long flags;
+               if (dm_io_flagged(io, DM_IO_ACCOUNTED))
+                       return;
+               /* Can afford locking given is_duplicate_bio */
+               spin_lock_irqsave(&io->startio_lock, flags);
+               dm_io_set_flag(io, DM_IO_ACCOUNTED);
+               spin_unlock_irqrestore(&io->startio_lock, flags);
+       }
 
        __dm_start_io_acct(io, bio);
 }
@@ -575,11 +582,10 @@ static struct dm_io *alloc_io(struct mapped_device *md, struct bio *bio)
        io->orig_bio = NULL;
        io->md = md;
        io->map_task = current;
+       spin_lock_init(&io->startio_lock);
        spin_lock_init(&io->endio_lock);
-
        io->start_time = jiffies;
-       io->start_io_acct = false;
-       io->was_accounted = 0;
+       io->flags = 0;
 
        dm_stats_record_start(&md->stats, &io->stats_aux);
 
@@ -868,7 +874,7 @@ static void dm_io_complete(struct dm_io *io)
        }
 
        io_error = io->status;
-       if (io->was_accounted)
+       if (dm_io_flagged(io, DM_IO_ACCOUNTED))
                dm_end_io_acct(io, bio);
        else if (!io_error) {
                /*
@@ -1218,7 +1224,7 @@ void dm_submit_bio_remap(struct bio *clone, struct bio *tgt_clone)
         */
        if (io->map_task == current) {
                /* Still in target's map function */
-               io->start_io_acct = true;
+               dm_io_set_flag(io, DM_IO_START_ACCT);
        } else {
                /*
                 * Called by another thread, managed by DM target,
@@ -1288,7 +1294,7 @@ static void __map_bio(struct bio *clone)
        case DM_MAPIO_SUBMITTED:
                /* target has assumed ownership of this io */
                if (!ti->accounts_remapped_io)
-                       io->start_io_acct = true;
+                       dm_io_set_flag(io, DM_IO_START_ACCT);
                break;
        case DM_MAPIO_REMAPPED:
                /*
@@ -1297,7 +1303,7 @@ static void __map_bio(struct bio *clone)
                 */
                __dm_submit_bio_remap(clone, disk_devt(io->md->disk),
                                      tio->old_sector);
-               io->start_io_acct = true;
+               dm_io_set_flag(io, DM_IO_START_ACCT);
                break;
        case DM_MAPIO_KILL:
        case DM_MAPIO_REQUEUE:
@@ -1591,7 +1597,7 @@ out:
        if (!orig_bio)
                orig_bio = bio;
        smp_store_release(&ci.io->orig_bio, orig_bio);
-       if (ci.io->start_io_acct)
+       if (dm_io_flagged(ci.io, DM_IO_START_ACCT))
                dm_start_io_acct(ci.io, NULL);
 
        /*