pmap problem in FreeBSD current

View: New views
16 Messages — Rating Filter:   Alert me  

pmap problem in FreeBSD current

by Michal Hajduk :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hello Mark,

While testing EHCI (FreeBSD 8-current with new USB-stack) on
ARM machine I have found some problem probably related to
svn commit *194459*
http://svn.freebsd.org/viewvc/base?view=revision&revision=194459
With compiled USB-stack I had vm_fault:

ehci0: <Marvell Integrated USB 2.0 controller> at mem
0xf1050000-0xf1050fff irq 48,19 on mbus0
lock order reversal: (sleepable after non-sleepable)
1st 0xc0f55a88 256 (UMA zone) @
/home/mih/git/marvell-current/sys/vm/uma_core.c:2036
2nd 0xc0bf2fbc user map (user map) @
/home/mih/git/marvell-current/sys/vm/vm_map.c:3520
KDB: stack backtrace:
db_trace_thread() at db_trace_thread+0x10
scp=0xc0b28458 rlv=0xc0916b78 ($a+0x34)
rsp=0xc0e46764 rfp=0xc0e46880
r10=0xc36236c0 r9=0x00000dc0
r8=0xc0d3504c r7=0xc3623930 r6=0xffffffff r5=0xc0b52180
r4=0xc0e4676c
$a() at $a+0x10
scp=0xc0916b54 rlv=0xc09f6ae0 (kdb_backtrace+0x3c)
rsp=0xc0e46884 rfp=0xc0e46894
r4=0xc0c05d60
kdb_backtrace() at kdb_backtrace+0x10
scp=0xc09f6ab4 rlv=0xc0a05e80 (_witness_debugger+0x5c)
rsp=0xc0e46898 rfp=0xc0e468ac
r4=0x00000001
_witness_debugger() at _witness_debugger+0x14
scp=0xc0a05e38 rlv=0xc0a069a8 (witness_checkorder+0x5f4)
rsp=0xc0e468b0 rfp=0xc0e468f8
r5=0xc0bf2fbc r4=0x00000000
witness_checkorder() at witness_checkorder+0x10
scp=0xc0a063c4 rlv=0xc09d5cdc (_sx_slock+0x30)
rsp=0xc0e468fc rfp=0xc0e46920
r10=0xc0e46b40 r9=0xc0e46a40
r8=0x00000000 r7=0x00000000 r6=0x00000dc0 r5=0xc0b89084
r4=0xc0bf2fbc
_sx_slock() at _sx_slock+0x10
scp=0xc09d5cbc rlv=0xc0b1171c (vm_map_lookup+0x3c)
rsp=0xc0e46924 rfp=0xc0e46964
r8=0x00000001 r7=0x00000001
r6=0xc0bf2f74 r5=0x00000000 r4=0xc0e46a68
vm_map_lookup() at vm_map_lookup+0x10
scp=0xc0b116f0 rlv=0xc0b0b61c (vm_fault+0x90)
rsp=0xc0e46968 rfp=0xc0e46a98
r10=0xc0e46b40 r9=0xc0e46ef8
r8=0x00000001 r7=0xc0bf2d40 r6=0x00000000 r5=0x00000000
r4=0xc0e46a68
vm_fault() at vm_fault+0x10
scp=0xc0b0b59c rlv=0xc0b37cf0 (data_abort_handler+0x1ec)
rsp=0xc0e46a9c rfp=0xc0e46b3c
r10=0xc0e46b40 r9=0xc0e46ef8
r8=0x00000001 r7=0xc0bf2d40 r6=0x00000000 r5=0x00000000
r4=0xc0bf2b00
data_abort_handler() at data_abort_handler+0x10
scp=0xc0b37b14 rlv=0xc0b29ee0 (exception_exit)
rsp=0xc0e46b40 rfp=0xc0e46bac
r10=0xc0f4a1a4 r9=0x0000001f
r8=0xc0f54c80 r7=0x00000000 r6=0xc0f54c80 r5=0xffff1004
r4=0xc0f55a80
$a() at $a+0x10
scp=0xc0b08b6c rlv=0xc0b08ef4 ($a+0x3c)
rsp=0xc0e46bb0 rfp=0xc0e46bc8
r7=0x0000000f r6=0xc0f54c80
r5=0x00000003 r4=0xc0f55a80
$a() at $a+0x10
scp=0xc0b08ec8 rlv=0xc0b0a13c (uma_zalloc_arg+0x32c)
rsp=0xc0e46bcc rfp=0xc0e46c10
r6=0xc3b5efa8 r5=0x0000000f
r4=0x0000000f
uma_zalloc_arg() at uma_zalloc_arg+0x10
scp=0xc0b09e20 rlv=0xc09bfefc (malloc+0x5c)
rsp=0xc0e46c14 rfp=0xc0e46c34
r10=0xc0e46c80 r9=0xc0bebeac
r8=0xc0bda080 r7=0x00000002 r6=0x00000100 r5=0xc0f54c80
r4=0x00000004
malloc() at malloc+0x14
scp=0xc09bfeb4 rlv=0xc0b26674 (bus_dmamem_alloc+0x258)
rsp=0xc0e46c38 rfp=0xc0e46c70
r8=0x00000004 r7=0x00000002
r6=0xc3621800 r5=0xc0d6a234 r4=0x00000080
bus_dmamem_alloc() at bus_dmamem_alloc+0x10
scp=0xc0b2642c rlv=0xc0966fc4 (usb_pc_alloc_mem+0xa4)
rsp=0xc0e46c74 rfp=0xc0e46cb0
r10=0xc3b4de28 r9=0xc0b64844
r8=0xc3b4d808 r7=0xc3b4ddfc r6=0x00000100 r5=0xc3b4bf20
r4=0x00000080
usb_pc_alloc_mem() at usb_pc_alloc_mem+0x10
scp=0xc0966f30 rlv=0xc0962748 ($a+0x2c)
rsp=0xc0e46cb4 rfp=0xc0e46cc4
r10=0x00000000 r9=0xc0b64844
r8=0xc095ac30 r7=0xc096271c r6=0xc3b4dc50 r5=0xc3b4a000
r4=0xc3b4dc50
$a() at $a+0x10
scp=0xc096272c rlv=0xc095ad00 (ehci_iterate_hw_softc+0xd0)
rsp=0xc0e46cc8 rfp=0xc0e46ce8
r4=0x00000078
ehci_iterate_hw_softc() at ehci_iterate_hw_softc+0x10
scp=0xc095ac40 rlv=0xc09626bc (usb_bus_mem_alloc_all+0xb8)
rsp=0xc0e46cec rfp=0xc0e46d18
r7=0xc3b4dc50 r6=0x00000000
r5=0xc3b4ddac r4=0x00000008
usb_bus_mem_alloc_all() at usb_bus_mem_alloc_all+0x10
scp=0xc0962614 rlv=0xc0b49494 ($a+0x60)
rsp=0xc0e46d1c rfp=0xc0e46d5c
r8=0xc3b4dc50 r7=0xc09f08fc
r6=0xc3620000 r5=0xc3b4a000 r4=0xc3620480
$a() at $a+0x10
scp=0xc0b49444 rlv=0xc09f1fc8 (device_attach+0x70)
rsp=0xc0e46d60 rfp=0xc0e46da0
r10=0x00000000 r9=0xc0b64844
r8=0xc3620000 r7=0xc09f08fc r6=0xc362004c r5=0xc36bd344
r4=0xc3620480
device_attach() at device_attach+0x10
scp=0xc09f1f68 rlv=0xc09f3060 (bus_generic_attach+0x20)
rsp=0xc0e46da4 rfp=0xc0e46db4
r10=0x00000000 r9=0xc0b64844
r8=0xc3620480 r7=0xc0bed508 r6=0xc0bed510 r5=0x00000001
r4=0xc3620000
bus_generic_attach() at bus_generic_attach+0x10
scp=0xc09f3050 rlv=0xc0b40864 ($a+0x1fc)
rsp=0xc0e46db8 rfp=0xc0e46de0
r4=0x00000020
$a() at $a+0x10
scp=0xc0b40678 rlv=0xc09f1fc8 (device_attach+0x70)
rsp=0xc0e46de4 rfp=0xc0e46e24
r8=0xc3620480 r7=0xc09f08fc
r6=0xc36204cc r5=0xc361b204 r4=0xc3620600
device_attach() at device_attach+0x10
scp=0xc09f1f68 rlv=0xc09f3060 (bus_generic_attach+0x20)
rsp=0xc0e46e28 rfp=0xc0e46e38
r10=0x00000000 r9=0xc0b64844
r8=0xc3620600 r7=0xc09f08fc r6=0xc362064c r5=0xc361b465
r4=0xc3620480
bus_generic_attach() at bus_generic_attach+0x10
scp=0xc09f3050 rlv=0xc0b2cdcc ($a+0x1c)
rsp=0xc0e46e3c rfp=0xc0e46e4c
r4=0xc3620600
$a() at $a+0x10
scp=0xc0b2cdc0 rlv=0xc09f1fc8 (device_attach+0x70)
rsp=0xc0e46e50 rfp=0xc0e46e90
r4=0x80000000
device_attach() at device_attach+0x10
scp=0xc09f1f68 rlv=0xc09f32a0 (bus_generic_new_pass+0x110)
rsp=0xc0e46e94 rfp=0xc0e46eb4
r10=0x00000000 r9=0x0100029c
r8=0xc0c05b68 r7=0xc3620a00 r6=0xc0bec458 r5=0xc0bd38d0
r4=0xc3620600
bus_generic_new_pass() at bus_generic_new_pass+0x10
scp=0xc09f31a0 rlv=0xc09efb28 (bus_set_pass+0x98)
rsp=0xc0e46eb8 rfp=0xc0e46ed4
r8=0x0103cc50 r7=0xc0c05b68
r6=0x7fffffff r5=0xc3620a00 r4=0xc361c820
bus_set_pass() at bus_set_pass+0x10
scp=0xc09efaa0 rlv=0xc0997a1c (mi_startup+0x8c)
rsp=0xc0e46ed8 rfp=0xc0e46ef4
r7=0xc0bf345c r6=0xc0bf3460
r5=0xc0bf3464 r4=0xc0b8f2f4
mi_startup() at mi_startup+0x10
scp=0xc09979a0 rlv=0xc09001e4 (virt_done+0x14)
rsp=0xc0e46ef8 rfp=0x00000000
r7=0x00900140 r6=0x0103e020
r5=0x0090014c r4=0x00900224

vm_fault(0xc0bf2f74, 0, 1, 0) -> 1
Fatal kernel mode data abort: 'Translation Fault (S)'
trapframe: 0xc0e46b40
FSR=00000005, FAR=00000004, spsr=600000d3
r0 =c0f55a80, r1 =c0f54c80, r2 =00000003, r3 =fffffffb
r4 =c0f55a80, r5 =00000003, r6 =c0f54c80, r7 =00000000
r8 =c0f54c80, r9 =0000001f, r10=c0f4a1a4, r11=c0e46bac
r12=c0e46bb0, ssp=c0e46b8c, slr=c0b08ef4, pc =c0b08c74

[thread pid 0 tid 100000 ]
Stopped at $a+0x118: ldr r2, [r7, #0x004]
db>

Without new-usb stack with booting from NFS I have a LOR on
the line which was added in svn commit *194459*
<http://svn.freebsd.org/viewvc/base?view=revision&revision=194459> :
mge0: link state changed to UP
NFS ROOT: 10.0.0.201:/nfsroot/rd6281/
lock order reversal:
1st 0xc36050b0 pmap (pmap) @
/home/mih/git/marvell-current/sys/arm/arm/pmap.c:971
2nd 0xc0d26038 vm object (uma object) @
/home/mih/git/marvell-current/sys/vm/uma_core.c:1011
KDB: stack backtrace:
db_trace_thread() at db_trace_thread+0x10
scp=0xc0af6ce8 rlv=0xc0907798 ($a+0x34)
rsp=0xcf404880 rfp=0xcf40499c
r10=0xc35c84b8 r9=0x000003f3
r8=0xc0cea35c r7=0xc35c8a00 r6=0xffffffff r5=0xc0b1e610
r4=0xcf404888
$a() at $a+0x10
scp=0xc0907774 rlv=0xc09c5370 (kdb_backtrace+0x3c)
rsp=0xcf4049a0 rfp=0xcf4049b0
r4=0xc0bbb1d0
kdb_backtrace() at kdb_backtrace+0x10
scp=0xc09c5344 rlv=0xc09d4710 (_witness_debugger+0x5c)
rsp=0xcf4049b4 rfp=0xcf4049c8
r4=0x00000001
_witness_debugger() at _witness_debugger+0x14
scp=0xc09d46c8 rlv=0xc09d5238 (witness_checkorder+0x5f4)
rsp=0xcf4049cc rfp=0xcf404a14
r5=0xc0d26038 r4=0x00000000
witness_checkorder() at witness_checkorder+0x10
scp=0xc09d4c54 rlv=0xc09912b4 (_mtx_lock_flags+0x34)
rsp=0xcf404a18 rfp=0xcf404a40
r10=0xc0d26b80 r9=0xc0ef86e0
r8=0x000003f3 r7=0xc0b46f74 r6=0x00000000 r5=0x00000000
r4=0xc0d26038
_mtx_lock_flags() at _mtx_lock_flags+0x10
scp=0xc0991290 rlv=0xc0ad56b0 ($a+0x3c)
rsp=0xcf404a44 rfp=0xcf404a80
r10=0x00001000 r8=0x00000101
r7=0x00000000 r6=0xc0ef86e0 r5=0xc0ef9600 r4=0xc0ef9600
$a() at $a+0x10
scp=0xc0ad5684 rlv=0xc0ad6f44 ($a+0x70)
rsp=0xcf404a84 rfp=0xcf404ac0
r10=0xc0ad5674 r9=0xc0ef86e0
r8=0x00000101 r7=0x00000000 r6=0xc0ef86e0 r5=0x00000001
r4=0xc0ef9600
$a() at $a+0x10
scp=0xc0ad6ee4 rlv=0xc0ad74c0 ($a+0xd4)
rsp=0xcf404ac4 rfp=0xcf404ae4
r10=0xc0ee4c48 r9=0x00000080
r8=0xc0ef86e0 r7=0x00000000 r6=0xc0ef86e0 r5=0x00000201
r4=0xc0ef9600
$a() at $a+0x10
scp=0xc0ad73fc rlv=0xc0ad7784 ($a+0x3c)
rsp=0xcf404ae8 rfp=0xcf404b00
r7=0x0000006f r6=0xc0ef86e0
r5=0x00000001 r4=0xc0ef9600
$a() at $a+0x10
scp=0xc0ad7758 rlv=0xc0ad89cc (uma_zalloc_arg+0x32c)
rsp=0xcf404b04 rfp=0xcf404b48
r6=0xc1888de8 r5=0x0000006f
r4=0x0000006f
uma_zalloc_arg() at uma_zalloc_arg+0x10
scp=0xc0ad86b0 rlv=0xc0b00ca4 ($a+0x870)
rsp=0xcf404b4c rfp=0xcf404bd0
r10=0x01f9a55e r9=0x0000003c
r8=0xc36050b0 r7=0x00000000 r6=0x00000000 r5=0x01f9a552
r4=0xc3cbe0b8
$a() at $a+0x10
scp=0xc0b00444 rlv=0xc0b0169c (pmap_enter+0x70)
rsp=0xcf404bd4 rfp=0xcf404c04
r10=0x00000007 r9=0xc0d1b948
r8=0xc0f951b8 r7=0x7ffff000 r6=0x00000000 r5=0xc36050b0
r4=0xc0b4a4bc
pmap_enter() at pmap_enter+0x10
scp=0xc0b0163c rlv=0xc0adaff0 ($a+0x17c)
rsp=0xcf404c08 rfp=0xcf404d38
r10=0xcf404de0 r9=0xcf404ef8
r8=0x00000002 r7=0x00000000 r6=0x00000000 r5=0x00000001
r4=0x00000000
vm_fault() at vm_fault+0x10
scp=0xc0ad9e2c rlv=0xc0b065f0 (data_abort_handler+0x1ec)
rsp=0xcf404d3c rfp=0xcf404ddc
r10=0xcf404de0 r9=0xcf404ef8
r8=0x00000002 r7=0xc3603000 r6=0x00000000 r5=0x7ffff000
r4=0xc3601088
data_abort_handler() at data_abort_handler+0x10
scp=0xc0b06414 rlv=0xc0af8770 (exception_exit)
rsp=0xcf404de0 rfp=0xcf404e80
r10=0xc0965f04 r9=0xc3601000
r8=0xc0b892c8 r7=0xc0b892d2 r6=0xcf404eac r5=0xffff1004
r4=0x7fffffff
$a() at $a+0x10
scp=0xc0965f14 rlv=0xc097c78c (fork_exit+0x64)
rsp=0xcf404e84 rfp=0xcf404ea8
r10=0xc0965f04 r9=0x00000000
r8=0x00000000 r7=0xc3601000 r6=0xcf404eac r5=0xc0d26b80
r4=0xc3603000
fork_exit() at fork_exit+0x10
scp=0xc097c738 rlv=0xc0b05c5c (fork_trampoline+0x14)
rsp=0xcf404eac rfp=0x00000000
r10=0x00000000 r8=0x00000000
r7=0xc0b29cb8 r6=0xcf45feac r5=0x00000000 r4=0xc0965f04
lock order reversal:
1st 0xc36050b0 pmap (pmap) @
/home/mih/git/marvell-current/sys/arm/arm/pmap.c:971
2nd 0xc0d1b948 vm page queue mutex (vm page queue mutex) @
/home/mih/git/marvell-current/sys/arm/arm/pmap.c:1696
KDB: stack backtrace:
db_trace_thread() at db_trace_thread+0x10
scp=0xc0af6ce8 rlv=0xc0907798 ($a+0x34)
rsp=0xcf4047e8 rfp=0xcf404904
r10=0xc35c84b8 r9=0x000006a0
r8=0xc0ce9ee4 r7=0xc35c8178 r6=0xffffffff r5=0xc0b1e610
r4=0xcf4047f0
$a() at $a+0x10
scp=0xc0907774 rlv=0xc09c5370 (kdb_backtrace+0x3c)
rsp=0xcf404908 rfp=0xcf404918
r4=0xc0bbb1d0
kdb_backtrace() at kdb_backtrace+0x10
scp=0xc09c5344 rlv=0xc09d4710 (_witness_debugger+0x5c)
rsp=0xcf40491c rfp=0xcf404930
r4=0x00000001
_witness_debugger() at _witness_debugger+0x14
scp=0xc09d46c8 rlv=0xc09d5238 (witness_checkorder+0x5f4)
rsp=0xcf404934 rfp=0xcf40497c
r5=0xc0d1b948 r4=0x00000000
witness_checkorder() at witness_checkorder+0x10
scp=0xc09d4c54 rlv=0xc09912b4 (_mtx_lock_flags+0x34)
rsp=0xcf404980 rfp=0xcf4049a8
r10=0xc0d26b80 r9=0x00000012
r8=0x000006a0 r7=0xc0b4a4bc r6=0x00000000 r5=0x00000000
r4=0xc0d1b948
_mtx_lock_flags() at _mtx_lock_flags+0x10
scp=0xc0991290 rlv=0xc0afc600 ($a+0x110)
rsp=0xcf4049ac rfp=0xcf4049d8
r10=0x00000000 r8=0xc0f95494
r7=0xc36054dc r6=0xc36050b0 r5=0xc0f95464 r4=0xc1889150
$a() at $a+0x10
scp=0xc0afc500 rlv=0xc0b00f90 ($a+0xb5c)
rsp=0xcf4049dc rfp=0xcf404a60
r10=0x01fa300e r9=0x00000000
r8=0xc36050b0 r7=0x00000000 r6=0x00000000 r5=0x01fa3002
r4=0xc3cbde90
$a() at $a+0x10
scp=0xc0b00444 rlv=0xc0b015c8 (pmap_enter_object+0x88)
rsp=0xcf404a64 rfp=0xcf404a98
r10=0x00000005 r9=0xc36050b0
r8=0xc0f95464 r7=0x00000000 r6=0x00000097 r5=0xc0f95464
r4=0x00000001
pmap_enter_object() at pmap_enter_object+0x10
scp=0xc0b01550 rlv=0xc0ade254 (vm_map_pmap_enter+0x294)
rsp=0xcf404a9c rfp=0xcf404af0
r10=0x00000000 r9=0x00000000
r8=0x00000000 r7=0x00000097 r6=0x00000000 r5=0x00000000
r4=0x0000000f
vm_map_pmap_enter() at vm_map_pmap_enter+0x14
scp=0xc0addfd4 rlv=0xc0adef74 (vm_map_insert+0x390)
rsp=0xcf404af4 rfp=0xcf404b44
r10=0x00008000 r9=0x00000000
r8=0x00000000 r7=0xc3cc1110 r6=0x00000000 r5=0x00000000
r4=0x00000000
vm_map_insert() at vm_map_insert+0x10
scp=0xc0adebf4 rlv=0xc0963f9c ($a+0x258)
rsp=0xcf404b48 rfp=0xcf404b8c
r10=0x0009f000 r9=0x00008000
r8=0xc3605000 r7=0x00000000 r6=0x00000000 r5=0x00000005
r4=0x00000000
$a() at $a+0x10
scp=0xc0963d54 rlv=0xc09640b0 ($a+0xe0)
rsp=0xcf404b90 rfp=0xcf404bd0
r10=0x00096208 r9=0x00008000
r8=0xc3cc1110 r7=0x00000000 r6=0x00096208 r5=0xfffff000
r4=0x0009f000
$a() at $a+0x10
scp=0xc0963fe0 rlv=0xc0965300 ($a+0x448)
rsp=0xcf404bd4 rfp=0xcf404c64
r10=0x00000000 r9=0xc0ba7eb4
r8=0xc0ba19a4 r7=0xcf404d58 r6=0xcf408000 r5=0x00000000
r4=0xcf408034
$a() at $a+0x10
scp=0xc0964ec8 rlv=0xc09799d0 (kern_execve+0x258)
rsp=0xcf404c68 rfp=0xcf404de4
r10=0x00000000 r9=0xc3603000
r8=0xcf404d58 r7=0xffffffff r6=0xc0ba8bb4 r5=0x00000000
r4=0x00000002
kern_execve() at kern_execve+0x10
scp=0xc0979788 rlv=0xc097a58c (execve+0x48)
rsp=0xcf404de8 rfp=0xcf404e28
r10=0x7ffffffd r9=0xc3601000
r8=0xc0b892c8 r7=0xc0b892d2 r6=0x7ffffff2 r5=0xcf404df0
r4=0xc3603000
execve() at execve+0x10
scp=0xc097a554 rlv=0xc09660f0 ($a+0x1ec)
rsp=0xcf404e2c rfp=0xcf404e80
r5=0x7fffffe4 r4=0x7fffffe8
$a() at $a+0x10
scp=0xc0965f14 rlv=0xc097c78c (fork_exit+0x64)
rsp=0xcf404e84 rfp=0xcf404ea8
r10=0xc0965f04 r9=0x00000000
r8=0x00000000 r7=0xc3601000 r6=0xcf404eac r5=0xc0d26b80
r4=0xc3603000
fork_exit() at fork_exit+0x10
scp=0xc097c738 rlv=0xc0b05c5c (fork_trampoline+0x14)
rsp=0xcf404eac rfp=0x00000000
r10=0x00000000 r8=0x00000000
r7=0xc0b29cb8 r6=0xcf45feac r5=0x00000000 r4=0xc0965f04

When I reverted changes in pmap from this svn commit I didn't have LORs
nor panics.
I will be grateful for any help or advice.

Best regards,
Michał Hajduk
_______________________________________________
freebsd-arm@... mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-arm
To unsubscribe, send any mail to "freebsd-arm-unsubscribe@..."

Re: pmap problem in FreeBSD current

by Stanislav Sedov-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Mon, 06 Jul 2009 11:12:22 +0200
Michal Hajduk <mih@...> mentioned:

> Hello Mark,
>
> While testing EHCI (FreeBSD 8-current with new USB-stack) on
> ARM machine I have found some problem probably related to
> svn commit *194459*
> http://svn.freebsd.org/viewvc/base?view=revision&revision=194459
> With compiled USB-stack I had vm_fault:
>

Hi, Michal!

This is the known problem and we currently working on fixing it.  It
looks like that r194459, while certainly good, uncovered a memory
corruption problem in ARM code.  As a workaround you can revert
r194459 for now.

--
Stanislav Sedov
ST4096-RIPE


attachment0 (817 bytes) Download Attachment

Re: pmap problem in FreeBSD current

by Michal Hajduk :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Stanislav Sedov wrote:

> On Mon, 06 Jul 2009 11:12:22 +0200
> Michal Hajduk <mih@...> mentioned:
>
>  
>> Hello Mark,
>>
>> While testing EHCI (FreeBSD 8-current with new USB-stack) on
>> ARM machine I have found some problem probably related to
>> svn commit *194459*
>> http://svn.freebsd.org/viewvc/base?view=revision&revision=194459
>> With compiled USB-stack I had vm_fault:
>>
>>    
>
> Hi, Michal!
>
> This is the known problem and we currently working on fixing it.  It
> looks like that r194459, while certainly good, uncovered a memory
> corruption problem in ARM code.  As a workaround you can revert
> r194459 for now.
>
>  
Hi, Stanislav!

Thank you for answering.
Could you tell something more about this memory
corruption problem in ARM code? Have you found
which part of FreeBSD code is responsible for this,
and what do you think about LORs related to
r194459?

Best regards,
Michał Hajduk
_______________________________________________
freebsd-arm@... mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-arm
To unsubscribe, send any mail to "freebsd-arm-unsubscribe@..."

Re: pmap problem in FreeBSD current

by Mark Tinguely :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

>  Michal Hajduk <mih@...> mentioned:
>
>  > Hello Mark,
>  >=20
>  > While testing EHCI (FreeBSD 8-current with new USB-stack) on
>  > ARM machine I have found some problem probably related to
>  > svn commit *194459*=20
>  > http://svn.freebsd.org/viewvc/base?view=3Drevision&revision=3D194459
>  > With compiled USB-stack I had vm_fault:
>  >=20
>
>  Hi, Michal!
>
>  This is the known problem and we currently working on fixing it.  It
>  looks like that r194459, while certainly good, uncovered a memory
>  corruption problem in ARM code.  As a workaround you can revert
>  r194459 for now.
>
>  --=20
>  Stanislav Sedov
>  ST4096-RIPE

Sorry about that guys. I will walk through the pmap logic again to see
if there is a problem with the patch.

--Mark Tinguely.
_______________________________________________
freebsd-arm@... mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-arm
To unsubscribe, send any mail to "freebsd-arm-unsubscribe@..."

Re: pmap problem in FreeBSD current

by Mark Tinguely :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

One quick observation:
in pmap_nuke_pv(), lower if statement cleans out the pv_list when there
is no other mapping besides the kernel mapping. If I remember correctly,
this was put in at the last minute. we had to remove the kernel mapping
because the page went back to the one of the queues and the kernel mapping
caused a panic.

When the kernel mapping is removed from the other-wise empty pv_list,
the PG_WRITABLE is turned off like is done when the pv_entry list is
normally emptied.

But at this point, we know that there still is a kernel mapping and the
pmap_enter() should have enabled the PG_WRITABLE flag because kernel mappings
should be writable. In my opinion, that flag should be enabled.

Does it make sense that we should leave the page modified bit
or will it panic on the freeing of the page?

        if (pv != NULL && (pv->pv_flags & PVF_UNMAN) &&
            TAILQ_NEXT(pv, pv_list) == NULL) {
                pg->md.pv_kva = pv->pv_va;
                        /* a recursive pmap_nuke_pv */
                TAILQ_REMOVE(&pg->md.pv_list, pv, pv_list);
                TAILQ_REMOVE(&pm->pm_pvlist, pv, pv_plist);
                if (pv->pv_flags & PVF_WIRED)
                        --pm->pm_stats.wired_count;
                pg->md.pvh_attrs &= ~PVF_REF;
- pg->md.pvh_attrs &= ~PVF_MOD;
- vm_page_flag_clear(pg, PG_WRITEABLE);
                pmap_free_pv_entry(pv);
        }


_______________________________________________
freebsd-arm@... mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-arm
To unsubscribe, send any mail to "freebsd-arm-unsubscribe@..."

Re: pmap problem in FreeBSD current

by Mark Tinguely :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


In arm_remap_nocache()/arm_unmap_nocache() a kernel shadow mapping is
made for BUS_DMA_COHERENT pages but is not removed. It is probably one
place that causes undeleted mappings required us to add the tail "if"
statement in pmap_nuke_pv() that I mentioned yesterday.

FYI future ideas: we can get rid of the shadow KVA for the BUS_DMA_COHERENT
by setting a bit in the page flags to denote a no_cache situation. The pmap
code can see that bit and refraim from turning caching on in pmap_fix_cache().

Speaking of pmap_nuke_pv() and in regards to my yesterday email, the more I
think of it, the more I believe the line "pg->md.pvh_attrs &= ~PVF_MOD;"
should remain in the code. The line, "vm_page_flag_clear(pg, PG_WRITEABLE);"
should be remove to avoid corruption.

It would be nice to remove all these unremoved mappings so that "if"
statement in pmap_nuke_pv() is unecessary. If we can't find all of
these unremoved mappings, we may need to clean out md.pv_kva when a
page is freed (or allocated) because we may be tricked into thinking the
page is shared when it really is not. This would not cause corruption,
but the cache will be turned off unnecessarily on a really unshared page.

vm_machdep.c:
void
arm_unmap_nocache(void *addr, vm_size_t size)
{
        vm_offset_t raddr = (vm_offset_t)addr;
        int i;

        size = round_page(size);
        i = (raddr - arm_nocache_startaddr) / (PAGE_SIZE);
- for (; size > 0; size -= PAGE_SIZE, i++)
+ for (; size > 0; size -= PAGE_SIZE, i++) {
                arm_nocache_allocated[i / BITS_PER_INT] &= ~(1 << (i %
                    BITS_PER_INT));
+ pmap_kremove(raddr);
+ raddr += PAGE_SIZE;
}

--Mark Tinguely
_______________________________________________
freebsd-arm@... mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-arm
To unsubscribe, send any mail to "freebsd-arm-unsubscribe@..."

Re: pmap problem in FreeBSD current

by Mark Tinguely :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


sf_buf_alloc()/sf_buf_free() in vm_machdep.c also leaves dangling kernel
mappings.

/*
 * Detatch mapped page and release resources back to the system.
 */
void
sf_buf_free(struct sf_buf *sf)
{
#ifndef ARM_USE_SMALL_ALLOC
        mtx_lock(&sf_buf_lock);
        sf->ref_count--;
        if (sf->ref_count == 0) {
                TAILQ_INSERT_TAIL(&sf_buf_freelist, sf, free_entry);
                nsfbufsused--;
+ pmap_kremove(sf->kva);
                if (sf_buf_alloc_want > 0)
                        wakeup_one(&sf_buf_freelist);
        }
        mtx_unlock(&sf_buf_lock);
#endif

--Mark Tinguely.
_______________________________________________
freebsd-arm@... mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-arm
To unsubscribe, send any mail to "freebsd-arm-unsubscribe@..."

Re: pmap problem in FreeBSD current

by Mark Tinguely :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


Apologies for the noise. I am not familiar with the sf_buf_alloc/sf_buf_free
code and sent a bad code sequence. If we remove the mapping, it has to
come off the active list also:

/*
 * Detatch mapped page and release resources back to the system.
 */
void
sf_buf_free(struct sf_buf *sf)
{
#ifndef ARM_USE_SMALL_ALLOC
        mtx_lock(&sf_buf_lock);
        sf->ref_count--;
        if (sf->ref_count == 0) {
                TAILQ_INSERT_TAIL(&sf_buf_freelist, sf, free_entry);
                nsfbufsused--;
+ pmap_kremove(sf->kva);
+ sf->m = NULL;
+ LIST_REMOVE(sf, list_entry);
                if (sf_buf_alloc_want > 0)
                        wakeup_one(&sf_buf_freelist);
        }
        mtx_unlock(&sf_buf_lock);
#endif

--Mark Tinguely.

_______________________________________________
freebsd-arm@... mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-arm
To unsubscribe, send any mail to "freebsd-arm-unsubscribe@..."

Re: pmap problem in FreeBSD current

by Michal Hajduk :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Mark Tinguely wrote:

> Apologies for the noise. I am not familiar with the sf_buf_alloc/sf_buf_free
> code and sent a bad code sequence. If we remove the mapping, it has to
> come off the active list also:
>
> /*
>  * Detatch mapped page and release resources back to the system.
>  */
> void
> sf_buf_free(struct sf_buf *sf)
> {
> #ifndef ARM_USE_SMALL_ALLOC
> mtx_lock(&sf_buf_lock);
> sf->ref_count--;
> if (sf->ref_count == 0) {
> TAILQ_INSERT_TAIL(&sf_buf_freelist, sf, free_entry);
> nsfbufsused--;
> + pmap_kremove(sf->kva);
> + sf->m = NULL;
> + LIST_REMOVE(sf, list_entry);
> if (sf_buf_alloc_want > 0)
> wakeup_one(&sf_buf_freelist);
> }
> mtx_unlock(&sf_buf_lock);
> #endif
>
> --Mark Tinguely.
>
>  
Hello Mark,
Thank you for looking again on r194459.

I've tried to compile kernel using your patch with
changes regarding PG_WRITABLE and arm_unmap_nocache(),
but it didn't help.

My problems are rather related to memory corruption, which
I've observed in uma_core (pointers had bad values and
count of free items in slab had negative value).

I am still concerned about LOR, which has appeared in
svn commit r194459 (I wrote about it in my first mail).
Could you take a look at this LOR?

Thanks for your help.

Best regards,
Michał Hajduk

_______________________________________________
freebsd-arm@... mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-arm
To unsubscribe, send any mail to "freebsd-arm-unsubscribe@..."

Re: pmap problem in FreeBSD current

by Mark Tinguely :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


>  Hello Mark,
>  Thank you for looking again on r194459.
>
>  I've tried to compile kernel using your patch with
>  changes regarding PG_WRITABLE and arm_unmap_nocache(),
>  but it didn't help.
>
>  My problems are rather related to memory corruption, which
>  I've observed in uma_core (pointers had bad values and
>  count of free items in slab had negative value).
>
>  I am still concerned about LOR, which has appeared in
>  svn commit r194459 (I wrote about it in my first mail).
>  Could you take a look at this LOR?
>
>  Thanks for your help.
>
>  Best regards,
>  Michał Hajduk


I don't think this is a corruption issue but an allocation of a l2_bucket
issue. The kernel map is locked to do the kenter. A new bucket is needed,
UMA is called and the new page is kenter into the map. In pmap_enter_pv()
before we allocate a pv_entry, we turn off the kmap lock. I am not sure if
the kmap lock should be turned off in the pmap_alloc_l2_bucket(), or the
caller, but here is a quick manually made  kmap lock disable patch:

I still think the last "vm_page_flag_clear(pg, PG_WRITEABLE);" needs
to be removed from pmap_nuke_pv(). All dangling kenters need to be
kremoved ...
                ------------------------

/*
 * Returns a pointer to the L2 bucket associated with the specified pmap
 * and VA.
 *
 * If no L2 bucket exists, perform the necessary allocations to put an L2
 * bucket/page table in place.
 *
 * Note that if a new L2 bucket/page was allocated, the caller *must*
 * increment the bucket occupancy counter appropriately *before*
 * releasing the pmap's lock to ensure no other thread or cpu deallocates
 * the bucket/page in the meantime.
 */
static struct l2_bucket *
pmap_alloc_l2_bucket(pmap_t pm, vm_offset_t va)
{
        struct l2_dtable *l2;
        struct l2_bucket *l2b;
        u_short l1idx;
+ int km = 0;

        l1idx = L1_IDX(va);

        PMAP_ASSERT_LOCKED(pm);
+ if ((pm != pmap_kernel()) && PMAP_OWNED(pmap_kernel()) {
+ km = 1;
+ PMAP_UNLOCK(pmap_kernel());
+ }
        mtx_assert(&vm_page_queue_mtx, MA_OWNED);
        if ((l2 = pm->pm_l2[L2_IDX(l1idx)]) == NULL) {
                /*
                 * No mapping at this address, as there is
                 * no entry in the L1 table.
                 * Need to allocate a new l2_dtable.
                 */
again_l2table:
                PMAP_UNLOCK(pm);
                vm_page_unlock_queues();
                if ((l2 = pmap_alloc_l2_dtable()) == NULL) {
                        vm_page_lock_queues();
                        PMAP_LOCK(pm);
+ if (km)
+ PMAP_LOCK(pmap_kernel());
                        return (NULL);
                }
                vm_page_lock_queues();
                PMAP_LOCK(pm);
                if (pm->pm_l2[L2_IDX(l1idx)] != NULL) {
                        PMAP_UNLOCK(pm);
                        vm_page_unlock_queues();
                        uma_zfree(l2table_zone, l2);
                        vm_page_lock_queues();
                        PMAP_LOCK(pm);
                        l2 = pm->pm_l2[L2_IDX(l1idx)];
                        if (l2 == NULL)
                                goto again_l2table;
                        /*
                         * Someone already allocated the l2_dtable while
                         * we were doing the same.
                         */
                } else {
                        bzero(l2, sizeof(*l2));
                        /*
                         * Link it into the parent pmap
                         */
                        pm->pm_l2[L2_IDX(l1idx)] = l2;
                }
        }

        l2b = &l2->l2_bucket[L2_BUCKET(l1idx)];

        /*
         * Fetch pointer to the L2 page table associated with the address.
         */
        if (l2b->l2b_kva == NULL) {
                pt_entry_t *ptep;

                /*
                 * No L2 page table has been allocated. Chances are, this
                 * is because we just allocated the l2_dtable, above.
                 */
again_ptep:
                PMAP_UNLOCK(pm);
                vm_page_unlock_queues();
                ptep = (void*)uma_zalloc(l2zone, M_NOWAIT|M_USE_RESERVE);
                vm_page_lock_queues();
                PMAP_LOCK(pm);
                if (l2b->l2b_kva != 0) {
                        /* We lost the race. */
                        PMAP_UNLOCK(pm);
                        vm_page_unlock_queues();
                        uma_zfree(l2zone, ptep);
                        vm_page_lock_queues();
                        PMAP_LOCK(pm);
                        if (l2b->l2b_kva == 0)
                                goto again_ptep;
                        return (l2b);
                }
                l2b->l2b_phys = vtophys(ptep);
                if (ptep == NULL) {
                        /*
                         * Oops, no more L2 page tables available at this
                         * time. We may need to deallocate the l2_dtable
                         * if we allocated a new one above.
                         */
                        if (l2->l2_occupancy == 0) {
                                pm->pm_l2[L2_IDX(l1idx)] = NULL;
                                pmap_free_l2_dtable(l2);
                        }
+ if (km)
+ PMAP_LOCK(pmap_kernel());
                        return (NULL);
                }

                l2->l2_occupancy++;
                l2b->l2b_kva = ptep;
                l2b->l2b_l1idx = l1idx;
        }

+ if (km)
+ PMAP_LOCK(pmap_kernel());
        return (l2b);
}
_______________________________________________
freebsd-arm@... mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-arm
To unsubscribe, send any mail to "freebsd-arm-unsubscribe@..."

Re: pmap problem in FreeBSD current

by Mark Tinguely :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

I forgot to CC the rest. pmap_get_pv_entry() is called from pmap_enter_locked
and can have the same UMA call that can happen in pmap_kenter_internal.
move the kmap lock protection from pmap_enter_pv() to pmap_get_pv_entry()

static void
pmap_enter_pv(struct vm_page *pg, struct pv_entry *pve, pmap_t pm,
    vm_offset_t va, u_int flags)
{

- int km;

        mtx_assert(&vm_page_queue_mtx, MA_OWNED);

        if (pg->md.pv_kva) {
                /* PMAP_ASSERT_LOCKED(pmap_kernel()); */
                pve->pv_pmap = pmap_kernel();
                pve->pv_va = pg->md.pv_kva;
                pve->pv_flags = PVF_WRITE | PVF_UNMAN;
                pg->md.pv_kva = 0;

                TAILQ_INSERT_HEAD(&pg->md.pv_list, pve, pv_list);
                TAILQ_INSERT_HEAD(&pm->pm_pvlist, pve, pv_plist);
- if ((km = PMAP_OWNED(pmap_kernel())))
- PMAP_UNLOCK(pmap_kernel());
                vm_page_unlock_queues();
                if ((pve = pmap_get_pv_entry()) == NULL)
                        panic("pmap_kenter_internal: no pv entries");
                vm_page_lock_queues();
- if (km)
- PMAP_LOCK(pmap_kernel());
        }

        PMAP_ASSERT_LOCKED(pm);
        pve->pv_pmap = pm;
        pve->pv_va = va;
        pve->pv_flags = flags;

        TAILQ_INSERT_HEAD(&pg->md.pv_list, pve, pv_list);
        TAILQ_INSERT_HEAD(&pm->pm_pvlist, pve, pv_plist);
        pg->md.pvh_attrs |= flags & (PVF_REF | PVF_MOD);
        if (pve->pv_flags & PVF_WIRED)
                ++pm->pm_stats.wired_count;
        vm_page_flag_set(pg, PG_REFERENCED);
}

static void
pmap_free_pv_entry(pv_entry_t pv)
{
+ int km;
        pv_entry_count--;
+ if ((km = PMAP_OWNED(pmap_kernel())))
+ PMAP_UNLOCK(pmap_kernel());
        uma_zfree(pvzone, pv);
+ if (km)
+ PMAP_LOCK(pmap_kernel());
}


/*
 * get a new pv_entry, allocating a block from the system
 * when needed.
 * the memory allocation is performed bypassing the malloc code
 * because of the possibility of allocations at interrupt time.
 */
static pv_entry_t
pmap_get_pv_entry(void)
{
        pv_entry_t ret_value;
+ int km;
       
        pv_entry_count++;
+ if ((km = PMAP_OWNED(pmap_kernel())))
+ PMAP_UNLOCK(pmap_kernel());
        if (pv_entry_count > pv_entry_high_water)
                pagedaemon_wakeup();
        ret_value = uma_zalloc(pvzone, M_NOWAIT);
+ if (km)
+ PMAP_LOCK(pmap_kernel());
        return ret_value;
}
_______________________________________________
freebsd-arm@... mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-arm
To unsubscribe, send any mail to "freebsd-arm-unsubscribe@..."

Re: pmap problem in FreeBSD current

by Michal Hajduk :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi Mark,
We've diagnosed the problem and it was related to arm_nocache_remap().
When the page was remaped into non-cacheable virtual memory region
there was no dcache write-back operation, so count of free items in
slab had differ value then should had.
This write-back operation should have been done in pmap_set_cache_entry()
but PVF_REF flag was missing so this part of code was omitted.

I think that we should enable PVF_REF flag in pmap_enter_pv().

================================================

diff --git a/sys/arm/arm/pmap.c b/sys/arm/arm/pmap.c
index 3cdab65..133dc6d 100644
--- a/sys/arm/arm/pmap.c
+++ b/sys/arm/arm/pmap.c
@@ -1683,7 +1683,7 @@ pmap_enter_pv(struct vm_page *pg, struct pv_entry
*pve, pmap_t pm,
/* PMAP_ASSERT_LOCKED(pmap_kernel()); */
pve->pv_pmap = pmap_kernel();
pve->pv_va = pg->md.pv_kva;
- pve->pv_flags = PVF_WRITE | PVF_UNMAN;
+ pve->pv_flags = PVF_WRITE | PVF_UNMAN | PVF_REF;
pg->md.pv_kva = 0;

TAILQ_INSERT_HEAD(&pg->md.pv_list, pve, pv_list);

=================================================

With this patch I've had no panics.

Many thanks,
Michał Hajduk
_______________________________________________
freebsd-arm@... mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-arm
To unsubscribe, send any mail to "freebsd-arm-unsubscribe@..."

Re: pmap problem in FreeBSD current

by Mark Tinguely :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


>  Hi Mark,
>  We've diagnosed the problem and it was related to arm_nocache_remap().
>  When the page was remaped into non-cacheable virtual memory region
>  there was no dcache write-back operation, so count of free items in
>  slab had differ value then should had.
>  This write-back operation should have been done in pmap_set_cache_entry()
>  but PVF_REF flag was missing so this part of code was omitted.
>
>  I think that we should enable PVF_REF flag in pmap_enter_pv().
>
>  ================================================
>
>  diff --git a/sys/arm/arm/pmap.c b/sys/arm/arm/pmap.c
>  index 3cdab65..133dc6d 100644
>  --- a/sys/arm/arm/pmap.c
>  +++ b/sys/arm/arm/pmap.c
>  @@ -1683,7 +1683,7 @@ pmap_enter_pv(struct vm_page *pg, struct pv_entry
>  *pve, pmap_t pm,
>  /* PMAP_ASSERT_LOCKED(pmap_kernel()); */
>  pve->pv_pmap = pmap_kernel();
>  pve->pv_va = pg->md.pv_kva;
>  - pve->pv_flags = PVF_WRITE | PVF_UNMAN;
>  + pve->pv_flags = PVF_WRITE | PVF_UNMAN | PVF_REF;
>  pg->md.pv_kva = 0;
>
>  TAILQ_INSERT_HEAD(&pg->md.pv_list, pve, pv_list);
>
>  =================================================
>
>  With this patch I've had no panics.
>
>  Many thanks,
>  Michał Hajduk
>

Good job. This strange, your inclusion writes back the whole page of the
original buffer. This writeback of just the original buffer size should be
done in bus_dmamem_alloc() in busdma_machdep.c after the arm_remap_nocache()
with the line "cpu_idcache_wbinv_range(vm_offset_t)*vaddr, dmat->maxsize)".

I wonder if your cpu_idcache_wbinv_range() implementation correctly
wb/invalidates when the buffer is not cache line aligned or is smaller
than a cache-line? The other situation that would do this is if your
cache line larger than you think. I know the ARMv7 use 64 byte caches
instead of the more traditional 32 bytes. This should not be your case
because last week I looked up your processor information and thought it
said it used a 32 byte cache line.

Did http://www.casselton.net/~tinguely/arm_pmap_unmanaged.diff fix the lock
problems?

Thank-you for the test information and the code scouting.

--Mark Tinguely.
_______________________________________________
freebsd-arm@... mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-arm
To unsubscribe, send any mail to "freebsd-arm-unsubscribe@..."

Re: pmap problem in FreeBSD current - PS

by Mark Tinguely :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


PS. sorry to even question your cpu_(l2)idcache_wbinv_range() implemetation.
    the cpu_idcache_wbinv_range() in bus_dmamem_alloc() is wrong.
    arm_remap_nocache() should wb/inv the entire page especially if the
    buffer that uses the page is less than a page size or non-page aligned.
    The cache lines NOT in the buffer is the data that can be lost if
    used while the nocache shadow mapping is in effect.

   As an open question to the group: should we add an explict page
   cpu_(l2)idcache_wbinv_range() in the arm_remap_nocache() routine,
   so we know that it happens rather than a side effect of the new
   managing of kernel pages?

   For freebsd-9, I will rewrite arm_remap_nocache() to get rid of the
   shadow map.

Did your lock problems go away?

Good work.

--Mark Tinguely
_______________________________________________
freebsd-arm@... mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-arm
To unsubscribe, send any mail to "freebsd-arm-unsubscribe@..."

Re: pmap problem in FreeBSD current - PS

by Michal Hajduk :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi Mark,

I've corrected busdma_machdep instead of adding this PVF_REF flag to arm
pmap code and it works good.
My patch:
===========================================================
diff --git a/sys/arm/arm/busdma_machdep.c b/sys/arm/arm/busdma_machdep.c
index a8b2de9..b55a714 100644
--- a/sys/arm/arm/busdma_machdep.c
+++ b/sys/arm/arm/busdma_machdep.c
@@ -631,10 +631,10 @@ bus_dmamem_alloc(bus_dma_tag_t dmat, void** vaddr,
int flags,
((vm_offset_t)*vaddr & PAGE_MASK));
newmap->origbuffer = *vaddr;
newmap->allocbuffer = tmpaddr;
- cpu_idcache_wbinv_range((vm_offset_t)*vaddr,
- dmat->maxsize);
- cpu_l2cache_wbinv_range((vm_offset_t)*vaddr,
- dmat->maxsize);
+ cpu_idcache_wbinv_range((vm_offset_t)*vaddr &
+ ~PAGE_MASK, PAGE_SIZE);
+ cpu_l2cache_wbinv_range((vm_offset_t)*vaddr &
+ ~PAGE_MASK, PAGE_SIZE);
*vaddr = tmpaddr;
} else
newmap->origbuffer = newmap->allocbuffer = NULL;

============================================================

While debugging this problem we've found another in pmap_kremove().
There was an
invalidation on va + PAGE_SIZE instead of page which contains va address.
My patch:

=====================================================
diff --git a/sys/arm/arm/pmap.c b/sys/arm/arm/pmap.c
index 3cdab65..7988f40 100644
--- a/sys/arm/arm/pmap.c
+++ b/sys/arm/arm/pmap.c
@@ -2984,8 +2984,8 @@ pmap_kremove(vm_offset_t va)
pmap_free_pv_entry(pve);
PMAP_UNLOCK(pmap_kernel());
vm_page_unlock_queues();
- cpu_dcache_wbinv_range(va, PAGE_SIZE);
- cpu_l2cache_wbinv_range(va, PAGE_SIZE);
+ cpu_dcache_wbinv_range(va & ~PAGE_MASK, PAGE_SIZE);
+ cpu_l2cache_wbinv_range(va & ~PAGE_MASK, PAGE_SIZE);
cpu_tlb_flushD_SE(va);
cpu_cpwait();
*pte = 0;
=====================================================

I suggest, that maybe for now we should only change the
cpu_(l2)idcache_wbinv_range()
routines by adding simple check:
If the va address is page aligned and size is equal to PAGE_SIZE we
should write-back
and invalidate whole page. Otherwise we should invalidate line by line.

I've also checked your patch and it didn't help (I had a panic)
...
uhub0: 1 port with 1 removable, self powered
Root mount waiting for: usbus0
panic: blockable sleep lock (sleep mutex) vm page queue mutex @
/home/mih/git/marvell-current/sys/arm/arm/pmap.c:1947
KDB: enter: panic
[thread pid 15 tid 100028 ]
Stopped at $d: ldrb r15, [r15, r15, ror r15]!

Many thanks,
Michał Hajduk
_______________________________________________
freebsd-arm@... mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-arm
To unsubscribe, send any mail to "freebsd-arm-unsubscribe@..."

Re: pmap problem in FreeBSD current - PS

by Michal Hajduk :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Michal Hajduk wrote:

> Hi Mark,
>
> I've corrected busdma_machdep instead of adding this PVF_REF flag to arm
> pmap code and it works good.
> My patch:
> ===========================================================
> diff --git a/sys/arm/arm/busdma_machdep.c b/sys/arm/arm/busdma_machdep.c
> index a8b2de9..b55a714 100644
> --- a/sys/arm/arm/busdma_machdep.c
> +++ b/sys/arm/arm/busdma_machdep.c
> ....
I've found another problem in busdma_machdep.c in function
bus_dmamem_alloc.
After write-back invalidate operation there is no tlb flush.
Below there is complete patch:

============================================================
diff --git a/sys/arm/arm/busdma_machdep.c b/sys/arm/arm/busdma_machdep.c
index a8b2de9..9562615 100644
--- a/sys/arm/arm/busdma_machdep.c
+++ b/sys/arm/arm/busdma_machdep.c
@@ -631,10 +631,11 @@ bus_dmamem_alloc(bus_dma_tag_t dmat, void** vaddr,
int flags,
((vm_offset_t)*vaddr & PAGE_MASK));
newmap->origbuffer = *vaddr;
newmap->allocbuffer = tmpaddr;
- cpu_idcache_wbinv_range((vm_offset_t)*vaddr,
- dmat->maxsize);
- cpu_l2cache_wbinv_range((vm_offset_t)*vaddr,
- dmat->maxsize);
+ cpu_dcache_wbinv_range((vm_offset_t)*vaddr &
+ ~PAGE_MASK, PAGE_SIZE);
+ cpu_l2cache_wbinv_range((vm_offset_t)*vaddr &
+ ~PAGE_MASK, PAGE_SIZE);
+ cpu_tlb_flushID_SE((vm_offset_t)*vaddr);
*vaddr = tmpaddr;
} else
newmap->origbuffer = newmap->allocbuffer = NULL;

============================================================

> I've also checked your patch and it didn't help (I had a panic)
> ...
> uhub0: 1 port with 1 removable, self powered
> Root mount waiting for: usbus0
> panic: blockable sleep lock (sleep mutex) vm page queue mutex @
> /home/mih/git/marvell-current/sys/arm/arm/pmap.c:1947
> KDB: enter: panic
> [thread pid 15 tid 100028 ]
> Stopped at $d: ldrb r15, [r15, r15, ror r15]!
>
> Many thanks,
> Michał Hajduk
>
Can we move vm_page_unlock_queues() (line 1693) and vm_page_lock_queues to
pmap_get_pv_entry() ? Is it added only because of pagedaemon_wakeup()?

If this is correct, I've prepared a patch:
===========================================================
diff --git a/sys/arm/arm/pmap.c b/sys/arm/arm/pmap.c
index 3cdab65..b4ffbbf 100644
--- a/sys/arm/arm/pmap.c
+++ b/sys/arm/arm/pmap.c
@@ -1690,10 +1690,8 @@ pmap_enter_pv(struct vm_page *pg, struct pv_entry
*pve, pmap_t pm,
TAILQ_INSERT_HEAD(&pm->pm_pvlist, pve, pv_plist);
if ((km = PMAP_OWNED(pmap_kernel())))
PMAP_UNLOCK(pmap_kernel());
- vm_page_unlock_queues();
if ((pve = pmap_get_pv_entry()) == NULL)
panic("pmap_kenter_internal: no pv entries");
- vm_page_lock_queues();
if (km)
PMAP_LOCK(pmap_kernel());
}
@@ -2904,10 +2902,8 @@ pmap_kenter_internal(vm_offset_t va, vm_offset_t
pa, int flags)
vm_page_lock_queues();
if (!TAILQ_EMPTY(&m->md.pv_list) || m->md.pv_kva) {
/* release vm_page lock for pv_entry UMA */
- vm_page_unlock_queues();
if ((pve = pmap_get_pv_entry()) == NULL)
panic("pmap_kenter_internal: no pv entries");
- vm_page_lock_queues();
PMAP_LOCK(pmap_kernel());
pmap_enter_pv(m, pve, pmap_kernel(), va,
PVF_WRITE | PVF_UNMAN);
@@ -2984,8 +2980,8 @@ pmap_kremove(vm_offset_t va)
pmap_free_pv_entry(pve);
PMAP_UNLOCK(pmap_kernel());
vm_page_unlock_queues();
- cpu_dcache_wbinv_range(va, PAGE_SIZE);
- cpu_l2cache_wbinv_range(va, PAGE_SIZE);
+ cpu_dcache_wbinv_range(va & ~PAGE_MASK, PAGE_SIZE);
+ cpu_l2cache_wbinv_range(va & ~PAGE_MASK, PAGE_SIZE);
cpu_tlb_flushD_SE(va);
cpu_cpwait();
*pte = 0;
@@ -3935,8 +3931,11 @@ pmap_get_pv_entry(void)
pv_entry_t ret_value;
pv_entry_count++;
- if (pv_entry_count > pv_entry_high_water)
+ if (pv_entry_count > pv_entry_high_water) {
+ vm_page_unlock_queues();
pagedaemon_wakeup();
+ vm_page_lock_queues();
+ }
ret_value = uma_zalloc(pvzone, M_NOWAIT);
return ret_value;
}
==========================================================

With this patch I didn't observe LORs (as well as with your + mine patch).

Thanks for your help.

Best regards,
Michał Hajduk
_______________________________________________
freebsd-arm@... mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-arm
To unsubscribe, send any mail to "freebsd-arm-unsubscribe@..."