Patch "s390/mm: Add cond_resched() to cmm_alloc/free_pages()" has been added to the 6.11-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    s390/mm: Add cond_resched() to cmm_alloc/free_pages()

to the 6.11-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     s390-mm-add-cond_resched-to-cmm_alloc-free_pages.patch
and it can be found in the queue-6.11 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit ee4def7b609410e84582e72034afab7e18b47011
Author: Gerald Schaefer <gerald.schaefer@xxxxxxxxxxxxx>
Date:   Mon Sep 2 14:02:19 2024 +0200

    s390/mm: Add cond_resched() to cmm_alloc/free_pages()
    
    [ Upstream commit 131b8db78558120f58c5dc745ea9655f6b854162 ]
    
    Adding/removing large amount of pages at once to/from the CMM balloon
    can result in rcu_sched stalls or workqueue lockups, because of busy
    looping w/o cond_resched().
    
    Prevent this by adding a cond_resched(). cmm_free_pages() holds a
    spin_lock while looping, so it cannot be added directly to the existing
    loop. Instead, introduce a wrapper function that operates on maximum 256
    pages at once, and add it there.
    
    Signed-off-by: Gerald Schaefer <gerald.schaefer@xxxxxxxxxxxxx>
    Reviewed-by: Heiko Carstens <hca@xxxxxxxxxxxxx>
    Signed-off-by: Heiko Carstens <hca@xxxxxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/arch/s390/mm/cmm.c b/arch/s390/mm/cmm.c
index 75d15bf41d97c..d01724a715d0f 100644
--- a/arch/s390/mm/cmm.c
+++ b/arch/s390/mm/cmm.c
@@ -95,11 +95,12 @@ static long cmm_alloc_pages(long nr, long *counter,
 		(*counter)++;
 		spin_unlock(&cmm_lock);
 		nr--;
+		cond_resched();
 	}
 	return nr;
 }
 
-static long cmm_free_pages(long nr, long *counter, struct cmm_page_array **list)
+static long __cmm_free_pages(long nr, long *counter, struct cmm_page_array **list)
 {
 	struct cmm_page_array *pa;
 	unsigned long addr;
@@ -123,6 +124,21 @@ static long cmm_free_pages(long nr, long *counter, struct cmm_page_array **list)
 	return nr;
 }
 
+static long cmm_free_pages(long nr, long *counter, struct cmm_page_array **list)
+{
+	long inc = 0;
+
+	while (nr) {
+		inc = min(256L, nr);
+		nr -= inc;
+		inc = __cmm_free_pages(inc, counter, list);
+		if (inc)
+			break;
+		cond_resched();
+	}
+	return nr + inc;
+}
+
 static int cmm_oom_notify(struct notifier_block *self,
 			  unsigned long dummy, void *parm)
 {




[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux