gpu: ion: make sure all clients are exposed in debugfs
authorMitchel Humpherys <mitchelh@codeaurora.org>
Mon, 7 Oct 2013 16:24:29 +0000 (09:24 -0700)
committerColin Cross <ccross@android.com>
Fri, 20 Dec 2013 03:25:40 +0000 (19:25 -0800)
Currently, if multiple Ion clients are created with the same name, only
the first one shows up in debugfs. Rectify this by adding a
monotonically-increasing serial number to the debug names of Ion
clients.

Change-Id: I000e45055d5029c7bccd88c36b238736929da3a5
Signed-off-by: Mitchel Humpherys <mitchelh@codeaurora.org>
drivers/staging/android/ion/ion.c

index 7627ffbc83600d655c53642915f78334a3d868b5..48774e3974aa02f13a4656541660f8f182549888 100644 (file)
@@ -71,6 +71,8 @@ struct ion_device {
  * @idr:               an idr space for allocating handle ids
  * @lock:              lock protecting the tree of handles
  * @name:              used for debugging
+ * @display_name:      used for debugging (unique version of @name)
+ * @display_serial:    used for debugging (to make display_name unique)
  * @task:              used for debugging
  *
  * A client represents a list of buffers this client may access.
@@ -84,6 +86,8 @@ struct ion_client {
        struct idr idr;
        struct mutex lock;
        const char *name;
+       char *display_name;
+       int display_serial;
        struct task_struct *task;
        pid_t pid;
        struct dentry *debug_root;
@@ -710,6 +714,21 @@ static const struct file_operations debug_client_fops = {
        .release = single_release,
 };
 
+static int ion_get_client_serial(const struct rb_root *root,
+                                       const unsigned char *name)
+{
+       int serial = -1;
+       struct rb_node *node;
+       for (node = rb_first(root); node; node = rb_next(node)) {
+               struct ion_client *client = rb_entry(node, struct ion_client,
+                                               node);
+               if (strcmp(client->name, name))
+                       continue;
+               serial = max(serial, client->display_serial);
+       }
+       return serial + 1;
+}
+
 struct ion_client *ion_client_create(struct ion_device *dev,
                                     const char *name)
 {
@@ -720,6 +739,11 @@ struct ion_client *ion_client_create(struct ion_device *dev,
        struct ion_client *entry;
        pid_t pid;
 
+       if (!name) {
+               pr_err("%s: Name cannot be null\n", __func__);
+               return ERR_PTR(-EINVAL);
+       }
+
        get_task_struct(current->group_leader);
        task_lock(current->group_leader);
        pid = task_pid_nr(current->group_leader);
@@ -748,6 +772,13 @@ struct ion_client *ion_client_create(struct ion_device *dev,
                goto err_free_client;
 
        down_write(&dev->lock);
+       client->display_serial = ion_get_client_serial(&dev->clients, name);
+       client->display_name = kasprintf(
+               GFP_KERNEL, "%s-%d", name, client->display_serial);
+       if (!client->display_name) {
+               up_write(&dev->lock);
+               goto err_free_client_name;
+       }
        p = &dev->clients.rb_node;
        while (*p) {
                parent = *p;
@@ -761,20 +792,22 @@ struct ion_client *ion_client_create(struct ion_device *dev,
        rb_link_node(&client->node, parent, p);
        rb_insert_color(&client->node, &dev->clients);
 
-       client->debug_root = debugfs_create_file(name, 0664,
+       client->debug_root = debugfs_create_file(client->display_name, 0664,
                                                dev->clients_debug_root,
                                                client, &debug_client_fops);
        if (!client->debug_root) {
                char buf[256], *path;
                path = dentry_path(dev->clients_debug_root, buf, 256);
                pr_err("Failed to create client debugfs at %s/%s\n",
-                       path, name);
+                       path, client->display_name);
        }
 
        up_write(&dev->lock);
 
        return client;
 
+err_free_client_name:
+       kfree(client->name);
 err_free_client:
        kfree(client);
 err_put_task_struct:
@@ -805,6 +838,7 @@ void ion_client_destroy(struct ion_client *client)
        debugfs_remove_recursive(client->debug_root);
        up_write(&dev->lock);
 
+       kfree(client->display_name);
        kfree(client->name);
        kfree(client);
 }