From 73aa808f10effc280e6eb70267314542a7c29426 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 30 Sep 2010 11:46:12 +0100 Subject: [PATCH] drm: Move the GTT accounting to i915 Only drm/i915 does the bookkeeping that makes the information useful, and the information maintained is driver specific, so move it out of the core and into its single user. Signed-off-by: Chris Wilson Cc: Dave Airlie --- drivers/gpu/drm/drm_debugfs.c | 1 - drivers/gpu/drm/drm_gem.c | 14 ---- drivers/gpu/drm/drm_info.c | 14 ---- drivers/gpu/drm/drm_proc.c | 1 - drivers/gpu/drm/i915/i915_debugfs.c | 26 +++++++ drivers/gpu/drm/i915/i915_drv.h | 9 +++ drivers/gpu/drm/i915/i915_gem.c | 110 +++++++++++++++++++--------- include/drm/drmP.h | 8 -- 8 files changed, 111 insertions(+), 72 deletions(-) diff --git a/drivers/gpu/drm/drm_debugfs.c b/drivers/gpu/drm/drm_debugfs.c index 677b275fa721..9d8c892d07c9 100644 --- a/drivers/gpu/drm/drm_debugfs.c +++ b/drivers/gpu/drm/drm_debugfs.c @@ -48,7 +48,6 @@ static struct drm_info_list drm_debugfs_list[] = { {"queues", drm_queues_info, 0}, {"bufs", drm_bufs_info, 0}, {"gem_names", drm_gem_name_info, DRIVER_GEM}, - {"gem_objects", drm_gem_object_info, DRIVER_GEM}, #if DRM_DEBUG_CODE {"vma", drm_vma_info, 0}, #endif diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c index cff7317d3830..3ea0692ce59a 100644 --- a/drivers/gpu/drm/drm_gem.c +++ b/drivers/gpu/drm/drm_gem.c @@ -92,12 +92,6 @@ drm_gem_init(struct drm_device *dev) spin_lock_init(&dev->object_name_lock); idr_init(&dev->object_name_idr); - atomic_set(&dev->object_count, 0); - atomic_set(&dev->object_memory, 0); - atomic_set(&dev->pin_count, 0); - atomic_set(&dev->pin_memory, 0); - atomic_set(&dev->gtt_count, 0); - atomic_set(&dev->gtt_memory, 0); mm = kzalloc(sizeof(struct drm_gem_mm), GFP_KERNEL); if (!mm) { @@ -151,9 +145,6 @@ int drm_gem_object_init(struct drm_device *dev, kref_init(&obj->handlecount); obj->size = size; - atomic_inc(&dev->object_count); - atomic_add(obj->size, &dev->object_memory); - return 0; } EXPORT_SYMBOL(drm_gem_object_init); @@ -180,8 +171,6 @@ drm_gem_object_alloc(struct drm_device *dev, size_t size) return obj; fput: /* Object_init mangles the global counters - readjust them. */ - atomic_dec(&dev->object_count); - atomic_sub(obj->size, &dev->object_memory); fput(obj->filp); free: kfree(obj); @@ -436,10 +425,7 @@ drm_gem_release(struct drm_device *dev, struct drm_file *file_private) void drm_gem_object_release(struct drm_gem_object *obj) { - struct drm_device *dev = obj->dev; fput(obj->filp); - atomic_dec(&dev->object_count); - atomic_sub(obj->size, &dev->object_memory); } EXPORT_SYMBOL(drm_gem_object_release); diff --git a/drivers/gpu/drm/drm_info.c b/drivers/gpu/drm/drm_info.c index 2ef2c7827243..5aff08e236cf 100644 --- a/drivers/gpu/drm/drm_info.c +++ b/drivers/gpu/drm/drm_info.c @@ -270,20 +270,6 @@ int drm_gem_name_info(struct seq_file *m, void *data) return 0; } -int drm_gem_object_info(struct seq_file *m, void* data) -{ - struct drm_info_node *node = (struct drm_info_node *) m->private; - struct drm_device *dev = node->minor->dev; - - seq_printf(m, "%d objects\n", atomic_read(&dev->object_count)); - seq_printf(m, "%d object bytes\n", atomic_read(&dev->object_memory)); - seq_printf(m, "%d pinned\n", atomic_read(&dev->pin_count)); - seq_printf(m, "%d pin bytes\n", atomic_read(&dev->pin_memory)); - seq_printf(m, "%d gtt bytes\n", atomic_read(&dev->gtt_memory)); - seq_printf(m, "%d gtt total\n", dev->gtt_total); - return 0; -} - #if DRM_DEBUG_CODE int drm_vma_info(struct seq_file *m, void *data) diff --git a/drivers/gpu/drm/drm_proc.c b/drivers/gpu/drm/drm_proc.c index e571de536dc5..9e5b07efebb7 100644 --- a/drivers/gpu/drm/drm_proc.c +++ b/drivers/gpu/drm/drm_proc.c @@ -55,7 +55,6 @@ static struct drm_info_list drm_proc_list[] = { {"queues", drm_queues_info, 0}, {"bufs", drm_bufs_info, 0}, {"gem_names", drm_gem_name_info, DRIVER_GEM}, - {"gem_objects", drm_gem_object_info, DRIVER_GEM}, #if DRM_DEBUG_CODE {"vma", drm_vma_info, 0}, #endif diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 0d9bbd595ff8..d598070fb279 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -188,6 +188,31 @@ static int i915_gem_object_list_info(struct seq_file *m, void *data) return 0; } +static int i915_gem_object_info(struct seq_file *m, void* data) +{ + struct drm_info_node *node = (struct drm_info_node *) m->private; + struct drm_device *dev = node->minor->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + int ret; + + ret = mutex_lock_interruptible(&dev->struct_mutex); + if (ret) + return ret; + + seq_printf(m, "%u objects\n", dev_priv->mm.object_count); + seq_printf(m, "%zu object bytes\n", dev_priv->mm.object_memory); + seq_printf(m, "%u pinned\n", dev_priv->mm.pin_count); + seq_printf(m, "%zu pin bytes\n", dev_priv->mm.pin_memory); + seq_printf(m, "%u objects in gtt\n", dev_priv->mm.gtt_count); + seq_printf(m, "%zu gtt bytes\n", dev_priv->mm.gtt_memory); + seq_printf(m, "%zu gtt total\n", dev_priv->mm.gtt_total); + + mutex_unlock(&dev->struct_mutex); + + return 0; +} + + static int i915_gem_pageflip_info(struct seq_file *m, void *data) { struct drm_info_node *node = (struct drm_info_node *) m->private; @@ -994,6 +1019,7 @@ static int i915_wedged_create(struct dentry *root, struct drm_minor *minor) static struct drm_info_list i915_debugfs_list[] = { {"i915_capabilities", i915_capabilities, 0, 0}, + {"i915_gem_objects", i915_gem_object_info, 0}, {"i915_gem_render_active", i915_gem_object_list_info, 0, (void *) RENDER_LIST}, {"i915_gem_bsd_active", i915_gem_object_list_info, 0, (void *) BSD_LIST}, {"i915_gem_flushing", i915_gem_object_list_info, 0, (void *) FLUSHING_LIST}, diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 66acc7c3bb03..7cfbc0fbd952 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -642,6 +642,15 @@ typedef struct drm_i915_private { struct drm_i915_gem_phys_object *phys_objs[I915_MAX_PHYS_OBJECT]; uint32_t flush_rings; + + /* accounting, useful for userland debugging */ + size_t object_memory; + size_t pin_memory; + size_t gtt_memory; + size_t gtt_total; + u32 object_count; + u32 pin_count; + u32 gtt_count; } mm; struct sdvo_device_mapping sdvo_mappings[2]; /* indicate whether the LVDS_BORDER should be enabled or not */ diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 302beee03197..16c4b7b9602c 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -68,6 +68,49 @@ i915_gem_object_put_pages(struct drm_gem_object *obj); static LIST_HEAD(shrink_list); static DEFINE_SPINLOCK(shrink_list_lock); +/* some bookkeeping */ +static void i915_gem_info_add_obj(struct drm_i915_private *dev_priv, + size_t size) +{ + dev_priv->mm.object_count++; + dev_priv->mm.object_memory += size; +} + +static void i915_gem_info_remove_obj(struct drm_i915_private *dev_priv, + size_t size) +{ + dev_priv->mm.object_count--; + dev_priv->mm.object_memory -= size; +} + +static void i915_gem_info_add_gtt(struct drm_i915_private *dev_priv, + size_t size) +{ + dev_priv->mm.gtt_count++; + dev_priv->mm.gtt_memory += size; +} + +static void i915_gem_info_remove_gtt(struct drm_i915_private *dev_priv, + size_t size) +{ + dev_priv->mm.gtt_count--; + dev_priv->mm.gtt_memory -= size; +} + +static void i915_gem_info_add_pin(struct drm_i915_private *dev_priv, + size_t size) +{ + dev_priv->mm.pin_count++; + dev_priv->mm.pin_memory += size; +} + +static void i915_gem_info_remove_pin(struct drm_i915_private *dev_priv, + size_t size) +{ + dev_priv->mm.pin_count--; + dev_priv->mm.pin_memory -= size; +} + int i915_gem_check_is_wedged(struct drm_device *dev) { @@ -128,7 +171,8 @@ i915_gem_object_is_inactive(struct drm_i915_gem_object *obj_priv) obj_priv->pin_count == 0; } -int i915_gem_do_init(struct drm_device *dev, unsigned long start, +int i915_gem_do_init(struct drm_device *dev, + unsigned long start, unsigned long end) { drm_i915_private_t *dev_priv = dev->dev_private; @@ -142,7 +186,7 @@ int i915_gem_do_init(struct drm_device *dev, unsigned long start, drm_mm_init(&dev_priv->mm.gtt_space, start, end - start); - dev->gtt_total = (uint32_t) (end - start); + dev_priv->mm.gtt_total = end - start; return 0; } @@ -165,14 +209,16 @@ int i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) { + struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_gem_get_aperture *args = data; if (!(dev->driver->driver_features & DRIVER_GEM)) return -ENODEV; - args->aper_size = dev->gtt_total; - args->aper_available_size = (args->aper_size - - atomic_read(&dev->pin_memory)); + mutex_lock(&dev->struct_mutex); + args->aper_size = dev_priv->mm.gtt_total; + args->aper_available_size = args->aper_size - dev_priv->mm.pin_memory; + mutex_unlock(&dev->struct_mutex); return 0; } @@ -2084,6 +2130,7 @@ int i915_gem_object_unbind(struct drm_gem_object *obj) { struct drm_device *dev = obj->dev; + struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); int ret = 0; @@ -2116,25 +2163,18 @@ i915_gem_object_unbind(struct drm_gem_object *obj) if (obj_priv->fence_reg != I915_FENCE_REG_NONE) i915_gem_clear_fence_reg(obj); - if (obj_priv->agp_mem != NULL) { - drm_unbind_agp(obj_priv->agp_mem); - drm_free_agp(obj_priv->agp_mem, obj->size / PAGE_SIZE); - obj_priv->agp_mem = NULL; - } + drm_unbind_agp(obj_priv->agp_mem); + drm_free_agp(obj_priv->agp_mem, obj->size / PAGE_SIZE); i915_gem_object_put_pages(obj); BUG_ON(obj_priv->pages_refcount); - if (obj_priv->gtt_space) { - atomic_dec(&dev->gtt_count); - atomic_sub(obj->size, &dev->gtt_memory); - - drm_mm_put_block(obj_priv->gtt_space); - obj_priv->gtt_space = NULL; - } - + i915_gem_info_remove_gtt(dev_priv, obj->size); list_del_init(&obj_priv->list); + drm_mm_put_block(obj_priv->gtt_space); + obj_priv->gtt_space = NULL; + if (i915_gem_object_is_purgeable(obj_priv)) i915_gem_object_truncate(obj); @@ -2619,7 +2659,7 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment) /* If the object is bigger than the entire aperture, reject it early * before evicting everything in a vain attempt to find space. */ - if (obj->size > dev->gtt_total) { + if (obj->size > dev_priv->mm.gtt_total) { DRM_ERROR("Attempting to bind an object larger than the aperture\n"); return -E2BIG; } @@ -2688,11 +2728,10 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment) goto search_free; } - atomic_inc(&dev->gtt_count); - atomic_add(obj->size, &dev->gtt_memory); /* keep track of bounds object by adding it to the inactive list */ list_add_tail(&obj_priv->list, &dev_priv->mm.inactive_list); + i915_gem_info_add_gtt(dev_priv, obj->size); /* Assert that the object is not currently in any GPU domain. As it * wasn't in the GTT, there shouldn't be any way it could have been in @@ -3779,15 +3818,16 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, pinned+1, args->buffer_count, total_size, num_fences, ret); - DRM_ERROR("%d objects [%d pinned], " - "%d object bytes [%d pinned], " - "%d/%d gtt bytes\n", - atomic_read(&dev->object_count), - atomic_read(&dev->pin_count), - atomic_read(&dev->object_memory), - atomic_read(&dev->pin_memory), - atomic_read(&dev->gtt_memory), - dev->gtt_total); + DRM_ERROR("%u objects [%u pinned, %u GTT], " + "%zu object bytes [%zu pinned], " + "%zu /%zu gtt bytes\n", + dev_priv->mm.object_count, + dev_priv->mm.pin_count, + dev_priv->mm.gtt_count, + dev_priv->mm.object_memory, + dev_priv->mm.pin_memory, + dev_priv->mm.gtt_memory, + dev_priv->mm.gtt_total); } goto err; } @@ -4119,8 +4159,7 @@ i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment) * remove it from the inactive list */ if (obj_priv->pin_count == 1) { - atomic_inc(&dev->pin_count); - atomic_add(obj->size, &dev->pin_memory); + i915_gem_info_add_pin(dev_priv, obj->size); if (!obj_priv->active) list_move_tail(&obj_priv->list, &dev_priv->mm.pinned_list); @@ -4150,8 +4189,7 @@ i915_gem_object_unpin(struct drm_gem_object *obj) if (!obj_priv->active) list_move_tail(&obj_priv->list, &dev_priv->mm.inactive_list); - atomic_dec(&dev->pin_count); - atomic_sub(obj->size, &dev->pin_memory); + i915_gem_info_remove_pin(dev_priv, obj->size); } WARN_ON(i915_verify_lists(dev)); } @@ -4378,6 +4416,7 @@ i915_gem_madvise_ioctl(struct drm_device *dev, void *data, struct drm_gem_object * i915_gem_alloc_object(struct drm_device *dev, size_t size) { + struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_gem_object *obj; obj = kzalloc(sizeof(*obj), GFP_KERNEL); @@ -4389,6 +4428,8 @@ struct drm_gem_object * i915_gem_alloc_object(struct drm_device *dev, return NULL; } + i915_gem_info_add_obj(dev_priv, size); + obj->base.write_domain = I915_GEM_DOMAIN_CPU; obj->base.read_domains = I915_GEM_DOMAIN_CPU; @@ -4429,6 +4470,7 @@ static void i915_gem_free_object_tail(struct drm_gem_object *obj) i915_gem_free_mmap_offset(obj); drm_gem_object_release(obj); + i915_gem_info_remove_obj(dev_priv, obj->size); kfree(obj_priv->page_cpu_valid); kfree(obj_priv->bit_17); diff --git a/include/drm/drmP.h b/include/drm/drmP.h index 30e827aeba02..bb5c41893c00 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -1041,13 +1041,6 @@ struct drm_device { /*@{ */ spinlock_t object_name_lock; struct idr object_name_idr; - atomic_t object_count; - atomic_t object_memory; - atomic_t pin_count; - atomic_t pin_memory; - atomic_t gtt_count; - atomic_t gtt_memory; - uint32_t gtt_total; uint32_t invalidate_domains; /* domains pending invalidation */ uint32_t flush_domains; /* domains pending flush */ /*@} */ @@ -1378,7 +1371,6 @@ extern int drm_bufs_info(struct seq_file *m, void *data); extern int drm_vblank_info(struct seq_file *m, void *data); extern int drm_clients_info(struct seq_file *m, void* data); extern int drm_gem_name_info(struct seq_file *m, void *data); -extern int drm_gem_object_info(struct seq_file *m, void* data); #if DRM_DEBUG_CODE extern int drm_vma_info(struct seq_file *m, void *data); -- GitLab