Linux Power Management development
 help / color / mirror / Atom feed
diff for duplicates of <ddbbc1db-2dd3-0c4d-26c0-0992867d35be@linaro.org>

diff --git a/a/1.txt b/N1/1.txt
index 9a0796f..d865628 100644
--- a/a/1.txt
+++ b/N1/1.txt
@@ -1,22 +1,10 @@
+From: Daniel Lezcano <daniel.lezcano@linaro.org>
+
 On 19/04/2022 15:54, Zhang Rui wrote:
 > CC Viresh.
 > 
 > On Tue, 2022-04-19 at 11:14 +0200, Daniel Lezcano wrote:
 >> On 19/04/2022 10:48, Zhang Rui wrote:
->>> On Sun, 2022-04-17 at 12:56 +0000, Junwen Wu wrote:
->>>> Very high cooling device max state value makes cooling device
->>>> stats
->>>> buffer allocation fails,like below.Using kzvalloc instead of
->>>> kzalloc
->>>> can avoid this issue.
->>>
->>> When a cooling device has big max_state, this patch can get ride of
->>> the
->>> warning here, but still we end up with the read failure of the
->>> trans_table in sysfs because it is larger than PAGE_SIZE.
->>>
->>> $ cat /sys/class/thermal/cooling_device8/stats/trans_table
->>> cat: /sys/class/thermal/cooling_device8/stats/trans_table: File too
 >>> large
 >>>
 >>> IMO, unless we can fix both places, I'd suggest we skip allocating
@@ -29,28 +17,247 @@ On 19/04/2022 15:54, Zhang Rui wrote:
 > 
 > The idea looks good to me.
 
-What about doing a percentile approach of the state indexes changes 
-instead of a raw matrix full of zeros ? So we show the most significant 
-transitions, perhaps something like:
+>What about doing a percentile approach of the state indexes changes 
+>instead of a raw matrix full of zeros ? So we show the most significant 
+>transitions, perhaps something like:
+>
+>99%:	7->6	6->7
+>98%:	6->5	5->6
+>95%:	5->4	4->5
+>90%:	7->5	5->7
+>80%:	6->4	4->6
+>70%:	7->1	7->2
+>50%:	...	...
 
-99%:	7->6	6->7
-98%:	6->5	5->6
-95%:	5->4	4->5
-90%:	7->5	5->7
-80%:	6->4	4->6
-70%:	7->1	7->2
-50%:	...	...
+>total:	123456	124573
 
-total:	123456	124573
 
+>And another statistics file containing some timings information like the 
+>total duration in mitigation, and the duration in the most significant 
+>states above?
 
-And another statistics file containing some timings information like the 
-total duration in mitigation, and the duration in the most significant 
-states above?
+Viresh, Zhang Rui,  Daniel,sorry for the delay indeed ,the trans_table is always full of zero,
+I introduce 'show_state' node(tunnable by user,default set as max_states/2) ,thus only show show_state'th  trans count
+to the max trans count change stats. in this way trans_table_show's buffer always less than PAGE_SIZE
+I create a patch v2
+like this:
+/sys/class/thermal/cooling_device0/stats # cat trans_table
+ From  :    Index_change
+state 0:      ->1( 1)      ->2( 2)      ->7( 1)
+state 1:      ->0( 1)      ->2( 1)
+state 2:      ->0( 2)      ->1( 1)
 
--- 
-<http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs
+here is the patch:
+From 64a7fefd008cb890a4a9ea4efd0dd388ac536ad5 Mon Sep 17 00:00:00 2001
+From: Junwen Wu <wudaemon@163.com>
+Date: Sun, 8 May 2022 14:50:14 +0000
+Subject: [PATCH v2] thermal/core: Make trans_table tunnable to avoid some
+ needless zero output
 
-Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
-<http://twitter.com/#!/linaroorg> Twitter |
-<http://www.linaro.org/linaro-blog/> Blog
+Very high cooling device max state value make trans_table node prompt File too large.
+we introduce show_state node, tunnable by user,thus trans_table only show show_state'th
+trans count to the max trans count, in this way trans_table_show's buffer is
+always less than PAGE_SIZE and shows the important changes.
+
+Signed-off-by: Junwen Wu <wudaemon@163.com>
+---
+V1 -> V2: avoid some needless zero output
+ drivers/thermal/thermal_sysfs.c | 136 +++++++++++++++++++++++---------
+ 1 file changed, 99 insertions(+), 37 deletions(-)
+
+diff --git a/drivers/thermal/thermal_sysfs.c b/drivers/thermal/thermal_sysfs.c
+index f154bada2906..1496088a1638 100644
+--- a/drivers/thermal/thermal_sysfs.c
++++ b/drivers/thermal/thermal_sysfs.c
+@@ -656,6 +656,7 @@ struct cooling_dev_stats {
+ 	spinlock_t lock;
+ 	unsigned int total_trans;
+ 	unsigned long state;
++	unsigned long show_state;
+ 	unsigned long max_states;
+ 	ktime_t last_time;
+ 	ktime_t *time_in_state;
+@@ -752,60 +753,119 @@ reset_store(struct device *dev, struct device_attribute *attr, const char *buf,
+ 	return count;
+ }
+ 
+-static ssize_t trans_table_show(struct device *dev,
+-				struct device_attribute *attr, char *buf)
++static ssize_t
++show_state_store(struct device *dev, struct device_attribute *attr, const char *buf,
++            size_t count)
+ {
+-	struct thermal_cooling_device *cdev = to_cooling_device(dev);
+-	struct cooling_dev_stats *stats = cdev->stats;
+-	ssize_t len = 0;
+-	int i, j;
++        struct thermal_cooling_device *cdev = to_cooling_device(dev);
++        struct cooling_dev_stats *stats = cdev->stats;
++        unsigned long state;
++	ssize_t ret;
+ 
+-	len += snprintf(buf + len, PAGE_SIZE - len, " From  :    To\n");
+-	len += snprintf(buf + len, PAGE_SIZE - len, "       : ");
+-	for (i = 0; i < stats->max_states; i++) {
+-		if (len >= PAGE_SIZE)
+-			break;
+-		len += snprintf(buf + len, PAGE_SIZE - len, "state%2u  ", i);
+-	}
+-	if (len >= PAGE_SIZE)
+-		return PAGE_SIZE;
++        spin_lock(&stats->lock);
+ 
+-	len += snprintf(buf + len, PAGE_SIZE - len, "\n");
++	ret = kstrtoul(buf, 10, &state);
++        if (ret || (state > stats->max_states))
++		goto unlock;
+ 
+-	for (i = 0; i < stats->max_states; i++) {
+-		if (len >= PAGE_SIZE)
+-			break;
++	stats->show_state = state;
++unlock:
++	spin_unlock(&stats->lock);
++        return count;
++}
+ 
+-		len += snprintf(buf + len, PAGE_SIZE - len, "state%2u:", i);
++static ssize_t
++show_state_show(struct device *dev, struct device_attribute *attr, char *buf)
++{
++        struct thermal_cooling_device *cdev = to_cooling_device(dev);
++        struct cooling_dev_stats *stats = cdev->stats;
++
++	return sprintf(buf, "%lu\n", stats->show_state);
++}
++
++static int find_show_state( int *nums, int numsSize, int k, unsigned int *max_value)
++{
++    int i, min = INT_MAX, max = 0;
++    for( i = 0; i < numsSize; ++i )
++    {
++        min = nums[i] < min ? nums[i] : min;
++        max = nums[i] > max ? nums[i] : max;
++    }
++    int l = min, r = max, mid, cnt = 0;
++    while( l < r )
++    {
++        mid = r - (r - l) / 2;
++        for( i = 0; i < numsSize; ++i )
++        {
++            if( nums[i] >= mid )
++                ++cnt;
++        }
++        if( cnt < k )
++        {
++            r = mid - 1;
++            cnt = 0;
++        }
++        else
++        {
++            l = mid;
++            cnt = 0;
++        }
++    }
++     *max_value = max;
++    return l;
++}
+ 
+-		for (j = 0; j < stats->max_states; j++) {
+-			if (len >= PAGE_SIZE)
+-				break;
+-			len += snprintf(buf + len, PAGE_SIZE - len, "%8u ",
+-				stats->trans_table[i * stats->max_states + j]);
+-		}
+-		if (len >= PAGE_SIZE)
+-			break;
+-		len += snprintf(buf + len, PAGE_SIZE - len, "\n");
+-	}
+ 
+-	if (len >= PAGE_SIZE) {
+-		pr_warn_once("Thermal transition table exceeds PAGE_SIZE. Disabling\n");
+-		return -EFBIG;
+-	}
+-	return len;
++
++static ssize_t trans_table_show(struct device *dev,
++				struct device_attribute *attr, char *buf)
++{
++	struct thermal_cooling_device *cdev = to_cooling_device(dev);
++        struct cooling_dev_stats *stats = cdev->stats;
++        ssize_t len = 0;
++        int i, j;
++        unsigned int show_state_value = 0;
++	unsigned int max_state_value = 0;
++
++        len += snprintf(buf + len, PAGE_SIZE - len, " From  :    Index_change\n");
++        for (i = 0; i < stats->max_states; i++) {
++                show_state_value = find_show_state(&stats->trans_table[i * stats->max_states], stats->max_states, stats->show_state, &max_state_value);
++                if (max_state_value) {
++                        len += snprintf(buf + len, PAGE_SIZE - len, "state%2u:", i);
++                }
++                else {
++                        continue;
++                }
++
++                for (j = 0; j < stats->max_states; j++) {
++                        if (stats->trans_table[i * stats->max_states + j] && (show_state_value <= stats->trans_table[i * stats->max_states + j])) {
++                                len += snprintf(buf + len, PAGE_SIZE - len, "     ->%u(%u)",j, stats->trans_table[i * stats->max_states + j]);
++                        }
++                }
++                if (len >= PAGE_SIZE)
++                        break;
++                len += snprintf(buf + len, PAGE_SIZE - len, "\n");
++        }
++
++        if (len >= PAGE_SIZE) {
++                pr_warn_once("Thermal transition table exceeds PAGE_SIZE. Disabling\n");
++                return -EFBIG;
++        }
++        return len;
+ }
+ 
+ static DEVICE_ATTR_RO(total_trans);
+ static DEVICE_ATTR_RO(time_in_state_ms);
+ static DEVICE_ATTR_WO(reset);
+ static DEVICE_ATTR_RO(trans_table);
++static DEVICE_ATTR_RW(show_state);
+ 
+ static struct attribute *cooling_device_stats_attrs[] = {
+ 	&dev_attr_total_trans.attr,
+ 	&dev_attr_time_in_state_ms.attr,
+ 	&dev_attr_reset.attr,
+ 	&dev_attr_trans_table.attr,
++	&dev_attr_show_state.attr,
+ 	NULL
+ };
+ 
+@@ -829,7 +889,7 @@ static void cooling_device_stats_setup(struct thermal_cooling_device *cdev)
+ 	var += sizeof(*stats->time_in_state) * states;
+ 	var += sizeof(*stats->trans_table) * states * states;
+ 
+-	stats = kzalloc(var, GFP_KERNEL);
++	stats = kvzalloc(var, GFP_KERNEL);
+ 	if (!stats)
+ 		return;
+ 
+@@ -838,6 +898,8 @@ static void cooling_device_stats_setup(struct thermal_cooling_device *cdev)
+ 	cdev->stats = stats;
+ 	stats->last_time = ktime_get();
+ 	stats->max_states = states;
++	/* default set show_state = max_states/2 */
++	stats->show_state = states / 2;
+ 
+ 	spin_lock_init(&stats->lock);
+ 
+@@ -848,7 +910,7 @@ static void cooling_device_stats_setup(struct thermal_cooling_device *cdev)
+ 
+ static void cooling_device_stats_destroy(struct thermal_cooling_device *cdev)
+ {
+-	kfree(cdev->stats);
++	kvfree(cdev->stats);
+ 	cdev->stats = NULL;
+ }
+ 
+-- 
+2.25.1
diff --git a/a/content_digest b/N1/content_digest
index a0925c4..a631646 100644
--- a/a/content_digest
+++ b/N1/content_digest
@@ -1,38 +1,24 @@
- "ref\020220417125601.18535-1-wudaemon@163.com\0"
- "ref\0a7861e9a6a311f09c03b2e6e47dd4d3283cb58e2.camel@intel.com\0"
- "ref\001f72a07-6adc-4854-eae2-286786d33aab@linaro.org\0"
  "ref\0df7e04d86dd64dc85125d536434d93bab3d6314d.camel@intel.com\0"
- "From\0Daniel Lezcano <daniel.lezcano@linaro.org>\0"
+ "From\0Junwen Wu <wudaemon@163.com>\0"
  "Subject\0Re: [PATCH v1] thermal/core: change mm alloc method to avoid kernel warning\0"
- "Date\0Tue, 19 Apr 2022 19:56:35 +0200\0"
- "To\0Zhang Rui <rui.zhang@intel.com>"
+ "Date\0Sun,  8 May 2022 15:07:50 +0000\0"
+ "To\0daniel.lezcano@linaro.org"
+  Zhang Rui <rui.zhang@intel.com>
   Junwen Wu <wudaemon@163.com>
   rafael@kernel.org
  " amitk@kernel.org\0"
  "Cc\0linux-kernel@vger.kernel.org"
   linux-pm@vger.kernel.org
- " Viresh Kumar <viresh.kumar@linaro.org>\0"
+ " viresh.kumar@linaro.org\0"
  "\00:1\0"
  "b\0"
+ "From: Daniel Lezcano <daniel.lezcano@linaro.org>\n"
+ "\n"
  "On 19/04/2022 15:54, Zhang Rui wrote:\n"
  "> CC Viresh.\n"
  "> \n"
  "> On Tue, 2022-04-19 at 11:14 +0200, Daniel Lezcano wrote:\n"
  ">> On 19/04/2022 10:48, Zhang Rui wrote:\n"
- ">>> On Sun, 2022-04-17 at 12:56 +0000, Junwen Wu wrote:\n"
- ">>>> Very high cooling device max state value makes cooling device\n"
- ">>>> stats\n"
- ">>>> buffer allocation fails,like below.Using kzvalloc instead of\n"
- ">>>> kzalloc\n"
- ">>>> can avoid this issue.\n"
- ">>>\n"
- ">>> When a cooling device has big max_state, this patch can get ride of\n"
- ">>> the\n"
- ">>> warning here, but still we end up with the read failure of the\n"
- ">>> trans_table in sysfs because it is larger than PAGE_SIZE.\n"
- ">>>\n"
- ">>> $ cat /sys/class/thermal/cooling_device8/stats/trans_table\n"
- ">>> cat: /sys/class/thermal/cooling_device8/stats/trans_table: File too\n"
  ">>> large\n"
  ">>>\n"
  ">>> IMO, unless we can fix both places, I'd suggest we skip allocating\n"
@@ -45,30 +31,249 @@
  "> \n"
  "> The idea looks good to me.\n"
  "\n"
- "What about doing a percentile approach of the state indexes changes \n"
- "instead of a raw matrix full of zeros ? So we show the most significant \n"
- "transitions, perhaps something like:\n"
+ ">What about doing a percentile approach of the state indexes changes \n"
+ ">instead of a raw matrix full of zeros ? So we show the most significant \n"
+ ">transitions, perhaps something like:\n"
+ ">\n"
+ ">99%:\t7->6\t6->7\n"
+ ">98%:\t6->5\t5->6\n"
+ ">95%:\t5->4\t4->5\n"
+ ">90%:\t7->5\t5->7\n"
+ ">80%:\t6->4\t4->6\n"
+ ">70%:\t7->1\t7->2\n"
+ ">50%:\t...\t...\n"
  "\n"
- "99%:\t7->6\t6->7\n"
- "98%:\t6->5\t5->6\n"
- "95%:\t5->4\t4->5\n"
- "90%:\t7->5\t5->7\n"
- "80%:\t6->4\t4->6\n"
- "70%:\t7->1\t7->2\n"
- "50%:\t...\t...\n"
+ ">total:\t123456\t124573\n"
  "\n"
- "total:\t123456\t124573\n"
  "\n"
+ ">And another statistics file containing some timings information like the \n"
+ ">total duration in mitigation, and the duration in the most significant \n"
+ ">states above?\n"
  "\n"
- "And another statistics file containing some timings information like the \n"
- "total duration in mitigation, and the duration in the most significant \n"
- "states above?\n"
+ "Viresh, Zhang Rui,  Daniel,sorry for the delay indeed ,the trans_table is always full of zero,\n"
+ "I introduce 'show_state' node(tunnable by user,default set as max_states/2) ,thus only show show_state'th  trans count\n"
+ "to the max trans count change stats. in this way trans_table_show's buffer always less than PAGE_SIZE\n"
+ "I create a patch v2\n"
+ "like this:\n"
+ "/sys/class/thermal/cooling_device0/stats # cat trans_table\n"
+ " From  :    Index_change\n"
+ "state 0:      ->1( 1)      ->2( 2)      ->7( 1)\n"
+ "state 1:      ->0( 1)      ->2( 1)\n"
+ "state 2:      ->0( 2)      ->1( 1)\n"
  "\n"
- "-- \n"
- "<http://www.linaro.org/> Linaro.org \342\224\202 Open source software for ARM SoCs\n"
+ "here is the patch:\n"
+ "From 64a7fefd008cb890a4a9ea4efd0dd388ac536ad5 Mon Sep 17 00:00:00 2001\n"
+ "From: Junwen Wu <wudaemon@163.com>\n"
+ "Date: Sun, 8 May 2022 14:50:14 +0000\n"
+ "Subject: [PATCH v2] thermal/core: Make trans_table tunnable to avoid some\n"
+ " needless zero output\n"
  "\n"
- "Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |\n"
- "<http://twitter.com/#!/linaroorg> Twitter |\n"
- <http://www.linaro.org/linaro-blog/> Blog
+ "Very high cooling device max state value make trans_table node prompt File too large.\n"
+ "we introduce show_state node, tunnable by user,thus trans_table only show show_state'th\n"
+ "trans count to the max trans count, in this way trans_table_show's buffer is\n"
+ "always less than PAGE_SIZE and shows the important changes.\n"
+ "\n"
+ "Signed-off-by: Junwen Wu <wudaemon@163.com>\n"
+ "---\n"
+ "V1 -> V2: avoid some needless zero output\n"
+ " drivers/thermal/thermal_sysfs.c | 136 +++++++++++++++++++++++---------\n"
+ " 1 file changed, 99 insertions(+), 37 deletions(-)\n"
+ "\n"
+ "diff --git a/drivers/thermal/thermal_sysfs.c b/drivers/thermal/thermal_sysfs.c\n"
+ "index f154bada2906..1496088a1638 100644\n"
+ "--- a/drivers/thermal/thermal_sysfs.c\n"
+ "+++ b/drivers/thermal/thermal_sysfs.c\n"
+ "@@ -656,6 +656,7 @@ struct cooling_dev_stats {\n"
+ " \tspinlock_t lock;\n"
+ " \tunsigned int total_trans;\n"
+ " \tunsigned long state;\n"
+ "+\tunsigned long show_state;\n"
+ " \tunsigned long max_states;\n"
+ " \tktime_t last_time;\n"
+ " \tktime_t *time_in_state;\n"
+ "@@ -752,60 +753,119 @@ reset_store(struct device *dev, struct device_attribute *attr, const char *buf,\n"
+ " \treturn count;\n"
+ " }\n"
+ " \n"
+ "-static ssize_t trans_table_show(struct device *dev,\n"
+ "-\t\t\t\tstruct device_attribute *attr, char *buf)\n"
+ "+static ssize_t\n"
+ "+show_state_store(struct device *dev, struct device_attribute *attr, const char *buf,\n"
+ "+            size_t count)\n"
+ " {\n"
+ "-\tstruct thermal_cooling_device *cdev = to_cooling_device(dev);\n"
+ "-\tstruct cooling_dev_stats *stats = cdev->stats;\n"
+ "-\tssize_t len = 0;\n"
+ "-\tint i, j;\n"
+ "+        struct thermal_cooling_device *cdev = to_cooling_device(dev);\n"
+ "+        struct cooling_dev_stats *stats = cdev->stats;\n"
+ "+        unsigned long state;\n"
+ "+\tssize_t ret;\n"
+ " \n"
+ "-\tlen += snprintf(buf + len, PAGE_SIZE - len, \" From  :    To\\n\");\n"
+ "-\tlen += snprintf(buf + len, PAGE_SIZE - len, \"       : \");\n"
+ "-\tfor (i = 0; i < stats->max_states; i++) {\n"
+ "-\t\tif (len >= PAGE_SIZE)\n"
+ "-\t\t\tbreak;\n"
+ "-\t\tlen += snprintf(buf + len, PAGE_SIZE - len, \"state%2u  \", i);\n"
+ "-\t}\n"
+ "-\tif (len >= PAGE_SIZE)\n"
+ "-\t\treturn PAGE_SIZE;\n"
+ "+        spin_lock(&stats->lock);\n"
+ " \n"
+ "-\tlen += snprintf(buf + len, PAGE_SIZE - len, \"\\n\");\n"
+ "+\tret = kstrtoul(buf, 10, &state);\n"
+ "+        if (ret || (state > stats->max_states))\n"
+ "+\t\tgoto unlock;\n"
+ " \n"
+ "-\tfor (i = 0; i < stats->max_states; i++) {\n"
+ "-\t\tif (len >= PAGE_SIZE)\n"
+ "-\t\t\tbreak;\n"
+ "+\tstats->show_state = state;\n"
+ "+unlock:\n"
+ "+\tspin_unlock(&stats->lock);\n"
+ "+        return count;\n"
+ "+}\n"
+ " \n"
+ "-\t\tlen += snprintf(buf + len, PAGE_SIZE - len, \"state%2u:\", i);\n"
+ "+static ssize_t\n"
+ "+show_state_show(struct device *dev, struct device_attribute *attr, char *buf)\n"
+ "+{\n"
+ "+        struct thermal_cooling_device *cdev = to_cooling_device(dev);\n"
+ "+        struct cooling_dev_stats *stats = cdev->stats;\n"
+ "+\n"
+ "+\treturn sprintf(buf, \"%lu\\n\", stats->show_state);\n"
+ "+}\n"
+ "+\n"
+ "+static int find_show_state( int *nums, int numsSize, int k, unsigned int *max_value)\n"
+ "+{\n"
+ "+    int i, min = INT_MAX, max = 0;\n"
+ "+    for( i = 0; i < numsSize; ++i )\n"
+ "+    {\n"
+ "+        min = nums[i] < min ? nums[i] : min;\n"
+ "+        max = nums[i] > max ? nums[i] : max;\n"
+ "+    }\n"
+ "+    int l = min, r = max, mid, cnt = 0;\n"
+ "+    while( l < r )\n"
+ "+    {\n"
+ "+        mid = r - (r - l) / 2;\n"
+ "+        for( i = 0; i < numsSize; ++i )\n"
+ "+        {\n"
+ "+            if( nums[i] >= mid )\n"
+ "+                ++cnt;\n"
+ "+        }\n"
+ "+        if( cnt < k )\n"
+ "+        {\n"
+ "+            r = mid - 1;\n"
+ "+            cnt = 0;\n"
+ "+        }\n"
+ "+        else\n"
+ "+        {\n"
+ "+            l = mid;\n"
+ "+            cnt = 0;\n"
+ "+        }\n"
+ "+    }\n"
+ "+     *max_value = max;\n"
+ "+    return l;\n"
+ "+}\n"
+ " \n"
+ "-\t\tfor (j = 0; j < stats->max_states; j++) {\n"
+ "-\t\t\tif (len >= PAGE_SIZE)\n"
+ "-\t\t\t\tbreak;\n"
+ "-\t\t\tlen += snprintf(buf + len, PAGE_SIZE - len, \"%8u \",\n"
+ "-\t\t\t\tstats->trans_table[i * stats->max_states + j]);\n"
+ "-\t\t}\n"
+ "-\t\tif (len >= PAGE_SIZE)\n"
+ "-\t\t\tbreak;\n"
+ "-\t\tlen += snprintf(buf + len, PAGE_SIZE - len, \"\\n\");\n"
+ "-\t}\n"
+ " \n"
+ "-\tif (len >= PAGE_SIZE) {\n"
+ "-\t\tpr_warn_once(\"Thermal transition table exceeds PAGE_SIZE. Disabling\\n\");\n"
+ "-\t\treturn -EFBIG;\n"
+ "-\t}\n"
+ "-\treturn len;\n"
+ "+\n"
+ "+static ssize_t trans_table_show(struct device *dev,\n"
+ "+\t\t\t\tstruct device_attribute *attr, char *buf)\n"
+ "+{\n"
+ "+\tstruct thermal_cooling_device *cdev = to_cooling_device(dev);\n"
+ "+        struct cooling_dev_stats *stats = cdev->stats;\n"
+ "+        ssize_t len = 0;\n"
+ "+        int i, j;\n"
+ "+        unsigned int show_state_value = 0;\n"
+ "+\tunsigned int max_state_value = 0;\n"
+ "+\n"
+ "+        len += snprintf(buf + len, PAGE_SIZE - len, \" From  :    Index_change\\n\");\n"
+ "+        for (i = 0; i < stats->max_states; i++) {\n"
+ "+                show_state_value = find_show_state(&stats->trans_table[i * stats->max_states], stats->max_states, stats->show_state, &max_state_value);\n"
+ "+                if (max_state_value) {\n"
+ "+                        len += snprintf(buf + len, PAGE_SIZE - len, \"state%2u:\", i);\n"
+ "+                }\n"
+ "+                else {\n"
+ "+                        continue;\n"
+ "+                }\n"
+ "+\n"
+ "+                for (j = 0; j < stats->max_states; j++) {\n"
+ "+                        if (stats->trans_table[i * stats->max_states + j] && (show_state_value <= stats->trans_table[i * stats->max_states + j])) {\n"
+ "+                                len += snprintf(buf + len, PAGE_SIZE - len, \"     ->%u(%u)\",j, stats->trans_table[i * stats->max_states + j]);\n"
+ "+                        }\n"
+ "+                }\n"
+ "+                if (len >= PAGE_SIZE)\n"
+ "+                        break;\n"
+ "+                len += snprintf(buf + len, PAGE_SIZE - len, \"\\n\");\n"
+ "+        }\n"
+ "+\n"
+ "+        if (len >= PAGE_SIZE) {\n"
+ "+                pr_warn_once(\"Thermal transition table exceeds PAGE_SIZE. Disabling\\n\");\n"
+ "+                return -EFBIG;\n"
+ "+        }\n"
+ "+        return len;\n"
+ " }\n"
+ " \n"
+ " static DEVICE_ATTR_RO(total_trans);\n"
+ " static DEVICE_ATTR_RO(time_in_state_ms);\n"
+ " static DEVICE_ATTR_WO(reset);\n"
+ " static DEVICE_ATTR_RO(trans_table);\n"
+ "+static DEVICE_ATTR_RW(show_state);\n"
+ " \n"
+ " static struct attribute *cooling_device_stats_attrs[] = {\n"
+ " \t&dev_attr_total_trans.attr,\n"
+ " \t&dev_attr_time_in_state_ms.attr,\n"
+ " \t&dev_attr_reset.attr,\n"
+ " \t&dev_attr_trans_table.attr,\n"
+ "+\t&dev_attr_show_state.attr,\n"
+ " \tNULL\n"
+ " };\n"
+ " \n"
+ "@@ -829,7 +889,7 @@ static void cooling_device_stats_setup(struct thermal_cooling_device *cdev)\n"
+ " \tvar += sizeof(*stats->time_in_state) * states;\n"
+ " \tvar += sizeof(*stats->trans_table) * states * states;\n"
+ " \n"
+ "-\tstats = kzalloc(var, GFP_KERNEL);\n"
+ "+\tstats = kvzalloc(var, GFP_KERNEL);\n"
+ " \tif (!stats)\n"
+ " \t\treturn;\n"
+ " \n"
+ "@@ -838,6 +898,8 @@ static void cooling_device_stats_setup(struct thermal_cooling_device *cdev)\n"
+ " \tcdev->stats = stats;\n"
+ " \tstats->last_time = ktime_get();\n"
+ " \tstats->max_states = states;\n"
+ "+\t/* default set show_state = max_states/2 */\n"
+ "+\tstats->show_state = states / 2;\n"
+ " \n"
+ " \tspin_lock_init(&stats->lock);\n"
+ " \n"
+ "@@ -848,7 +910,7 @@ static void cooling_device_stats_setup(struct thermal_cooling_device *cdev)\n"
+ " \n"
+ " static void cooling_device_stats_destroy(struct thermal_cooling_device *cdev)\n"
+ " {\n"
+ "-\tkfree(cdev->stats);\n"
+ "+\tkvfree(cdev->stats);\n"
+ " \tcdev->stats = NULL;\n"
+ " }\n"
+ " \n"
+ "-- \n"
+ 2.25.1
 
-2737173c024dd0ddafc1bd89c5114ccda4f7a1d9ca772061609e7f6ae9fb06a2
+f805676c4ff978c13fe57d286b53ea7f0a785272868e5928792bbcafffb8c5d8

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox