On Tue, Jul 01, 2025 at 04:57:14AM -0300, K R wrote:
> On Mon, Jun 30, 2025 at 2:39 AM K R <daharmaster...@gmail.com> wrote:
> >
> > On Fri, Jun 27, 2025 at 3:34 AM Martin Pieuchot <m...@grenadille.net> wrote:
> > >
> > > On 26/06/25(Thu) 11:02, K R wrote:
> > > > On Wed, Jun 25, 2025 at 1:30 PM K R <daharmaster...@gmail.com> wrote:
> > > > >
> > > > > [...]
> > > > > > Hi Alexander,
> > > > > >
> > > > > > The good news: I can consistently reproduce the hang problem.  But 
> > > > > > the
> > > > > > bad news is that even with a WITNESS kernel and kern.witness.watch=2
> > > > > > (or even 3) I don't see any message or kernel panic.
> > >
> > > Do you mind sharing your recipe to reproduce the hang?
> 
> Another one.  This time I've included output from 'show witness /b', below:
> 
> pmap_tlb_shootwait: spun outStopped at  db_enter+0x14:  popq    %rbp

I think the number one question here is why did pmap_tlb_shootwait spin
out?
This is waiting for other CPUs to finish their work.
So first of all what value has tlb_shoot_wait (x /qx tlb_shoot_wait)
The probably also the values of tlb_shoot_first_pcid, tlb_shoot_addr1 and
tlb_shoot_addr2 are of interest. (use x /qx for the addrs and x /x for
first_pcid).

The question to answer is why does tlb_shoot_wait not reach 0.
The above information may shed some light (maybe).

> ddb{3}> show locks
> exclusive rwlock amaplk r = 0 (0xfffffd9619a06de0)
> shared rwlock vmmaplk r = 0 (0xfffffd9ca1d22e38)

Please also include 'show all locks'.

> ddb{3}> show witness /b
> Number of known direct relationships is 400
> 
> Lock order reversal between "&mp->mnt_lock"(rwlock) and 
> "&ip->i_lock"(rrwlock)!
> 
> witness: incomplete path, depth 4
> ddb{3}> trace
> db_enter() at db_enter+0x14
> pmap_enter(fffffda07ffdfc00,9f5a20cd000,160950d000,3,22) at pmap_enter+0x725
> uvm_fault_lower(ffff800055e422b8,ffff800055e422f0,ffff800055e42230) at 
> uvm_faul
> t_lower+0x27f
> uvm_fault(fffffd9ca1d22d38,9f5a20cd000,0,2) at uvm_fault+0x1c5
> upageflttrap(ffff800055e42420,9f5a20cd000) at upageflttrap+0x6c
> usertrap(ffff800055e42420) at usertrap+0x1f5
> recall_trap() at recall_trap+0x8
> end of kernel
> end trace frame: 0x9f54e22cfd0, count: -7

Looking at pmap_enter() I see this:

        if (! pmap_valid_entry(opte)) {
                PTE_BASE[pl1_i(va)] = npte;
        } else if ((opte | (npte ^ PG_RW)) & PG_RW) {
                /* previously writable or not making writable */
                PTE_BASE[pl1_i(va)] = npte;
                if (nocache && (opte & PG_N) == 0)
                        wbinvd_on_all_cpus();
                pmap_tlb_shootpage(pmap, va, shootself);
        } else {
                PTE_BASE[pl1_i(va)] = npte ^ PG_RW;
                if (nocache && (opte & PG_N) == 0) /* XXX impossible? */
                        wbinvd_on_all_cpus();
                pmap_tlb_shootpage(pmap, va, shootself);
                pmap_tlb_shootwait();
                PTE_BASE[pl1_i(va)] = npte;
        }

        pmap_unmap_ptes(pmap, scr3);
        pmap_tlb_shootwait();

        error = 0;

The else case of the above if block does pmap_tlb_shootwait() but then
after that a 2nd pmap_tlb_shootwait() is issued. Not sure if this is safe
in all cases. Especially the first pmap_tlb_shootwait() is done with the
pm_mtx locked.

-- 
:wq Claudio

Reply via email to