From b9f6a788aa4007e158306d2951325e7282522434 Mon Sep 17 00:00:00 2001
From: Guo Mengqi <guomengqi3@huawei.com>
Date: Thu, 29 Sep 2022 11:39:51 +0000
Subject: [PATCH] mm: sharepool: fix potential AA deadlock

hulk inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I5R0X9
CVE: NA

--------------------------------

Fix a AA deadlock caused by nested lock in mg_sp_group_add_task().

Deadlock path:

mg_sp_group_add_task()

    down_write(sp_group_sem)
    find_or_alloc_sp_group()
	!spg_valid()
	sp_group_drop()
	    free_sp_group() -> down_write(sp_group_sem)
    ---> AA deadlock

Signed-off-by: Guo Mengqi <guomengqi3@huawei.com>
Reviewed-by: Weilong Chen <chenweilong@huawei.com>
Signed-off-by: Yongqiang Liu <liuyongqiang13@huawei.com>
---
 mm/share_pool.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/mm/share_pool.c b/mm/share_pool.c
index fb1722e8fbf1..41ed3a3b8682 100644
--- a/mm/share_pool.c
+++ b/mm/share_pool.c
@@ -946,6 +946,14 @@ static void free_sp_group(struct sp_group *spg)
 	up_write(&sp_group_sem);
 }
 
+static void sp_group_drop_locked(struct sp_group *spg)
+{
+	lockdep_assert_held_exclusive(&sp_group_sem);
+
+	if (atomic_dec_and_test(&spg->use_count))
+		free_sp_group_locked(spg);
+}
+
 static void sp_group_drop(struct sp_group *spg)
 {
 	if (atomic_dec_and_test(&spg->use_count))
@@ -1234,7 +1242,7 @@ static struct sp_group *find_or_alloc_sp_group(int spg_id, unsigned long flag)
 		down_read(&spg->rw_lock);
 		if (!spg_valid(spg)) {
 			up_read(&spg->rw_lock);
-			sp_group_drop(spg);
+			sp_group_drop_locked(spg);
 			return ERR_PTR(-ENODEV);
 		}
 		up_read(&spg->rw_lock);
-- 
GitLab