radeon_cp_texture: page fault with non-sleepable locks held

Andriy Gapon avg at freebsd.org
Wed Nov 10 05:18:59 UTC 2010

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) @ /usr/src/sys/dev/drm/drm_drv.c:791
2nd 0xffffff000a621510 user map (user map) @ /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.

Andriy Gapon

More information about the freebsd-current mailing list