Re: radeon_cp_texture: page fault with non-sleepable locks held

From: Andriy Gapon <avg_at_freebsd.org>
Date: Thu, 11 Nov 2010 13:27:47 +0200
on 10/11/2010 10:34 Kostik Belousov said the following:
> On Wed, Nov 10, 2010 at 07:18:54AM +0200, Andriy Gapon wrote:
>> on 09/11/2010 16:05 Kostik Belousov said the following:
>>> Easiest would be for DRM to provide wrappers for copyin/copyout that
>>> unlock, do operation and lock.
>>
>> I am a little bit worried about this approach in general.
>> Driver state may be changed by a process running in parallel while the lock is
>> dropped.  And I don't think that we have any mechanism in DRM to check for that
>> and to restart operations or otherwise account for the state change.  The code
>> seems to be written with an assumption that it runs in exclusive mode from DRM
>> ioctl start to its completion.
>>
>>> Where is the reverse order (user map -> drm) ?
>>
>> You mean the following or the opposite?
>>
>> 1st 0xffffff0001b968a0 drmdev (drmdev) _at_ /usr/src/sys/dev/drm/drm_drv.c:791
>> 2nd 0xffffff000a621510 user map (user map) _at_ /usr/src/sys/vm/vm_map.c:3548
>> KDB: stack backtrace:
>> db_trace_self_wrapper() at 0xffffffff801b8b3a = db_trace_self_wrapper+0x2a
>> kdb_backtrace() at 0xffffffff803a7a8a = kdb_backtrace+0x3a
>> _witness_debugger() at 0xffffffff803bd42c = _witness_debugger+0x2c
>> witness_checkorder() at 0xffffffff803be899 = witness_checkorder+0x959
>> _sx_slock() at 0xffffffff80378af8 = _sx_slock+0x88
>> _vm_map_lock_read() at 0xffffffff80510a06 = _vm_map_lock_read+0x36
>> vm_map_lookup() at 0xffffffff805127d4 = vm_map_lookup+0x54
>> vm_fault() at 0xffffffff80509819 = vm_fault+0xf9
>> trap_pfault() at 0xffffffff80545d6f = trap_pfault+0x11f
>> trap() at 0xffffffff805465f7 = trap+0x657
>> calltrap() at 0xffffffff80530628 = calltrap+0x8
>> --- trap 0xc, rip = 0xffffffff805440bd, rsp = 0xffffff8123fe37f0, rbp =
>> 0xffffff8123fe3870 ---
>> copyin() at 0xffffffff805440bd = copyin+0x3d
>> radeon_cp_texture() at 0xffffffff8022fbd7 = radeon_cp_texture+0x167
>> drm_ioctl() at 0xffffffff8020fa38 = drm_ioctl+0x318
>> devfs_ioctl_f() at 0xffffffff802dd649 = devfs_ioctl_f+0x109
>> kern_ioctl() at 0xffffffff803c1127 = kern_ioctl+0x1f7
>> ioctl() at 0xffffffff803c12e8 = ioctl+0x168
>> syscallenter() at 0xffffffff803b57de = syscallenter+0x26e
>> syscall() at 0xffffffff80545eb2 = syscall+0x42
>> Xfast_syscall() at 0xffffffff80530902 = Xfast_syscall+0xe2
>>
>> If you meant the opposite order, how can I check it?
>> I guess that it could be in a mmap() call for drm cdev.
> 
> Explicitely insert the reversed order into the witness array and watch.

Here it is:
lock order reversal:
1st 0xffffff0001a51b30 user map (user map) _at_ /usr/src/sys/vm/vm_map.c:1400
2nd 0xffffff0001b968a0 drmdev (drmdev) _at_ /usr/src/sys/dev/drm/drm_vm.c:84
KDB: stack backtrace:
db_trace_self_wrapper() at 0xffffffff801b8b3a = db_trace_self_wrapper+0x2a
kdb_backtrace() at 0xffffffff803a7a8a = kdb_backtrace+0x3a
_witness_debugger() at 0xffffffff803bd42c = _witness_debugger+0x2c
witness_checkorder() at 0xffffffff803be899 = witness_checkorder+0x959
_sx_xlock() at 0xffffffff803789b8 = _sx_xlock+0x88
drm_mmap() at 0xffffffff8021587a = drm_mmap+0x18a
dev_pager_getpages() at 0xffffffff804fdcce = dev_pager_getpages+0xce
vm_object_populate() at 0xffffffff80515c2f = vm_object_populate+0x9f
pmap_object_init_pt() at 0xffffffff8053d600 = pmap_object_init_pt+0xa0
vm_map_pmap_enter() at 0xffffffff8050f1b7 = vm_map_pmap_enter+0x97
vm_map_insert() at 0xffffffff8050fa5d = vm_map_insert+0x45d
vm_map_find() at 0xffffffff8051097d = vm_map_find+0xdd
vm_mmap() at 0xffffffff80514158 = vm_mmap+0x578
mmap() at 0xffffffff80514903 = mmap+0x383
syscallenter() at 0xffffffff803b57de = syscallenter+0x26e
syscall() at 0xffffffff80545f92 = syscall+0x42
Xfast_syscall() at 0xffffffff805309e2 = Xfast_syscall+0xe2

-- 
Andriy Gapon
Received on Thu Nov 11 2010 - 10:27:53 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:40:09 UTC