ANDROID: PM: Fix suspend spinlock in IRQ context
Fix bug in abort of fs_sync during suspend feature, since a spinlock is
taken in IRQ context, we need to use spinlock_irqsave(). This feature is
not yet upstream, so fix needs to be made here.
Link: https://lore.kernel.org/all/20250911185314.2377124-1-wusamuel@google.com/
Bug: 452395562
Change-Id: I8652a579ebd6bb3a6d218f2dd8983712ba6a6578
Signed-off-by: Samuel Wu <wusamuel@google.com>
diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c
index f6b0ec6..5c8efcd 100644
--- a/kernel/power/suspend.c
+++ b/kernel/power/suspend.c
@@ -88,9 +88,11 @@ static DECLARE_COMPLETION(suspend_fs_sync_complete);
*/
void suspend_abort_fs_sync(void)
{
- spin_lock(&suspend_fs_sync_lock);
+ unsigned long flags;
+
+ spin_lock_irqsave(&suspend_fs_sync_lock, flags);
complete(&suspend_fs_sync_complete);
- spin_unlock(&suspend_fs_sync_lock);
+ spin_unlock_irqrestore(&suspend_fs_sync_lock, flags);
}
void s2idle_set_ops(const struct platform_s2idle_ops *ops)
@@ -425,12 +427,13 @@ MODULE_PARM_DESC(pm_fs_abort,
static void sync_filesystems_fn(struct work_struct *work)
{
+ unsigned long flags;
ksys_sync_helper();
- spin_lock(&suspend_fs_sync_lock);
+ spin_lock_irqsave(&suspend_fs_sync_lock, flags);
suspend_fs_sync_queued = false;
complete(&suspend_fs_sync_complete);
- spin_unlock(&suspend_fs_sync_lock);
+ spin_unlock_irqrestore(&suspend_fs_sync_lock, flags);
}
static DECLARE_WORK(sync_filesystems, sync_filesystems_fn);
@@ -447,9 +450,10 @@ static int suspend_fs_sync_with_abort(void)
return 0;
}
bool need_suspend_fs_sync_requeue;
+ unsigned long flags;
Start_fs_sync:
- spin_lock(&suspend_fs_sync_lock);
+ spin_lock_irqsave(&suspend_fs_sync_lock, flags);
reinit_completion(&suspend_fs_sync_complete);
/*
* Handle the case where a suspend immediately follows a previous
@@ -464,7 +468,7 @@ static int suspend_fs_sync_with_abort(void)
suspend_fs_sync_queued = true;
schedule_work(&sync_filesystems);
}
- spin_unlock(&suspend_fs_sync_lock);
+ spin_unlock_irqrestore(&suspend_fs_sync_lock, flags);
/*
* Completion is triggered by fs_sync finishing or a suspend abort