On 06/07/25(Sun) 21:15, Jeremie Courreges-Anglas wrote:
> On Tue, Jul 01, 2025 at 06:18:37PM +0200, Jeremie Courreges-Anglas wrote:
> > On Tue, Jun 24, 2025 at 05:21:56PM +0200, Jeremie Courreges-Anglas wrote:
> > >
> > > I think it's uvm_purge(), as far as I can see it happens when building
> > > rust with cvs up -D2025/06/04 in /sys, not with -D2025/06/03. Maybe I
> > > missed lang/rust when testing the diff.
> > >
> > > This is with additional MP_LOCKDEBUG support for mutexes, and
> > > __mp_lock_spinout = 50L * INT_MAX.
> > >
> > > Suggested by claudio: tr /t 0t269515 fails.
> >
> > Should be fixed, at least for CPUs that ddb actually managed to
> > stop...
> >
> > > WITNESS doesn't flag an obvious lock ordering issue. I'm not even
> > > sure there is one. It also happen with CPU_MAX_BUSY_CYCLES == 64.
> > >
> > > Maybe we're still hammering too much the locks? Input and ideas to
> > > test welcome. Right now I'm running with just uvm_purge() reverted.
> >
> > Reverting uvm_purge() did not help. I've been able to reproduce the
> > hangs up to cvs up -D2025/05/18, backporting the arm64 ddb trace fix,
> > mpi's mutex backoff diff and the mtx_enter MP_LOCKDEBUG diff.
> > Currently trying to reproduce with cvs up -D2025/05/07 as suggested by
> > dlg.
>
> cvs up -D2025/05/07 also did not help. -current still locks up, but
> the db_mutex fix helps get proper stacktraces:
Thanks for the report.
> --8<--
> login: mtf_fnxe0:00nf2ffmrte8 0m21xt2 8xlef_ cf2nktft esl8r_u0f k00t
> sxor2f0
>
> 0tf
> 8oeff
>
> ftff
> efStopped at mtx_enter+0x13c: ldr x26, [x25,#2376]
What is your value of __mp_lock_spinout?
>From the ddb traces I understand that the `sched_lock' mutex is contended.
It's not clear to me why but I believe that's because rustc use
sched_yield(2) in a loop. Could you figure out where this syscall is
coming from?
I'm upset that sched_yield() is still used and causing trouble. Now
that `sched_lock' is a mutex without guarantee of progress it is easy
to hang the machine by calling it in a loop. A proper solution would be
to stop using sched_yield(2). This will bite us as long as it is here.
A workaround would be to use a backoff mechanism inside the loop.
Another workaround could be to never spin on the `sched_lock' in
sys_sched_yield() and instead sleep.
Because of such contention all wakeup(9)s inside the pmemrange allocator
add contention on the `fpageqlock' which is what is "hanging" your machine.
Diff below is another workaround that might help.
Index: uvm/uvm_pmemrange.c
===================================================================
RCS file: /cvs/src/sys/uvm/uvm_pmemrange.c,v
diff -u -p -r1.77 uvm_pmemrange.c
--- uvm/uvm_pmemrange.c 19 Feb 2025 11:10:54 -0000 1.77
+++ uvm/uvm_pmemrange.c 7 Jul 2025 05:53:41 -0000
@@ -1321,7 +1321,6 @@ uvm_pmr_freepages(struct vm_page *pg, ps
}
uvm_lock_fpageq();
-
for (i = count; i > 0; i -= pmr_count) {
pmr = uvm_pmemrange_find(atop(VM_PAGE_TO_PHYS(pg)));
KASSERT(pmr != NULL);
@@ -1333,13 +1332,13 @@ uvm_pmr_freepages(struct vm_page *pg, ps
uvmexp.free += pmr_count;
pg += pmr_count;
}
+ uvm_wakeup_pla(VM_PAGE_TO_PHYS(firstpg), ptoa(count));
+ uvm_unlock_fpageq();
+
wakeup(&uvmexp.free);
if (uvmexp.zeropages < UVM_PAGEZERO_TARGET)
wakeup(&uvmexp.zeropages);
- uvm_wakeup_pla(VM_PAGE_TO_PHYS(firstpg), ptoa(count));
-
- uvm_unlock_fpageq();
}
/*
@@ -1385,12 +1384,11 @@ uvm_pmr_freepageq(struct pglist *pgl)
uvm_wakeup_pla(pstart, ptoa(plen));
}
+ uvm_unlock_fpageq();
+
wakeup(&uvmexp.free);
if (uvmexp.zeropages < UVM_PAGEZERO_TARGET)
wakeup(&uvmexp.zeropages);
- uvm_unlock_fpageq();
-
- return;
}
/*