From: Stephen Rothwell <sfr@canb.auug.org.au>
To: Jeff Chua <jeffchua@silk.corp.fedex.com>,
Greg Louis <glouis@dynamicro.on.ca>
Cc: VANDROVE@vc.cvut.cz, jdthood@mail.com, alan@lxorguk.ukuu.org.uk,
linux-kernel@vger.kernel.org, skraw@ithnet.com
Subject: Re: 2.4.18-pre7 slow ... apm problem
Date: Wed, 30 Jan 2002 16:50:58 +1100 [thread overview]
Message-ID: <20020130165058.0dc3147f.sfr@canb.auug.org.au> (raw)
In-Reply-To: <Pine.LNX.4.44.0201300841160.3719-100000@boston.corp.fedex.com>
In-Reply-To: <104D80077517@vcnet.vc.cvut.cz> <Pine.LNX.4.44.0201300841160.3719-100000@boston.corp.fedex.com>
Hi Jeff, Greg and other interested parties,
Would you like to try another patch? :-)
This is rather longer than needed, it has some tidy ups from Thomas
Hood as well. I have basically simplified the idle loop and added
a couple of more points where it can escape.
I am not seeing your problems, but then again I am running on an IBM
Thinkpad, so I do BIOS calls with interrupts enabled and the BIOS halts
on idle (as opposed to slowing the CPU). I also have SpeedStep
disabled.
--
Cheers,
Stephen Rothwell sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/
diff -ruN 2.4.18-pre7/arch/i386/kernel/apm.c 2.4.18-pre7-APM.1/arch/i386/kernel/apm.c
--- 2.4.18-pre7/arch/i386/kernel/apm.c Thu Jan 24 11:33:54 2002
+++ 2.4.18-pre7-APM.1/arch/i386/kernel/apm.c Tue Jan 29 22:56:09 2002
@@ -380,7 +380,7 @@
static int set_pm_idle;
static int suspends_pending;
static int standbys_pending;
-static int waiting_for_resume;
+static int ignore_sys_suspend;
static int ignore_normal_resume;
static int bounce_interval = DEFAULT_BOUNCE_INTERVAL;
@@ -761,15 +761,6 @@
}
}
-/*
- * If no process has really been interested in
- * the CPU for some time, we want to call BIOS
- * power management - we probably want
- * to conserve power.
- */
-#define IDLE_CALC_LIMIT (HZ * 100)
-#define IDLE_LEAKY_MAX 16
-
static void (*sys_idle)(void);
extern void default_idle(void);
@@ -777,28 +768,24 @@
/**
* apm_cpu_idle - cpu idling for APM capable Linux
*
- * This is the idling function the kernel executes when APM is available. It
- * tries to do BIOS powermanagement based on the average system idle time.
- * Furthermore it calls the system default idle routine.
+ * This is the idling function the kernel executes when APM is available.
+ * It tries to do BIOS power management based on the average system
+ * idle time. Furthermore it calls the system idle routines.
*/
static void apm_cpu_idle(void)
{
- static int use_apm_idle = 0;
- static unsigned int last_jiffies = 0;
- static unsigned int last_stime = 0;
-
- int apm_is_idle = 0;
- unsigned int jiffies_since_last_check = jiffies - last_jiffies;
- unsigned int t1;
+ static int use_apm_idle;
+ static unsigned int last_jiffies;
+ static unsigned int last_stime;
+ int apm_idle_done = 0;
+ unsigned int jiffies_since_last_check;
+
+ jiffies_since_last_check = jiffies - last_jiffies;
recalc:
- if (jiffies_since_last_check > IDLE_CALC_LIMIT) {
- use_apm_idle = 0;
- last_jiffies = jiffies;
- last_stime = current->times.tms_stime;
- } else if (jiffies_since_last_check > idle_period) {
+ if (jiffies_since_last_check > idle_period) {
unsigned int idle_percentage;
idle_percentage = current->times.tms_stime - last_stime;
@@ -809,39 +796,33 @@
last_stime = current->times.tms_stime;
}
- t1 = IDLE_LEAKY_MAX;
-
while (!current->need_resched) {
if (use_apm_idle) {
- unsigned int t;
+ unsigned int t = jiffies;
- t = jiffies;
switch (apm_do_idle()) {
- case 0: apm_is_idle = 1;
- if (t != jiffies) {
- if (t1) {
- t1 = IDLE_LEAKY_MAX;
- continue;
- }
- } else if (t1) {
- t1--;
+ case 0: apm_idle_done = 1;
+ if (t != jiffies)
continue;
- }
break;
- case 1: apm_is_idle = 1;
+ case 1: apm_idle_done = 1;
break;
}
}
+ if (current->need_resched)
+ break;
if (sys_idle)
sys_idle();
else
default_idle();
+ if (current->need_resched)
+ break;
jiffies_since_last_check = jiffies - last_jiffies;
if (jiffies_since_last_check > idle_period)
goto recalc;
}
- if (apm_is_idle)
+ if (apm_idle_done)
apm_do_busy();
}
@@ -1196,7 +1177,7 @@
if (apm_info.connection_version > 0x100)
apm_set_power_state(APM_STATE_REJECT);
err = -EBUSY;
- waiting_for_resume = 0;
+ ignore_sys_suspend = 0;
printk(KERN_WARNING "apm: suspend was vetoed.\n");
goto out;
}
@@ -1295,16 +1276,15 @@
break;
}
/*
- * If we are already processing a SUSPEND,
- * then further SUSPEND events from the BIOS
- * will be ignored. We also return here to
- * cope with the fact that the Thinkpads keep
- * sending a SUSPEND event until something else
- * happens!
+ * If we are already processing a SUSPEND, then
+ * further SUSPEND events from the BIOS should
+ * be ignored. We have to check for this because
+ * Thinkpads keep sending SUSPEND events until
+ * something else happens!
*/
- if (waiting_for_resume)
+ if (ignore_sys_suspend)
return;
- waiting_for_resume = 1;
+ ignore_sys_suspend = 1;
queue_event(event, NULL);
if (suspends_pending <= 0)
(void) suspend(1);
@@ -1313,7 +1293,7 @@
case APM_NORMAL_RESUME:
case APM_CRITICAL_RESUME:
case APM_STANDBY_RESUME:
- waiting_for_resume = 0;
+ ignore_sys_suspend = 0;
last_resume = jiffies;
ignore_bounce = 1;
if ((event != APM_NORMAL_RESUME)
@@ -1381,7 +1361,7 @@
if (exit_kapmd)
break;
/*
- * Ok, check all events, check for idle (and mark us sleeping
+ * Ok, check all events (and mark us sleeping
* so as not to count towards the load average)..
*/
set_current_state(TASK_INTERRUPTIBLE);
@@ -1455,6 +1435,11 @@
return 0;
}
+/*
+ * Note that the drivers may reject a suspend request.
+ * When this happens, no suspend is done, and the ioctl()
+ * returns the EBUSY error code to the user.
+ */
static int do_ioctl(struct inode * inode, struct file *filp,
u_int cmd, u_long arg)
{
next prev parent reply other threads:[~2002-01-30 5:52 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2002-01-29 18:53 Petr Vandrovec
2002-01-29 22:47 ` Stephan von Krawczynski
2002-01-30 0:44 ` Jeff Chua
2002-01-30 5:50 ` Stephen Rothwell [this message]
2002-01-30 9:27 ` Jeff Chua
2002-02-01 13:20 ` Jeff Chua
-- strict thread matches above, loose matches on Subject: below --
2002-01-28 23:22 Petr Vandrovec
2002-01-28 0:15 Thomas Hood
2002-01-28 0:32 ` Alan Cox
2002-01-28 2:37 ` Thomas Hood
2002-01-28 10:14 ` Alan Cox
2002-01-28 11:25 ` Thomas Hood
2002-01-28 13:18 ` Alan Cox
2002-01-28 16:19 ` Thomas Hood
2002-01-28 13:03 ` Stephan von Krawczynski
2002-01-28 3:22 ` Thomas Hood
2002-01-28 20:11 ` Jeff Chua
2002-01-28 20:28 ` Thomas Hood
2002-01-28 22:20 ` Alan Cox
2002-01-29 12:36 ` Jeff Chua
2002-01-30 1:12 ` Thomas Hood
2002-01-30 9:22 ` Jeff Chua
2002-01-28 21:14 ` Thomas Hood
2002-01-28 21:17 ` Jeff Chua
2002-01-28 23:09 ` Stephan von Krawczynski
2002-01-29 13:01 ` Jeff Chua
2002-01-27 10:08 Jeff Chua
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20020130165058.0dc3147f.sfr@canb.auug.org.au \
--to=sfr@canb.auug.org.au \
--cc=VANDROVE@vc.cvut.cz \
--cc=alan@lxorguk.ukuu.org.uk \
--cc=glouis@dynamicro.on.ca \
--cc=jdthood@mail.com \
--cc=jeffchua@silk.corp.fedex.com \
--cc=linux-kernel@vger.kernel.org \
--cc=skraw@ithnet.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®