lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20220622163209.GA6246@Mahakal>
Date:   Wed, 22 Jun 2022 22:02:42 +0530
From:   "<Vishal Badole>" <badolevishal1116@...il.com>
To:     Stephen Boyd <sboyd@...nel.org>, mturquette@...libre.com,
        inux-clk@...r.kernel.org, linux-kernel@...r.kernel.org
Cc:     chinmoyghosh2001@...il.com, mintupatel89@...il.com
Subject: Re: [PATCH] Common clock: ​​To list
 active consumers of clocks


>From eba241016ea868b841473ba73ece16173a6b5aee Mon Sep 17 00:00:00 2001
From: Vishal Badole <badolevishal1116@...il.com>
Date: Tue, 31 May 2022 21:23:34 +0530
Subject: [PATCH] Common clock: To list active consumers of clocks

This feature lists the name of clocks and their consumer devices.
Using this feature user can easily check which device is using a
perticular clock.

for example:
debian@...glebone:~$ cat /sys/kernel/debug/clk/clk_devices_name
            clock_name                                  devices_name
-------------------------------------------------------------------------
             l4-wkup-clkctrl:0008:0              44e07000.target-module
                l4ls-clkctrl:0074:0              4804c000.target-module
                l4ls-clkctrl:0058:0              48311fe0.target-module
              l4-rtc-clkctrl:0000:0              44e3e074.target-module
                       clk_32768_ck                        44e3e000.rtc
                l4ls-clkctrl:00d8:0              480c8000.target-module
         cpsw-125mhz-clkctrl:0014:0              4a101200.target-module

Signed-off-by: Vishal Badole <badolevishal1116@...il.com>
Signed-off-by: Chinmoy Ghosh <chinmoyghosh2001@...il.com>
Signed-off-by: Mintu Patel <mintupatel89@...il.com>
Signed-off-by: Vimal Kumar <vimal.kumar32@...il.com>
---
 drivers/clk/Kconfig |   8 ++++
 drivers/clk/clk.c   | 120 +++++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 127 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index c44247d..549cdda 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -23,6 +23,14 @@ config COMMON_CLK
 menu "Common Clock Framework"
 	depends on COMMON_CLK
 
+config DEBUG_CLK_CONSUMER
+	bool "Debug feature to list clocks and their active consumers"
+	depends on DEBUG_FS && COMMON_CLK
+	help
+	  Clock consumer debug feature supports for clock debugging. Chose y
+	  to get debug entry in file system to list clocks and their active
+	  consumer devices.
+
 config COMMON_CLK_WM831X
 	tristate "Clock driver for WM831x/2x PMICs"
 	depends on MFD_WM831X
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 13332f8..dccbd35 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -105,6 +105,84 @@ struct clk {
 	struct hlist_node clks_node;
 };
 
+#ifdef CONFIG_DEBUG_CLK_CONSUMER
+/*Linked List Node*/
+struct clk_dev_list {
+	struct list_head list;
+	const char *clk_name;
+	const char *dev_name;
+};
+
+/*Declare and init the head node of the linked list*/
+LIST_HEAD(head_node);
+
+static void clk_dev_entry(struct clk *clk_ptr)
+{
+	struct clk_dev_list *new_node_ptr = NULL;
+	struct clk_dev_list *temp_node_ptr = NULL;
+	int repeat_count = 0;
+	static bool is_first_node;
+	const char *clk_name_ptr = NULL;
+	const char *dev_name_ptr = NULL;
+
+	if (clk_ptr->dev) {
+		dev_name_ptr = dev_name(clk_ptr->dev);
+
+		clk_name_ptr = clk_ptr->core->name;
+
+		if (is_first_node) {
+			/* Iterate the list to check duplicate entry */
+			list_for_each_entry(temp_node_ptr, &head_node, list) {
+				if (temp_node_ptr->clk_name == clk_name_ptr &&
+				    temp_node_ptr->dev_name == dev_name_ptr) {
+					repeat_count++;
+					break;
+				}
+			}
+		}
+
+		is_first_node = 1;
+
+		if (!repeat_count && clk_ptr->core->enable_count) {
+			/*Creating Node*/
+			new_node_ptr = kmalloc(sizeof(*new_node_ptr),
+					       GFP_KERNEL);
+			if (!new_node_ptr)
+				return;
+
+			/*Assgin the data that is received*/
+			new_node_ptr->clk_name = clk_name_ptr;
+			new_node_ptr->dev_name = dev_name_ptr;
+
+			/*Init the list within the struct*/
+			INIT_LIST_HEAD(&new_node_ptr->list);
+
+			/*Add Node to Linked List*/
+			list_add_tail(&new_node_ptr->list, &head_node);
+		}
+	}
+}
+
+/* Function to remove the clk and device entry */
+static void clk_dev_dentry(struct clk *clk)
+{
+	struct clk_dev_list *temp_node_ptr = NULL;
+	struct clk_dev_list *cur_node_ptr = NULL;
+
+	if (clk->dev) {
+		/* Go through the list and free the memory */
+		list_for_each_entry_safe(cur_node_ptr, temp_node_ptr,
+					 &head_node, list) {
+			if (cur_node_ptr->clk_name == clk->core->name &&
+			    cur_node_ptr->dev_name == dev_name(clk->dev)) {
+				list_del(&cur_node_ptr->list);
+				kfree(cur_node_ptr);
+			}
+		}
+	}
+}
+#endif
+
 /***           runtime pm          ***/
 static int clk_pm_runtime_get(struct clk_core *core)
 {
@@ -1020,6 +1098,9 @@ void clk_disable(struct clk *clk)
 		return;
 
 	clk_core_disable_lock(clk->core);
+#ifdef CONFIG_DEBUG_CLK_CONSUMER
+	clk_dev_dentry(clk);
+#endif
 }
 EXPORT_SYMBOL_GPL(clk_disable);
 
@@ -1181,10 +1262,21 @@ EXPORT_SYMBOL_GPL(clk_restore_context);
  */
 int clk_enable(struct clk *clk)
 {
+#ifdef CONFIG_DEBUG_CLK_CONSUMER
+	int ret = 0;
+#endif
 	if (!clk)
 		return 0;
 
+#ifndef CONFIG_DEBUG_CLK_CONSUMER
 	return clk_core_enable_lock(clk->core);
+#else
+	ret = clk_core_enable_lock(clk->core);
+	if (!ret)
+		clk_dev_entry(clk);
+
+	return ret;
+#endif
 }
 EXPORT_SYMBOL_GPL(clk_enable);
 
@@ -2986,6 +3078,29 @@ static void clk_dump_one(struct seq_file *s, struct clk_core *c, int level)
 		   clk_core_get_scaled_duty_cycle(c, 100000));
 }
 
+#ifdef CONFIG_DEBUG_CLK_CONSUMER
+static int clk_devices_show(struct seq_file *s, void *data)
+{
+	struct clk_dev_list *clk_dev_node;
+
+	seq_puts(s, "            clock_name                                  devices_name\n");
+	seq_puts(s, "-------------------------------------------------------------------------\n");
+
+	clk_prepare_lock();
+
+	/*Traversing Linked List and Print its Members*/
+	list_for_each_entry(clk_dev_node, &head_node, list) {
+		seq_printf(s, "%35s %35s\n", clk_dev_node->clk_name,
+			   clk_dev_node->dev_name);
+	}
+
+	clk_prepare_unlock();
+
+	return 0;
+}
+DEFINE_SHOW_ATTRIBUTE(clk_devices);
+#endif
+
 static void clk_dump_subtree(struct seq_file *s, struct clk_core *c, int level)
 {
 	struct clk_core *child;
@@ -3256,7 +3371,10 @@ static int __init clk_debug_init(void)
 			    &clk_summary_fops);
 	debugfs_create_file("clk_orphan_dump", 0444, rootdir, &orphan_list,
 			    &clk_dump_fops);
-
+#ifdef CONFIG_DEBUG_CLK_CONSUMER
+	debugfs_create_file("clk_devices_name", 0444, rootdir, NULL,
+			    &clk_devices_fops);
+#endif
 	mutex_lock(&clk_debug_lock);
 	hlist_for_each_entry(core, &clk_debug_list, debug_node)
 		clk_debug_create_one(core, rootdir);
-- 
2.7.4

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ