I run parsec with mode set to 1024x768 (see http://www.parsec.org) on Linux with the latest Mesa/I965_dri and Drm/i915, but I965_dri always gets “intelWaitIrq: drmI830IrqWait: -16”, then X crashes, and gets the following error:
Error in I830WaitLpRing(), now is 6864091, start is 6862090
pgetbl_ctl: 0x7ff80001 pgetbl_err: 0x0
ipeir: 0 iphdr: 0
LP ring tail: cc80 head: ec98 len: 1f001 start 0
eir: 0 esr: 1 emr: ffdf
instdone: 0 instpm: 0
memmode: 0 instps: 0
hwstam: cffe ier: 22 imr: 0 iir: 1080
space: 8208 wanted 131064
Fatal server error:
I looked into it and noticed that drm/i915 uses a magic number 10000 in the for_statement (see i915_wait_ring in i915_dma.c), and the driver doesn’t check the return value in macro BEGIN_LP_RING(in i915_drv.h). If i915_wait_ring returns error, BEGIN_LP_RING will destroy the entire ring buffer.
I guess 10000 are too small in the following case: There is a Batch Buffer command in the ring buffer, and the Batch Buffer(or Batch Buffer chaining) are enough long, and the CPU is enough fast. So I try 1000000 and it works well. Then I notice drm/i830 uses an OS-timer(see i830_wait_ring in i830_dma.c), and I use the same method in drm/i915 and It works well too.
So I think the current method in drm/i915 has some risk: It is hard to control the waiting time. EBUSY will happen however the ring buffer doesn’t stall. But I have not a good idea to fix this issue.
Could anyone give some comments?
Thank in advance