Move the atomic context detection logic from erofs's z_erofs_in_atomic()
into the block layer as bio_in_atomic(). This helper returns true when
the current context is unsafe for sleeping bio completion handlers (e.g.,
hard/soft IRQ, preempt-disabled).

The logic was originally added to erofs in commit c99fab6e80b7 ("erofs:
fix atomic context detection when !CONFIG_DEBUG_LOCK_ALLOC"). A
subsequent patch will use it in the block layer's bio completion
infrastructure, so move it to include/linux/bio.h where both subsystems
can share it.

Convert erofs to call the new bio_in_atomic() directly.

Suggested-by: Christoph Hellwig <[email protected]>
Signed-off-by: Tal Zussman <[email protected]>
---
 fs/erofs/zdata.c    | 11 +----------
 include/linux/bio.h | 15 +++++++++++++++
 2 files changed, 16 insertions(+), 10 deletions(-)

diff --git a/fs/erofs/zdata.c b/fs/erofs/zdata.c
index 74520e910259..f796bb3ef53b 100644
--- a/fs/erofs/zdata.c
+++ b/fs/erofs/zdata.c
@@ -1427,15 +1427,6 @@ static void z_erofs_decompressqueue_kthread_work(struct 
kthread_work *work)
 }
 #endif
 
-/* Use (kthread_)work in atomic contexts to minimize scheduling overhead */
-static inline bool z_erofs_in_atomic(void)
-{
-       if (IS_ENABLED(CONFIG_PREEMPTION) && rcu_preempt_depth())
-               return true;
-       if (!IS_ENABLED(CONFIG_PREEMPT_COUNT))
-               return true;
-       return !preemptible();
-}
 
 static void z_erofs_decompress_kickoff(struct z_erofs_decompressqueue *io,
                                       int bios)
@@ -1452,7 +1443,7 @@ static void z_erofs_decompress_kickoff(struct 
z_erofs_decompressqueue *io,
 
        if (atomic_add_return(bios, &io->pending_bios))
                return;
-       if (z_erofs_in_atomic()) {
+       if (bio_in_atomic()) {
                /* See `sync_decompress` in sysfs-fs-erofs for more details */
                if (sbi->sync_decompress == EROFS_SYNC_DECOMPRESS_AUTO)
                        sbi->sync_decompress = EROFS_SYNC_DECOMPRESS_FORCE_ON;
diff --git a/include/linux/bio.h b/include/linux/bio.h
index 8f33f717b14f..62a983758e09 100644
--- a/include/linux/bio.h
+++ b/include/linux/bio.h
@@ -368,6 +368,21 @@ static inline struct bio *bio_alloc(struct block_device 
*bdev,
 
 void submit_bio(struct bio *bio);
 
+/**
+ * bio_in_atomic - check if the current context is unsafe for bio completion
+ *
+ * Return: %true in atomic contexts (e.g. hard/soft IRQ, preempt-disabled);
+ * %false when a bio can be safely completed in the current context.
+ */
+static inline bool bio_in_atomic(void)
+{
+       if (IS_ENABLED(CONFIG_PREEMPTION) && rcu_preempt_depth())
+               return true;
+       if (!IS_ENABLED(CONFIG_PREEMPT_COUNT))
+               return true;
+       return !preemptible();
+}
+
 extern void bio_endio(struct bio *);
 
 /**

-- 
2.39.5


Reply via email to