mirror of
https://github.com/torvalds/linux.git
synced 2024-11-02 18:21:49 +00:00
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 <chris@chris-wilson.co.uk> Cc: Dave Airlie <airlied@redhat.com>
This commit is contained in:
parent
6a04002bea
commit
73aa808f10
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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},
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user