On Thu, 27 Mar 2025 09:58:48 -0700
Eric Grosse <[email protected]> wrote:

> With your patch, system has been running fine with various loads
> applied. I'll update in a couple weeks to confirm this resolved the
> issue. Thanks! (And I recognize that this is only a temporary patch.)

To get back my 500M of ram, I removed my old patch and made this new
patch, which uses an atomic compare-and-swap to check if another cpu
allocated the same thing.  My goal is the same, to protect the
kernel_pmap without a vp lock.  This patch only affects allocations
of structs pmapvp1 and pmapvp2, not pte_desc.

With this patch, I am trying to fix a problem that never seems to
happen to me.  I am less than sure of this fix.

--gkoehler

Index: arch/powerpc64/powerpc64/pmap.c
===================================================================
RCS file: /cvs/src/sys/arch/powerpc64/powerpc64/pmap.c,v
diff -u -p -r1.64 pmap.c
--- arch/powerpc64/powerpc64/pmap.c     28 Nov 2024 18:54:36 -0000      1.64
+++ arch/powerpc64/powerpc64/pmap.c     8 Apr 2025 01:04:58 -0000
@@ -598,6 +598,10 @@ pmap_vp_enter(pmap_t pm, vaddr_t va, str
        struct slb_desc *slbd;
        struct pmapvp1 *vp1;
        struct pmapvp2 *vp2;
+#ifdef MULTIPROCESSOR
+       struct pmapvp1 *old_vp1;
+       struct pmapvp2 *old_vp2;
+#endif
 
        slbd = pmap_slbd_lookup(pm, va);
        if (slbd == NULL) {
@@ -617,7 +621,15 @@ pmap_vp_enter(pmap_t pm, vaddr_t va, str
                                panic("%s: unable to allocate L1", __func__);
                        return ENOMEM;
                }
+#ifdef MULTIPROCESSOR
+               old_vp1 = atomic_cas_ptr(&slbd->slbd_vp, NULL, vp1);
+               if (old_vp1 != NULL) {
+                       pool_put(&pmap_vp_pool, vp1);
+                       vp1 = old_vp1;
+               }
+#else
                slbd->slbd_vp = vp1;
+#endif
        }
 
        vp2 = vp1->vp[VP_IDX1(va)];
@@ -628,7 +640,15 @@ pmap_vp_enter(pmap_t pm, vaddr_t va, str
                                panic("%s: unable to allocate L2", __func__);
                        return ENOMEM;
                }
+#ifdef MULTIPROCESSOR
+               old_vp2 = atomic_cas_ptr(&vp1->vp[VP_IDX1(va)], NULL, vp2);
+               if (old_vp2 != NULL) {
+                       pool_put(&pmap_vp_pool, vp2);
+                       vp2 = old_vp2;
+               }
+#else
                vp1->vp[VP_IDX1(va)] = vp2;
+#endif
        }
 
        vp2->vp[VP_IDX2(va)] = pted;

Reply via email to