| Summary: | DRM: Kernel panic "pmap_mapdev: Couldn't alloc kernel virtual memory" starting XFree86 | ||
|---|---|---|---|
| Product: | Base System | Reporter: | frank |
| Component: | i386 | Assignee: | Eric Anholt <anholt> |
| Status: | Closed FIXED | ||
| Severity: | Affects Only Me | ||
| Priority: | Normal | ||
| Version: | 4.11-STABLE | ||
| Hardware: | Any | ||
| OS: | Any | ||
Responsible Changed From-To: freebsd-i386->anholt Grab this one. The proper fix is to bus_space and bus_dma-ify the DRM, so we can have failing allocations, and to also not map the framebuffer in kernel unless necessary. State Changed From-To: open->closed This is fixed in 5-stable by a DRM change to not map framebuffer in the kernel, since it's unnecessary. I'm not supporting DRM on 4.x any more so I'm closing the PR. The issue resurfaced in -current in a different code path, but kern/80718 is covering the issue and I've got a patch ready for testing. |
I consistently hit a panic, "pmap_mapdev: Couldn't alloc kernel virtual memory," when I try to start XFree86 4.4 with agp.ko and radeon.ko loaded. I have a Radeon 8500 display card with 128MB of memory and I would like to do direct rendering on it, but this bug makes doing so impossible. The stack looks like: #3 0xc01837d9 in poweroff_wait (junk=0xc0341340, howto=0xc5397300) at /usr/src/sys/kern/kern_shutdown.c:612 #4 0xc02dbbb2 in pmap_mapdev (pa=0xe0000000, size=0x8000000) at /usr/src/sys/i386/i386/pmap.c:3067 #5 0xc54d377a in radeon_ioremap (dev=0xc54c4000, map=0xc5397300) at @/dev/drm/drm_memory.h:243 #6 0xc54cf001 in radeon_addmap (kdev=0xc54c6d00, cmd=0xc0186415, data=0xf90d6ea4 "", flags=0x3, p=0xf8f6ad40) at @/dev/drm/drm_bufs.h:125 #7 0xc54d21ec in radeon_ioctl (kdev=0xc54c6d00, cmd=0xc0186415, data=0xf90d6ea4 "", flags=0x3, p=0xf8f6ad40) at @/dev/drm/drm_drv.h:1122 #8 0xc01bd8ee in spec_poll (ap=0xf90d6de0) at /usr/src/sys/miscfs/specfs/spec_vnops.c:323 #9 0xc01bd619 in spec_open (ap=0xf90d6de0) at /usr/src/sys/miscfs/specfs/spec_vnops.c:147 #10 0xc025c84d in default_pager_getpages (object=0xf90d6de0, m=0xc54fccc0, count=0x0, reqpage=0x18) at /usr/src/sys/vm/default_pager.c:100 #11 0xc01b9f57 in vn_ioctl (fp=0xc54fccc0, com=0xc0186415, data=0xf90d6ea4 "", p=0xf8f6ad40) at /usr/src/sys/kern/vfs_vnops.c:607 #12 0xc0192e52 in ioctl (p=0xf8f6ad40, uap=0xf90d6f80) at /usr/src/sys/kern/sys_generic.c:637 #13 0xc02dde79 in syscall2 (frame={tf_fs = 0x2f, tf_es = 0x2f, tf_ds = 0x2f, tf_edi = 0x883f010, tf_esi = 0x7, tf_ebp = 0xbfbff580, tf_isp = 0xf90d6fd4, tf_ebx = 0x0, tf_edx = 0x8000000, tf_ecx = 0x0, tf_eax = 0x36, tf_trapno = 0xc, tf_err = 0x2, tf_eip = 0x4822568c, tf_cs = 0x1f, tf_eflags = 0x3293, tf_esp = 0xbfbff554, tf_ss = 0x2f}) at /usr/src/sys/i386/i386/trap.c:1175 And the request like: (kgdb) print *map $5 = { offset = 0xe0000000, size = 0x8000000, type = _DRM_FRAME_BUFFER, flags = 0, handle = 0x0, mtrr = 0x1, iot = 0x0, ioh = 0x0 } (kgdb) print request $6 = { offset = 0xe0000000, size = 0x8000000, type = _DRM_FRAME_BUFFER, flags = 0, handle = 0x0, mtrr = 0x7 } Looking at the code in question, it's clear that it's trying to allocate the virtual space for the frame buffer, described in the logfile: (--) RADEON(0): Chipset: "ATI Radeon 8500 QL (AGP)" (ChipID = 0x514c) (--) RADEON(0): Linear framebuffer at 0xe0000000 (--) RADEON(0): VideoRAM: 131072 kByte (128 bit DDR SDRAM) And the allocation is failing. It seems somewhat unfriendly to panic the kernel in this case, especially since the calling code in radeon_ioremap() knows how to handle a null return from pmap_mapdev() (it bumps a "fail" counter and returns NULL). It would also be really nice to know just why the allocation is failing, since this machine has 2GB in it. Do I need to increase the number of PTEs somehow? Just FYI, kernel_map looks like (kgdb) print *kernel_map $20 = { header = { prev = 0xe09d9ff0, next = 0xc03a2330, start = 0xbfeff000, end = 0xffbff000, avail_ssize = 0x0, object = { vm_object = 0x0, sub_map = 0x0 }, offset = 0x0, eflags = 0x0, protection = 0x0, max_protection = 0x0, inheritance = 0x0, wired_count = 0x0, lastr = 0x0 }, lock = { lk_interlock = { lock_data = 0x0 }, lk_flags = 0x1000000, lk_sharecount = 0x0, lk_waitcount = 0x0, lk_exclusivecount = 0x0, lk_prio = 0x4, lk_wmesg = 0xc0326554 "thrd_sleep", lk_timo = 0x0, lk_lockholder = 0xffffffff }, nentries = 0xc3, size = 0x391ab000, system_map = 0x1, infork = 0x0, hint = 0xe09da470, timestamp = 0x49a, first_free = 0xe09d9300, pmap = 0xc03b2720 } I'll have the dump lying around for a while, so if there's any more information you would like, let me know.