drm/radeon/kms: implement bo busy check + current domain
Dave Airlie [Sun, 16 Aug 2009 11:05:45 +0000 (21:05 +1000)]
This implements the busy ioctl along with a current domain check.
returns 0 or -EBUSY
puts the current domain no matter what the answer.

Signed-off-by: Dave Airlie <airlied@redhat.com>

drivers/gpu/drm/radeon/radeon.h
drivers/gpu/drm/radeon/radeon_gem.c
drivers/gpu/drm/radeon/radeon_object.c
include/drm/radeon_drm.h

index 87170a5..79ad982 100644 (file)
@@ -242,6 +242,7 @@ int radeon_object_pin(struct radeon_object *robj, uint32_t domain,
                      uint64_t *gpu_addr);
 void radeon_object_unpin(struct radeon_object *robj);
 int radeon_object_wait(struct radeon_object *robj);
+int radeon_object_busy_domain(struct radeon_object *robj, uint32_t *cur_placement);
 int radeon_object_evict_vram(struct radeon_device *rdev);
 int radeon_object_mmap(struct radeon_object *robj, uint64_t *offset);
 void radeon_object_force_delete(struct radeon_device *rdev);
index cded518..d4ceff1 100644 (file)
@@ -262,7 +262,27 @@ int radeon_gem_mmap_ioctl(struct drm_device *dev, void *data,
 int radeon_gem_busy_ioctl(struct drm_device *dev, void *data,
                          struct drm_file *filp)
 {
-       /* FIXME: implement */
+       struct drm_radeon_gem_busy *args = data;
+       struct drm_gem_object *gobj;
+       struct radeon_object *robj;
+       int r;
+       uint32_t cur_placement;
+
+       gobj = drm_gem_object_lookup(dev, filp, args->handle);
+       if (gobj == NULL) {
+               return -EINVAL;
+       }
+       robj = gobj->driver_private;
+       r = radeon_object_busy_domain(robj, &cur_placement);
+       if (cur_placement == TTM_PL_VRAM)
+               args->domain = RADEON_GEM_DOMAIN_VRAM;
+       if (cur_placement == TTM_PL_FLAG_TT)
+               args->domain = RADEON_GEM_DOMAIN_GTT;
+       if (cur_placement == TTM_PL_FLAG_SYSTEM)
+               args->domain = RADEON_GEM_DOMAIN_CPU;
+       mutex_lock(&dev->struct_mutex);
+       drm_gem_object_unreference(gobj);
+       mutex_unlock(&dev->struct_mutex);
        return 0;
 }
 
index e98cae3..b85fb83 100644 (file)
@@ -316,6 +316,25 @@ int radeon_object_wait(struct radeon_object *robj)
        return r;
 }
 
+int radeon_object_busy_domain(struct radeon_object *robj, uint32_t *cur_placement)
+{
+       int r = 0;
+
+       r = radeon_object_reserve(robj, true);
+       if (unlikely(r != 0)) {
+               DRM_ERROR("radeon: failed to reserve object for waiting.\n");
+               return r;
+       }
+       spin_lock(&robj->tobj.lock);
+       *cur_placement = robj->tobj.mem.mem_type;
+       if (robj->tobj.sync_obj) {
+               r = ttm_bo_wait(&robj->tobj, true, true, true);
+       }
+       spin_unlock(&robj->tobj.lock);
+       radeon_object_unreserve(robj);
+       return r;
+}
+
 int radeon_object_evict_vram(struct radeon_device *rdev)
 {
        if (rdev->flags & RADEON_IS_IGP) {
index af4b482..f81c323 100644 (file)
@@ -838,7 +838,7 @@ struct drm_radeon_gem_wait_idle {
 
 struct drm_radeon_gem_busy {
        uint32_t        handle;
-       uint32_t        busy;
+       uint32_t        domain;
 };
 
 struct drm_radeon_gem_pread {