Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Mitchel Humpherys and committed by
Greg Kroah-Hartman
2803ac7b ae5cbf4a

+36 -2
+36 -2
drivers/staging/android/ion/ion.c
··· 72 72 * @idr: an idr space for allocating handle ids 73 73 * @lock: lock protecting the tree of handles 74 74 * @name: used for debugging 75 + * @display_name: used for debugging (unique version of @name) 76 + * @display_serial: used for debugging (to make display_name unique) 75 77 * @task: used for debugging 76 78 * 77 79 * A client represents a list of buffers this client may access. ··· 87 85 struct idr idr; 88 86 struct mutex lock; 89 87 const char *name; 88 + char *display_name; 89 + int display_serial; 90 90 struct task_struct *task; 91 91 pid_t pid; 92 92 struct dentry *debug_root; ··· 715 711 .release = single_release, 716 712 }; 717 713 714 + static int ion_get_client_serial(const struct rb_root *root, 715 + const unsigned char *name) 716 + { 717 + int serial = -1; 718 + struct rb_node *node; 719 + for (node = rb_first(root); node; node = rb_next(node)) { 720 + struct ion_client *client = rb_entry(node, struct ion_client, 721 + node); 722 + if (strcmp(client->name, name)) 723 + continue; 724 + serial = max(serial, client->display_serial); 725 + } 726 + return serial + 1; 727 + } 728 + 718 729 struct ion_client *ion_client_create(struct ion_device *dev, 719 730 const char *name) 720 731 { ··· 739 720 struct rb_node *parent = NULL; 740 721 struct ion_client *entry; 741 722 pid_t pid; 723 + 724 + if (!name) { 725 + pr_err("%s: Name cannot be null\n", __func__); 726 + return ERR_PTR(-EINVAL); 727 + } 742 728 743 729 get_task_struct(current->group_leader); 744 730 task_lock(current->group_leader); ··· 773 749 goto err_free_client; 774 750 775 751 down_write(&dev->lock); 752 + client->display_serial = ion_get_client_serial(&dev->clients, name); 753 + client->display_name = kasprintf( 754 + GFP_KERNEL, "%s-%d", name, client->display_serial); 755 + if (!client->display_name) { 756 + up_write(&dev->lock); 757 + goto err_free_client_name; 758 + } 776 759 p = &dev->clients.rb_node; 777 760 while (*p) { 778 761 parent = *p; ··· 793 762 rb_link_node(&client->node, parent, p); 794 763 rb_insert_color(&client->node, &dev->clients); 795 764 796 - client->debug_root = debugfs_create_file(name, 0664, 765 + client->debug_root = debugfs_create_file(client->display_name, 0664, 797 766 dev->clients_debug_root, 798 767 client, &debug_client_fops); 799 768 if (!client->debug_root) { 800 769 char buf[256], *path; 801 770 path = dentry_path(dev->clients_debug_root, buf, 256); 802 771 pr_err("Failed to create client debugfs at %s/%s\n", 803 - path, name); 772 + path, client->display_name); 804 773 } 805 774 806 775 up_write(&dev->lock); 807 776 808 777 return client; 809 778 779 + err_free_client_name: 780 + kfree(client->name); 810 781 err_free_client: 811 782 kfree(client); 812 783 err_put_task_struct: ··· 839 806 debugfs_remove_recursive(client->debug_root); 840 807 up_write(&dev->lock); 841 808 809 + kfree(client->display_name); 842 810 kfree(client->name); 843 811 kfree(client); 844 812 }