Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2dd98f16 authored by Ram Chandrasekar's avatar Ram Chandrasekar
Browse files

drivers: thermal: Use high priority work queue for thermal processing



Thermal framework uses system freezable work queue for processing the
governor action and mitigation action will be performed in the same
context. System work queue can have one max active event processing
and if the mitigation action is delayed, that will bottleneck the
rest of the work queue event processing. This will result in delayed
action and temperature overshoot.

To avoid this, a new high priority thermal work queue is created and all
the passive monitoring will be done in the high priority context. Also
this work queue has a max active count defined as 16, which will allow
multi-processing of work events.

Change-Id: Id506f21c1583e0ba2e022f8b7bc28e3972c592ef
Signed-off-by: default avatarRam Chandrasekar <rkumbako@codeaurora.org>
parent 5f7c0080
Loading
Loading
Loading
Loading
+27 −8
Original line number Diff line number Diff line
@@ -49,6 +49,8 @@ MODULE_AUTHOR("Zhang Rui");
MODULE_DESCRIPTION("Generic thermal management sysfs support");
MODULE_LICENSE("GPL v2");

#define THERMAL_MAX_ACTIVE	16

static DEFINE_IDR(thermal_tz_idr);
static DEFINE_IDR(thermal_cdev_idr);
static DEFINE_MUTEX(thermal_idr_lock);
@@ -64,6 +66,8 @@ static atomic_t in_suspend;

static struct thermal_governor *def_governor;

static struct workqueue_struct *thermal_passive_wq;

static struct thermal_governor *__find_governor(const char *name)
{
	struct thermal_governor *pos;
@@ -392,14 +396,15 @@ static void bind_tz(struct thermal_zone_device *tz)
	mutex_unlock(&thermal_list_lock);
}

static void thermal_zone_device_set_polling(struct thermal_zone_device *tz,
static void thermal_zone_device_set_polling(struct workqueue_struct *queue,
					    struct thermal_zone_device *tz,
					    int delay)
{
	if (delay > 1000)
		mod_delayed_work(system_freezable_wq, &tz->poll_queue,
		mod_delayed_work(queue, &tz->poll_queue,
				 round_jiffies(msecs_to_jiffies(delay)));
	else if (delay)
		mod_delayed_work(system_freezable_wq, &tz->poll_queue,
		mod_delayed_work(queue, &tz->poll_queue,
				 msecs_to_jiffies(delay));
	else
		cancel_delayed_work(&tz->poll_queue);
@@ -410,11 +415,13 @@ static void monitor_thermal_zone(struct thermal_zone_device *tz)
	mutex_lock(&tz->lock);

	if (tz->passive)
		thermal_zone_device_set_polling(tz, tz->passive_delay);
		thermal_zone_device_set_polling(thermal_passive_wq,
						tz, tz->passive_delay);
	else if (tz->polling_delay)
		thermal_zone_device_set_polling(tz, tz->polling_delay);
		thermal_zone_device_set_polling(system_freezable_wq,
						tz, tz->polling_delay);
	else
		thermal_zone_device_set_polling(tz, 0);
		thermal_zone_device_set_polling(NULL, tz, 0);

	mutex_unlock(&tz->lock);
}
@@ -2069,7 +2076,7 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz)

	mutex_unlock(&thermal_list_lock);

	thermal_zone_device_set_polling(tz, 0);
	thermal_zone_device_set_polling(NULL, tz, 0);

	if (tz->type[0])
		device_remove_file(&tz->device, &dev_attr_type);
@@ -2329,9 +2336,18 @@ static int __init thermal_init(void)
{
	int result;

	thermal_passive_wq = alloc_workqueue("thermal_passive_wq",
						WQ_HIGHPRI | WQ_UNBOUND
						| WQ_FREEZABLE,
						THERMAL_MAX_ACTIVE);
	if (!thermal_passive_wq) {
		result = -ENOMEM;
		goto init_exit;
	}

	result = thermal_register_governors();
	if (result)
		goto init_exit;
		goto destroy_wq;

	result = class_register(&thermal_class);
	if (result)
@@ -2352,6 +2368,8 @@ static int __init thermal_init(void)
	class_unregister(&thermal_class);
unregister_governors:
	thermal_unregister_governors();
destroy_wq:
	destroy_workqueue(thermal_passive_wq);
init_exit:
	idr_destroy(&thermal_tz_idr);
	idr_destroy(&thermal_cdev_idr);
@@ -2365,6 +2383,7 @@ static void __exit thermal_exit(void)
{
	unregister_pm_notifier(&thermal_pm_nb);
	of_thermal_destroy_zones();
	destroy_workqueue(thermal_passive_wq);
	genetlink_exit();
	class_unregister(&thermal_class);
	thermal_unregister_governors();