On Tue, May 21, 2024 at 02:51:39AM +0200, Jeremie Courreges-Anglas wrote:
> On Sat, May 18, 2024 at 01:11:56PM -0700, Eric Grosse wrote:
> > The openbsd-ppc64-n2vi Go builder machine is converting over to LUCI
> > build infrastructure and the new workload may have stepped on a
> > pagedaemon corner case. While running 7.5-stable I reproducibly get
> > kernel panics "pmap_enter: failed to allocate pted". I saw recent
> > powerpc64/pmap.c changes from gkoehler@ and kettenis@, so updated the
> > machine to 7.5-snapshot and now see "trap type 300" from pmap_remove.
> 
> Is that also reproducible?  cc'ing bugs@.
> 
> > In an effort to reproduce this with a more familiar workload, I tried
> > "/usr/src$ make -j32 build" to pound on the hardware with a similar
> > load average and temperature, but that runs without crashing. I'd
> > welcome suggestions on anything I can do to reduce this to a useful
> > bug report.
> > 
> > https://n2vi.com/t.dmesg   latest dmesg
> > https://n2vi.com/t.crash1   ddb serial console from the 7.5-stable panics
> 
> This doesn't look powerpc64-specific.  It feels like
> uvm_km_kmemalloc_pla() should call pmap_enter() with PMAP_CANFAIL and
> unwind in case of a resource shortage.

The diff below behaves when I inject fake pmap_enter() failures on
amd64.  It would be nice to test it on -stable and/or -current,
depending on whether it happens on -stable only or also on -current.


diff --git a/sys/uvm/uvm_km.c b/sys/uvm/uvm_km.c
index a715173529a..3779ea3d7ee 100644
--- a/sys/uvm/uvm_km.c
+++ b/sys/uvm/uvm_km.c
@@ -335,7 +335,7 @@ uvm_km_kmemalloc_pla(struct vm_map *map, struct uvm_object 
*obj, vsize_t size,
        vaddr_t kva, loopva;
        voff_t offset;
        struct vm_page *pg;
-       struct pglist pgl;
+       struct pglist pgl, pgldone;
        int pla_flags;
 
        KASSERT(vm_map_pmap(map) == pmap_kernel());
@@ -372,6 +372,7 @@ uvm_km_kmemalloc_pla(struct vm_map *map, struct uvm_object 
*obj, vsize_t size,
         * whom should ever get a handle on this area of VM.
         */
        TAILQ_INIT(&pgl);
+       TAILQ_INIT(&pgldone);
        pla_flags = 0;
        KASSERT(uvmexp.swpgonly <= uvmexp.swpages);
        if ((flags & UVM_KMF_NOWAIT) ||
@@ -396,6 +397,7 @@ uvm_km_kmemalloc_pla(struct vm_map *map, struct uvm_object 
*obj, vsize_t size,
        while (loopva != kva + size) {
                pg = TAILQ_FIRST(&pgl);
                TAILQ_REMOVE(&pgl, pg, pageq);
+               TAILQ_INSERT_TAIL(&pgldone, pg, pageq);
                uvm_pagealloc_pg(pg, obj, offset, NULL);
                atomic_clearbits_int(&pg->pg_flags, PG_BUSY);
                UVM_PAGE_OWN(pg, NULL);
@@ -408,9 +410,28 @@ uvm_km_kmemalloc_pla(struct vm_map *map, struct uvm_object 
*obj, vsize_t size,
                        pmap_kenter_pa(loopva, VM_PAGE_TO_PHYS(pg),
                            PROT_READ | PROT_WRITE);
                } else {
-                       pmap_enter(map->pmap, loopva, VM_PAGE_TO_PHYS(pg),
+                       if (pmap_enter(map->pmap, loopva, VM_PAGE_TO_PHYS(pg),
                            PROT_READ | PROT_WRITE,
-                           PROT_READ | PROT_WRITE | PMAP_WIRED);
+                           PROT_READ | PROT_WRITE | PMAP_WIRED |
+                           PMAP_CANFAIL) != 0) {
+                               pmap_remove(map->pmap, kva, loopva);
+
+                               while ((pg = TAILQ_LAST(&pgldone, pglist))) {
+                                       TAILQ_REMOVE(&pgldone, pg, pageq);
+                                       TAILQ_INSERT_HEAD(&pgl, pg, pageq);
+                                       uvm_lock_pageq();
+                                       uvm_pageclean(pg);
+                                       uvm_unlock_pageq();
+                               }
+
+                               if (obj != NULL)
+                                       rw_exit(obj->vmobjlock);
+
+                               uvm_unmap(map, kva, kva + size);
+                               uvm_pglistfree(&pgl);
+
+                               return 0;
+                       }
                }
                loopva += PAGE_SIZE;
                offset += PAGE_SIZE;


-- 
jca

Reply via email to