Alex Deucher pointed out an error on IRC; I'm not using radeon_irq_kms_sw_irq_get and put to manage the IRQ enablement.
I've fixed this up (as per the partial hunk below), and my bug goes away. I will be cleaning these patches up for proper submission.
Simon
On Tuesday 31 January 2012, Simon Farnsworth simon.farnsworth@onelan.co.uk wrote: <snip>
+int radeon_gem_wait_user_fence_ioctl(struct drm_device *dev, void *data,
struct drm_file *filp)
+{
- struct drm_radeon_gem_wait_user_fence *args = data;
- struct radeon_device *rdev = dev->dev_private;
- struct drm_gem_object *gobj;
- struct radeon_bo *robj;
- void *buffer_data;
- uint32_t *fence_data;
- int r = 0;
- long timeout;
- printk( KERN_INFO "wait_user_fence offset %lld value %d timeout %lld\n", args->offset, args->value, args->timeout_usec );
- gobj = drm_gem_object_lookup(dev, filp, args->handle);
- if (gobj == NULL) {
return -ENOENT;
- }
- robj = gem_to_radeon_bo(gobj);
- if (gobj->size < args->offset) {
printk( KERN_INFO "Offset too large\n" );
r = -EINVAL;
goto unreference;
- }
- r = radeon_bo_reserve(robj, true);
- if (r) {
printk( KERN_INFO "Reserve fail\n" );
goto unreference;
- }
- r = radeon_bo_pin(robj, RADEON_GEM_DOMAIN_GTT, NULL);
- if (r) {
printk( KERN_INFO "Pin fail\n" );
goto unreserve;
- }
- r = radeon_bo_kmap(robj, &buffer_data);
- if (r) {
printk( KERN_INFO "kmap fail\n" );
goto unpin;
- }
Missing radeon_irq_kms_sw_irq_get(rdev, RADEON_RING_TYPE_GFX_INDEX); here
- fence_data = (uint32_t*)buffer_data;
- printk( KERN_INFO "Current data value %d\n", fence_data[args->offset >> 2] );
- timeout = wait_event_interruptible_timeout(rdev->userspace_fence_wait_queue,
fence_data[args->offset >> 2] != args->value,
usecs_to_jiffies(args->timeout_usec));
And missing radeon_irq_kms_sw_irq_put(rdev, RADEON_RING_TYPE_GFX_INDEX); here.
- if (timeout == 0)
r = -ETIMEDOUT;
- else if (timeout < 0)
r = timeout;
- printk( KERN_INFO "wait_user_fence offset %lld value %d timeout %lld\n", args->offset, args->value, args->timeout_usec );
- printk( KERN_INFO "Finished data value %d\n", fence_data[args->offset >> 2] );
- radeon_bo_kunmap(robj);
+unpin:
- radeon_bo_unpin(robj);
+unreserve:
- radeon_bo_unreserve(robj);
+unreference:
- drm_gem_object_unreference_unlocked(gobj);
- return r;
+}