2019-10-15 07:04:24

by Wei Wang

[permalink] [raw]
Subject: [PATCH] thermal: create softlink by name for thermal_zone and cooling_device

The paths thermal_zone%d and cooling_device%d are not intuitive and the
numbers are subject to change due to device tree change. This usually
leads to tree traversal in userspace code.
The patch creates `tz-by-name' and `cdev-by-name' for thermal zone and
cooling_device respectively.

Signed-off-by: Wei Wang <[email protected]>
---
drivers/thermal/thermal_core.c | 23 +++++++++++++++++++++--
1 file changed, 21 insertions(+), 2 deletions(-)

diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
index d4481cc8958f..0ff8fb1d7b0a 100644
--- a/drivers/thermal/thermal_core.c
+++ b/drivers/thermal/thermal_core.c
@@ -22,6 +22,7 @@
#include <net/netlink.h>
#include <net/genetlink.h>
#include <linux/suspend.h>
+#include <linux/kobject.h>

#define CREATE_TRACE_POINTS
#include <trace/events/thermal.h>
@@ -46,6 +47,8 @@ static DEFINE_MUTEX(poweroff_lock);

static atomic_t in_suspend;
static bool power_off_triggered;
+static struct kobject *cdev_link_kobj;
+static struct kobject *tz_link_kobj;

static struct thermal_governor *def_governor;

@@ -954,7 +957,7 @@ __thermal_cooling_device_register(struct device_node *np,
struct thermal_zone_device *pos = NULL;
int result;

- if (type && strlen(type) >= THERMAL_NAME_LENGTH)
+ if (!type || !type[0] || strlen(type) >= THERMAL_NAME_LENGTH)
return ERR_PTR(-EINVAL);

if (!ops || !ops->get_max_state || !ops->get_cur_state ||
@@ -989,9 +992,15 @@ __thermal_cooling_device_register(struct device_node *np,
return ERR_PTR(result);
}

- /* Add 'this' new cdev to the global cdev list */
+ /* Add 'this' new cdev to the global cdev list and create link*/
mutex_lock(&thermal_list_lock);
list_add(&cdev->node, &thermal_cdev_list);
+ if (!cdev_link_kobj)
+ cdev_link_kobj = kobject_create_and_add("cdev-by-name",
+ cdev->device.kobj.parent);
+ if (!cdev_link_kobj || sysfs_create_link(cdev_link_kobj,
+ &cdev->device.kobj, cdev->type))
+ dev_err(&cdev->device, "Failed to create cdev-by-name link\n");
mutex_unlock(&thermal_list_lock);

/* Update binding information for 'this' new cdev */
@@ -1157,6 +1166,8 @@ void thermal_cooling_device_unregister(struct thermal_cooling_device *cdev)
}
}
}
+ if (cdev_link_kobj)
+ sysfs_remove_link(cdev_link_kobj, cdev->type);

mutex_unlock(&thermal_list_lock);

@@ -1340,6 +1351,12 @@ thermal_zone_device_register(const char *type, int trips, int mask,

mutex_lock(&thermal_list_lock);
list_add_tail(&tz->node, &thermal_tz_list);
+ if (!tz_link_kobj)
+ tz_link_kobj = kobject_create_and_add("tz-by-name",
+ tz->device.kobj.parent);
+ if (!tz_link_kobj || sysfs_create_link(tz_link_kobj,
+ &tz->device.kobj, tz->type))
+ dev_err(&tz->device, "Failed to create tz-by-name link\n");
mutex_unlock(&thermal_list_lock);

/* Bind cooling devices for this zone */
@@ -1411,6 +1428,8 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz)
}
}
}
+ if (tz_link_kobj)
+ sysfs_remove_link(tz_link_kobj, tz->type);

mutex_unlock(&thermal_list_lock);

--
2.23.0.700.g56cf767bdb-goog


2019-10-17 12:36:14

by Amit Kucheria

[permalink] [raw]
Subject: Re: [PATCH] thermal: create softlink by name for thermal_zone and cooling_device

On Tue, Oct 15, 2019 at 11:43 AM Wei Wang <[email protected]> wrote:
>
> The paths thermal_zone%d and cooling_device%d are not intuitive and the
> numbers are subject to change due to device tree change. This usually
> leads to tree traversal in userspace code.
> The patch creates `tz-by-name' and `cdev-by-name' for thermal zone and
> cooling_device respectively.

I like this.

> Signed-off-by: Wei Wang <[email protected]>
> ---
> drivers/thermal/thermal_core.c | 23 +++++++++++++++++++++--
> 1 file changed, 21 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
> index d4481cc8958f..0ff8fb1d7b0a 100644
> --- a/drivers/thermal/thermal_core.c
> +++ b/drivers/thermal/thermal_core.c
> @@ -22,6 +22,7 @@
> #include <net/netlink.h>
> #include <net/genetlink.h>
> #include <linux/suspend.h>
> +#include <linux/kobject.h>
>
> #define CREATE_TRACE_POINTS
> #include <trace/events/thermal.h>
> @@ -46,6 +47,8 @@ static DEFINE_MUTEX(poweroff_lock);
>
> static atomic_t in_suspend;
> static bool power_off_triggered;
> +static struct kobject *cdev_link_kobj;
> +static struct kobject *tz_link_kobj;
>
> static struct thermal_governor *def_governor;
>
> @@ -954,7 +957,7 @@ __thermal_cooling_device_register(struct device_node *np,
> struct thermal_zone_device *pos = NULL;
> int result;
>
> - if (type && strlen(type) >= THERMAL_NAME_LENGTH)
> + if (!type || !type[0] || strlen(type) >= THERMAL_NAME_LENGTH)
> return ERR_PTR(-EINVAL);

This should be a separate fix, if needed.

> if (!ops || !ops->get_max_state || !ops->get_cur_state ||
> @@ -989,9 +992,15 @@ __thermal_cooling_device_register(struct device_node *np,
> return ERR_PTR(result);
> }
>
> - /* Add 'this' new cdev to the global cdev list */
> + /* Add 'this' new cdev to the global cdev list and create link*/
> mutex_lock(&thermal_list_lock);
> list_add(&cdev->node, &thermal_cdev_list);
> + if (!cdev_link_kobj)
> + cdev_link_kobj = kobject_create_and_add("cdev-by-name",
> + cdev->device.kobj.parent);
> + if (!cdev_link_kobj || sysfs_create_link(cdev_link_kobj,
> + &cdev->device.kobj, cdev->type))
> + dev_err(&cdev->device, "Failed to create cdev-by-name link\n");

Any reason not to use the following form instead? It seems easier to read.

if (!cdev_link_kobj) {
cdev_link_kobj = kobject_create_and_add("cdev-by-name",
cdev->device.kobj.parent);
ret = sysfs_create_link(cdev_link_kobj,
&cdev->device.kobj, cdev->type))
if (ret)
dev_err(&cdev->device, "Failed to create
cdev-by-name link\n");
}

> mutex_unlock(&thermal_list_lock);
>
> /* Update binding information for 'this' new cdev */
> @@ -1157,6 +1166,8 @@ void thermal_cooling_device_unregister(struct thermal_cooling_device *cdev)
> }
> }
> }
> + if (cdev_link_kobj)
> + sysfs_remove_link(cdev_link_kobj, cdev->type);
>
> mutex_unlock(&thermal_list_lock);
>
> @@ -1340,6 +1351,12 @@ thermal_zone_device_register(const char *type, int trips, int mask,
>
> mutex_lock(&thermal_list_lock);
> list_add_tail(&tz->node, &thermal_tz_list);
> + if (!tz_link_kobj)
> + tz_link_kobj = kobject_create_and_add("tz-by-name",
> + tz->device.kobj.parent);
> + if (!tz_link_kobj || sysfs_create_link(tz_link_kobj,
> + &tz->device.kobj, tz->type))
> + dev_err(&tz->device, "Failed to create tz-by-name link\n");

Same as above.

> mutex_unlock(&thermal_list_lock);
>
> /* Bind cooling devices for this zone */
> @@ -1411,6 +1428,8 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz)
> }
> }
> }
> + if (tz_link_kobj)
> + sysfs_remove_link(tz_link_kobj, tz->type);
>
> mutex_unlock(&thermal_list_lock);
>
> --
> 2.23.0.700.g56cf767bdb-goog
>

2019-10-17 12:49:12

by Amit Kucheria

[permalink] [raw]
Subject: Re: [PATCH] thermal: create softlink by name for thermal_zone and cooling_device

On Wed, Oct 16, 2019 at 10:20 PM Amit Kucheria
<[email protected]> wrote:
>
> On Tue, Oct 15, 2019 at 11:43 AM Wei Wang <[email protected]> wrote:
> >
> > The paths thermal_zone%d and cooling_device%d are not intuitive and the
> > numbers are subject to change due to device tree change. This usually
> > leads to tree traversal in userspace code.
> > The patch creates `tz-by-name' and `cdev-by-name' for thermal zone and
> > cooling_device respectively.
>
> I like this.
>
> > Signed-off-by: Wei Wang <[email protected]>
> > ---
> > drivers/thermal/thermal_core.c | 23 +++++++++++++++++++++--
> > 1 file changed, 21 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
> > index d4481cc8958f..0ff8fb1d7b0a 100644
> > --- a/drivers/thermal/thermal_core.c
> > +++ b/drivers/thermal/thermal_core.c
> > @@ -22,6 +22,7 @@
> > #include <net/netlink.h>
> > #include <net/genetlink.h>
> > #include <linux/suspend.h>
> > +#include <linux/kobject.h>
> >
> > #define CREATE_TRACE_POINTS
> > #include <trace/events/thermal.h>
> > @@ -46,6 +47,8 @@ static DEFINE_MUTEX(poweroff_lock);
> >
> > static atomic_t in_suspend;
> > static bool power_off_triggered;
> > +static struct kobject *cdev_link_kobj;
> > +static struct kobject *tz_link_kobj;
> >
> > static struct thermal_governor *def_governor;
> >
> > @@ -954,7 +957,7 @@ __thermal_cooling_device_register(struct device_node *np,
> > struct thermal_zone_device *pos = NULL;
> > int result;
> >
> > - if (type && strlen(type) >= THERMAL_NAME_LENGTH)
> > + if (!type || !type[0] || strlen(type) >= THERMAL_NAME_LENGTH)
> > return ERR_PTR(-EINVAL);
>
> This should be a separate fix, if needed.
>
> > if (!ops || !ops->get_max_state || !ops->get_cur_state ||
> > @@ -989,9 +992,15 @@ __thermal_cooling_device_register(struct device_node *np,
> > return ERR_PTR(result);
> > }
> >
> > - /* Add 'this' new cdev to the global cdev list */
> > + /* Add 'this' new cdev to the global cdev list and create link*/
> > mutex_lock(&thermal_list_lock);
> > list_add(&cdev->node, &thermal_cdev_list);
> > + if (!cdev_link_kobj)
> > + cdev_link_kobj = kobject_create_and_add("cdev-by-name",
> > + cdev->device.kobj.parent);
> > + if (!cdev_link_kobj || sysfs_create_link(cdev_link_kobj,
> > + &cdev->device.kobj, cdev->type))
> > + dev_err(&cdev->device, "Failed to create cdev-by-name link\n");
>
> Any reason not to use the following form instead? It seems easier to read.
>
> if (!cdev_link_kobj) {
> cdev_link_kobj = kobject_create_and_add("cdev-by-name",
> cdev->device.kobj.parent);
> ret = sysfs_create_link(cdev_link_kobj,
> &cdev->device.kobj, cdev->type))
> if (ret)
> dev_err(&cdev->device, "Failed to create
> cdev-by-name link\n");
> }

I can now see why you had to do that - none of the other links would
get created after the first one.

Perhaps create the directories in the __init functions and only create
the links here?


> > mutex_unlock(&thermal_list_lock);
> >
> > /* Update binding information for 'this' new cdev */
> > @@ -1157,6 +1166,8 @@ void thermal_cooling_device_unregister(struct thermal_cooling_device *cdev)
> > }
> > }
> > }
> > + if (cdev_link_kobj)
> > + sysfs_remove_link(cdev_link_kobj, cdev->type);
> >
> > mutex_unlock(&thermal_list_lock);
> >
> > @@ -1340,6 +1351,12 @@ thermal_zone_device_register(const char *type, int trips, int mask,
> >
> > mutex_lock(&thermal_list_lock);
> > list_add_tail(&tz->node, &thermal_tz_list);
> > + if (!tz_link_kobj)
> > + tz_link_kobj = kobject_create_and_add("tz-by-name",
> > + tz->device.kobj.parent);
> > + if (!tz_link_kobj || sysfs_create_link(tz_link_kobj,
> > + &tz->device.kobj, tz->type))
> > + dev_err(&tz->device, "Failed to create tz-by-name link\n");
>
> Same as above.
>
> > mutex_unlock(&thermal_list_lock);
> >
> > /* Bind cooling devices for this zone */
> > @@ -1411,6 +1428,8 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz)
> > }
> > }
> > }
> > + if (tz_link_kobj)
> > + sysfs_remove_link(tz_link_kobj, tz->type);
> >
> > mutex_unlock(&thermal_list_lock);
> >
> > --
> > 2.23.0.700.g56cf767bdb-goog
> >

2019-10-17 14:06:45

by Wei Wang

[permalink] [raw]
Subject: Re: [PATCH] thermal: create softlink by name for thermal_zone and cooling_device

On Wed, Oct 16, 2019 at 10:16 AM Amit Kucheria
<[email protected]> wrote:
>
> On Wed, Oct 16, 2019 at 10:20 PM Amit Kucheria
> <[email protected]> wrote:
> >
> > On Tue, Oct 15, 2019 at 11:43 AM Wei Wang <[email protected]> wrote:
> > >
> > > The paths thermal_zone%d and cooling_device%d are not intuitive and the
> > > numbers are subject to change due to device tree change. This usually
> > > leads to tree traversal in userspace code.
> > > The patch creates `tz-by-name' and `cdev-by-name' for thermal zone and
> > > cooling_device respectively.
> >
> > I like this.
> >
> > > Signed-off-by: Wei Wang <[email protected]>
> > > ---
> > > drivers/thermal/thermal_core.c | 23 +++++++++++++++++++++--
> > > 1 file changed, 21 insertions(+), 2 deletions(-)
> > >
> > > diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
> > > index d4481cc8958f..0ff8fb1d7b0a 100644
> > > --- a/drivers/thermal/thermal_core.c
> > > +++ b/drivers/thermal/thermal_core.c
> > > @@ -22,6 +22,7 @@
> > > #include <net/netlink.h>
> > > #include <net/genetlink.h>
> > > #include <linux/suspend.h>
> > > +#include <linux/kobject.h>
> > >
> > > #define CREATE_TRACE_POINTS
> > > #include <trace/events/thermal.h>
> > > @@ -46,6 +47,8 @@ static DEFINE_MUTEX(poweroff_lock);
> > >
> > > static atomic_t in_suspend;
> > > static bool power_off_triggered;
> > > +static struct kobject *cdev_link_kobj;
> > > +static struct kobject *tz_link_kobj;
> > >
> > > static struct thermal_governor *def_governor;
> > >
> > > @@ -954,7 +957,7 @@ __thermal_cooling_device_register(struct device_node *np,
> > > struct thermal_zone_device *pos = NULL;
> > > int result;
> > >
> > > - if (type && strlen(type) >= THERMAL_NAME_LENGTH)
> > > + if (!type || !type[0] || strlen(type) >= THERMAL_NAME_LENGTH)
> > > return ERR_PTR(-EINVAL);
> >
> > This should be a separate fix, if needed.
Agree, but the link now requires that "" as invalid _type_.


> >
> > > if (!ops || !ops->get_max_state || !ops->get_cur_state ||
> > > @@ -989,9 +992,15 @@ __thermal_cooling_device_register(struct device_node *np,
> > > return ERR_PTR(result);
> > > }
> > >
> > > - /* Add 'this' new cdev to the global cdev list */
> > > + /* Add 'this' new cdev to the global cdev list and create link*/
> > > mutex_lock(&thermal_list_lock);
> > > list_add(&cdev->node, &thermal_cdev_list);
> > > + if (!cdev_link_kobj)
> > > + cdev_link_kobj = kobject_create_and_add("cdev-by-name",
> > > + cdev->device.kobj.parent);
> > > + if (!cdev_link_kobj || sysfs_create_link(cdev_link_kobj,
> > > + &cdev->device.kobj, cdev->type))
> > > + dev_err(&cdev->device, "Failed to create cdev-by-name link\n");
> >
> > Any reason not to use the following form instead? It seems easier to read.
> >
> > if (!cdev_link_kobj) {
> > cdev_link_kobj = kobject_create_and_add("cdev-by-name",
> > cdev->device.kobj.parent);
> > ret = sysfs_create_link(cdev_link_kobj,
> > &cdev->device.kobj, cdev->type))
> > if (ret)
> > dev_err(&cdev->device, "Failed to create
> > cdev-by-name link\n");
> > }
>
> I can now see why you had to do that - none of the other links would
> get created after the first one.
>
> Perhaps create the directories in the __init functions and only create
> the links here?
>
AFAICT, this is no such API except the private get_device_parent()
under driver/base/. Also the lazy initialization makes sense in such
case when there is no thermal device attached. Looks like the class
dir is also lazy-initialized when first device registered
https://elixir.bootlin.com/linux/v5.3.5/source/drivers/base/core.c#L1790.

>
> > > mutex_unlock(&thermal_list_lock);
> > >
> > > /* Update binding information for 'this' new cdev */
> > > @@ -1157,6 +1166,8 @@ void thermal_cooling_device_unregister(struct thermal_cooling_device *cdev)
> > > }
> > > }
> > > }
> > > + if (cdev_link_kobj)
> > > + sysfs_remove_link(cdev_link_kobj, cdev->type);
> > >
> > > mutex_unlock(&thermal_list_lock);
> > >
> > > @@ -1340,6 +1351,12 @@ thermal_zone_device_register(const char *type, int trips, int mask,
> > >
> > > mutex_lock(&thermal_list_lock);
> > > list_add_tail(&tz->node, &thermal_tz_list);
> > > + if (!tz_link_kobj)
> > > + tz_link_kobj = kobject_create_and_add("tz-by-name",
> > > + tz->device.kobj.parent);
> > > + if (!tz_link_kobj || sysfs_create_link(tz_link_kobj,
> > > + &tz->device.kobj, tz->type))
> > > + dev_err(&tz->device, "Failed to create tz-by-name link\n");
> >
> > Same as above.
> >
> > > mutex_unlock(&thermal_list_lock);
> > >
> > > /* Bind cooling devices for this zone */
> > > @@ -1411,6 +1428,8 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz)
> > > }
> > > }
> > > }
> > > + if (tz_link_kobj)
> > > + sysfs_remove_link(tz_link_kobj, tz->type);
> > >
> > > mutex_unlock(&thermal_list_lock);
> > >
> > > --
> > > 2.23.0.700.g56cf767bdb-goog
> > >

2019-11-11 05:28:08

by Amit Kucheria

[permalink] [raw]
Subject: Re: [PATCH] thermal: create softlink by name for thermal_zone and cooling_device

On Thu, Oct 17, 2019 at 3:04 AM Wei Wang <[email protected]> wrote:
>
> On Wed, Oct 16, 2019 at 10:16 AM Amit Kucheria
> <[email protected]> wrote:
> >
> > On Wed, Oct 16, 2019 at 10:20 PM Amit Kucheria
> > <[email protected]> wrote:
> > >
> > > On Tue, Oct 15, 2019 at 11:43 AM Wei Wang <[email protected]> wrote:
> > > >
> > > > The paths thermal_zone%d and cooling_device%d are not intuitive and the
> > > > numbers are subject to change due to device tree change. This usually
> > > > leads to tree traversal in userspace code.
> > > > The patch creates `tz-by-name' and `cdev-by-name' for thermal zone and
> > > > cooling_device respectively.
> > >
> > > I like this.
> > >
> > > > Signed-off-by: Wei Wang <[email protected]>
> > > > ---
> > > > drivers/thermal/thermal_core.c | 23 +++++++++++++++++++++--
> > > > 1 file changed, 21 insertions(+), 2 deletions(-)
> > > >
> > > > diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
> > > > index d4481cc8958f..0ff8fb1d7b0a 100644
> > > > --- a/drivers/thermal/thermal_core.c
> > > > +++ b/drivers/thermal/thermal_core.c
> > > > @@ -22,6 +22,7 @@
> > > > #include <net/netlink.h>
> > > > #include <net/genetlink.h>
> > > > #include <linux/suspend.h>
> > > > +#include <linux/kobject.h>
> > > >
> > > > #define CREATE_TRACE_POINTS
> > > > #include <trace/events/thermal.h>
> > > > @@ -46,6 +47,8 @@ static DEFINE_MUTEX(poweroff_lock);
> > > >
> > > > static atomic_t in_suspend;
> > > > static bool power_off_triggered;
> > > > +static struct kobject *cdev_link_kobj;
> > > > +static struct kobject *tz_link_kobj;
> > > >
> > > > static struct thermal_governor *def_governor;
> > > >
> > > > @@ -954,7 +957,7 @@ __thermal_cooling_device_register(struct device_node *np,
> > > > struct thermal_zone_device *pos = NULL;
> > > > int result;
> > > >
> > > > - if (type && strlen(type) >= THERMAL_NAME_LENGTH)
> > > > + if (!type || !type[0] || strlen(type) >= THERMAL_NAME_LENGTH)
> > > > return ERR_PTR(-EINVAL);
> > >
> > > This should be a separate fix, if needed.
> Agree, but the link now requires that "" as invalid _type_.

I'm not sure I understand. What does this change have to do with
adding symlinks below?

> > >
> > > > if (!ops || !ops->get_max_state || !ops->get_cur_state ||
> > > > @@ -989,9 +992,15 @@ __thermal_cooling_device_register(struct device_node *np,
> > > > return ERR_PTR(result);
> > > > }
> > > >
> > > > - /* Add 'this' new cdev to the global cdev list */
> > > > + /* Add 'this' new cdev to the global cdev list and create link*/
> > > > mutex_lock(&thermal_list_lock);
> > > > list_add(&cdev->node, &thermal_cdev_list);
> > > > + if (!cdev_link_kobj)
> > > > + cdev_link_kobj = kobject_create_and_add("cdev-by-name",
> > > > + cdev->device.kobj.parent);
> > > > + if (!cdev_link_kobj || sysfs_create_link(cdev_link_kobj,
> > > > + &cdev->device.kobj, cdev->type))
> > > > + dev_err(&cdev->device, "Failed to create cdev-by-name link\n");
> > >
> > > Any reason not to use the following form instead? It seems easier to read.
> > >
> > > if (!cdev_link_kobj) {
> > > cdev_link_kobj = kobject_create_and_add("cdev-by-name",
> > > cdev->device.kobj.parent);
> > > ret = sysfs_create_link(cdev_link_kobj,
> > > &cdev->device.kobj, cdev->type))
> > > if (ret)
> > > dev_err(&cdev->device, "Failed to create
> > > cdev-by-name link\n");
> > > }
> >
> > I can now see why you had to do that - none of the other links would
> > get created after the first one.
> >
> > Perhaps create the directories in the __init functions and only create
> > the links here?
> >
> AFAICT, this is no such API except the private get_device_parent()
> under driver/base/. Also the lazy initialization makes sense in such
> case when there is no thermal device attached. Looks like the class
> dir is also lazy-initialized when first device registered
> https://elixir.bootlin.com/linux/v5.3.5/source/drivers/base/core.c#L1790.

OK.

> >
> > > > mutex_unlock(&thermal_list_lock);
> > > >
> > > > /* Update binding information for 'this' new cdev */
> > > > @@ -1157,6 +1166,8 @@ void thermal_cooling_device_unregister(struct thermal_cooling_device *cdev)
> > > > }
> > > > }
> > > > }
> > > > + if (cdev_link_kobj)
> > > > + sysfs_remove_link(cdev_link_kobj, cdev->type);
> > > >
> > > > mutex_unlock(&thermal_list_lock);
> > > >
> > > > @@ -1340,6 +1351,12 @@ thermal_zone_device_register(const char *type, int trips, int mask,
> > > >
> > > > mutex_lock(&thermal_list_lock);
> > > > list_add_tail(&tz->node, &thermal_tz_list);
> > > > + if (!tz_link_kobj)
> > > > + tz_link_kobj = kobject_create_and_add("tz-by-name",
> > > > + tz->device.kobj.parent);
> > > > + if (!tz_link_kobj || sysfs_create_link(tz_link_kobj,
> > > > + &tz->device.kobj, tz->type))
> > > > + dev_err(&tz->device, "Failed to create tz-by-name link\n");
> > >
> > > Same as above.
> > >
> > > > mutex_unlock(&thermal_list_lock);
> > > >
> > > > /* Bind cooling devices for this zone */
> > > > @@ -1411,6 +1428,8 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz)
> > > > }
> > > > }
> > > > }
> > > > + if (tz_link_kobj)
> > > > + sysfs_remove_link(tz_link_kobj, tz->type);
> > > >
> > > > mutex_unlock(&thermal_list_lock);
> > > >
> > > > --
> > > > 2.23.0.700.g56cf767bdb-goog
> > > >

2019-11-11 17:54:02

by Wei Wang

[permalink] [raw]
Subject: Re: [PATCH] thermal: create softlink by name for thermal_zone and cooling_device

On Sun, Nov 10, 2019 at 9:26 PM Amit Kucheria
<[email protected]> wrote:
>
> On Thu, Oct 17, 2019 at 3:04 AM Wei Wang <[email protected]> wrote:
> >
> > On Wed, Oct 16, 2019 at 10:16 AM Amit Kucheria
> > <[email protected]> wrote:
> > >
> > > On Wed, Oct 16, 2019 at 10:20 PM Amit Kucheria
> > > <[email protected]> wrote:
> > > >
> > > > On Tue, Oct 15, 2019 at 11:43 AM Wei Wang <[email protected]> wrote:
> > > > >
> > > > > The paths thermal_zone%d and cooling_device%d are not intuitive and the
> > > > > numbers are subject to change due to device tree change. This usually
> > > > > leads to tree traversal in userspace code.
> > > > > The patch creates `tz-by-name' and `cdev-by-name' for thermal zone and
> > > > > cooling_device respectively.
> > > >
> > > > I like this.
> > > >
> > > > > Signed-off-by: Wei Wang <[email protected]>
> > > > > ---
> > > > > drivers/thermal/thermal_core.c | 23 +++++++++++++++++++++--
> > > > > 1 file changed, 21 insertions(+), 2 deletions(-)
> > > > >
> > > > > diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
> > > > > index d4481cc8958f..0ff8fb1d7b0a 100644
> > > > > --- a/drivers/thermal/thermal_core.c
> > > > > +++ b/drivers/thermal/thermal_core.c
> > > > > @@ -22,6 +22,7 @@
> > > > > #include <net/netlink.h>
> > > > > #include <net/genetlink.h>
> > > > > #include <linux/suspend.h>
> > > > > +#include <linux/kobject.h>
> > > > >
> > > > > #define CREATE_TRACE_POINTS
> > > > > #include <trace/events/thermal.h>
> > > > > @@ -46,6 +47,8 @@ static DEFINE_MUTEX(poweroff_lock);
> > > > >
> > > > > static atomic_t in_suspend;
> > > > > static bool power_off_triggered;
> > > > > +static struct kobject *cdev_link_kobj;
> > > > > +static struct kobject *tz_link_kobj;
> > > > >
> > > > > static struct thermal_governor *def_governor;
> > > > >
> > > > > @@ -954,7 +957,7 @@ __thermal_cooling_device_register(struct device_node *np,
> > > > > struct thermal_zone_device *pos = NULL;
> > > > > int result;
> > > > >
> > > > > - if (type && strlen(type) >= THERMAL_NAME_LENGTH)
> > > > > + if (!type || !type[0] || strlen(type) >= THERMAL_NAME_LENGTH)
> > > > > return ERR_PTR(-EINVAL);
> > > >
> > > > This should be a separate fix, if needed.
> > Agree, but the link now requires that "" as invalid _type_.
>
> I'm not sure I understand. What does this change have to do with
> adding symlinks below?
>

cdev->type will be used later in sysfs_create_link and adding "" as
symlink is kind of bad practise AIUI.

thanks


> > > >
> > > > > if (!ops || !ops->get_max_state || !ops->get_cur_state ||
> > > > > @@ -989,9 +992,15 @@ __thermal_cooling_device_register(struct device_node *np,
> > > > > return ERR_PTR(result);
> > > > > }
> > > > >
> > > > > - /* Add 'this' new cdev to the global cdev list */
> > > > > + /* Add 'this' new cdev to the global cdev list and create link*/
> > > > > mutex_lock(&thermal_list_lock);
> > > > > list_add(&cdev->node, &thermal_cdev_list);
> > > > > + if (!cdev_link_kobj)
> > > > > + cdev_link_kobj = kobject_create_and_add("cdev-by-name",
> > > > > + cdev->device.kobj.parent);
> > > > > + if (!cdev_link_kobj || sysfs_create_link(cdev_link_kobj,
> > > > > + &cdev->device.kobj, cdev->type))
> > > > > + dev_err(&cdev->device, "Failed to create cdev-by-name link\n");
> > > >
> > > > Any reason not to use the following form instead? It seems easier to read.
> > > >
> > > > if (!cdev_link_kobj) {
> > > > cdev_link_kobj = kobject_create_and_add("cdev-by-name",
> > > > cdev->device.kobj.parent);
> > > > ret = sysfs_create_link(cdev_link_kobj,
> > > > &cdev->device.kobj, cdev->type))
> > > > if (ret)
> > > > dev_err(&cdev->device, "Failed to create
> > > > cdev-by-name link\n");
> > > > }
> > >
> > > I can now see why you had to do that - none of the other links would
> > > get created after the first one.
> > >
> > > Perhaps create the directories in the __init functions and only create
> > > the links here?
> > >
> > AFAICT, this is no such API except the private get_device_parent()
> > under driver/base/. Also the lazy initialization makes sense in such
> > case when there is no thermal device attached. Looks like the class
> > dir is also lazy-initialized when first device registered
> > https://elixir.bootlin.com/linux/v5.3.5/source/drivers/base/core.c#L1790.
>
> OK.
>
> > >
> > > > > mutex_unlock(&thermal_list_lock);
> > > > >
> > > > > /* Update binding information for 'this' new cdev */
> > > > > @@ -1157,6 +1166,8 @@ void thermal_cooling_device_unregister(struct thermal_cooling_device *cdev)
> > > > > }
> > > > > }
> > > > > }
> > > > > + if (cdev_link_kobj)
> > > > > + sysfs_remove_link(cdev_link_kobj, cdev->type);
> > > > >
> > > > > mutex_unlock(&thermal_list_lock);
> > > > >
> > > > > @@ -1340,6 +1351,12 @@ thermal_zone_device_register(const char *type, int trips, int mask,
> > > > >
> > > > > mutex_lock(&thermal_list_lock);
> > > > > list_add_tail(&tz->node, &thermal_tz_list);
> > > > > + if (!tz_link_kobj)
> > > > > + tz_link_kobj = kobject_create_and_add("tz-by-name",
> > > > > + tz->device.kobj.parent);
> > > > > + if (!tz_link_kobj || sysfs_create_link(tz_link_kobj,
> > > > > + &tz->device.kobj, tz->type))
> > > > > + dev_err(&tz->device, "Failed to create tz-by-name link\n");
> > > >
> > > > Same as above.
> > > >
> > > > > mutex_unlock(&thermal_list_lock);
> > > > >
> > > > > /* Bind cooling devices for this zone */
> > > > > @@ -1411,6 +1428,8 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz)
> > > > > }
> > > > > }
> > > > > }
> > > > > + if (tz_link_kobj)
> > > > > + sysfs_remove_link(tz_link_kobj, tz->type);
> > > > >
> > > > > mutex_unlock(&thermal_list_lock);
> > > > >
> > > > > --
> > > > > 2.23.0.700.g56cf767bdb-goog
> > > > >

2019-12-04 12:47:06

by Amit Kucheria

[permalink] [raw]
Subject: Re: [PATCH] thermal: create softlink by name for thermal_zone and cooling_device

On Mon, Nov 11, 2019 at 11:22 PM Wei Wang <[email protected]> wrote:
>
> On Sun, Nov 10, 2019 at 9:26 PM Amit Kucheria
> <[email protected]> wrote:
> >
> > On Thu, Oct 17, 2019 at 3:04 AM Wei Wang <[email protected]> wrote:
> > >
> > > On Wed, Oct 16, 2019 at 10:16 AM Amit Kucheria
> > > <[email protected]> wrote:
> > > >
> > > > On Wed, Oct 16, 2019 at 10:20 PM Amit Kucheria
> > > > <[email protected]> wrote:
> > > > >
> > > > > On Tue, Oct 15, 2019 at 11:43 AM Wei Wang <[email protected]> wrote:
> > > > > >
> > > > > > The paths thermal_zone%d and cooling_device%d are not intuitive and the
> > > > > > numbers are subject to change due to device tree change. This usually
> > > > > > leads to tree traversal in userspace code.
> > > > > > The patch creates `tz-by-name' and `cdev-by-name' for thermal zone and
> > > > > > cooling_device respectively.
> > > > >
> > > > > I like this.
> > > > >
> > > > > > Signed-off-by: Wei Wang <[email protected]>
> > > > > > ---
> > > > > > drivers/thermal/thermal_core.c | 23 +++++++++++++++++++++--
> > > > > > 1 file changed, 21 insertions(+), 2 deletions(-)
> > > > > >
> > > > > > diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
> > > > > > index d4481cc8958f..0ff8fb1d7b0a 100644
> > > > > > --- a/drivers/thermal/thermal_core.c
> > > > > > +++ b/drivers/thermal/thermal_core.c
> > > > > > @@ -22,6 +22,7 @@
> > > > > > #include <net/netlink.h>
> > > > > > #include <net/genetlink.h>
> > > > > > #include <linux/suspend.h>
> > > > > > +#include <linux/kobject.h>
> > > > > >
> > > > > > #define CREATE_TRACE_POINTS
> > > > > > #include <trace/events/thermal.h>
> > > > > > @@ -46,6 +47,8 @@ static DEFINE_MUTEX(poweroff_lock);
> > > > > >
> > > > > > static atomic_t in_suspend;
> > > > > > static bool power_off_triggered;
> > > > > > +static struct kobject *cdev_link_kobj;
> > > > > > +static struct kobject *tz_link_kobj;
> > > > > >
> > > > > > static struct thermal_governor *def_governor;
> > > > > >
> > > > > > @@ -954,7 +957,7 @@ __thermal_cooling_device_register(struct device_node *np,
> > > > > > struct thermal_zone_device *pos = NULL;
> > > > > > int result;
> > > > > >
> > > > > > - if (type && strlen(type) >= THERMAL_NAME_LENGTH)
> > > > > > + if (!type || !type[0] || strlen(type) >= THERMAL_NAME_LENGTH)
> > > > > > return ERR_PTR(-EINVAL);
> > > > >
> > > > > This should be a separate fix, if needed.
> > > Agree, but the link now requires that "" as invalid _type_.
> >
> > I'm not sure I understand. What does this change have to do with
> > adding symlinks below?
> >
>
> cdev->type will be used later in sysfs_create_link and adding "" as
> symlink is kind of bad practise AIUI.
>

Perhaps I'm being dense here, in which case my apologies.

But what stops us from splitting the patch into two?
1. Make type == "" as invalid by using your change above and fixing up
the strlcpy(cdev->type....) further down.
2. Create the actual symlinks in a separate patch.

Regards,
Amit

> > > > >
> > > > > > if (!ops || !ops->get_max_state || !ops->get_cur_state ||
> > > > > > @@ -989,9 +992,15 @@ __thermal_cooling_device_register(struct device_node *np,
> > > > > > return ERR_PTR(result);
> > > > > > }
> > > > > >
> > > > > > - /* Add 'this' new cdev to the global cdev list */
> > > > > > + /* Add 'this' new cdev to the global cdev list and create link*/
> > > > > > mutex_lock(&thermal_list_lock);
> > > > > > list_add(&cdev->node, &thermal_cdev_list);
> > > > > > + if (!cdev_link_kobj)
> > > > > > + cdev_link_kobj = kobject_create_and_add("cdev-by-name",
> > > > > > + cdev->device.kobj.parent);
> > > > > > + if (!cdev_link_kobj || sysfs_create_link(cdev_link_kobj,
> > > > > > + &cdev->device.kobj, cdev->type))
> > > > > > + dev_err(&cdev->device, "Failed to create cdev-by-name link\n");
> > > > >
> > > > > Any reason not to use the following form instead? It seems easier to read.
> > > > >
> > > > > if (!cdev_link_kobj) {
> > > > > cdev_link_kobj = kobject_create_and_add("cdev-by-name",
> > > > > cdev->device.kobj.parent);
> > > > > ret = sysfs_create_link(cdev_link_kobj,
> > > > > &cdev->device.kobj, cdev->type))
> > > > > if (ret)
> > > > > dev_err(&cdev->device, "Failed to create
> > > > > cdev-by-name link\n");
> > > > > }
> > > >
> > > > I can now see why you had to do that - none of the other links would
> > > > get created after the first one.
> > > >
> > > > Perhaps create the directories in the __init functions and only create
> > > > the links here?
> > > >
> > > AFAICT, this is no such API except the private get_device_parent()
> > > under driver/base/. Also the lazy initialization makes sense in such
> > > case when there is no thermal device attached. Looks like the class
> > > dir is also lazy-initialized when first device registered
> > > https://elixir.bootlin.com/linux/v5.3.5/source/drivers/base/core.c#L1790.
> >
> > OK.
> >
> > > >
> > > > > > mutex_unlock(&thermal_list_lock);
> > > > > >
> > > > > > /* Update binding information for 'this' new cdev */
> > > > > > @@ -1157,6 +1166,8 @@ void thermal_cooling_device_unregister(struct thermal_cooling_device *cdev)
> > > > > > }
> > > > > > }
> > > > > > }
> > > > > > + if (cdev_link_kobj)
> > > > > > + sysfs_remove_link(cdev_link_kobj, cdev->type);
> > > > > >
> > > > > > mutex_unlock(&thermal_list_lock);
> > > > > >
> > > > > > @@ -1340,6 +1351,12 @@ thermal_zone_device_register(const char *type, int trips, int mask,
> > > > > >
> > > > > > mutex_lock(&thermal_list_lock);
> > > > > > list_add_tail(&tz->node, &thermal_tz_list);
> > > > > > + if (!tz_link_kobj)
> > > > > > + tz_link_kobj = kobject_create_and_add("tz-by-name",
> > > > > > + tz->device.kobj.parent);
> > > > > > + if (!tz_link_kobj || sysfs_create_link(tz_link_kobj,
> > > > > > + &tz->device.kobj, tz->type))
> > > > > > + dev_err(&tz->device, "Failed to create tz-by-name link\n");
> > > > >
> > > > > Same as above.
> > > > >
> > > > > > mutex_unlock(&thermal_list_lock);
> > > > > >
> > > > > > /* Bind cooling devices for this zone */
> > > > > > @@ -1411,6 +1428,8 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz)
> > > > > > }
> > > > > > }
> > > > > > }
> > > > > > + if (tz_link_kobj)
> > > > > > + sysfs_remove_link(tz_link_kobj, tz->type);
> > > > > >
> > > > > > mutex_unlock(&thermal_list_lock);
> > > > > >
> > > > > > --
> > > > > > 2.23.0.700.g56cf767bdb-goog
> > > > > >

2019-12-04 21:57:09

by Wei Wang

[permalink] [raw]
Subject: [PATCH v2 0/2] thermal: introduce by-name softlink

The paths thermal_zone%d and cooling_device%d are not intuitive and the
numbers are subject to change due to device tree change. This usually
leads to tree traversal in userspace code.
The patch creates `tz-by-name' and `cdev-by-name' for thermal zone and
cooling_device respectively.

Changes since v1 [1]:
* Split cooling device registration into a seperate patch

[1]: v1: https://lore.kernel.org/patchwork/patch/1139450/

Wei Wang (2):
thermal: fix and clean up tz and cdev registration
thermal: create softlink by name for thermal_zone and cooling_device

drivers/thermal/thermal_core.c | 37 +++++++++++++++++++++++++++++-----
1 file changed, 32 insertions(+), 5 deletions(-)

--
2.24.0.393.g34dc348eaf-goog

2019-12-04 21:57:27

by Wei Wang

[permalink] [raw]
Subject: [PATCH v2 1/2] thermal: fix and clean up tz and cdev registration

Make cooling device registration behavior consistent with
thermal zone. This patch also cleans up a unnecessary
nullptr check.

Signed-off-by: Wei Wang <[email protected]>
---
drivers/thermal/thermal_core.c | 16 ++++++++++++----
1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
index d4481cc8958f..64fbb59c2f44 100644
--- a/drivers/thermal/thermal_core.c
+++ b/drivers/thermal/thermal_core.c
@@ -954,8 +954,16 @@ __thermal_cooling_device_register(struct device_node *np,
struct thermal_zone_device *pos = NULL;
int result;

- if (type && strlen(type) >= THERMAL_NAME_LENGTH)
- return ERR_PTR(-EINVAL);
+ if (!type || !type[0]) {
+ pr_err("Error: No cooling device type defined\n");
+ return ERR_PTR(-EINVAL);
+ }
+
+ if (strlen(type) >= THERMAL_NAME_LENGTH) {
+ pr_err("Error: Cooling device name (%s) too long, "
+ "should be under %d chars\n", type, THERMAL_NAME_LENGTH);
+ return ERR_PTR(-EINVAL);
+ }

if (!ops || !ops->get_max_state || !ops->get_cur_state ||
!ops->set_cur_state)
@@ -972,7 +980,7 @@ __thermal_cooling_device_register(struct device_node *np,
}

cdev->id = result;
- strlcpy(cdev->type, type ? : "", sizeof(cdev->type));
+ strlcpy(cdev->type, type, sizeof(cdev->type));
mutex_init(&cdev->lock);
INIT_LIST_HEAD(&cdev->thermal_instances);
cdev->np = np;
@@ -1250,7 +1258,7 @@ thermal_zone_device_register(const char *type, int trips, int mask,
return ERR_PTR(-EINVAL);
}

- if (type && strlen(type) >= THERMAL_NAME_LENGTH) {
+ if (strlen(type) >= THERMAL_NAME_LENGTH) {
pr_err("Error: Thermal zone name (%s) too long, should be under %d chars\n",
type, THERMAL_NAME_LENGTH);
return ERR_PTR(-EINVAL);
--
2.24.0.393.g34dc348eaf-goog

2019-12-04 21:57:39

by Wei Wang

[permalink] [raw]
Subject: [PATCH v2 2/2] thermal: create softlink by name for thermal_zone and cooling_device

The paths thermal_zone%d and cooling_device%d are not intuitive and the
numbers are subject to change due to device tree change. This usually
leads to tree traversal in userspace code.
The patch creates `tz-by-name' and `cdev-by-name' for thermal zone and
cooling_device respectively.

Signed-off-by: Wei Wang <[email protected]>
---
drivers/thermal/thermal_core.c | 21 ++++++++++++++++++++-
1 file changed, 20 insertions(+), 1 deletion(-)

diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
index 64fbb59c2f44..4f55e3f16265 100644
--- a/drivers/thermal/thermal_core.c
+++ b/drivers/thermal/thermal_core.c
@@ -22,6 +22,7 @@
#include <net/netlink.h>
#include <net/genetlink.h>
#include <linux/suspend.h>
+#include <linux/kobject.h>

#define CREATE_TRACE_POINTS
#include <trace/events/thermal.h>
@@ -46,6 +47,8 @@ static DEFINE_MUTEX(poweroff_lock);

static atomic_t in_suspend;
static bool power_off_triggered;
+static struct kobject *cdev_link_kobj;
+static struct kobject *tz_link_kobj;

static struct thermal_governor *def_governor;

@@ -997,9 +1000,15 @@ __thermal_cooling_device_register(struct device_node *np,
return ERR_PTR(result);
}

- /* Add 'this' new cdev to the global cdev list */
+ /* Add 'this' new cdev to the global cdev list and create link*/
mutex_lock(&thermal_list_lock);
list_add(&cdev->node, &thermal_cdev_list);
+ if (!cdev_link_kobj)
+ cdev_link_kobj = kobject_create_and_add("cdev-by-name",
+ cdev->device.kobj.parent);
+ if (!cdev_link_kobj || sysfs_create_link(cdev_link_kobj,
+ &cdev->device.kobj, cdev->type))
+ dev_err(&cdev->device, "Failed to create cdev-by-name link\n");
mutex_unlock(&thermal_list_lock);

/* Update binding information for 'this' new cdev */
@@ -1165,6 +1174,8 @@ void thermal_cooling_device_unregister(struct thermal_cooling_device *cdev)
}
}
}
+ if (cdev_link_kobj)
+ sysfs_remove_link(cdev_link_kobj, cdev->type);

mutex_unlock(&thermal_list_lock);

@@ -1348,6 +1359,12 @@ thermal_zone_device_register(const char *type, int trips, int mask,

mutex_lock(&thermal_list_lock);
list_add_tail(&tz->node, &thermal_tz_list);
+ if (!tz_link_kobj)
+ tz_link_kobj = kobject_create_and_add("tz-by-name",
+ tz->device.kobj.parent);
+ if (!tz_link_kobj || sysfs_create_link(tz_link_kobj,
+ &tz->device.kobj, tz->type))
+ dev_err(&tz->device, "Failed to create tz-by-name link\n");
mutex_unlock(&thermal_list_lock);

/* Bind cooling devices for this zone */
@@ -1419,6 +1436,8 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz)
}
}
}
+ if (tz_link_kobj)
+ sysfs_remove_link(tz_link_kobj, tz->type);

mutex_unlock(&thermal_list_lock);

--
2.24.0.393.g34dc348eaf-goog

2019-12-04 21:59:47

by Wei Wang

[permalink] [raw]
Subject: Re: [PATCH] thermal: create softlink by name for thermal_zone and cooling_device

On Wed, Dec 4, 2019 at 4:45 AM Amit Kucheria
<[email protected]> wrote:
>
> On Mon, Nov 11, 2019 at 11:22 PM Wei Wang <[email protected]> wrote:
> >
> > On Sun, Nov 10, 2019 at 9:26 PM Amit Kucheria
> > <[email protected]> wrote:
> > >
> > > On Thu, Oct 17, 2019 at 3:04 AM Wei Wang <[email protected]> wrote:
> > > >
> > > > On Wed, Oct 16, 2019 at 10:16 AM Amit Kucheria
> > > > <[email protected]> wrote:
> > > > >
> > > > > On Wed, Oct 16, 2019 at 10:20 PM Amit Kucheria
> > > > > <[email protected]> wrote:
> > > > > >
> > > > > > On Tue, Oct 15, 2019 at 11:43 AM Wei Wang <[email protected]> wrote:
> > > > > > >
> > > > > > > The paths thermal_zone%d and cooling_device%d are not intuitive and the
> > > > > > > numbers are subject to change due to device tree change. This usually
> > > > > > > leads to tree traversal in userspace code.
> > > > > > > The patch creates `tz-by-name' and `cdev-by-name' for thermal zone and
> > > > > > > cooling_device respectively.
> > > > > >
> > > > > > I like this.
> > > > > >
> > > > > > > Signed-off-by: Wei Wang <[email protected]>
> > > > > > > ---
> > > > > > > drivers/thermal/thermal_core.c | 23 +++++++++++++++++++++--
> > > > > > > 1 file changed, 21 insertions(+), 2 deletions(-)
> > > > > > >
> > > > > > > diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
> > > > > > > index d4481cc8958f..0ff8fb1d7b0a 100644
> > > > > > > --- a/drivers/thermal/thermal_core.c
> > > > > > > +++ b/drivers/thermal/thermal_core.c
> > > > > > > @@ -22,6 +22,7 @@
> > > > > > > #include <net/netlink.h>
> > > > > > > #include <net/genetlink.h>
> > > > > > > #include <linux/suspend.h>
> > > > > > > +#include <linux/kobject.h>
> > > > > > >
> > > > > > > #define CREATE_TRACE_POINTS
> > > > > > > #include <trace/events/thermal.h>
> > > > > > > @@ -46,6 +47,8 @@ static DEFINE_MUTEX(poweroff_lock);
> > > > > > >
> > > > > > > static atomic_t in_suspend;
> > > > > > > static bool power_off_triggered;
> > > > > > > +static struct kobject *cdev_link_kobj;
> > > > > > > +static struct kobject *tz_link_kobj;
> > > > > > >
> > > > > > > static struct thermal_governor *def_governor;
> > > > > > >
> > > > > > > @@ -954,7 +957,7 @@ __thermal_cooling_device_register(struct device_node *np,
> > > > > > > struct thermal_zone_device *pos = NULL;
> > > > > > > int result;
> > > > > > >
> > > > > > > - if (type && strlen(type) >= THERMAL_NAME_LENGTH)
> > > > > > > + if (!type || !type[0] || strlen(type) >= THERMAL_NAME_LENGTH)
> > > > > > > return ERR_PTR(-EINVAL);
> > > > > >
> > > > > > This should be a separate fix, if needed.
> > > > Agree, but the link now requires that "" as invalid _type_.
> > >
> > > I'm not sure I understand. What does this change have to do with
> > > adding symlinks below?
> > >
> >
> > cdev->type will be used later in sysfs_create_link and adding "" as
> > symlink is kind of bad practise AIUI.
> >
>
> Perhaps I'm being dense here, in which case my apologies.
>
> But what stops us from splitting the patch into two?
> 1. Make type == "" as invalid by using your change above and fixing up
> the strlcpy(cdev->type....) further down.
> 2. Create the actual symlinks in a separate patch.
>
> Regards,
> Amit
>
Updated with v2, thanks.

>
> > > > > >
> > > > > > > if (!ops || !ops->get_max_state || !ops->get_cur_state ||
> > > > > > > @@ -989,9 +992,15 @@ __thermal_cooling_device_register(struct device_node *np,
> > > > > > > return ERR_PTR(result);
> > > > > > > }
> > > > > > >
> > > > > > > - /* Add 'this' new cdev to the global cdev list */
> > > > > > > + /* Add 'this' new cdev to the global cdev list and create link*/
> > > > > > > mutex_lock(&thermal_list_lock);
> > > > > > > list_add(&cdev->node, &thermal_cdev_list);
> > > > > > > + if (!cdev_link_kobj)
> > > > > > > + cdev_link_kobj = kobject_create_and_add("cdev-by-name",
> > > > > > > + cdev->device.kobj.parent);
> > > > > > > + if (!cdev_link_kobj || sysfs_create_link(cdev_link_kobj,
> > > > > > > + &cdev->device.kobj, cdev->type))
> > > > > > > + dev_err(&cdev->device, "Failed to create cdev-by-name link\n");
> > > > > >
> > > > > > Any reason not to use the following form instead? It seems easier to read.
> > > > > >
> > > > > > if (!cdev_link_kobj) {
> > > > > > cdev_link_kobj = kobject_create_and_add("cdev-by-name",
> > > > > > cdev->device.kobj.parent);
> > > > > > ret = sysfs_create_link(cdev_link_kobj,
> > > > > > &cdev->device.kobj, cdev->type))
> > > > > > if (ret)
> > > > > > dev_err(&cdev->device, "Failed to create
> > > > > > cdev-by-name link\n");
> > > > > > }
> > > > >
> > > > > I can now see why you had to do that - none of the other links would
> > > > > get created after the first one.
> > > > >
> > > > > Perhaps create the directories in the __init functions and only create
> > > > > the links here?
> > > > >
> > > > AFAICT, this is no such API except the private get_device_parent()
> > > > under driver/base/. Also the lazy initialization makes sense in such
> > > > case when there is no thermal device attached. Looks like the class
> > > > dir is also lazy-initialized when first device registered
> > > > https://elixir.bootlin.com/linux/v5.3.5/source/drivers/base/core.c#L1790.
> > >
> > > OK.
> > >
> > > > >
> > > > > > > mutex_unlock(&thermal_list_lock);
> > > > > > >
> > > > > > > /* Update binding information for 'this' new cdev */
> > > > > > > @@ -1157,6 +1166,8 @@ void thermal_cooling_device_unregister(struct thermal_cooling_device *cdev)
> > > > > > > }
> > > > > > > }
> > > > > > > }
> > > > > > > + if (cdev_link_kobj)
> > > > > > > + sysfs_remove_link(cdev_link_kobj, cdev->type);
> > > > > > >
> > > > > > > mutex_unlock(&thermal_list_lock);
> > > > > > >
> > > > > > > @@ -1340,6 +1351,12 @@ thermal_zone_device_register(const char *type, int trips, int mask,
> > > > > > >
> > > > > > > mutex_lock(&thermal_list_lock);
> > > > > > > list_add_tail(&tz->node, &thermal_tz_list);
> > > > > > > + if (!tz_link_kobj)
> > > > > > > + tz_link_kobj = kobject_create_and_add("tz-by-name",
> > > > > > > + tz->device.kobj.parent);
> > > > > > > + if (!tz_link_kobj || sysfs_create_link(tz_link_kobj,
> > > > > > > + &tz->device.kobj, tz->type))
> > > > > > > + dev_err(&tz->device, "Failed to create tz-by-name link\n");
> > > > > >
> > > > > > Same as above.
> > > > > >
> > > > > > > mutex_unlock(&thermal_list_lock);
> > > > > > >
> > > > > > > /* Bind cooling devices for this zone */
> > > > > > > @@ -1411,6 +1428,8 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz)
> > > > > > > }
> > > > > > > }
> > > > > > > }
> > > > > > > + if (tz_link_kobj)
> > > > > > > + sysfs_remove_link(tz_link_kobj, tz->type);
> > > > > > >
> > > > > > > mutex_unlock(&thermal_list_lock);
> > > > > > >
> > > > > > > --
> > > > > > > 2.23.0.700.g56cf767bdb-goog
> > > > > > >

2019-12-05 04:14:27

by Amit Kucheria

[permalink] [raw]
Subject: Re: [PATCH v2 1/2] thermal: fix and clean up tz and cdev registration

Hi Wei,

On Thu, Dec 5, 2019 at 3:26 AM Wei Wang <[email protected]> wrote:
>
> Make cooling device registration behavior consistent with

Consistent how? Please add details.

> thermal zone. This patch also cleans up a unnecessary
> nullptr check.
>
> Signed-off-by: Wei Wang <[email protected]>
> ---
> drivers/thermal/thermal_core.c | 16 ++++++++++++----
> 1 file changed, 12 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
> index d4481cc8958f..64fbb59c2f44 100644
> --- a/drivers/thermal/thermal_core.c
> +++ b/drivers/thermal/thermal_core.c
> @@ -954,8 +954,16 @@ __thermal_cooling_device_register(struct device_node *np,
> struct thermal_zone_device *pos = NULL;
> int result;
>
> - if (type && strlen(type) >= THERMAL_NAME_LENGTH)
> - return ERR_PTR(-EINVAL);
> + if (!type || !type[0]) {
> + pr_err("Error: No cooling device type defined\n");
> + return ERR_PTR(-EINVAL);
> + }
> +
> + if (strlen(type) >= THERMAL_NAME_LENGTH) {
> + pr_err("Error: Cooling device name (%s) too long, "
> + "should be under %d chars\n", type, THERMAL_NAME_LENGTH);

Consider fitting into a single greppable string as "Error: Cooling
device name over %d chars: %s\n"

> + return ERR_PTR(-EINVAL);
> + }
>
> if (!ops || !ops->get_max_state || !ops->get_cur_state ||
> !ops->set_cur_state)
> @@ -972,7 +980,7 @@ __thermal_cooling_device_register(struct device_node *np,
> }
>
> cdev->id = result;
> - strlcpy(cdev->type, type ? : "", sizeof(cdev->type));
> + strlcpy(cdev->type, type, sizeof(cdev->type));
> mutex_init(&cdev->lock);
> INIT_LIST_HEAD(&cdev->thermal_instances);
> cdev->np = np;
> @@ -1250,7 +1258,7 @@ thermal_zone_device_register(const char *type, int trips, int mask,
> return ERR_PTR(-EINVAL);
> }
>
> - if (type && strlen(type) >= THERMAL_NAME_LENGTH) {
> + if (strlen(type) >= THERMAL_NAME_LENGTH) {
> pr_err("Error: Thermal zone name (%s) too long, should be under %d chars\n",
> type, THERMAL_NAME_LENGTH);
> return ERR_PTR(-EINVAL);
> --
> 2.24.0.393.g34dc348eaf-goog
>

2019-12-05 04:15:32

by Amit Kucheria

[permalink] [raw]
Subject: Re: [PATCH v2 2/2] thermal: create softlink by name for thermal_zone and cooling_device

On Thu, Dec 5, 2019 at 3:26 AM Wei Wang <[email protected]> wrote:
>
> The paths thermal_zone%d and cooling_device%d are not intuitive and the
> numbers are subject to change due to device tree change. This usually
> leads to tree traversal in userspace code.
> The patch creates `tz-by-name' and `cdev-by-name' for thermal zone and
> cooling_device respectively.
>
> Signed-off-by: Wei Wang <[email protected]>

Reviewed-by: Amit Kucheria <[email protected]>

> ---
> drivers/thermal/thermal_core.c | 21 ++++++++++++++++++++-
> 1 file changed, 20 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
> index 64fbb59c2f44..4f55e3f16265 100644
> --- a/drivers/thermal/thermal_core.c
> +++ b/drivers/thermal/thermal_core.c
> @@ -22,6 +22,7 @@
> #include <net/netlink.h>
> #include <net/genetlink.h>
> #include <linux/suspend.h>
> +#include <linux/kobject.h>
>
> #define CREATE_TRACE_POINTS
> #include <trace/events/thermal.h>
> @@ -46,6 +47,8 @@ static DEFINE_MUTEX(poweroff_lock);
>
> static atomic_t in_suspend;
> static bool power_off_triggered;
> +static struct kobject *cdev_link_kobj;
> +static struct kobject *tz_link_kobj;
>
> static struct thermal_governor *def_governor;
>
> @@ -997,9 +1000,15 @@ __thermal_cooling_device_register(struct device_node *np,
> return ERR_PTR(result);
> }
>
> - /* Add 'this' new cdev to the global cdev list */
> + /* Add 'this' new cdev to the global cdev list and create link*/
> mutex_lock(&thermal_list_lock);
> list_add(&cdev->node, &thermal_cdev_list);
> + if (!cdev_link_kobj)
> + cdev_link_kobj = kobject_create_and_add("cdev-by-name",
> + cdev->device.kobj.parent);
> + if (!cdev_link_kobj || sysfs_create_link(cdev_link_kobj,
> + &cdev->device.kobj, cdev->type))
> + dev_err(&cdev->device, "Failed to create cdev-by-name link\n");
> mutex_unlock(&thermal_list_lock);
>
> /* Update binding information for 'this' new cdev */
> @@ -1165,6 +1174,8 @@ void thermal_cooling_device_unregister(struct thermal_cooling_device *cdev)
> }
> }
> }
> + if (cdev_link_kobj)
> + sysfs_remove_link(cdev_link_kobj, cdev->type);
>
> mutex_unlock(&thermal_list_lock);
>
> @@ -1348,6 +1359,12 @@ thermal_zone_device_register(const char *type, int trips, int mask,
>
> mutex_lock(&thermal_list_lock);
> list_add_tail(&tz->node, &thermal_tz_list);
> + if (!tz_link_kobj)
> + tz_link_kobj = kobject_create_and_add("tz-by-name",
> + tz->device.kobj.parent);
> + if (!tz_link_kobj || sysfs_create_link(tz_link_kobj,
> + &tz->device.kobj, tz->type))
> + dev_err(&tz->device, "Failed to create tz-by-name link\n");
> mutex_unlock(&thermal_list_lock);
>
> /* Bind cooling devices for this zone */
> @@ -1419,6 +1436,8 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz)
> }
> }
> }
> + if (tz_link_kobj)
> + sysfs_remove_link(tz_link_kobj, tz->type);
>
> mutex_unlock(&thermal_list_lock);
>
> --
> 2.24.0.393.g34dc348eaf-goog
>

2019-12-05 06:16:25

by Wei Wang

[permalink] [raw]
Subject: Re: [PATCH v2 1/2] thermal: fix and clean up tz and cdev registration

On Wed, Dec 4, 2019 at 8:13 PM Amit Kucheria
<[email protected]> wrote:
>
> Hi Wei,
>
> On Thu, Dec 5, 2019 at 3:26 AM Wei Wang <[email protected]> wrote:
> >
> > Make cooling device registration behavior consistent with
>
> Consistent how? Please add details.
>
Consistent with
https://lore.kernel.org/linux-pm/[email protected]/

will include aboce in next version.

> > thermal zone. This patch also cleans up a unnecessary
> > nullptr check.
> >
> > Signed-off-by: Wei Wang <[email protected]>
> > ---
> > drivers/thermal/thermal_core.c | 16 ++++++++++++----
> > 1 file changed, 12 insertions(+), 4 deletions(-)
> >
> > diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
> > index d4481cc8958f..64fbb59c2f44 100644
> > --- a/drivers/thermal/thermal_core.c
> > +++ b/drivers/thermal/thermal_core.c
> > @@ -954,8 +954,16 @@ __thermal_cooling_device_register(struct device_node *np,
> > struct thermal_zone_device *pos = NULL;
> > int result;
> >
> > - if (type && strlen(type) >= THERMAL_NAME_LENGTH)
> > - return ERR_PTR(-EINVAL);
> > + if (!type || !type[0]) {
> > + pr_err("Error: No cooling device type defined\n");
> > + return ERR_PTR(-EINVAL);
> > + }
> > +
> > + if (strlen(type) >= THERMAL_NAME_LENGTH) {
> > + pr_err("Error: Cooling device name (%s) too long, "
> > + "should be under %d chars\n", type, THERMAL_NAME_LENGTH);
>
> Consider fitting into a single greppable string as "Error: Cooling
> device name over %d chars: %s\n"
>
Was intentionally keep it the same as this
https://lore.kernel.org/linux-pm/31a29628894a14e716fff113fd9ce945fe649c05.1562876950.git.amit.kucheria@linaro.org/
Will make it shorter in both places next verion

> > + return ERR_PTR(-EINVAL);
> > + }
> >
> > if (!ops || !ops->get_max_state || !ops->get_cur_state ||
> > !ops->set_cur_state)
> > @@ -972,7 +980,7 @@ __thermal_cooling_device_register(struct device_node *np,
> > }
> >
> > cdev->id = result;
> > - strlcpy(cdev->type, type ? : "", sizeof(cdev->type));
> > + strlcpy(cdev->type, type, sizeof(cdev->type));
> > mutex_init(&cdev->lock);
> > INIT_LIST_HEAD(&cdev->thermal_instances);
> > cdev->np = np;
> > @@ -1250,7 +1258,7 @@ thermal_zone_device_register(const char *type, int trips, int mask,
> > return ERR_PTR(-EINVAL);
> > }
> >
> > - if (type && strlen(type) >= THERMAL_NAME_LENGTH) {
> > + if (strlen(type) >= THERMAL_NAME_LENGTH) {
> > pr_err("Error: Thermal zone name (%s) too long, should be under %d chars\n",
> > type, THERMAL_NAME_LENGTH);
> > return ERR_PTR(-EINVAL);
> > --
> > 2.24.0.393.g34dc348eaf-goog
> >

2019-12-05 06:29:55

by Amit Kucheria

[permalink] [raw]
Subject: Re: [PATCH v2 1/2] thermal: fix and clean up tz and cdev registration

On Thu, Dec 5, 2019 at 11:44 AM Wei Wang <[email protected]> wrote:
>
> On Wed, Dec 4, 2019 at 8:13 PM Amit Kucheria
> <[email protected]> wrote:
> >
> > Hi Wei,
> >
> > On Thu, Dec 5, 2019 at 3:26 AM Wei Wang <[email protected]> wrote:
> > >
> > > Make cooling device registration behavior consistent with
> >
> > Consistent how? Please add details.
> >
> Consistent with
> https://lore.kernel.org/linux-pm/[email protected]/
>
> will include aboce in next version.

Thanks.

>
> > > thermal zone. This patch also cleans up a unnecessary
> > > nullptr check.
> > >
> > > Signed-off-by: Wei Wang <[email protected]>
> > > ---
> > > drivers/thermal/thermal_core.c | 16 ++++++++++++----
> > > 1 file changed, 12 insertions(+), 4 deletions(-)
> > >
> > > diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
> > > index d4481cc8958f..64fbb59c2f44 100644
> > > --- a/drivers/thermal/thermal_core.c
> > > +++ b/drivers/thermal/thermal_core.c
> > > @@ -954,8 +954,16 @@ __thermal_cooling_device_register(struct device_node *np,
> > > struct thermal_zone_device *pos = NULL;
> > > int result;
> > >
> > > - if (type && strlen(type) >= THERMAL_NAME_LENGTH)
> > > - return ERR_PTR(-EINVAL);
> > > + if (!type || !type[0]) {
> > > + pr_err("Error: No cooling device type defined\n");
> > > + return ERR_PTR(-EINVAL);
> > > + }
> > > +
> > > + if (strlen(type) >= THERMAL_NAME_LENGTH) {
> > > + pr_err("Error: Cooling device name (%s) too long, "
> > > + "should be under %d chars\n", type, THERMAL_NAME_LENGTH);
> >
> > Consider fitting into a single greppable string as "Error: Cooling
> > device name over %d chars: %s\n"
> >
> Was intentionally keep it the same as this
> https://lore.kernel.org/linux-pm/31a29628894a14e716fff113fd9ce945fe649c05.1562876950.git.amit.kucheria@linaro.org/
> Will make it shorter in both places next verion

Yes please, make it a separate patch. We didn't catch it during review.

>
> > > + return ERR_PTR(-EINVAL);
> > > + }
> > >
> > > if (!ops || !ops->get_max_state || !ops->get_cur_state ||
> > > !ops->set_cur_state)
> > > @@ -972,7 +980,7 @@ __thermal_cooling_device_register(struct device_node *np,
> > > }
> > >
> > > cdev->id = result;
> > > - strlcpy(cdev->type, type ? : "", sizeof(cdev->type));
> > > + strlcpy(cdev->type, type, sizeof(cdev->type));
> > > mutex_init(&cdev->lock);
> > > INIT_LIST_HEAD(&cdev->thermal_instances);
> > > cdev->np = np;
> > > @@ -1250,7 +1258,7 @@ thermal_zone_device_register(const char *type, int trips, int mask,
> > > return ERR_PTR(-EINVAL);
> > > }
> > >
> > > - if (type && strlen(type) >= THERMAL_NAME_LENGTH) {
> > > + if (strlen(type) >= THERMAL_NAME_LENGTH) {
> > > pr_err("Error: Thermal zone name (%s) too long, should be under %d chars\n",
> > > type, THERMAL_NAME_LENGTH);
> > > return ERR_PTR(-EINVAL);
> > > --
> > > 2.24.0.393.g34dc348eaf-goog
> > >

2019-12-05 07:06:57

by Amit Kucheria

[permalink] [raw]
Subject: Re: [PATCH v2 1/2] thermal: fix and clean up tz and cdev registration

On Thu, Dec 5, 2019 at 11:56 AM Amit Kucheria
<[email protected]> wrote:
>
> On Thu, Dec 5, 2019 at 11:44 AM Wei Wang <[email protected]> wrote:
> >
> > On Wed, Dec 4, 2019 at 8:13 PM Amit Kucheria
> > <[email protected]> wrote:
> > >
> > > Hi Wei,
> > >
> > > On Thu, Dec 5, 2019 at 3:26 AM Wei Wang <[email protected]> wrote:
> > > >
> > > > Make cooling device registration behavior consistent with
> > >
> > > Consistent how? Please add details.
> > >
> > Consistent with
> > https://lore.kernel.org/linux-pm/[email protected]/

Studying this a bit more, git blame pointed to this SHA[1] that fixed
it so that NULL value for 'type' is allowed, we just check for it.
However, none of the users of thermal_cooling_device_register() seem
to pass NULL.

Rui, any insight into the history of why we would NOT want to create a
sysfs attribute by passing NULL? Do we still need to allow for NULL
values or should we cleanup the API to prevent NULL values?

[1] 204dd1d39c32f39a95


> >
> > will include aboce in next version.
>
> Thanks.
>
> >
> > > > thermal zone. This patch also cleans up a unnecessary
> > > > nullptr check.
> > > >
> > > > Signed-off-by: Wei Wang <[email protected]>
> > > > ---
> > > > drivers/thermal/thermal_core.c | 16 ++++++++++++----
> > > > 1 file changed, 12 insertions(+), 4 deletions(-)
> > > >
> > > > diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
> > > > index d4481cc8958f..64fbb59c2f44 100644
> > > > --- a/drivers/thermal/thermal_core.c
> > > > +++ b/drivers/thermal/thermal_core.c
> > > > @@ -954,8 +954,16 @@ __thermal_cooling_device_register(struct device_node *np,
> > > > struct thermal_zone_device *pos = NULL;
> > > > int result;
> > > >
> > > > - if (type && strlen(type) >= THERMAL_NAME_LENGTH)
> > > > - return ERR_PTR(-EINVAL);
> > > > + if (!type || !type[0]) {
> > > > + pr_err("Error: No cooling device type defined\n");
> > > > + return ERR_PTR(-EINVAL);
> > > > + }
> > > > +
> > > > + if (strlen(type) >= THERMAL_NAME_LENGTH) {
> > > > + pr_err("Error: Cooling device name (%s) too long, "
> > > > + "should be under %d chars\n", type, THERMAL_NAME_LENGTH);
> > >
> > > Consider fitting into a single greppable string as "Error: Cooling
> > > device name over %d chars: %s\n"
> > >
> > Was intentionally keep it the same as this
> > https://lore.kernel.org/linux-pm/31a29628894a14e716fff113fd9ce945fe649c05.1562876950.git.amit.kucheria@linaro.org/
> > Will make it shorter in both places next verion
>
> Yes please, make it a separate patch. We didn't catch it during review.
>
> >
> > > > + return ERR_PTR(-EINVAL);
> > > > + }
> > > >
> > > > if (!ops || !ops->get_max_state || !ops->get_cur_state ||
> > > > !ops->set_cur_state)
> > > > @@ -972,7 +980,7 @@ __thermal_cooling_device_register(struct device_node *np,
> > > > }
> > > >
> > > > cdev->id = result;
> > > > - strlcpy(cdev->type, type ? : "", sizeof(cdev->type));
> > > > + strlcpy(cdev->type, type, sizeof(cdev->type));
> > > > mutex_init(&cdev->lock);
> > > > INIT_LIST_HEAD(&cdev->thermal_instances);
> > > > cdev->np = np;
> > > > @@ -1250,7 +1258,7 @@ thermal_zone_device_register(const char *type, int trips, int mask,
> > > > return ERR_PTR(-EINVAL);
> > > > }
> > > >
> > > > - if (type && strlen(type) >= THERMAL_NAME_LENGTH) {
> > > > + if (strlen(type) >= THERMAL_NAME_LENGTH) {
> > > > pr_err("Error: Thermal zone name (%s) too long, should be under %d chars\n",
> > > > type, THERMAL_NAME_LENGTH);
> > > > return ERR_PTR(-EINVAL);
> > > > --
> > > > 2.24.0.393.g34dc348eaf-goog
> > > >

2019-12-05 07:58:33

by Zhang Rui

[permalink] [raw]
Subject: Re: [PATCH v2 1/2] thermal: fix and clean up tz and cdev registration

On Thu, 2019-12-05 at 12:36 +0530, Amit Kucheria wrote:
> On Thu, Dec 5, 2019 at 11:56 AM Amit Kucheria
> <[email protected]> wrote:
> >
> > On Thu, Dec 5, 2019 at 11:44 AM Wei Wang <[email protected]> wrote:
> > >
> > > On Wed, Dec 4, 2019 at 8:13 PM Amit Kucheria
> > > <[email protected]> wrote:
> > > >
> > > > Hi Wei,
> > > >
> > > > On Thu, Dec 5, 2019 at 3:26 AM Wei Wang <[email protected]> wrote:
> > > > >
> > > > > Make cooling device registration behavior consistent with
> > > >
> > > > Consistent how? Please add details.
> > > >
> > >
> > > Consistent with
> > >
https://lore.kernel.org/linux-pm/[email protected]/
>
> Studying this a bit more, git blame pointed to this SHA[1] that fixed
> it so that NULL value for 'type' is allowed, we just check for it.
> However, none of the users of thermal_cooling_device_register() seem
> to pass NULL.
>
> Rui, any insight into the history of why we would NOT want to create
> a
> sysfs attribute by passing NULL?

Actually, I don't recall there is any requirement that wants to
register a cooling_device without "type".

> Do we still need to allow for NULL
> values or should we cleanup the API to prevent NULL values?
>
well, my suggestion is to make this (do NULL check) a separate patch
and see if we have any complains, if yes, we can revert it easily.

thanks,
rui

> [1] 204dd1d39c32f39a95
>
>
> > >
> > > will include aboce in next version.
> >
> > Thanks.
> >
> > >
> > > > > thermal zone. This patch also cleans up a unnecessary
> > > > > nullptr check.
> > > > >
> > > > > Signed-off-by: Wei Wang <[email protected]>
> > > > > ---
> > > > > drivers/thermal/thermal_core.c | 16 ++++++++++++----
> > > > > 1 file changed, 12 insertions(+), 4 deletions(-)
> > > > >
> > > > > diff --git a/drivers/thermal/thermal_core.c
> > > > > b/drivers/thermal/thermal_core.c
> > > > > index d4481cc8958f..64fbb59c2f44 100644
> > > > > --- a/drivers/thermal/thermal_core.c
> > > > > +++ b/drivers/thermal/thermal_core.c
> > > > > @@ -954,8 +954,16 @@ __thermal_cooling_device_register(struct
> > > > > device_node *np,
> > > > > struct thermal_zone_device *pos = NULL;
> > > > > int result;
> > > > >
> > > > > - if (type && strlen(type) >= THERMAL_NAME_LENGTH)
> > > > > - return ERR_PTR(-EINVAL);
> > > > > + if (!type || !type[0]) {
> > > > > + pr_err("Error: No cooling device type
> > > > > defined\n");
> > > > > + return ERR_PTR(-EINVAL);
> > > > > + }
> > > > > +
> > > > > + if (strlen(type) >= THERMAL_NAME_LENGTH) {
> > > > > + pr_err("Error: Cooling device name (%s) too long,
> > > > > "
> > > > > + "should be under %d chars\n", type,
> > > > > THERMAL_NAME_LENGTH);
> > > >
> > > > Consider fitting into a single greppable string as "Error:
> > > > Cooling
> > > > device name over %d chars: %s\n"
> > > >
> > >
> > > Was intentionally keep it the same as this
> > >
https://lore.kernel.org/linux-pm/31a29628894a14e716fff113fd9ce945fe649c05.1562876950.git.amit.kucheria@linaro.org/
> > > Will make it shorter in both places next verion
> >
> > Yes please, make it a separate patch. We didn't catch it during
> > review.
> >
> > >
> > > > > + return ERR_PTR(-EINVAL);
> > > > > + }
> > > > >
> > > > > if (!ops || !ops->get_max_state || !ops-
> > > > > >get_cur_state ||
> > > > > !ops->set_cur_state)
> > > > > @@ -972,7 +980,7 @@ __thermal_cooling_device_register(struct
> > > > > device_node *np,
> > > > > }
> > > > >
> > > > > cdev->id = result;
> > > > > - strlcpy(cdev->type, type ? : "", sizeof(cdev->type));
> > > > > + strlcpy(cdev->type, type, sizeof(cdev->type));
> > > > > mutex_init(&cdev->lock);
> > > > > INIT_LIST_HEAD(&cdev->thermal_instances);
> > > > > cdev->np = np;
> > > > > @@ -1250,7 +1258,7 @@ thermal_zone_device_register(const char
> > > > > *type, int trips, int mask,
> > > > > return ERR_PTR(-EINVAL);
> > > > > }
> > > > >
> > > > > - if (type && strlen(type) >= THERMAL_NAME_LENGTH) {
> > > > > + if (strlen(type) >= THERMAL_NAME_LENGTH) {
> > > > > pr_err("Error: Thermal zone name (%s) too
> > > > > long, should be under %d chars\n",
> > > > > type, THERMAL_NAME_LENGTH);
> > > > > return ERR_PTR(-EINVAL);
> > > > > --
> > > > > 2.24.0.393.g34dc348eaf-goog
> > > > >