|
@@ -72,6 +72,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.
|
|
@@ -85,6 +87,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;
|
|
@@ -711,6 +715,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)
|
|
|
{
|
|
@@ -721,6 +740,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);
|
|
@@ -749,6 +773,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;
|
|
@@ -762,20 +793,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:
|
|
@@ -806,6 +839,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);
|
|
|
}
|