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
next prev parent 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.