lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Thu, 06 Nov 2014 16:26:27 +0530
From:	Yadwinder Singh Brar <yadi.brar@...sung.com>
To:	'Eduardo Valentin' <edubezval@...il.com>
Cc:	linux-pm@...r.kernel.org, linux-kernel@...r.kernel.org,
	rui.zhang@...el.com, amit.daniel@...sung.com,
	viresh.kumar@...aro.org, linux-samsung-soc@...r.kernel.org,
	yadi.brar01@...il.com
Subject: RE: [PATCH] thermal: cpu_cooling: Update always cpufreq policy with
 thermal constraints

Hello Eduardo Valentin,

On Thursday, November 06, 2014 2:17 AM, Eduardo Valentin wrote:
> Hello Yadwinder,
> 
> On Wed, Nov 05, 2014 at 05:46:25PM +0530, Yadwinder Singh Brar wrote:
> > Existing code updates cupfreq policy only while executing
> > cpufreq_apply_cooling() function (i.e. when notify_device !=
> NOTIFY_INVALID).
> 
> Correct. The case you mention is when we receive a notification from
> cpufreq. But also, updates the cpufreq policy when the cooling device
> changes state, a call from thermal framework.

I mentioned thermal framework case only, existing code updates
cupfreq policy only when (notify_device != NOTIFY_INVALID),
which happens only when notification comes from cpufreq_update_policy
while changing cooling device's state(i.e. cpufreq_apply_cooling()).
In case of other notifications notify_device is always NOTIFY_INVALID.

> 
> > It doesn't apply constraints when cpufreq policy update happens from
> > any other place but it should update the cpufreq policy with thermal
> > constraints every time when there is a cpufreq policy update, to keep
> > state of cpufreq_cooling_device and max_feq of cpufreq policy in
> sync.
> 
> I am not sure I follow you here. Can you please elaborate on 'any other
> places'? Could you please mention (also in the commit log) what are the
> case the current code does not cover? For instance, the
> cpufreq_apply_cooling gets called on notification coming from thermal
> subsystem, and for changes in cpufreq subsystem,
> cpufreq_thermal_notifier is called.
> 

"Other places" mean possible places from where cpufreq_update_policy()
can be called at runtime, an instance in present kernel is cpufreq_resume().
But since cpufreq_update_policy() is an exposed API, I think
for robustness, generic cpu cooling should be able to take care of any
possible case(in future as well).

> >
> > This patch modifies code to maintain a global cpufreq_dev_list and
> get
> > corresponding cpufreq_cooling_device for policy's cpu from
> > cpufreq_dev_list when there is any policy update.
> 
> OK. Please give real examples of when the current code fails to catch
> the event.
> 

While resuming cpufreq updates cpufreq_policy for boot cpu and it
restores default policy->usr_policy irrespective of cooling device's
cpufreq_state since notification gets missed because (notify_device ==
NOTIFY_INVALID).
Another thing, Rather I would say an issue, I observed is that
Userspace is able to change max_freq irrespective of cooling
device's state, as notification gets missed.
  
> 
> BR,
> 
> Eduardo Valentin
> 
> >
> > Signed-off-by: Yadwinder Singh Brar <yadi.brar@...sung.com>
> > ---
> >  drivers/thermal/cpu_cooling.c |   37 ++++++++++++++++++++-----------
> ------
> >  1 files changed, 20 insertions(+), 17 deletions(-)
> >
> > diff --git a/drivers/thermal/cpu_cooling.c
> > b/drivers/thermal/cpu_cooling.c index 1ab0018..5546278 100644
> > --- a/drivers/thermal/cpu_cooling.c
> > +++ b/drivers/thermal/cpu_cooling.c
> > @@ -50,15 +50,14 @@ struct cpufreq_cooling_device {
> >  	unsigned int cpufreq_state;
> >  	unsigned int cpufreq_val;
> >  	struct cpumask allowed_cpus;
> > +	struct list_head node;
> >  };
> >  static DEFINE_IDR(cpufreq_idr);
> >  static DEFINE_MUTEX(cooling_cpufreq_lock);
> >
> >  static unsigned int cpufreq_dev_count;
> >
> > -/* notify_table passes value to the CPUFREQ_ADJUST callback
> function.
> > */ -#define NOTIFY_INVALID NULL -static struct cpufreq_cooling_device
> > *notify_device;
> > +static LIST_HEAD(cpufreq_dev_list);
> >
> >  /**
> >   * get_idr - function to get a unique id.
> > @@ -287,15 +286,12 @@ static int cpufreq_apply_cooling(struct
> > cpufreq_cooling_device *cpufreq_device,
> >
> >  	cpufreq_device->cpufreq_state = cooling_state;
> >  	cpufreq_device->cpufreq_val = clip_freq;
> > -	notify_device = cpufreq_device;
> >
> >  	for_each_cpu(cpuid, mask) {
> >  		if (is_cpufreq_valid(cpuid))
> >  			cpufreq_update_policy(cpuid);
> >  	}
> >
> > -	notify_device = NOTIFY_INVALID;
> > -
> >  	return 0;
> >  }
> >
> > @@ -316,21 +312,27 @@ static int cpufreq_thermal_notifier(struct
> > notifier_block *nb,  {
> >  	struct cpufreq_policy *policy = data;
> >  	unsigned long max_freq = 0;
> > +	struct cpufreq_cooling_device *cpufreq_dev;
> >
> > -	if (event != CPUFREQ_ADJUST || notify_device == NOTIFY_INVALID)
> > +	if (event != CPUFREQ_ADJUST)
> >  		return 0;
> >
> > -	if (cpumask_test_cpu(policy->cpu, &notify_device->allowed_cpus))
> > -		max_freq = notify_device->cpufreq_val;
> > -	else
> > -		return 0;
> > +	mutex_lock(&cooling_cpufreq_lock);
> > +	list_for_each_entry(cpufreq_dev, &cpufreq_dev_list, node) {
> > +		if (!cpumask_test_cpu(policy->cpu,
> > +					&cpufreq_dev->allowed_cpus))
> > +			continue;
> >
> > -	/* Never exceed user_policy.max */
> > -	if (max_freq > policy->user_policy.max)
> > -		max_freq = policy->user_policy.max;
> > +		max_freq = cpufreq_dev->cpufreq_val;
> >

I think I missed to post updated patch,
Actually it should be :

+	if (!cpufreq_dev->cpufreq_val)
+		cpufreq_dev->cpufreq_val = get_cpu_frequency(
+
cpumask_any(&cpufreq_dev->allowed_cpus),
+							cpufreq_dev->state);
+	max_freq = cpufreq_dev->cpufreq_val;

I will send another version of patch.

> > -	if (policy->max != max_freq)
> > -		cpufreq_verify_within_limits(policy, 0, max_freq);
> > +		/* Never exceed user_policy.max */
> > +		if (max_freq > policy->user_policy.max)
> > +			max_freq = policy->user_policy.max;
> > +
> > +		if (policy->max != max_freq)
> > +			cpufreq_verify_within_limits(policy, 0, max_freq);
> > +	}
> > +	mutex_unlock(&cooling_cpufreq_lock);
> 
> So, the problem is when we have several cpu cooling devices and you
> want to search for the real max among the existing cpu cooling devices?
>

Sorry I didn't get your question completely I think.
No, above code doesn't find max among existing cooling devices.
It simply finds cooling device corresponding to policy's cpu
and applies updates policy accordingly.

Regards,
Yadwinder
 
> >  	return 0;
> >  }
> > @@ -486,7 +488,7 @@ __cpufreq_cooling_register(struct device_node
> *np,
> >  		cpufreq_register_notifier(&thermal_cpufreq_notifier_block,
> >  					  CPUFREQ_POLICY_NOTIFIER);
> >  	cpufreq_dev_count++;
> > -
> > +	list_add(&cpufreq_dev->node, &cpufreq_dev_list);
> >  	mutex_unlock(&cooling_cpufreq_lock);
> >
> >  	return cool_dev;
> > @@ -549,6 +551,7 @@ void cpufreq_cooling_unregister(struct
> > thermal_cooling_device *cdev)
> >
> >  	cpufreq_dev = cdev->devdata;
> >  	mutex_lock(&cooling_cpufreq_lock);
> > +	list_del(&cpufreq_dev->node);
> >  	cpufreq_dev_count--;
> >
> >  	/* Unregister the notifier for the last cpufreq cooling device */
> > --
> > 1.7.0.4
> >

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ