Commit 73aa808f authored by Chris Wilson's avatar Chris Wilson

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: default avatarChris Wilson <chris@chris-wilson.co.uk>
Cc: Dave Airlie <airlied@redhat.com>
parent 6a04002b
...@@ -48,7 +48,6 @@ static struct drm_info_list drm_debugfs_list[] = { ...@@ -48,7 +48,6 @@ static struct drm_info_list drm_debugfs_list[] = {
{"queues", drm_queues_info, 0}, {"queues", drm_queues_info, 0},
{"bufs", drm_bufs_info, 0}, {"bufs", drm_bufs_info, 0},
{"gem_names", drm_gem_name_info, DRIVER_GEM}, {"gem_names", drm_gem_name_info, DRIVER_GEM},
{"gem_objects", drm_gem_object_info, DRIVER_GEM},
#if DRM_DEBUG_CODE #if DRM_DEBUG_CODE
{"vma", drm_vma_info, 0}, {"vma", drm_vma_info, 0},
#endif #endif
......
...@@ -92,12 +92,6 @@ drm_gem_init(struct drm_device *dev) ...@@ -92,12 +92,6 @@ drm_gem_init(struct drm_device *dev)
spin_lock_init(&dev->object_name_lock); spin_lock_init(&dev->object_name_lock);
idr_init(&dev->object_name_idr); 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); mm = kzalloc(sizeof(struct drm_gem_mm), GFP_KERNEL);
if (!mm) { if (!mm) {
...@@ -151,9 +145,6 @@ int drm_gem_object_init(struct drm_device *dev, ...@@ -151,9 +145,6 @@ int drm_gem_object_init(struct drm_device *dev,
kref_init(&obj->handlecount); kref_init(&obj->handlecount);
obj->size = size; obj->size = size;
atomic_inc(&dev->object_count);
atomic_add(obj->size, &dev->object_memory);
return 0; return 0;
} }
EXPORT_SYMBOL(drm_gem_object_init); EXPORT_SYMBOL(drm_gem_object_init);
...@@ -180,8 +171,6 @@ drm_gem_object_alloc(struct drm_device *dev, size_t size) ...@@ -180,8 +171,6 @@ drm_gem_object_alloc(struct drm_device *dev, size_t size)
return obj; return obj;
fput: fput:
/* Object_init mangles the global counters - readjust them. */ /* Object_init mangles the global counters - readjust them. */
atomic_dec(&dev->object_count);
atomic_sub(obj->size, &dev->object_memory);
fput(obj->filp); fput(obj->filp);
free: free:
kfree(obj); kfree(obj);
...@@ -436,10 +425,7 @@ drm_gem_release(struct drm_device *dev, struct drm_file *file_private) ...@@ -436,10 +425,7 @@ drm_gem_release(struct drm_device *dev, struct drm_file *file_private)
void void
drm_gem_object_release(struct drm_gem_object *obj) drm_gem_object_release(struct drm_gem_object *obj)
{ {
struct drm_device *dev = obj->dev;
fput(obj->filp); fput(obj->filp);
atomic_dec(&dev->object_count);
atomic_sub(obj->size, &dev->object_memory);
} }
EXPORT_SYMBOL(drm_gem_object_release); EXPORT_SYMBOL(drm_gem_object_release);
......
...@@ -270,20 +270,6 @@ int drm_gem_name_info(struct seq_file *m, void *data) ...@@ -270,20 +270,6 @@ int drm_gem_name_info(struct seq_file *m, void *data)
return 0; 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 #if DRM_DEBUG_CODE
int drm_vma_info(struct seq_file *m, void *data) int drm_vma_info(struct seq_file *m, void *data)
......
...@@ -55,7 +55,6 @@ static struct drm_info_list drm_proc_list[] = { ...@@ -55,7 +55,6 @@ static struct drm_info_list drm_proc_list[] = {
{"queues", drm_queues_info, 0}, {"queues", drm_queues_info, 0},
{"bufs", drm_bufs_info, 0}, {"bufs", drm_bufs_info, 0},
{"gem_names", drm_gem_name_info, DRIVER_GEM}, {"gem_names", drm_gem_name_info, DRIVER_GEM},
{"gem_objects", drm_gem_object_info, DRIVER_GEM},
#if DRM_DEBUG_CODE #if DRM_DEBUG_CODE
{"vma", drm_vma_info, 0}, {"vma", drm_vma_info, 0},
#endif #endif
......
...@@ -188,6 +188,31 @@ static int i915_gem_object_list_info(struct seq_file *m, void *data) ...@@ -188,6 +188,31 @@ static int i915_gem_object_list_info(struct seq_file *m, void *data)
return 0; 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) static int i915_gem_pageflip_info(struct seq_file *m, void *data)
{ {
struct drm_info_node *node = (struct drm_info_node *) m->private; 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) ...@@ -994,6 +1019,7 @@ static int i915_wedged_create(struct dentry *root, struct drm_minor *minor)
static struct drm_info_list i915_debugfs_list[] = { static struct drm_info_list i915_debugfs_list[] = {
{"i915_capabilities", i915_capabilities, 0, 0}, {"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_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_bsd_active", i915_gem_object_list_info, 0, (void *) BSD_LIST},
{"i915_gem_flushing", i915_gem_object_list_info, 0, (void *) FLUSHING_LIST}, {"i915_gem_flushing", i915_gem_object_list_info, 0, (void *) FLUSHING_LIST},
......
...@@ -642,6 +642,15 @@ typedef struct drm_i915_private { ...@@ -642,6 +642,15 @@ typedef struct drm_i915_private {
struct drm_i915_gem_phys_object *phys_objs[I915_MAX_PHYS_OBJECT]; struct drm_i915_gem_phys_object *phys_objs[I915_MAX_PHYS_OBJECT];
uint32_t flush_rings; 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; } mm;
struct sdvo_device_mapping sdvo_mappings[2]; struct sdvo_device_mapping sdvo_mappings[2];
/* indicate whether the LVDS_BORDER should be enabled or not */ /* indicate whether the LVDS_BORDER should be enabled or not */
......
...@@ -68,6 +68,49 @@ i915_gem_object_put_pages(struct drm_gem_object *obj); ...@@ -68,6 +68,49 @@ i915_gem_object_put_pages(struct drm_gem_object *obj);
static LIST_HEAD(shrink_list); static LIST_HEAD(shrink_list);
static DEFINE_SPINLOCK(shrink_list_lock); 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 int
i915_gem_check_is_wedged(struct drm_device *dev) 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) ...@@ -128,7 +171,8 @@ i915_gem_object_is_inactive(struct drm_i915_gem_object *obj_priv)
obj_priv->pin_count == 0; 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) unsigned long end)
{ {
drm_i915_private_t *dev_priv = dev->dev_private; 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, ...@@ -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, drm_mm_init(&dev_priv->mm.gtt_space, start,
end - start); end - start);
dev->gtt_total = (uint32_t) (end - start); dev_priv->mm.gtt_total = end - start;
return 0; return 0;
} }
...@@ -165,14 +209,16 @@ int ...@@ -165,14 +209,16 @@ int
i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data, i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv) struct drm_file *file_priv)
{ {
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_i915_gem_get_aperture *args = data; struct drm_i915_gem_get_aperture *args = data;
if (!(dev->driver->driver_features & DRIVER_GEM)) if (!(dev->driver->driver_features & DRIVER_GEM))
return -ENODEV; return -ENODEV;
args->aper_size = dev->gtt_total; mutex_lock(&dev->struct_mutex);
args->aper_available_size = (args->aper_size - args->aper_size = dev_priv->mm.gtt_total;
atomic_read(&dev->pin_memory)); args->aper_available_size = args->aper_size - dev_priv->mm.pin_memory;
mutex_unlock(&dev->struct_mutex);
return 0; return 0;
} }
...@@ -2084,6 +2130,7 @@ int ...@@ -2084,6 +2130,7 @@ int
i915_gem_object_unbind(struct drm_gem_object *obj) i915_gem_object_unbind(struct drm_gem_object *obj)
{ {
struct drm_device *dev = obj->dev; 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); struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
int ret = 0; int ret = 0;
...@@ -2116,25 +2163,18 @@ i915_gem_object_unbind(struct drm_gem_object *obj) ...@@ -2116,25 +2163,18 @@ i915_gem_object_unbind(struct drm_gem_object *obj)
if (obj_priv->fence_reg != I915_FENCE_REG_NONE) if (obj_priv->fence_reg != I915_FENCE_REG_NONE)
i915_gem_clear_fence_reg(obj); i915_gem_clear_fence_reg(obj);
if (obj_priv->agp_mem != NULL) { drm_unbind_agp(obj_priv->agp_mem);
drm_unbind_agp(obj_priv->agp_mem); drm_free_agp(obj_priv->agp_mem, obj->size / PAGE_SIZE);
drm_free_agp(obj_priv->agp_mem, obj->size / PAGE_SIZE);
obj_priv->agp_mem = NULL;
}
i915_gem_object_put_pages(obj); i915_gem_object_put_pages(obj);
BUG_ON(obj_priv->pages_refcount); BUG_ON(obj_priv->pages_refcount);
if (obj_priv->gtt_space) { i915_gem_info_remove_gtt(dev_priv, obj->size);
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;
}
list_del_init(&obj_priv->list); 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)) if (i915_gem_object_is_purgeable(obj_priv))
i915_gem_object_truncate(obj); i915_gem_object_truncate(obj);
...@@ -2619,7 +2659,7 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment) ...@@ -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 /* If the object is bigger than the entire aperture, reject it early
* before evicting everything in a vain attempt to find space. * 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"); DRM_ERROR("Attempting to bind an object larger than the aperture\n");
return -E2BIG; return -E2BIG;
} }
...@@ -2688,11 +2728,10 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment) ...@@ -2688,11 +2728,10 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment)
goto search_free; 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 */ /* keep track of bounds object by adding it to the inactive list */
list_add_tail(&obj_priv->list, &dev_priv->mm.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 /* 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 * 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, ...@@ -3779,15 +3818,16 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
pinned+1, args->buffer_count, pinned+1, args->buffer_count,
total_size, num_fences, total_size, num_fences,
ret); ret);
DRM_ERROR("%d objects [%d pinned], " DRM_ERROR("%u objects [%u pinned, %u GTT], "
"%d object bytes [%d pinned], " "%zu object bytes [%zu pinned], "
"%d/%d gtt bytes\n", "%zu /%zu gtt bytes\n",
atomic_read(&dev->object_count), dev_priv->mm.object_count,
atomic_read(&dev->pin_count), dev_priv->mm.pin_count,
atomic_read(&dev->object_memory), dev_priv->mm.gtt_count,
atomic_read(&dev->pin_memory), dev_priv->mm.object_memory,
atomic_read(&dev->gtt_memory), dev_priv->mm.pin_memory,
dev->gtt_total); dev_priv->mm.gtt_memory,
dev_priv->mm.gtt_total);
} }
goto err; goto err;
} }
...@@ -4119,8 +4159,7 @@ i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment) ...@@ -4119,8 +4159,7 @@ i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment)
* remove it from the inactive list * remove it from the inactive list
*/ */
if (obj_priv->pin_count == 1) { if (obj_priv->pin_count == 1) {
atomic_inc(&dev->pin_count); i915_gem_info_add_pin(dev_priv, obj->size);
atomic_add(obj->size, &dev->pin_memory);
if (!obj_priv->active) if (!obj_priv->active)
list_move_tail(&obj_priv->list, list_move_tail(&obj_priv->list,
&dev_priv->mm.pinned_list); &dev_priv->mm.pinned_list);
...@@ -4150,8 +4189,7 @@ i915_gem_object_unpin(struct drm_gem_object *obj) ...@@ -4150,8 +4189,7 @@ i915_gem_object_unpin(struct drm_gem_object *obj)
if (!obj_priv->active) if (!obj_priv->active)
list_move_tail(&obj_priv->list, list_move_tail(&obj_priv->list,
&dev_priv->mm.inactive_list); &dev_priv->mm.inactive_list);
atomic_dec(&dev->pin_count); i915_gem_info_remove_pin(dev_priv, obj->size);
atomic_sub(obj->size, &dev->pin_memory);
} }
WARN_ON(i915_verify_lists(dev)); WARN_ON(i915_verify_lists(dev));
} }
...@@ -4378,6 +4416,7 @@ i915_gem_madvise_ioctl(struct drm_device *dev, void *data, ...@@ -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, struct drm_gem_object * i915_gem_alloc_object(struct drm_device *dev,
size_t size) size_t size)
{ {
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_i915_gem_object *obj; struct drm_i915_gem_object *obj;
obj = kzalloc(sizeof(*obj), GFP_KERNEL); obj = kzalloc(sizeof(*obj), GFP_KERNEL);
...@@ -4389,6 +4428,8 @@ struct drm_gem_object * i915_gem_alloc_object(struct drm_device *dev, ...@@ -4389,6 +4428,8 @@ struct drm_gem_object * i915_gem_alloc_object(struct drm_device *dev,
return NULL; return NULL;
} }
i915_gem_info_add_obj(dev_priv, size);
obj->base.write_domain = I915_GEM_DOMAIN_CPU; obj->base.write_domain = I915_GEM_DOMAIN_CPU;
obj->base.read_domains = 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) ...@@ -4429,6 +4470,7 @@ static void i915_gem_free_object_tail(struct drm_gem_object *obj)
i915_gem_free_mmap_offset(obj); i915_gem_free_mmap_offset(obj);
drm_gem_object_release(obj); drm_gem_object_release(obj);
i915_gem_info_remove_obj(dev_priv, obj->size);
kfree(obj_priv->page_cpu_valid); kfree(obj_priv->page_cpu_valid);
kfree(obj_priv->bit_17); kfree(obj_priv->bit_17);
......
...@@ -1041,13 +1041,6 @@ struct drm_device { ...@@ -1041,13 +1041,6 @@ struct drm_device {
/*@{ */ /*@{ */
spinlock_t object_name_lock; spinlock_t object_name_lock;
struct idr object_name_idr; 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 invalidate_domains; /* domains pending invalidation */
uint32_t flush_domains; /* domains pending flush */ uint32_t flush_domains; /* domains pending flush */
/*@} */ /*@} */
...@@ -1378,7 +1371,6 @@ extern int drm_bufs_info(struct seq_file *m, void *data); ...@@ -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_vblank_info(struct seq_file *m, void *data);
extern int drm_clients_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_name_info(struct seq_file *m, void *data);
extern int drm_gem_object_info(struct seq_file *m, void* data);
#if DRM_DEBUG_CODE #if DRM_DEBUG_CODE
extern int drm_vma_info(struct seq_file *m, void *data); extern int drm_vma_info(struct seq_file *m, void *data);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment