From: Pavel Begunkov <asml.sile...@gmail.com>

[ Upstream commit 8fc058597a283e9a37720abb0e8d68e342b9387d ]

btrfs_discard_workfn() drops discard_ctl->lock just to take it again in
a moment in btrfs_discard_schedule_work(). Avoid that and also reuse
ktime.

Reviewed-by: Josef Bacik <jo...@toxicpanda.com>
Signed-off-by: Pavel Begunkov <asml.sile...@gmail.com>
Reviewed-by: David Sterba <dste...@suse.com>
Signed-off-by: David Sterba <dste...@suse.com>
Signed-off-by: Sasha Levin <sas...@kernel.org>
---
 fs/btrfs/discard.c | 43 +++++++++++++++++++++++--------------------
 1 file changed, 23 insertions(+), 20 deletions(-)

diff --git a/fs/btrfs/discard.c b/fs/btrfs/discard.c
index d1a5380e8827d..9e1a06144e32d 100644
--- a/fs/btrfs/discard.c
+++ b/fs/btrfs/discard.c
@@ -328,28 +328,15 @@ void btrfs_discard_queue_work(struct btrfs_discard_ctl 
*discard_ctl,
                btrfs_discard_schedule_work(discard_ctl, false);
 }
 
-/**
- * btrfs_discard_schedule_work - responsible for scheduling the discard work
- * @discard_ctl: discard control
- * @override: override the current timer
- *
- * Discards are issued by a delayed workqueue item.  @override is used to
- * update the current delay as the baseline delay interval is reevaluated on
- * transaction commit.  This is also maxed with any other rate limit.
- */
-void btrfs_discard_schedule_work(struct btrfs_discard_ctl *discard_ctl,
-                                bool override)
+static void __btrfs_discard_schedule_work(struct btrfs_discard_ctl 
*discard_ctl,
+                                         u64 now, bool override)
 {
        struct btrfs_block_group *block_group;
-       const u64 now = ktime_get_ns();
-
-       spin_lock(&discard_ctl->lock);
 
        if (!btrfs_run_discard_work(discard_ctl))
-               goto out;
-
+               return;
        if (!override && delayed_work_pending(&discard_ctl->work))
-               goto out;
+               return;
 
        block_group = find_next_block_group(discard_ctl, now);
        if (block_group) {
@@ -382,7 +369,24 @@ void btrfs_discard_schedule_work(struct btrfs_discard_ctl 
*discard_ctl,
                mod_delayed_work(discard_ctl->discard_workers,
                                 &discard_ctl->work, delay);
        }
-out:
+}
+
+/*
+ * btrfs_discard_schedule_work - responsible for scheduling the discard work
+ * @discard_ctl:  discard control
+ * @override:     override the current timer
+ *
+ * Discards are issued by a delayed workqueue item.  @override is used to
+ * update the current delay as the baseline delay interval is reevaluated on
+ * transaction commit.  This is also maxed with any other rate limit.
+ */
+void btrfs_discard_schedule_work(struct btrfs_discard_ctl *discard_ctl,
+                                bool override)
+{
+       const u64 now = ktime_get_ns();
+
+       spin_lock(&discard_ctl->lock);
+       __btrfs_discard_schedule_work(discard_ctl, now, override);
        spin_unlock(&discard_ctl->lock);
 }
 
@@ -487,9 +491,8 @@ static void btrfs_discard_workfn(struct work_struct *work)
 
        spin_lock(&discard_ctl->lock);
        discard_ctl->block_group = NULL;
+       __btrfs_discard_schedule_work(discard_ctl, now, false);
        spin_unlock(&discard_ctl->lock);
-
-       btrfs_discard_schedule_work(discard_ctl, false);
 }
 
 /**
-- 
2.27.0



Reply via email to