Do not cache pages belonging to memory ranges with a `use' count.
authormpi <mpi@openbsd.org>
Sun, 18 Aug 2024 08:18:49 +0000 (08:18 +0000)
committermpi <mpi@openbsd.org>
Sun, 18 Aug 2024 08:18:49 +0000 (08:18 +0000)
Such pages belong to the DMA or ISA memory ranges and caching them
accelerate their exhaustion.  On amd64, at least, the kernel relies
on having low pages available at any time and cannot recover from
their exhaustion.

Should prevent livelocks reported by jsg@ and tb@ on amd64.

ok deraadt@

sys/uvm/uvm_pmemrange.c

index 04abd46..0830fd4 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: uvm_pmemrange.c,v 1.66 2024/05/01 12:54:27 mpi Exp $  */
+/*     $OpenBSD: uvm_pmemrange.c,v 1.67 2024/08/18 08:18:49 mpi Exp $  */
 
 /*
  * Copyright (c) 2024 Martin Pieuchot <mpi@openbsd.org>
@@ -2303,8 +2303,19 @@ uvm_pmr_cache_put(struct vm_page *pg)
 {
        struct uvm_pmr_cache *upc = &curcpu()->ci_uvm;
        struct uvm_pmr_cache_item *upci;
+       struct uvm_pmemrange *pmr;
        int s;
 
+       /*
+        * Always give back low pages to the allocator to not accelerate
+        * their exhaustion.
+        */
+       pmr = uvm_pmemrange_find(atop(VM_PAGE_TO_PHYS(pg)));
+       if (pmr->use > 0) {
+               uvm_pmr_freepages(pg, 1);
+               return;
+       }
+
        s = splvm();
        upci = &upc->upc_magz[upc->upc_actv];
        if (upci->upci_npages >= UVM_PMR_CACHEMAGSZ) {