From: Liu Shixin liushixin2@huawei.com
hulk inclusion category: bugfix bugzilla: 46904, https://gitee.com/openeuler/kernel/issues/I6KOXL CVE: NA
--------------------------------
When memory is fragmented, update_reserve_pages() may call migrate_pages() to collect continuous memory. This function can sleep, so we should use mutex lock instead of spin lock.
Fixes: 3eb69101b5e6 ("mm: Add two interface for dhugetlb") Signed-off-by: Liu Shixin liushixin2@huawei.com Reviewed-by: Nanyong Sun sunnanyong@huawei.com Reviewed-by: tong tiangen tongtiangen@huawei.com Reviewed-by: Kefeng Wang wangkefeng.wang@huawei.com Signed-off-by: Yongqiang Liu liuyongqiang13@huawei.com --- include/linux/hugetlb.h | 2 +- mm/hugetlb.c | 2 +- mm/memcontrol.c | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h index d44eea25c0d6..dfd9a8c945e1 100644 --- a/include/linux/hugetlb.h +++ b/include/linux/hugetlb.h @@ -696,7 +696,7 @@ struct small_page_pool { struct dhugetlb_pool { int nid; spinlock_t lock; - spinlock_t reserved_lock; + struct mutex reserved_lock; atomic_t refcnt;
struct mem_cgroup *attach_memcg; diff --git a/mm/hugetlb.c b/mm/hugetlb.c index 9f974270c84d..a468d94bc16a 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -3327,7 +3327,7 @@ struct dhugetlb_pool *hpool_alloc(unsigned long nid) return NULL;
spin_lock_init(&hpool->lock); - spin_lock_init(&hpool->reserved_lock); + mutex_init(&hpool->reserved_lock); hpool->nid = nid; atomic_set(&hpool->refcnt, 1); INIT_LIST_HEAD(&hpool->dhugetlb_1G_freelists); diff --git a/mm/memcontrol.c b/mm/memcontrol.c index fd40fef49e45..886d6b0a4fce 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -4950,9 +4950,9 @@ static int update_reserve_pages(struct kernfs_open_file *of, hpool = get_dhugetlb_pool_from_memcg(memcg); if (!hpool) return -EINVAL; - spin_lock(&hpool->reserved_lock); + mutex_lock(&hpool->reserved_lock); dhugetlb_reserve_hugepages(hpool, size, gigantic); - spin_unlock(&hpool->reserved_lock); + mutex_unlock(&hpool->reserved_lock); dhugetlb_pool_put(hpool); return 0; }