mirror of https://gitee.com/openkylin/linux.git
staging: ion: Make sure all clients are exposed in debugfs
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. Cc: Colin Cross <ccross@android.com> Cc: Android Kernel Team <kernel-team@android.com> Signed-off-by: Mitchel Humpherys <mitchelh@codeaurora.org> [jstultz: Minor commit subject tweaks] Signed-off-by: John Stultz <john.stultz@linaro.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
ae5cbf4a5a
commit
2803ac7bf2
|
@ -72,6 +72,8 @@ struct ion_device {
|
||||||
* @idr: an idr space for allocating handle ids
|
* @idr: an idr space for allocating handle ids
|
||||||
* @lock: lock protecting the tree of handles
|
* @lock: lock protecting the tree of handles
|
||||||
* @name: used for debugging
|
* @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
|
* @task: used for debugging
|
||||||
*
|
*
|
||||||
* A client represents a list of buffers this client may access.
|
* A client represents a list of buffers this client may access.
|
||||||
|
@ -85,6 +87,8 @@ struct ion_client {
|
||||||
struct idr idr;
|
struct idr idr;
|
||||||
struct mutex lock;
|
struct mutex lock;
|
||||||
const char *name;
|
const char *name;
|
||||||
|
char *display_name;
|
||||||
|
int display_serial;
|
||||||
struct task_struct *task;
|
struct task_struct *task;
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
struct dentry *debug_root;
|
struct dentry *debug_root;
|
||||||
|
@ -711,6 +715,21 @@ static const struct file_operations debug_client_fops = {
|
||||||
.release = single_release,
|
.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,
|
struct ion_client *ion_client_create(struct ion_device *dev,
|
||||||
const char *name)
|
const char *name)
|
||||||
{
|
{
|
||||||
|
@ -721,6 +740,11 @@ struct ion_client *ion_client_create(struct ion_device *dev,
|
||||||
struct ion_client *entry;
|
struct ion_client *entry;
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
|
|
||||||
|
if (!name) {
|
||||||
|
pr_err("%s: Name cannot be null\n", __func__);
|
||||||
|
return ERR_PTR(-EINVAL);
|
||||||
|
}
|
||||||
|
|
||||||
get_task_struct(current->group_leader);
|
get_task_struct(current->group_leader);
|
||||||
task_lock(current->group_leader);
|
task_lock(current->group_leader);
|
||||||
pid = task_pid_nr(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;
|
goto err_free_client;
|
||||||
|
|
||||||
down_write(&dev->lock);
|
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;
|
p = &dev->clients.rb_node;
|
||||||
while (*p) {
|
while (*p) {
|
||||||
parent = *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_link_node(&client->node, parent, p);
|
||||||
rb_insert_color(&client->node, &dev->clients);
|
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,
|
dev->clients_debug_root,
|
||||||
client, &debug_client_fops);
|
client, &debug_client_fops);
|
||||||
if (!client->debug_root) {
|
if (!client->debug_root) {
|
||||||
char buf[256], *path;
|
char buf[256], *path;
|
||||||
path = dentry_path(dev->clients_debug_root, buf, 256);
|
path = dentry_path(dev->clients_debug_root, buf, 256);
|
||||||
pr_err("Failed to create client debugfs at %s/%s\n",
|
pr_err("Failed to create client debugfs at %s/%s\n",
|
||||||
path, name);
|
path, client->display_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
up_write(&dev->lock);
|
up_write(&dev->lock);
|
||||||
|
|
||||||
return client;
|
return client;
|
||||||
|
|
||||||
|
err_free_client_name:
|
||||||
|
kfree(client->name);
|
||||||
err_free_client:
|
err_free_client:
|
||||||
kfree(client);
|
kfree(client);
|
||||||
err_put_task_struct:
|
err_put_task_struct:
|
||||||
|
@ -806,6 +839,7 @@ void ion_client_destroy(struct ion_client *client)
|
||||||
debugfs_remove_recursive(client->debug_root);
|
debugfs_remove_recursive(client->debug_root);
|
||||||
up_write(&dev->lock);
|
up_write(&dev->lock);
|
||||||
|
|
||||||
|
kfree(client->display_name);
|
||||||
kfree(client->name);
|
kfree(client->name);
|
||||||
kfree(client);
|
kfree(client);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue