Date: Sun, 24 Apr 2005 20:49:07 -0400 From: "Alexandre \"Sunny\" Kovalenko" <Alex.Kovalenko@verizon.net> To: Lukas Ertl <le@FreeBSD.org> Cc: sebastian ssmoller <sebastian.ssmoller@gmx.net> Subject: Re: powerd(8) Message-ID: <1114390147.944.8.camel@RabbitsDen> In-Reply-To: <20050418135458.M53307@pcle2.cc.univie.ac.at> References: <20050416213144.9A08C7306E@freebsd-current.sentex.ca> <20050418134818.62d172f2.sebastian.ssmoller@gmx.net> <20050418135458.M53307@pcle2.cc.univie.ac.at>
next in thread | previous in thread | raw e-mail | index | archive | help
--Boundary_(ID_YOsjHkpanzf8T0SB17/sSw)
Content-type: text/plain; charset=iso-8859-5
Content-transfer-encoding: 8BIT
On Mon, 2005-04-18 at 13:55 +0200, Lukas Ertl wrote:
> On Mon, 18 Apr 2005, sebastian ssmoller wrote:
>
> > the currently implemented strategy caused the fan of my notebook to switch
> > on within 15 min which it never did with estctrl running :( ...
>
> I also noticed that powerd in adaptive mode keeps my laptop pretty warm.
>
> cheers,
> le
>
When I was messing around with my laptop's cooling system (fan,
heatsink, etc.) I have come up with the patch to powerd to keep
temperature below certain level and added -t switch to command line with
the single argument -- temperature limit in Celsius.
I have attached it just in case someone finds it useful. It was
originally made against powerd 1.4, I have subsequently changed it to
patch against 1.6, but have not tested it extensively after that.
--
Alexandre "Sunny" Kovalenko (Олександр Коваленко)
--Boundary_(ID_YOsjHkpanzf8T0SB17/sSw)
Content-type: text/x-patch; name=powerd.c.patch; charset=ASCII
Content-transfer-encoding: 7BIT
Content-disposition: attachment; filename=powerd.c.patch
--- ./usr.sbin/powerd/powerd.c Sun Apr 17 11:25:41 2005
+++ /home/sunny/powerd.c Sun Apr 24 20:46:40 2005
@@ -46,7 +46,8 @@
#define DEFAULT_ACTIVE_PERCENT 65
#define DEFAULT_IDLE_PERCENT 90
-#define DEFAULT_POLL_INTERVAL 500 /* Poll interval in milliseconds */
+#define DEFAULT_POLL_INTERVAL 500 /* Poll interval in milliseconds */
+#define VERY_HIGH_TEMPERATURE 200
enum modes_t {
MODE_MIN,
@@ -83,11 +84,13 @@
static int freq_mib[4];
static int levels_mib[4];
static int acline_mib[3];
+static int temp_mib[5];
/* Configuration */
static int cpu_running_mark;
static int cpu_idle_mark;
static int poll_ival;
+static int passive_cooling_mark;
static int apm_fd;
static int exit_requested;
@@ -244,7 +247,7 @@
{
fprintf(stderr,
-"usage: powerd [-v] [-a mode] [-b mode] [-i %%] [-n mode] [-p ival] [-r %%]\n");
+"usage: powerd [-v] [-a mode] [-b mode] [-i %%] [-n mode] [-p ival] [-r %%] [-t temperature]\n");
exit(1);
}
@@ -252,7 +255,7 @@
main(int argc, char * argv[])
{
long idle, total;
- int curfreq, *freqs, i, *mwatts, numfreqs;
+ int curfreq, *freqs, i, *mwatts, numfreqs, temperature;
int ch, mode_ac, mode_battery, mode_none, acline, mode, vflag;
uint64_t mjoules_used;
size_t len;
@@ -263,10 +266,11 @@
cpu_idle_mark = DEFAULT_IDLE_PERCENT;
poll_ival = DEFAULT_POLL_INTERVAL;
mjoules_used = 0;
+ passive_cooling_mark = VERY_HIGH_TEMPERATURE;
vflag = 0;
apm_fd = -1;
- while ((ch = getopt(argc, argv, "a:b:i:n:p:r:v")) != EOF)
+ while ((ch = getopt(argc, argv, "a:b:i:n:p:r:t:v")) != EOF)
switch (ch) {
case 'a':
parse_mode(optarg, &mode_ac, ch);
@@ -300,6 +304,16 @@
usage();
}
break;
+ case 't':
+ passive_cooling_mark = atoi(optarg);
+ if(passive_cooling_mark < 0 || passive_cooling_mark > 100) {
+ warnx("%d is not valid temperature for passive cooling",
+ passive_cooling_mark);
+ usage();
+ }
+ passive_cooling_mark *= 10;
+ passive_cooling_mark += 2733;
+ break;
case 'v':
vflag = 1;
break;
@@ -320,6 +334,9 @@
len = 4;
if (sysctlnametomib("dev.cpu.0.freq_levels", levels_mib, &len))
err(1, "lookup freq_levels");
+ len = 5;
+ if (sysctlnametomib("hw.acpi.thermal.tz0.temperature", temp_mib, &len))
+ err(1, "lookup temperature");
/* Check if we can read the idle time and supported freqs. */
if (read_usage_times(NULL, NULL))
@@ -370,6 +387,10 @@
len = sizeof(curfreq);
if (sysctl(freq_mib, 4, &curfreq, &len, NULL, 0))
err(1, "error reading current CPU frequency");
+ /* Read current temperature. */
+ len = sizeof(temperature);
+ if(sysctl(temp_mib, 5, &temperature, &len, NULL, 0))
+ err(1, "error reading current temperature");
if (vflag) {
for (i = 0; i < numfreqs; i++) {
@@ -410,12 +431,31 @@
err(1, "error setting CPU freq %d",
freqs[0]);
}
+ /* Check for passive cooling override */
+ if(temperature > passive_cooling_mark) {
+ if (vflag) {
+ printf("passive cooling override; "
+ "changing frequency to %d MHz\n",
+ freqs[numfreqs - 1]);
+ }
+ if (set_freq(freqs[numfreqs - 1]))
+ err(1, "error setting CPU freq %d",
+ freqs[numfreqs - 1]);
+ }
continue;
}
/* Adaptive mode; get the current CPU usage times. */
if (read_usage_times(&idle, &total))
err(1, "read_usage_times");
+ /*
+ * If temperature has risen over passive cooling mark, we
+ * would want to decrease frequency regardless of the load,
+ * Simplest way to go about this would be to report 100%
+ * idle CPU and let adaptive algorithm do its job.
+ */
+ if(temperature > passive_cooling_mark)
+ idle = total;
/*
* If we're idle less than the active mark, jump the CPU to
--Boundary_(ID_YOsjHkpanzf8T0SB17/sSw)--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?1114390147.944.8.camel>
