Subject: Re: "pmap_unwire: wiring ... didn't change!"
To: None <firstname.lastname@example.org>
From: Izumi Tsutsui <email@example.com>
Date: 08/27/2005 14:08:51
In article <20050430223332.GA23230@spathi.chuq.com>
> I checked in the #2 approach from below earlier today.
> I'll request pullups to release branches in a few days
> if no one reports any problems.
> On Sat, Feb 12, 2005 at 04:32:47PM -0800, Chuck Silvers wrote:
> > hi,
> > I looked into the "pmap_unwire: wiring ... didn't change!" problem.
> > what's happening is that sometimes we're going through uvm_fault() again
> > for one of the wired pages, and the pmap_enter() which results from that
> > replaces the wired pmap entry with non-wired one. so why would we go through
> > uvm_fault() again? that's happening because sometimes the TLB entry is
> > recycled after the page mapped by one side of the entry is wired and before
> > the other page is wired. and when MachTLBUpdate() is called for the second
> > page, the entry it creates only has the second side filled in. this causes
> > us to get a "TLB invalid" trap when we access the other half of the TLB entry
> > instead of the "TLB miss" trap that we would get if there were no TLB entry
> > at all. the handler for "TLB invalid" traps from usermode always calls
> > trap() instead of looking at the PTEs.
> > so the problem is that the PTEs and the TLB get out of sync, and the trap
> > handlers aren't expecting that. I see several possible fixes, in
> > approximate decreasing order of preference:
> > - change MachTLBUpdate() to take both PTEs for the TLB entry for MIPS3.
> > - change the MIPS3 MachTLBUpdate() to only update existing TLB entries,
> > not create new ones.
> > - have the MIPS3 user "TLB invalid" trap handler try to reload from the
> > PTEs before calling trap().
> > - use MIPS3_TBIS() instead of MachTLBUpdate() for user mappings on MIPS3.
> > the last one was the easiest, so I implemented that one and it appears to
> > make the problem go away. the patch is attached. does anyone want to
> > implement one of the better solutions soon? if not, I'll just check in
> > what I've got (after updating it to be friendly to MIPS1, etc).
Today I'm working to update Uchiyama-san's NetBSD/ews4800mips port
but it seems this mipsX_subr.S rev 1.16 change causes kernel panic
right after cpu_configure(9) is finished:
NetBSD 3.99.8 (CEDIA) #69: Sat Aug 27 13:53:22 JST 2005
NEC EWS4800/360AD (TR2A) 150MHz
total memory = 32768 KB
avail memory = 29208 KB
cpu0 at mainbus0: MIPS R4400 CPU (0x450) Rev. 5.0 with MIPS R4010 FPC Rev. 0.0
cpu0: 16KB/32B direct-mapped L1 Instruction cache, 48 TLB entries
cpu0: 16KB/16B direct-mapped write-back L1 Data cache
cpu0: 1024KB/128B direct-mapped write-back L2 Unified cache
sbd0 at mainbus0
fb0 at sbd0 at 0xf0000000, 0xf5f00000
wsdisplay0 at fb0 kbdmux 1: console (std, vt100 emulation), using wskbd0
wsmux1: connecting to wsdisplay0
trap: TLB miss (load or instr. fetch) in kernel mode
status=0x2004ff02, cause=0x8008, epc=0x8019b55c, vaddr=0x0
pid=0 cmd=swapper usp=0x0 ksp=0x802f6bc0
Stopped in pid0.1 (swapper) at netbsd:uvm_pageidlezero+0x280: beq s0,v0,<uvm_pageidlezero+33c> [addr:0x8019b618]
bdslot: sw s1,0(a1)
("scsibus0: waiting 2 seconds for devices to settle..." should
appear after wsmux1 line)
The actual function where panic happens is inline uvm_pageinsert_after().
Furthermore, pmap_kenter_pa(9) (which is used to map framebuffer VRAM)
shows some strange behavior. The VRAM (at paddr 0xf0000000) is mapped
by pmap_kenter_pa(9) to VA allocated by uvm_km_alloc() with
UVM_KMF_VAONLY flag, and on my 4800/360AD the VA is 0xc3029000.
But when the fb driver tries to write data to top of VRAM via
the VA 0xc3029000, the data is written VRAM at PA 0xf0029000.
Reverting mipsX_subr.S 1.16 solves both problems.
(There is another PR (kern/30590) on hpcmips about this change)
A new TLB entry need be created in MIPS3 MachTLBUpdate() on some case?
Note arc (Express5800/230, R4400, 256MB), sgimips (O2, R5000, 192MB)
and cobalt (RaQ2, Rm5200, 256MB) have no problem with rev 1.16.