public inbox for intel-gfx@lists.freedesktop.org
 help / color / mirror / Atom feed
From: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com>
To: Chris Wilson <chris@chris-wilson.co.uk>,
	Tvrtko Ursulin <tursulin@ursulin.net>,
	Intel-gfx@lists.freedesktop.org
Subject: Re: [RFC 2/5] drm/i915: Expose list of clients in sysfs
Date: Thu, 15 Feb 2018 09:35:44 +0000	[thread overview]
Message-ID: <783628d0-9b2f-c7b1-5cba-0bec8cb3dd17@linux.intel.com> (raw)
In-Reply-To: <151863562773.31524.12827255988009592114@mail.alporthouse.com>


On 14/02/2018 19:13, Chris Wilson wrote:
> Quoting Tvrtko Ursulin (2018-02-14 18:50:32)
>> From: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
>>
>> Expose a list of clients with open file handles in sysfs.
>>
>> This will be a basis for a top-like utility showing per-client and per-
>> engine GPU load.
>>
>> Currently we only expose each client's pid and name under opaque numbered
>> directories in /sys/class/drm/card0/clients/.
>>
>> For instance:
>>
>> /sys/class/drm/card0/clients/3/name: Xorg
>> /sys/class/drm/card0/clients/3/pid: 5664
>>
>> Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
>> ---
>>   drivers/gpu/drm/i915/i915_drv.h   |  13 +++++
>>   drivers/gpu/drm/i915/i915_gem.c   | 112 +++++++++++++++++++++++++++++++++++---
>>   drivers/gpu/drm/i915/i915_sysfs.c |   8 +++
>>   3 files changed, 126 insertions(+), 7 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
>> index 70cf289855af..2133e67f5fbc 100644
>> --- a/drivers/gpu/drm/i915/i915_drv.h
>> +++ b/drivers/gpu/drm/i915/i915_drv.h
>> @@ -345,6 +345,16 @@ struct drm_i915_file_private {
>>    */
>>   #define I915_MAX_CLIENT_CONTEXT_BANS 3
>>          atomic_t context_bans;
>> +
> 
> struct {
> 
>> +       unsigned int client_sysfs_id;
>> +       unsigned int client_pid;
>> +       char *client_name;
>> +       struct kobject *client_root;
> 
> } client;

client_sysfs?

>> +
>> +       struct {
>> +               struct device_attribute pid;
>> +               struct device_attribute name;
>> +       } attr;
> 
> sysfs_attr?

Ok.

>>   };
>>   
>>   /* Interface history:
>> @@ -2365,6 +2375,9 @@ struct drm_i915_private {
>>   
>>          struct i915_pmu pmu;
>>   
>> +       struct kobject *clients_root;
>> +       atomic_t client_serial;
> 
> I'd start a new substruct { } clients;

Ok.

>>          /*
>>           * NOTE: This is the dri1/ums dungeon, don't add stuff here. Your patch
>>           * will be rejected. Instead look for a better place.
>> diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
>> index fc68b35854df..24607bce2efe 100644
>> --- a/drivers/gpu/drm/i915/i915_gem.c
>> +++ b/drivers/gpu/drm/i915/i915_gem.c
>> @@ -5613,6 +5613,89 @@ int i915_gem_freeze_late(struct drm_i915_private *dev_priv)
>>          return 0;
>>   }
>>   
>> +static ssize_t
>> +show_client_name(struct device *kdev, struct device_attribute *attr, char *buf)
>> +{
>> +       struct drm_i915_file_private *file_priv =
>> +               container_of(attr, struct drm_i915_file_private, attr.name);
>> +
>> +       return snprintf(buf, PAGE_SIZE, "%s", file_priv->client_name);
>> +}
>> +
>> +static ssize_t
>> +show_client_pid(struct device *kdev, struct device_attribute *attr, char *buf)
>> +{
>> +       struct drm_i915_file_private *file_priv =
>> +               container_of(attr, struct drm_i915_file_private, attr.pid);
>> +
>> +       return snprintf(buf, PAGE_SIZE, "%u", file_priv->client_pid);
>> +}
>> +
>> +static int
>> +i915_gem_add_client(struct drm_i915_private *i915,
>> +               struct drm_i915_file_private *file_priv,
>> +               struct task_struct *task,
>> +               unsigned int serial)
>> +{
>> +       int ret = -ENOMEM;
>> +       struct device_attribute *attr;
>> +       char id[32];
>> +
>> +       file_priv->client_name = kstrdup(task->comm, GFP_KERNEL);
>> +       if (!file_priv->client_name)
>> +               goto err_name;
>> +
>> +       snprintf(id, sizeof(id), "%u", serial);
>> +       file_priv->client_root = kobject_create_and_add(id,
>> +                                                       i915->clients_root);
> 
> Do we have to care about i915->clients_root being NULL here?

Yep, due our lax handling of sysfs registration failures. :/

>> +       if (!file_priv->client_root)
>> +               goto err_client;
>> +
>> +       attr = &file_priv->attr.name;
>> +       attr->attr.name = "name";
>> +       attr->attr.mode = 0444;
>> +       attr->show = show_client_name;
>> +
>> +       ret = sysfs_create_file(file_priv->client_root,
>> +                               (struct attribute *)attr);
>> +       if (ret)
>> +               goto err_attr_name;
>> +
>> +       attr = &file_priv->attr.pid;
>> +       attr->attr.name = "pid";
>> +       attr->attr.mode = 0444;
>> +       attr->show = show_client_pid;
>> +
>> +       ret = sysfs_create_file(file_priv->client_root,
>> +                               (struct attribute *)attr);
>> +       if (ret)
>> +               goto err_attr_pid;
>> +
>> +       file_priv->client_pid = pid_nr(get_task_pid(task, PIDTYPE_PID));
> 
> Are we before or after the "create_context get new pid"? Just wondering
> aloud how that's going to tie in.

Before, create_context then updates it in a following patch. Which 
probably needs improving to avoid remove and re-add, and add a proper 
update helper.

> 
>> +
>> +       return 0;
>> +
>> +err_attr_pid:
>> +       sysfs_remove_file(file_priv->client_root,
>> +                         (struct attribute *)&file_priv->attr.name);
>> +err_attr_name:
>> +       kobject_put(file_priv->client_root);
>> +err_client:
>> +       kfree(file_priv->client_name);
>> +err_name:
>> +       return ret;
>> +}
>> +
>> +static void i915_gem_remove_client(struct drm_i915_file_private *file_priv)
>> +{
>> +       sysfs_remove_file(file_priv->client_root,
>> +                         (struct attribute *)&file_priv->attr.pid);
>> +       sysfs_remove_file(file_priv->client_root,
>> +                         (struct attribute *)&file_priv->attr.name);
>> +       kobject_put(file_priv->client_root);
>> +       kfree(file_priv->client_name);
>> +}
>> +
>>   void i915_gem_release(struct drm_device *dev, struct drm_file *file)
>>   {
>>          struct drm_i915_file_private *file_priv = file->driver_priv;
>> @@ -5626,32 +5709,47 @@ void i915_gem_release(struct drm_device *dev, struct drm_file *file)
>>          list_for_each_entry(request, &file_priv->mm.request_list, client_link)
>>                  request->file_priv = NULL;
>>          spin_unlock(&file_priv->mm.lock);
>> +
>> +       i915_gem_remove_client(file_priv);
>>   }
>>   
>>   int i915_gem_open(struct drm_i915_private *i915, struct drm_file *file)
>>   {
>> +       int ret = -ENOMEM;
>>          struct drm_i915_file_private *file_priv;
>> -       int ret;
>>   
>>          DRM_DEBUG("\n");
>>   
>>          file_priv = kzalloc(sizeof(*file_priv), GFP_KERNEL);
>>          if (!file_priv)
>> -               return -ENOMEM;
>> +               goto err_alloc;
>> +
>> +       file_priv->client_sysfs_id = atomic_inc_return(&i915->client_serial);
> 
> What's the use for client_sysfd_id? I don't see it used again.

Used from context create pid update, but its weak.. I'll eliminate it 
after above mentioned improvements.

Regards,

Tvrtko

> 
>> +       ret = i915_gem_add_client(i915, file_priv, current,
>> +                                 file_priv->client_sysfs_id);
>> +       if (ret)
>> +               goto err_client;
>>   
>>          file->driver_priv = file_priv;
>> +       ret = i915_gem_context_open(i915, file);
>> +       if (ret)
>> +               goto err_context;
>> +
>>          file_priv->dev_priv = i915;
>>          file_priv->file = file;
>> +       file_priv->bsd_engine = -1;
>>   
>>          spin_lock_init(&file_priv->mm.lock);
>>          INIT_LIST_HEAD(&file_priv->mm.request_list);
>>   
>> -       file_priv->bsd_engine = -1;
>> -
>> -       ret = i915_gem_context_open(i915, file);
>> -       if (ret)
>> -               kfree(file_priv);
>> +       return 0;
>>   
>> +err_context:
>> +       i915_gem_remove_client(file_priv);
>> +err_client:
>> +       atomic_dec(&i915->client_serial);
>> +       kfree(file_priv);
>> +err_alloc:
>>          return ret;
>>   }
>>   
>> diff --git a/drivers/gpu/drm/i915/i915_sysfs.c b/drivers/gpu/drm/i915/i915_sysfs.c
>> index b33d2158c234..6cf032bc1573 100644
>> --- a/drivers/gpu/drm/i915/i915_sysfs.c
>> +++ b/drivers/gpu/drm/i915/i915_sysfs.c
>> @@ -575,6 +575,11 @@ void i915_setup_sysfs(struct drm_i915_private *dev_priv)
>>          struct device *kdev = dev_priv->drm.primary->kdev;
>>          int ret;
>>   
>> +       dev_priv->clients_root =
>> +               kobject_create_and_add("clients", &kdev->kobj);
>> +       if (!dev_priv->clients_root)
>> +               DRM_ERROR("Per-client sysfs setup failed\n");
>> +
>>   #ifdef CONFIG_PM
>>          if (HAS_RC6(dev_priv)) {
>>                  ret = sysfs_merge_group(&kdev->kobj,
>> @@ -635,4 +640,7 @@ void i915_teardown_sysfs(struct drm_i915_private *dev_priv)
>>          sysfs_unmerge_group(&kdev->kobj, &rc6_attr_group);
>>          sysfs_unmerge_group(&kdev->kobj, &rc6p_attr_group);
>>   #endif
>> +
>> +       if (dev_priv->clients_root)
>> +               kobject_put(dev_priv->clients_root);
>>   }
>> -- 
>> 2.14.1
>>
>> _______________________________________________
>> Intel-gfx mailing list
>> Intel-gfx@lists.freedesktop.org
>> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
> 
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

  reply	other threads:[~2018-02-15  9:35 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-02-14 18:50 [RFC 0/5] Per-client engine stats Tvrtko Ursulin
2018-02-14 18:50 ` [RFC 1/5] drm/i915: Track per-context engine busyness Tvrtko Ursulin
2018-02-14 19:07   ` Chris Wilson
2018-02-15  9:29     ` Tvrtko Ursulin
2018-02-15  9:35       ` Chris Wilson
2018-02-14 18:50 ` [RFC 2/5] drm/i915: Expose list of clients in sysfs Tvrtko Ursulin
2018-02-14 19:13   ` Chris Wilson
2018-02-15  9:35     ` Tvrtko Ursulin [this message]
2018-02-14 18:50 ` [RFC 3/5] drm/i915: Update client name on context create Tvrtko Ursulin
2018-02-14 18:50 ` [RFC 4/5] drm/i915: Expose per-engine client busyness Tvrtko Ursulin
2018-02-14 19:17   ` Chris Wilson
2018-02-15  9:41     ` Tvrtko Ursulin
2018-02-15  9:44       ` Chris Wilson
2018-02-15 15:13         ` Tvrtko Ursulin
2018-02-14 18:50 ` [RFC 5/5] drm/i915: Add sysfs toggle to enable per-client engine stats Tvrtko Ursulin
2018-02-14 18:55 ` ✗ Fi.CI.CHECKPATCH: warning for Per-client " Patchwork
2018-02-14 19:11 ` ✓ Fi.CI.BAT: success " Patchwork
2018-02-14 19:20 ` [RFC 0/5] " Chris Wilson
2018-02-15  9:44   ` Tvrtko Ursulin
2018-02-15  9:47     ` Chris Wilson
2018-02-15 10:50       ` Tvrtko Ursulin
2018-02-15  2:19 ` ✓ Fi.CI.IGT: success for " Patchwork
  -- strict thread matches above, loose matches on Subject: below --
2019-10-25 14:21 [RFC 0/5] Per client engine busyness (all aboard the sysfs train!) Tvrtko Ursulin
2019-10-25 14:21 ` [RFC 2/5] drm/i915: Expose list of clients in sysfs Tvrtko Ursulin
2019-10-25 14:35   ` Chris Wilson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=783628d0-9b2f-c7b1-5cba-0bec8cb3dd17@linux.intel.com \
    --to=tvrtko.ursulin@linux.intel.com \
    --cc=Intel-gfx@lists.freedesktop.org \
    --cc=chris@chris-wilson.co.uk \
    --cc=tursulin@ursulin.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox