Re: Unable to recycle any page

Michael Kelly <[email protected]>
Newsgroups gmane.linux.debian.ports.hurd
Message-ID <[email protected]>
On 12/06/2025 14:14, Michael Kelly wrote:
> I have restructured vm_page_seg_pull_inactive_page() and 
> vm_page_seg_pull_active_page() to search all appropriate lists and 
> have been able to run the test case to completion many times without 
> the 'vm_page warning' occurring with swap usage reaching up to ~500M 
> in some instances. See appended patch. As usual, please feel free to 
> alter before inclusion, make suggestions or reject as appropriate.
Patch replacement attached. Apologies for any inconvenience.
vm_page.c.patch (text/x-patch, 3.3 KB)
diff --git a/vm/vm_page.c b/vm/vm_page.c
index 6c5eba22..f07d6c78 100644
--- a/vm/vm_page.c
+++ b/vm/vm_page.c
@@ -555,24 +555,6 @@ vm_page_queue_remove(struct vm_page_queue *queue, struct vm_page *page)
     list_remove(&page->node);
 }
 
-static struct vm_page *
-vm_page_queue_first(struct vm_page_queue *queue, boolean_t external_only)
-{
-    struct vm_page *page;
-
-    if (!list_empty(&queue->external_pages)) {
-        page = list_first_entry(&queue->external_pages, struct vm_page, node);
-        return page;
-    }
-
-    if (!external_only && !list_empty(&queue->internal_pages)) {
-        page = list_first_entry(&queue->internal_pages, struct vm_page, node);
-        return page;
-    }
-
-    return NULL;
-}
-
 static struct vm_page_seg *
 vm_page_seg_get(unsigned short index)
 {
@@ -813,28 +795,53 @@ vm_page_seg_remove_inactive_page(struct vm_page_seg *seg, struct vm_page *page)
     vm_page_inactive_count--;
 }
 
+static inline struct list*
+vm_page_next_page_list(struct list* cur_page_list,
+		       struct vm_page_queue* queue,
+		       boolean_t external_only)
+{
+  return (external_only
+	  ? NULL
+	  : (cur_page_list == &queue->external_pages
+	     ? &queue->internal_pages
+	     : NULL));
+}
+
 /*
  * Attempt to pull an active page.
  *
  * If successful, the object containing the page is locked.
  */
+
 static struct vm_page *
 vm_page_seg_pull_active_page(struct vm_page_seg *seg, boolean_t external_only)
 {
     struct vm_page *page, *first;
+    struct list* page_list;
     boolean_t locked;
 
     first = NULL;
 
+    page_list = &seg->active_pages.external_pages;
+
     for (;;) {
-        page = vm_page_queue_first(&seg->active_pages, external_only);
 
-        if (page == NULL) {
+        page = (list_empty(page_list)
+		? NULL
+		: list_first_entry(page_list, struct vm_page, node));
+
+        if (page == NULL || page == first) {
+          page_list = vm_page_next_page_list(page_list, &seg->active_pages, external_only);
+
+          if (page_list == NULL)
             break;
+          else
+            {
+              first = NULL;
+              continue;
+            }
         } else if (first == NULL) {
             first = page;
-        } else if (first == page) {
-            break;
         }
 
         vm_page_seg_remove_active_page(seg, page);
@@ -868,19 +875,31 @@ static struct vm_page *
 vm_page_seg_pull_inactive_page(struct vm_page_seg *seg, boolean_t external_only)
 {
     struct vm_page *page, *first;
+    struct list* page_list;
     boolean_t locked;
 
     first = NULL;
 
+    page_list = &seg->inactive_pages.external_pages;
+
     for (;;) {
-        page = vm_page_queue_first(&seg->inactive_pages, external_only);
 
-        if (page == NULL) {
+        page = (list_empty(page_list)
+		? NULL
+		: list_first_entry(page_list, struct vm_page, node));
+
+        if (page == NULL || page == first) {
+          page_list = vm_page_next_page_list(page_list, &seg->inactive_pages, external_only);
+
+          if (page_list == NULL)
             break;
+          else
+            {
+              first = NULL;
+              continue;
+            }
         } else if (first == NULL) {
             first = page;
-        } else if (first == page) {
-            break;
         }
 
         vm_page_seg_remove_inactive_page(seg, page);
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.