It's been happening every two days lately, so I've decided to look
through the code, and the bug became obvious (though I don't know the
proper solution).

The first stack trace shows a warning:

WARNING: at /build/buildd/linux-3.5.0/drivers/gpu/drm/i915/i915_gem.c:3052 
i915_gem_object_pin+0x15d/0x1b0 [i915]()
[...]
 Call Trace:
  [<ffffffff81051c1f>] warn_slowpath_common+0x7f/0xc0
  [<ffffffff81051c7a>] warn_slowpath_null+0x1a/0x20
  [<ffffffffa00a094d>] i915_gem_object_pin+0x15d/0x1b0 [i915]
  [<ffffffffa00a0a28>] i915_gem_object_pin_to_display_plane+0x88/0x100 [i915]
  [<ffffffffa00b14c6>] intel_pin_and_fence_fb_obj+0x56/0x120 [i915]
  [<ffffffffa00b17b3>] intel_gen6_queue_flip+0x43/0x160 [i915]
  [<ffffffffa00b58a8>] ? intel_crtc_page_flip+0x58/0x330 [i915]
  [<ffffffffa00b58a8>] ? intel_crtc_page_flip+0x58/0x330 [i915]
  [<ffffffffa00b59c1>] intel_crtc_page_flip+0x171/0x330 [i915]
  [<ffffffffa002e559>] drm_mode_page_flip_ioctl+0x229/0x2b0 [drm]
  [<ffffffffa0028c56>] ? drm_mode_object_find+0x66/0x90 [drm]
  [<ffffffffa0028b21>] ? drm_crtc_convert_to_umode+0xd1/0x150 [drm]
  [<ffffffffa001b6d3>] drm_ioctl+0x4d3/0x580 [drm]
  [<ffffffffa002e330>] ? drm_mode_gamma_get_ioctl+0x120/0x120 [drm]
  [<ffffffff81193d59>] do_vfs_ioctl+0x99/0x590
  [<ffffffff811942e9>] sys_ioctl+0x99/0xa0
  [<ffffffff8168bd29>] system_call_fastpath+0x16/0x1b

In the i915_gem_object_pin function, we see:

        if (WARN_ON(obj->pin_count == DRM_I915_GEM_OBJECT_MAX_PIN_COUNT))
                return -EBUSY;

So, the pin_count did not get incremented because it has reached the
maximum.

If we go up a few stack frames, to intel_crtc_page_flip, we'll see:

        crtc->fb = fb;

        [...]

        ret = dev_priv->display.queue_flip(dev, crtc, fb, obj);
        if (ret)
                goto cleanup_pending;

So crtc->fb got set, but the page flip failed.

Now, let's look at the second stack trace, with the actual bug:

kernel BUG at /build/buildd/linux-3.5.0/drivers/gpu/drm/i915/i915_gem.c:3090!
[...]
Call Trace:
 [<ffffffffa00b15cc>] intel_unpin_fb_obj+0x3c/0x40 [i915]
 [<ffffffffa00b4a6c>] intel_crtc_disable+0x8c/0xb0 [i915]
 [<ffffffffa007a855>] drm_helper_disable_unused_functions+0x115/0x170 
[drm_kms_helper]
 [<ffffffffa007c182>] drm_crtc_helper_set_config+0x952/0xb10 [drm_kms_helper]
 [<ffffffff81124726>] ? __generic_file_aio_write+0x236/0x440
 [<ffffffff8132e5be>] ? radix_tree_lookup_slot+0xe/0x10
 [<ffffffffa002987e>] drm_framebuffer_cleanup+0xfe/0x180 [drm]
 [<ffffffffa00aeee1>] intel_user_framebuffer_destroy+0x21/0x80 [i915]
 [<ffffffffa002d2c3>] drm_mode_rmfb+0x103/0x110 [drm]
 [<ffffffffa001b6d3>] drm_ioctl+0x4d3/0x580 [drm]
 [<ffffffffa002d1c0>] ? drm_mode_addfb2+0x6c0/0x6c0 [drm]
 [<ffffffff81181b16>] ? do_sync_write+0xe6/0x120
 [<ffffffff811c0bbb>] ? fsnotify+0x24b/0x340
 [<ffffffff81193d59>] do_vfs_ioctl+0x99/0x590
 [<ffffffff811942e9>] sys_ioctl+0x99/0xa0
 [<ffffffff8168bd29>] system_call_fastpath+0x16/0x1b

In intel_crtc_disable, we see:

        if (crtc->fb) {
                mutex_lock(&dev->struct_mutex);
                intel_unpin_fb_obj(to_intel_framebuffer(crtc->fb)->obj);
                mutex_unlock(&dev->struct_mutex);
        }

The condition is true, since crtc->fb got set earlier. So it calls
intel_unpin_fb_obj, even though pin_count never got incremented! It will
eventually reach 0 and cause the bug in i915_gem_object_unpin:

        BUG_ON(obj->pin_count == 0);

Hope this is useful...

-- 
You received this bug notification because you are a member of Ubuntu
Bugs, which is subscribed to Ubuntu.
https://bugs.launchpad.net/bugs/1100138

Title:
  Screen turned off and Xorg froze due to an intel video driver bug

To manage notifications about this bug go to:
https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1100138/+subscriptions

-- 
ubuntu-bugs mailing list
ubuntu-bugs@lists.ubuntu.com
https://lists.ubuntu.com/mailman/listinfo/ubuntu-bugs

Reply via email to