From: huangqibo <[email protected]>
Because creating a cooling device may have duplicate names.
When creating, first check thermal_cdev_list whether
there is a device with the same name. If it has the same name,
it returns a reference to the cooling device.
Signed-off-by: huangqibo <[email protected]>
---
drivers/thermal/thermal_core.c | 34 ++++++++++++++++++++++++++++++++++
1 file changed, 34 insertions(+)
diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
index 117eeaf7dd24..092c7732a294 100644
--- a/drivers/thermal/thermal_core.c
+++ b/drivers/thermal/thermal_core.c
@@ -873,6 +873,12 @@ __thermal_cooling_device_register(struct device_node *np,
!ops->set_cur_state)
return ERR_PTR(-EINVAL);
+ if (type)
+ cdev = thermal_cdev_get_zone_by_name(type);
+
+ if (!IS_ERR_OR_NULL(cdev))
+ return cdev;
+
cdev = kzalloc(sizeof(*cdev), GFP_KERNEL);
if (!cdev)
return ERR_PTR(-ENOMEM);
@@ -1435,6 +1441,34 @@ struct thermal_zone_device *thermal_zone_get_zone_by_name(const char *name)
}
EXPORT_SYMBOL_GPL(thermal_zone_get_zone_by_name);
+struct thermal_cooling_device *thermal_cdev_get_zone_by_name(const char *name)
+{
+ struct thermal_cooling_device *pos = NULL, *ref = ERR_PTR(-EINVAL);
+ unsigned int found = 0;
+
+ if (!name)
+ goto exit;
+
+ mutex_lock(&thermal_list_lock);
+ list_for_each_entry(pos, &thermal_cdev_list, node)
+ if (!strncasecmp(name, pos->type, THERMAL_NAME_LENGTH)) {
+ found++;
+ ref = pos;
+ }
+ mutex_unlock(&thermal_list_lock);
+
+ /* nothing has been found, thus an error code for it */
+ if (found == 0)
+ ref = ERR_PTR(-ENODEV);
+ else if (found > 1)
+ /* Success only when an unique zone is found */
+ ref = ERR_PTR(-EEXIST);
+
+exit:
+ return ref;
+}
+EXPORT_SYMBOL_GPL(thermal_cdev_get_zone_by_name);
+
static int thermal_pm_notify(struct notifier_block *nb,
unsigned long mode, void *_unused)
{
--
2.36.1
Hi Qibo,
Thank you for the patch! Perhaps something to improve:
[auto build test WARNING on rafael-pm/thermal]
[also build test WARNING on linus/master v6.1-rc2 next-20221026]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Qibo-Huang/thermal-core-cooling-device-duplicate-creation-check/20221026-200457
base: https://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git thermal
patch link: https://lore.kernel.org/r/20221026120321.735-1-huangqibo.tech%40gmail.com
patch subject: [PATCH] thermal/core: cooling device duplicate creation check
config: m68k-allyesconfig
compiler: m68k-linux-gcc (GCC) 12.1.0
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# https://github.com/intel-lab-lkp/linux/commit/b9ffa61b51bd8fb000c57f602e94908c46345283
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review Qibo-Huang/thermal-core-cooling-device-duplicate-creation-check/20221026-200457
git checkout b9ffa61b51bd8fb000c57f602e94908c46345283
# save the config file
mkdir build_dir && cp config build_dir/.config
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=m68k SHELL=/bin/bash drivers/
If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <[email protected]>
All warnings (new ones prefixed by >>):
drivers/thermal/thermal_core.c: In function '__thermal_cooling_device_register':
drivers/thermal/thermal_core.c:877:24: error: implicit declaration of function 'thermal_cdev_get_zone_by_name'; did you mean 'thermal_zone_get_zone_by_name'? [-Werror=implicit-function-declaration]
877 | cdev = thermal_cdev_get_zone_by_name(type);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| thermal_zone_get_zone_by_name
>> drivers/thermal/thermal_core.c:877:22: warning: assignment to 'struct thermal_cooling_device *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
877 | cdev = thermal_cdev_get_zone_by_name(type);
| ^
drivers/thermal/thermal_core.c: At top level:
>> drivers/thermal/thermal_core.c:1444:32: warning: no previous prototype for 'thermal_cdev_get_zone_by_name' [-Wmissing-prototypes]
1444 | struct thermal_cooling_device *thermal_cdev_get_zone_by_name(const char *name)
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/thermal/thermal_core.c:1444:32: error: conflicting types for 'thermal_cdev_get_zone_by_name'; have 'struct thermal_cooling_device *(const char *)'
drivers/thermal/thermal_core.c:877:24: note: previous implicit declaration of 'thermal_cdev_get_zone_by_name' with type 'int()'
877 | cdev = thermal_cdev_get_zone_by_name(type);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
cc1: some warnings being treated as errors
vim +877 drivers/thermal/thermal_core.c
846
847 /**
848 * __thermal_cooling_device_register() - register a new thermal cooling device
849 * @np: a pointer to a device tree node.
850 * @type: the thermal cooling device type.
851 * @devdata: device private data.
852 * @ops: standard thermal cooling devices callbacks.
853 *
854 * This interface function adds a new thermal cooling device (fan/processor/...)
855 * to /sys/class/thermal/ folder as cooling_device[0-*]. It tries to bind itself
856 * to all the thermal zone devices registered at the same time.
857 * It also gives the opportunity to link the cooling device to a device tree
858 * node, so that it can be bound to a thermal zone created out of device tree.
859 *
860 * Return: a pointer to the created struct thermal_cooling_device or an
861 * ERR_PTR. Caller must check return value with IS_ERR*() helpers.
862 */
863 static struct thermal_cooling_device *
864 __thermal_cooling_device_register(struct device_node *np,
865 const char *type, void *devdata,
866 const struct thermal_cooling_device_ops *ops)
867 {
868 struct thermal_cooling_device *cdev;
869 struct thermal_zone_device *pos = NULL;
870 int id, ret;
871
872 if (!ops || !ops->get_max_state || !ops->get_cur_state ||
873 !ops->set_cur_state)
874 return ERR_PTR(-EINVAL);
875
876 if (type)
> 877 cdev = thermal_cdev_get_zone_by_name(type);
878
879 if (!IS_ERR_OR_NULL(cdev))
880 return cdev;
881
882 cdev = kzalloc(sizeof(*cdev), GFP_KERNEL);
883 if (!cdev)
884 return ERR_PTR(-ENOMEM);
885
886 ret = ida_alloc(&thermal_cdev_ida, GFP_KERNEL);
887 if (ret < 0)
888 goto out_kfree_cdev;
889 cdev->id = ret;
890 id = ret;
891
892 ret = dev_set_name(&cdev->device, "cooling_device%d", cdev->id);
893 if (ret)
894 goto out_ida_remove;
895
896 cdev->type = kstrdup(type ? type : "", GFP_KERNEL);
897 if (!cdev->type) {
898 ret = -ENOMEM;
899 goto out_ida_remove;
900 }
901
902 mutex_init(&cdev->lock);
903 INIT_LIST_HEAD(&cdev->thermal_instances);
904 cdev->np = np;
905 cdev->ops = ops;
906 cdev->updated = false;
907 cdev->device.class = &thermal_class;
908 cdev->devdata = devdata;
909 thermal_cooling_device_setup_sysfs(cdev);
910 ret = device_register(&cdev->device);
911 if (ret)
912 goto out_kfree_type;
913
914 /* Add 'this' new cdev to the global cdev list */
915 mutex_lock(&thermal_list_lock);
916 list_add(&cdev->node, &thermal_cdev_list);
917 mutex_unlock(&thermal_list_lock);
918
919 /* Update binding information for 'this' new cdev */
920 bind_cdev(cdev);
921
922 mutex_lock(&thermal_list_lock);
923 list_for_each_entry(pos, &thermal_tz_list, node)
924 if (atomic_cmpxchg(&pos->need_update, 1, 0))
925 thermal_zone_device_update(pos,
926 THERMAL_EVENT_UNSPECIFIED);
927 mutex_unlock(&thermal_list_lock);
928
929 return cdev;
930
931 out_kfree_type:
932 thermal_cooling_device_destroy_sysfs(cdev);
933 kfree(cdev->type);
934 put_device(&cdev->device);
935 cdev = NULL;
936 out_ida_remove:
937 ida_free(&thermal_cdev_ida, id);
938 out_kfree_cdev:
939 kfree(cdev);
940 return ERR_PTR(ret);
941 }
942
--
0-DAY CI Kernel Test Service
https://01.org/lkp
Hi Qibo,
Thank you for the patch! Perhaps something to improve:
[auto build test WARNING on rafael-pm/thermal]
[also build test WARNING on linus/master v6.1-rc2 next-20221026]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Qibo-Huang/thermal-core-cooling-device-duplicate-creation-check/20221026-200457
base: https://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git thermal
patch link: https://lore.kernel.org/r/20221026120321.735-1-huangqibo.tech%40gmail.com
patch subject: [PATCH] thermal/core: cooling device duplicate creation check
config: i386-randconfig-a013
compiler: clang version 14.0.6 (https://github.com/llvm/llvm-project f28c006a5895fc0e329fe15fead81e37457cb1d1)
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# https://github.com/intel-lab-lkp/linux/commit/b9ffa61b51bd8fb000c57f602e94908c46345283
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review Qibo-Huang/thermal-core-cooling-device-duplicate-creation-check/20221026-200457
git checkout b9ffa61b51bd8fb000c57f602e94908c46345283
# save the config file
mkdir build_dir && cp config build_dir/.config
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=i386 SHELL=/bin/bash drivers/thermal/
If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <[email protected]>
All warnings (new ones prefixed by >>):
drivers/thermal/thermal_core.c:877:10: error: implicit declaration of function 'thermal_cdev_get_zone_by_name' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
cdev = thermal_cdev_get_zone_by_name(type);
^
drivers/thermal/thermal_core.c:877:10: note: did you mean 'thermal_zone_get_zone_by_name'?
include/linux/thermal.h:368:29: note: 'thermal_zone_get_zone_by_name' declared here
struct thermal_zone_device *thermal_zone_get_zone_by_name(const char *name);
^
>> drivers/thermal/thermal_core.c:877:8: warning: incompatible integer to pointer conversion assigning to 'struct thermal_cooling_device *' from 'int' [-Wint-conversion]
cdev = thermal_cdev_get_zone_by_name(type);
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/thermal/thermal_core.c:1444:32: error: conflicting types for 'thermal_cdev_get_zone_by_name'
struct thermal_cooling_device *thermal_cdev_get_zone_by_name(const char *name)
^
drivers/thermal/thermal_core.c:877:10: note: previous implicit declaration is here
cdev = thermal_cdev_get_zone_by_name(type);
^
1 warning and 2 errors generated.
vim +877 drivers/thermal/thermal_core.c
846
847 /**
848 * __thermal_cooling_device_register() - register a new thermal cooling device
849 * @np: a pointer to a device tree node.
850 * @type: the thermal cooling device type.
851 * @devdata: device private data.
852 * @ops: standard thermal cooling devices callbacks.
853 *
854 * This interface function adds a new thermal cooling device (fan/processor/...)
855 * to /sys/class/thermal/ folder as cooling_device[0-*]. It tries to bind itself
856 * to all the thermal zone devices registered at the same time.
857 * It also gives the opportunity to link the cooling device to a device tree
858 * node, so that it can be bound to a thermal zone created out of device tree.
859 *
860 * Return: a pointer to the created struct thermal_cooling_device or an
861 * ERR_PTR. Caller must check return value with IS_ERR*() helpers.
862 */
863 static struct thermal_cooling_device *
864 __thermal_cooling_device_register(struct device_node *np,
865 const char *type, void *devdata,
866 const struct thermal_cooling_device_ops *ops)
867 {
868 struct thermal_cooling_device *cdev;
869 struct thermal_zone_device *pos = NULL;
870 int id, ret;
871
872 if (!ops || !ops->get_max_state || !ops->get_cur_state ||
873 !ops->set_cur_state)
874 return ERR_PTR(-EINVAL);
875
876 if (type)
> 877 cdev = thermal_cdev_get_zone_by_name(type);
878
879 if (!IS_ERR_OR_NULL(cdev))
880 return cdev;
881
882 cdev = kzalloc(sizeof(*cdev), GFP_KERNEL);
883 if (!cdev)
884 return ERR_PTR(-ENOMEM);
885
886 ret = ida_alloc(&thermal_cdev_ida, GFP_KERNEL);
887 if (ret < 0)
888 goto out_kfree_cdev;
889 cdev->id = ret;
890 id = ret;
891
892 ret = dev_set_name(&cdev->device, "cooling_device%d", cdev->id);
893 if (ret)
894 goto out_ida_remove;
895
896 cdev->type = kstrdup(type ? type : "", GFP_KERNEL);
897 if (!cdev->type) {
898 ret = -ENOMEM;
899 goto out_ida_remove;
900 }
901
902 mutex_init(&cdev->lock);
903 INIT_LIST_HEAD(&cdev->thermal_instances);
904 cdev->np = np;
905 cdev->ops = ops;
906 cdev->updated = false;
907 cdev->device.class = &thermal_class;
908 cdev->devdata = devdata;
909 thermal_cooling_device_setup_sysfs(cdev);
910 ret = device_register(&cdev->device);
911 if (ret)
912 goto out_kfree_type;
913
914 /* Add 'this' new cdev to the global cdev list */
915 mutex_lock(&thermal_list_lock);
916 list_add(&cdev->node, &thermal_cdev_list);
917 mutex_unlock(&thermal_list_lock);
918
919 /* Update binding information for 'this' new cdev */
920 bind_cdev(cdev);
921
922 mutex_lock(&thermal_list_lock);
923 list_for_each_entry(pos, &thermal_tz_list, node)
924 if (atomic_cmpxchg(&pos->need_update, 1, 0))
925 thermal_zone_device_update(pos,
926 THERMAL_EVENT_UNSPECIFIED);
927 mutex_unlock(&thermal_list_lock);
928
929 return cdev;
930
931 out_kfree_type:
932 thermal_cooling_device_destroy_sysfs(cdev);
933 kfree(cdev->type);
934 put_device(&cdev->device);
935 cdev = NULL;
936 out_ida_remove:
937 ida_free(&thermal_cdev_ida, id);
938 out_kfree_cdev:
939 kfree(cdev);
940 return ERR_PTR(ret);
941 }
942
--
0-DAY CI Kernel Test Service
https://01.org/lkp
Hi Qibo,
Thank you for the patch! Yet something to improve:
[auto build test ERROR on rafael-pm/thermal]
[also build test ERROR on linus/master v6.1-rc2 next-20221026]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Qibo-Huang/thermal-core-cooling-device-duplicate-creation-check/20221026-200457
base: https://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git thermal
patch link: https://lore.kernel.org/r/20221026120321.735-1-huangqibo.tech%40gmail.com
patch subject: [PATCH] thermal/core: cooling device duplicate creation check
config: mips-randconfig-r021-20221026
compiler: clang version 16.0.0 (https://github.com/llvm/llvm-project 791a7ae1ba3efd6bca96338e10ffde557ba83920)
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# install mips cross compiling tool for clang build
# apt-get install binutils-mips64el-linux-gnuabi64
# https://github.com/intel-lab-lkp/linux/commit/b9ffa61b51bd8fb000c57f602e94908c46345283
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review Qibo-Huang/thermal-core-cooling-device-duplicate-creation-check/20221026-200457
git checkout b9ffa61b51bd8fb000c57f602e94908c46345283
# save the config file
mkdir build_dir && cp config build_dir/.config
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=mips SHELL=/bin/bash drivers/
If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <[email protected]>
All errors (new ones prefixed by >>):
>> drivers/thermal/thermal_core.c:877:10: error: call to undeclared function 'thermal_cdev_get_zone_by_name'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
cdev = thermal_cdev_get_zone_by_name(type);
^
drivers/thermal/thermal_core.c:877:10: note: did you mean 'thermal_zone_get_zone_by_name'?
include/linux/thermal.h:368:29: note: 'thermal_zone_get_zone_by_name' declared here
struct thermal_zone_device *thermal_zone_get_zone_by_name(const char *name);
^
>> drivers/thermal/thermal_core.c:877:8: error: incompatible integer to pointer conversion assigning to 'struct thermal_cooling_device *' from 'int' [-Wint-conversion]
cdev = thermal_cdev_get_zone_by_name(type);
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/thermal/thermal_core.c:1444:32: error: conflicting types for 'thermal_cdev_get_zone_by_name'
struct thermal_cooling_device *thermal_cdev_get_zone_by_name(const char *name)
^
drivers/thermal/thermal_core.c:877:10: note: previous implicit declaration is here
cdev = thermal_cdev_get_zone_by_name(type);
^
3 errors generated.
vim +/thermal_cdev_get_zone_by_name +877 drivers/thermal/thermal_core.c
846
847 /**
848 * __thermal_cooling_device_register() - register a new thermal cooling device
849 * @np: a pointer to a device tree node.
850 * @type: the thermal cooling device type.
851 * @devdata: device private data.
852 * @ops: standard thermal cooling devices callbacks.
853 *
854 * This interface function adds a new thermal cooling device (fan/processor/...)
855 * to /sys/class/thermal/ folder as cooling_device[0-*]. It tries to bind itself
856 * to all the thermal zone devices registered at the same time.
857 * It also gives the opportunity to link the cooling device to a device tree
858 * node, so that it can be bound to a thermal zone created out of device tree.
859 *
860 * Return: a pointer to the created struct thermal_cooling_device or an
861 * ERR_PTR. Caller must check return value with IS_ERR*() helpers.
862 */
863 static struct thermal_cooling_device *
864 __thermal_cooling_device_register(struct device_node *np,
865 const char *type, void *devdata,
866 const struct thermal_cooling_device_ops *ops)
867 {
868 struct thermal_cooling_device *cdev;
869 struct thermal_zone_device *pos = NULL;
870 int id, ret;
871
872 if (!ops || !ops->get_max_state || !ops->get_cur_state ||
873 !ops->set_cur_state)
874 return ERR_PTR(-EINVAL);
875
876 if (type)
> 877 cdev = thermal_cdev_get_zone_by_name(type);
878
879 if (!IS_ERR_OR_NULL(cdev))
880 return cdev;
881
882 cdev = kzalloc(sizeof(*cdev), GFP_KERNEL);
883 if (!cdev)
884 return ERR_PTR(-ENOMEM);
885
886 ret = ida_alloc(&thermal_cdev_ida, GFP_KERNEL);
887 if (ret < 0)
888 goto out_kfree_cdev;
889 cdev->id = ret;
890 id = ret;
891
892 ret = dev_set_name(&cdev->device, "cooling_device%d", cdev->id);
893 if (ret)
894 goto out_ida_remove;
895
896 cdev->type = kstrdup(type ? type : "", GFP_KERNEL);
897 if (!cdev->type) {
898 ret = -ENOMEM;
899 goto out_ida_remove;
900 }
901
902 mutex_init(&cdev->lock);
903 INIT_LIST_HEAD(&cdev->thermal_instances);
904 cdev->np = np;
905 cdev->ops = ops;
906 cdev->updated = false;
907 cdev->device.class = &thermal_class;
908 cdev->devdata = devdata;
909 thermal_cooling_device_setup_sysfs(cdev);
910 ret = device_register(&cdev->device);
911 if (ret)
912 goto out_kfree_type;
913
914 /* Add 'this' new cdev to the global cdev list */
915 mutex_lock(&thermal_list_lock);
916 list_add(&cdev->node, &thermal_cdev_list);
917 mutex_unlock(&thermal_list_lock);
918
919 /* Update binding information for 'this' new cdev */
920 bind_cdev(cdev);
921
922 mutex_lock(&thermal_list_lock);
923 list_for_each_entry(pos, &thermal_tz_list, node)
924 if (atomic_cmpxchg(&pos->need_update, 1, 0))
925 thermal_zone_device_update(pos,
926 THERMAL_EVENT_UNSPECIFIED);
927 mutex_unlock(&thermal_list_lock);
928
929 return cdev;
930
931 out_kfree_type:
932 thermal_cooling_device_destroy_sysfs(cdev);
933 kfree(cdev->type);
934 put_device(&cdev->device);
935 cdev = NULL;
936 out_ida_remove:
937 ida_free(&thermal_cdev_ida, id);
938 out_kfree_cdev:
939 kfree(cdev);
940 return ERR_PTR(ret);
941 }
942
--
0-DAY CI Kernel Test Service
https://01.org/lkp