[Intel-gfx] [PATCH] drm/i915: Show number of objects without client
Mika Kuoppala
mika.kuoppala at linux.intel.com
Thu Apr 19 15:34:27 UTC 2018
Chris Wilson <chris at chris-wilson.co.uk> writes:
> Quoting Mika Kuoppala (2018-04-19 15:16:16)
>> Output the number of objects not tied to a client
>> or to a vma. This amount should be quite small and
>> on oom issues we can rule out significant bo leaks
>> quickly by inspecting these values. Note that we are not
>> fully accurate due to how we take and release the locks
>> during transversal of related lists.
>>
>> Cc: Chris Wilson <chris at chris-wilson.co.uk>
>> Cc: Eero Tamminen <eero.t.tamminen at intel.com>
>> Signed-off-by: Mika Kuoppala <mika.kuoppala at linux.intel.com>
>> ---
>> drivers/gpu/drm/i915/i915_debugfs.c | 24 +++++++++++++++++-------
>> 1 file changed, 17 insertions(+), 7 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
>> index e0274f41bc76..b1cbecfca716 100644
>> --- a/drivers/gpu/drm/i915/i915_debugfs.c
>> +++ b/drivers/gpu/drm/i915/i915_debugfs.c
>> @@ -354,8 +354,8 @@ static int per_file_stats(int id, void *ptr, void *data)
>> stats.unbound); \
>> } while (0)
>>
>> -static void print_batch_pool_stats(struct seq_file *m,
>> - struct drm_i915_private *dev_priv)
>> +static unsigned int print_batch_pool_stats(struct seq_file *m,
>> + struct drm_i915_private *dev_priv)
>> {
>> struct drm_i915_gem_object *obj;
>> struct file_stats stats;
>> @@ -375,6 +375,7 @@ static void print_batch_pool_stats(struct seq_file *m,
>> }
>>
>> print_file_stats(m, "[k]batch pool", stats);
>> + return stats.count;
>> }
>>
>> static int per_file_ctx_stats(int id, void *ptr, void *data)
>> @@ -392,8 +393,8 @@ static int per_file_ctx_stats(int id, void *ptr, void *data)
>> return 0;
>> }
>>
>> -static void print_context_stats(struct seq_file *m,
>> - struct drm_i915_private *dev_priv)
>> +static unsigned int print_context_stats(struct seq_file *m,
>> + struct drm_i915_private *dev_priv)
>> {
>> struct drm_device *dev = &dev_priv->drm;
>> struct file_stats stats;
>> @@ -412,6 +413,7 @@ static void print_context_stats(struct seq_file *m,
>> mutex_unlock(&dev->struct_mutex);
>>
>> print_file_stats(m, "[k]contexts", stats);
>> + return stats.count;
>> }
>>
>> static int i915_gem_object_info(struct seq_file *m, void *data)
>> @@ -422,7 +424,7 @@ static int i915_gem_object_info(struct seq_file *m, void *data)
>> u32 count, mapped_count, purgeable_count, dpy_count, huge_count;
>> u64 size, mapped_size, purgeable_size, dpy_size, huge_size;
>> struct drm_i915_gem_object *obj;
>> - unsigned int page_sizes = 0;
>> + unsigned int page_sizes = 0, client_count = 0, vma_count = 0;
>> struct drm_file *file;
>> char buf[80];
>> int ret;
>> @@ -462,6 +464,7 @@ static int i915_gem_object_info(struct seq_file *m, void *data)
>> }
>> }
>> seq_printf(m, "%u unbound objects, %llu bytes\n", count, size);
>> + vma_count += count;
>>
>> size = count = dpy_size = dpy_count = 0;
>> list_for_each_entry(obj, &dev_priv->mm.bound_list, mm.link) {
>> @@ -490,6 +493,7 @@ static int i915_gem_object_info(struct seq_file *m, void *data)
>> }
>> }
>> spin_unlock(&dev_priv->mm.obj_lock);
>> + vma_count += count;
>>
>> seq_printf(m, "%u bound objects, %llu bytes\n",
>> count, size);
>> @@ -511,11 +515,11 @@ static int i915_gem_object_info(struct seq_file *m, void *data)
>> buf, sizeof(buf)));
>>
>> seq_putc(m, '\n');
>> - print_batch_pool_stats(m, dev_priv);
>> + client_count += print_batch_pool_stats(m, dev_priv);
>> mutex_unlock(&dev->struct_mutex);
>>
>> mutex_lock(&dev->filelist_mutex);
>> - print_context_stats(m, dev_priv);
>> + client_count += print_context_stats(m, dev_priv);
>> list_for_each_entry_reverse(file, &dev->filelist, lhead) {
>> struct file_stats stats;
>> struct drm_i915_file_private *file_priv = file->driver_priv;
>> @@ -543,12 +547,18 @@ static int i915_gem_object_info(struct seq_file *m, void *data)
>> request->ctx->pid : file->pid,
>> PIDTYPE_PID);
>> print_file_stats(m, task ? task->comm : "<unknown>", stats);
>> + client_count += stats.count;
>> rcu_read_unlock();
>>
>> mutex_unlock(&dev->struct_mutex);
>> }
>> mutex_unlock(&dev->filelist_mutex);
>>
>> + seq_printf(m, "\n%d objects without vma\n",
>> + dev_priv->mm.object_count - vma_count);
>
> What does "without vma" mean? Instantiated but never used on the gpu, a
> very small subset of unbound. I'm not sure if it has value and worry
> that "without vma" is unclear internal language.
>
Noticed that after reboot on a system we had 3 objects
without usage. Thought it could add some value as a noticing
leaks.
> "%d unused objects (without any attached vma)" I think works better.
Or just "unused objects" ?
>
>> + seq_printf(m, "%d objects without client\n",
>> + dev_priv->mm.object_count - client_count);
>
> What does "without client" mean? What are you going to do when it is
> negative (as computed it can legitimately be negative).
"objects without handle" better? or "unassociated objects" ?
Negative would be wrong, so the tracking of batchbool/context
must be wrong in here then.
-Mika
More information about the Intel-gfx
mailing list