Commit Graph

29 Commits

Author SHA1 Message Date
jhb
4fb93663e6 Fix a few edge cases with error handling in cpufreq(4)'s CPUFREQ_GET()
method:
- If the last of the child cpufreq drivers returns an error while trying to
  fetch its list of supported frequencies but an earlier driver found the
  requested frequency, don't return an error to the caller.
- If all of the child cpufreq drivers fail and the attempt to match the
  frequency based on 'cpu_est_clockrate()' fails, return ENXIO rather than
  returning success and returning a frequency of CPUFREQ_VAL_UNKNOWN.

MFC after:	3 days
PR:		kern/121433
Reported by:	Eugene Grosbein  eugen ! kuzbass dot ru
2008-05-05 19:13:52 +00:00
njl
27739d97dc Remove duplicate cpufreq levels, i.e. ones that are within 25 Mhz of each
other.  The first one survives, the rest are removed.  So far, it appears
only some acpi_perf(4) BIOS tables have these invalid states, but address
this in the core to be sure to handle other potential driver data.

PR:		kern/114722
Tested by:	stefan.lambrev / moneybookers.com
MFC after:	3 days
2008-01-16 01:05:21 +00:00
njl
53b7cf834c If we're on an SMP kernel and there is more than 1 CPU, reject any attempts
to change the freq before the other CPUs are active.  The current code
always attempts to change all CPUs to match each other, and the requisite
sched_bind() call won't work before APs are launched.
2007-10-30 22:18:08 +00:00
njl
4140a5b735 Always call sched_bind(), even if on the CPU in question. It is wrong to
check if we're already on that cpu and skip the bind since the thread could
be migrated off in the meantime.

Suggested by:	jeff
Approved by:	re
2007-08-20 06:28:26 +00:00
njl
7d2f282057 Use a different loop variable for the inner loop. This previous reuse could
have caused a hang, but we got lucky with the available multi-CPU states
on actual hardware.

Submitted by:	Bjorn Koenig <bkoenig / alpha-tierchen.de>
Approved by:	re
MFC after:	3 days
2007-08-19 20:34:13 +00:00
jeff
91d1501790 Commit 14/14 of sched_lock decomposition.
- Use thread_lock() rather than sched_lock for per-thread scheduling
   sychronization.
 - Use the per-process spinlock rather than the sched_lock for per-process
   scheduling synchronization.

Tested by:      kris, current@
Tested on:      i386, amd64, ULE, 4BSD, libthr, libkse, PREEMPTION, etc.
Discussed with: kris, attilio, kmacy, jhb, julian, bde (small parts each)
2007-06-05 00:00:57 +00:00
njl
4933ca0aa0 Add an interface for drivers to be notified of changes to CPU frequency.
cpufreq_pre_change is called before the change, giving each driver a chance
to revoke the change.  cpufreq_post_change provides the results of the
change (success or failure).  cpufreq_levels_changed gives the unit number
of the cpufreq device whose number of available levels has changed.  Hook
in all the drivers I could find that needed it.

* TSC: update TSC frequency value.  When the available levels change, take the
highest possible level and notify the timecounter set_cputicker() of that
freq.  This gets rid of the "calcru: runtime went backwards" messages.
* identcpu: updates the sysctl hw.clockrate value
* Profiling: if profiling is active when the clock changes, let the user
know the results may be inaccurate.

Reviewed by:	bde, phk
MFC after:	1 month
2007-03-26 18:03:29 +00:00
mnag
f24ee2a85a - Print message about cpufreq and timecounter TSC
Approved by:	njl
MFC after:	1 day
2006-03-03 02:06:04 +00:00
ume
68576cc813 make saved cpu level stackable. 2005-10-03 06:57:29 +00:00
njl
b0c4bd3081 Break out the checks for duplicates and absolute settings being too high
instead of trying to do them all at once.  This should fix the level sorting
problems from the previous revision.

Testing help:	ume
2005-09-02 16:32:43 +00:00
njl
63a52296e3 Eliminate cpufreq levels for two cases that are less than optimal:
1. Walk the absolute list in reverse to prefer duplicated levels that have
a lower absolute setting, i.e. 800 Mhz/50% is better than 1600 Mhz/25% even
though both have the same actual frequency.  This also removes the need to
check for already-modified levels since by definition, those will be added
later in the sorted list.

2. Compare the absolute settings for derived levels and don't use the new
level if it's higher.  For example, a level of 800 Mhz/75% is preferable to
1600 Mhz/25% even though the latter has a lower total frequency.

This work is based on a patch from the submitter but reworked by myself.

Submitted by:	Tijl Coosemans (tijl/ulyssis.org)
2005-08-30 04:45:32 +00:00
ume
d72dbf2615 - don't forget to save freqency when priority is raised.
- nuke redundant variable initialization.
2005-08-18 16:41:25 +00:00
ume
57562e0618 don't forget to update curr_priority. even when frequency is
not changed, priority may be changed.
2005-08-18 16:08:56 +00:00
ume
69a7276f8f Save cpu level only when priority is greater than PRIO_USER
to make CPUFREQ_SET(NULL, prio) work.
TODO: implement saved_level as stack.

Reviewed by:	njl
2005-08-16 20:03:08 +00:00
njl
1198d2f2a8 The "lowest" sysctl setting makes more sense as the lowest one to use, so
discard all levels less than this setting, not less than/equal to.

MFC after:	1 day
2005-08-11 18:40:58 +00:00
njl
46ef074ef7 Add debugging prints to all the methods in case there are problems with
managing levels.  This can be enabled with the debug.cpufreq.verbose
tunable and sysctl.
2005-04-10 19:11:23 +00:00
njl
749e1a55dd Add a check for cpufreq_unregister() being called with no cpufreq device
active.  Note that the logic indicates this should not be possible so
generate a warning if this ever happens.

Found by:	Coverity Prevent (via sam)
2005-03-31 18:56:54 +00:00
njl
24b8592306 Add locking to handle multiple threads getting/setting frequencies at the
same time.  We use an sx lock and serialize the cpufreq device's
get/set/levels methods.
2005-02-27 01:34:08 +00:00
njl
d63a2d86cd Allow users to reject levels below a given frequency (in MHz) via the
debug.cpufreq.lowest tunable and sysctl.  Some systems seem to have problems
with the lowest frequencies so setting this prevents them from being
available or used.
2005-02-26 22:37:49 +00:00
njl
82088e2e10 Bump the maximum number of levels to 64 and add warning messages about
what to do to fix reduced functionality if the number of levels is too low.
2005-02-24 20:21:41 +00:00
njl
1a502bbeb2 Add the "freq_settings" sysctl to each device that registers with cpufreq
so their individual settings can be seen separately for debugging.
2005-02-20 00:59:15 +00:00
njl
18a69f46e3 Introduce a new method, cpufreq_drv_type(), that returns the type of the
driver.  This used to be handled by cpufreq_drv_settings() but it's
useful to get the type/flags separately from getting the settings.
(For example, you don't have to pass an array of cf_setting just to find
the driver type.)

Use this new method in our in-tree drivers to detect reliably if acpi_perf
is present and owns the hardware.  This simplifies logic in drivers as well
as fixing a bug introduced in my last commit where too many drivers attached.
2005-02-18 00:23:36 +00:00
njl
5cd9fb8f6c When dealing with systems with no absolute drivers attached, only calibrate
the rate for the 100% state once.  Afterwards, use that value for deriving
states.  This should fix the problem where the calibrated frequency was
different once a switch was done, giving a different set of levels each
time.  Also, properly search for the right cpufreqX device when detaching.
2005-02-15 07:43:48 +00:00
njl
ea80935c2a Bind to the driver's parent cpu before switching, for both absolute and
relative drivers.  Remove some extraneous KASSERTs since NULL pointers
will be found when they're used right afterwards.
2005-02-15 07:22:42 +00:00
njl
6e0f1dda0a Implement priorities. This allows a driver (say, for cooling purposes) to
override the current freq level temporarily and restore it when the
higher priority condition is past.  Note that only the first overridden
value is saved.  Callers pass NULL to CPUFREQ_SET to restore the saved
level.  Priorities are not yet used so this commit should have no effect.
2005-02-14 18:16:35 +00:00
njl
db1d2335dc Add support for the CPUFREQ_FLAG_INFO_ONLY flag. Devices that report this
are not added to the list(s) of available settings.  However, other drivers
can call the CPUFREQ_DRV_SETTINGS() method on those devices directly to
get info about available settings.

Update the acpi_perf(4) driver to use this flag in the presence of
"functional fixed hardware."  Thus, future drivers like Powernow can
query acpi_perf for platform info but perform frequency transitions
themselves.
2005-02-13 18:49:48 +00:00
njl
29d152dbfd Set levels on all CPUs and attach a cpufreq device to each one. Sysctl
on dev.cpu.0 will affect all of the CPUs together.  In the future,
independent control will be supported but this is good enough for now.
Check that the timecounter isn't TSC before switching (from Colin Percival.)
2005-02-13 17:31:56 +00:00
njl
2163789671 Add support for relative cpufreq drivers. Such drivers modulate clock
frequency as a percentage of the base rate and do not change the base
rate directly.  The cpufreq framework combines these with absolute drivers
to produce synthesized levels made of one or more settings.
2005-02-06 21:08:35 +00:00
njl
ed695e1533 Add the cpufreq framework. This code manages multiple drivers and presents
a unified kernel and user interface for controlling cpu frequencies.
2005-02-04 05:39:19 +00:00