From patchwork Thu Mar 31 03:16:29 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Len Brown X-Patchwork-Id: 678441 Received: from smtp1.linux-foundation.org (smtp1.linux-foundation.org [140.211.169.13]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id p2V3KfMw010282 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL) for ; Thu, 31 Mar 2011 03:21:16 GMT Received: from daredevil.linux-foundation.org (localhost [127.0.0.1]) by smtp1.linux-foundation.org (8.14.2/8.14.2/Debian-2build1) with ESMTP id p2V3Hjmj002791; Wed, 30 Mar 2011 20:18:16 -0700 Received: from vms173019pub.verizon.net (vms173019pub.verizon.net [206.46.173.19]) by smtp1.linux-foundation.org (8.14.2/8.14.2/Debian-2build1) with ESMTP id p2V3H47t002694 for ; Wed, 30 Mar 2011 20:17:06 -0700 Received: from localhost.localdomain ([unknown] [74.104.148.74]) by vms173019.mailsrvcs.net (Sun Java(tm) System Messaging Server 7u2-7.02 32bit (built Apr 16 2009)) with ESMTPA id <0LIW007B1JRR8830@vms173019.mailsrvcs.net> for linux-pm@lists.linux-foundation.org; Wed, 30 Mar 2011 22:16:46 -0500 (CDT) Received: from localhost.localdomain (x980 [127.0.0.1]) by localhost.localdomain (8.14.4/8.14.4) with ESMTP id p2V3GYTt002487; Wed, 30 Mar 2011 23:16:35 -0400 Received: from localhost (lenb@localhost) by localhost.localdomain (8.14.4/8.14.4/Submit) with ESMTP id p2V3GT76002482; Wed, 30 Mar 2011 23:16:30 -0400 X-Authentication-warning: localhost.localdomain: lenb owned process doing -bs Date: Wed, 30 Mar 2011 23:16:29 -0400 (EDT) From: Len Brown X-X-Sender: lenb@x980 To: Jiri Kosina In-reply-to: Message-id: References: <20110326172204.05e52c10.sfr@canb.auug.org.au> <20110329004438.d9e755ef.sfr@canb.auug.org.au> <20110328174542.GW21838@one.firstfloor.org> <4D90CC0B.8070105@zytor.com> <20110328182123.GX21838@one.firstfloor.org> User-Agent: Alpine 2.02 (LFD 1266 2009-07-14) MIME-version: 1.0 Received-SPF: pass (localhost is always allowed.) X-Spam-Status: No, hits=-5.789 required=5 tests=AWL, BAYES_00, OSDL_HEADER_SUBJECT_BRACKETED, PATCH_SUBJECT_OSDL X-Spam-Checker-Version: SpamAssassin 3.2.4-osdl_revision__1.47__ X-MIMEDefang-Filter: lf$Revision: 1.188 $ X-Scanned-By: MIMEDefang 2.63 on 140.211.169.21 Cc: Stephen Rothwell , Ingo Molnar , x86@kernel.org, LKML , Andi Kleen , Thomas Gleixner , Henrique de Moraes Holschuh , "H. Peter Anvin" , Ondrej Zary , Andrew Morton , Linus Torvalds , linux-pm@lists.linux-foundation.org Subject: [linux-pm] [PATCH] x86 idle APM: delete apm_cpu_idle(), and its use of pm_idle X-BeenThere: linux-pm@lists.linux-foundation.org X-Mailman-Version: 2.1.9 Precedence: list List-Id: Linux power management List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: linux-pm-bounces@lists.linux-foundation.org Errors-To: linux-pm-bounces@lists.linux-foundation.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter1.kernel.org [140.211.167.41]); Thu, 31 Mar 2011 03:21:17 +0000 (UTC) diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index d5ed94d..681bb25 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -1809,17 +1809,6 @@ config APM_DO_ENABLE T400CDT. This is off by default since most machines do fine without this feature. -config APM_CPU_IDLE - bool "Make CPU Idle calls when idle" - ---help--- - Enable calls to APM CPU Idle/CPU Busy inside the kernel's idle loop. - On some machines, this can activate improved power savings, such as - a slowed CPU clock rate, when the machine is idle. These idle calls - are made after the idle loop has run for some length of time (e.g., - 333 mS). On some machines, this will cause a hang at boot time or - whenever the CPU becomes idle. (On machines with more than one CPU, - this option does nothing.) - config APM_DISPLAY_BLANK bool "Enable console blanking using APM" ---help--- diff --git a/arch/x86/kernel/apm_32.c b/arch/x86/kernel/apm_32.c index 0e4f24c..5bc37aa 100644 --- a/arch/x86/kernel/apm_32.c +++ b/arch/x86/kernel/apm_32.c @@ -175,8 +175,6 @@ * Ignore first resume after we generate our own resume event * after a suspend (Thomas Hood) * Daemonize now gets rid of our controlling terminal (sfr). - * CONFIG_APM_CPU_IDLE now just affects the default value of - * idle_threshold (sfr). * Change name of kernel apm daemon (as it no longer idles) (sfr). * 1.16ac: Fix up SMP support somewhat. You can now force SMP on and we * make _all_ APM calls on the CPU#0. Fix unsafe sign bug. @@ -261,12 +259,6 @@ extern int (*console_blank_hook)(int); * [no-]smp Use apm even on an SMP box * bounce[-_]interval= number of ticks to ignore suspend * bounces - * idle[-_]threshold= System idle percentage above which to - * make APM BIOS idle calls. Set it to - * 100 to disable. - * idle[-_]period= Period (in 1/100s of a second) over - * which the idle percentage is - * calculated. */ /* KNOWN PROBLEM MACHINES: @@ -356,26 +348,12 @@ struct apm_user { #define APM_BIOS_MAGIC 0x4101 /* - * idle percentage above which bios idle calls are done - */ -#ifdef CONFIG_APM_CPU_IDLE -#define DEFAULT_IDLE_THRESHOLD 95 -#else -#define DEFAULT_IDLE_THRESHOLD 100 -#endif -#define DEFAULT_IDLE_PERIOD (100 / 3) - -/* * Local variables */ static struct { unsigned long offset; unsigned short segment; } apm_bios_entry; -static int clock_slowed; -static int idle_threshold __read_mostly = DEFAULT_IDLE_THRESHOLD; -static int idle_period __read_mostly = DEFAULT_IDLE_PERIOD; -static int set_pm_idle; static int suspends_pending; static int standbys_pending; static int ignore_sys_suspend; @@ -805,165 +783,6 @@ static int set_system_power_state(u_short state) } /** - * apm_do_idle - perform power saving - * - * This function notifies the BIOS that the processor is (in the view - * of the OS) idle. It returns -1 in the event that the BIOS refuses - * to handle the idle request. On a success the function returns 1 - * if the BIOS did clock slowing or 0 otherwise. - */ - -static int apm_do_idle(void) -{ - u32 eax; - u8 ret = 0; - int idled = 0; - int polling; - int err = 0; - - polling = !!(current_thread_info()->status & TS_POLLING); - if (polling) { - current_thread_info()->status &= ~TS_POLLING; - /* - * TS_POLLING-cleared state must be visible before we - * test NEED_RESCHED: - */ - smp_mb(); - } - if (!need_resched()) { - idled = 1; - ret = apm_bios_call_simple(APM_FUNC_IDLE, 0, 0, &eax, &err); - } - if (polling) - current_thread_info()->status |= TS_POLLING; - - if (!idled) - return 0; - - if (ret) { - static unsigned long t; - - /* This always fails on some SMP boards running UP kernels. - * Only report the failure the first 5 times. - */ - if (++t < 5) { - printk(KERN_DEBUG "apm_do_idle failed (%d)\n", err); - t = jiffies; - } - return -1; - } - clock_slowed = (apm_info.bios.flags & APM_IDLE_SLOWS_CLOCK) != 0; - return clock_slowed; -} - -/** - * apm_do_busy - inform the BIOS the CPU is busy - * - * Request that the BIOS brings the CPU back to full performance. - */ - -static void apm_do_busy(void) -{ - u32 dummy; - int err; - - if (clock_slowed || ALWAYS_CALL_BUSY) { - (void)apm_bios_call_simple(APM_FUNC_BUSY, 0, 0, &dummy, &err); - clock_slowed = 0; - } -} - -/* - * 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 (*original_pm_idle)(void) __read_mostly; - -/** - * 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. - */ - -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_idle_done = 0; - unsigned int jiffies_since_last_check = jiffies - last_jiffies; - unsigned int bucket; - -recalc: - if (jiffies_since_last_check > IDLE_CALC_LIMIT) { - use_apm_idle = 0; - last_jiffies = jiffies; - last_stime = current->stime; - } else if (jiffies_since_last_check > idle_period) { - unsigned int idle_percentage; - - idle_percentage = current->stime - last_stime; - idle_percentage *= 100; - idle_percentage /= jiffies_since_last_check; - use_apm_idle = (idle_percentage > idle_threshold); - if (apm_info.forbid_idle) - use_apm_idle = 0; - last_jiffies = jiffies; - last_stime = current->stime; - } - - bucket = IDLE_LEAKY_MAX; - - while (!need_resched()) { - if (use_apm_idle) { - unsigned int t; - - t = jiffies; - switch (apm_do_idle()) { - case 0: - apm_idle_done = 1; - if (t != jiffies) { - if (bucket) { - bucket = IDLE_LEAKY_MAX; - continue; - } - } else if (bucket) { - bucket--; - continue; - } - break; - case 1: - apm_idle_done = 1; - break; - default: /* BIOS refused */ - break; - } - } - if (original_pm_idle) - original_pm_idle(); - else - default_idle(); - local_irq_disable(); - jiffies_since_last_check = jiffies - last_jiffies; - if (jiffies_since_last_check > idle_period) - goto recalc; - } - - if (apm_idle_done) - apm_do_busy(); - - local_irq_enable(); -} - -/** * apm_power_off - ask the BIOS to power off * * Handle the power off sequence. This is the one piece of code we @@ -1881,12 +1700,6 @@ static int __init apm_setup(char *str) if ((strncmp(str, "bounce-interval=", 16) == 0) || (strncmp(str, "bounce_interval=", 16) == 0)) bounce_interval = simple_strtol(str + 16, NULL, 0); - if ((strncmp(str, "idle-threshold=", 15) == 0) || - (strncmp(str, "idle_threshold=", 15) == 0)) - idle_threshold = simple_strtol(str + 15, NULL, 0); - if ((strncmp(str, "idle-period=", 12) == 0) || - (strncmp(str, "idle_period=", 12) == 0)) - idle_period = simple_strtol(str + 12, NULL, 0); invert = (strncmp(str, "no-", 3) == 0) || (strncmp(str, "no_", 3) == 0); if (invert) @@ -1898,7 +1711,6 @@ static int __init apm_setup(char *str) power_off = !invert; if (strncmp(str, "smp", 3) == 0) { smp = !invert; - idle_threshold = 100; } if ((strncmp(str, "allow-ints", 10) == 0) || (strncmp(str, "allow_ints", 10) == 0)) @@ -1999,17 +1811,6 @@ static int __init apm_is_horked_d850md(const struct dmi_system_id *d) return 0; } -/* Some APM bioses hang on APM idle calls */ -static int __init apm_likes_to_melt(const struct dmi_system_id *d) -{ - if (apm_info.forbid_idle == 0) { - apm_info.forbid_idle = 1; - printk(KERN_INFO "%s machine detected. " - "Disabling APM idle calls.\n", d->ident); - } - return 0; -} - /* * Check for clue free BIOS implementations who use * the following QA technique @@ -2150,16 +1951,6 @@ static struct dmi_system_id __initdata apm_dmi_table[] = { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"), DMI_MATCH(DMI_BIOS_VERSION, "A11"), }, }, - { /* APM idle hangs */ - apm_likes_to_melt, "Jabil AMD", - { DMI_MATCH(DMI_BIOS_VENDOR, "American Megatrends Inc."), - DMI_MATCH(DMI_BIOS_VERSION, "0AASNP06"), }, - }, - { /* APM idle hangs */ - apm_likes_to_melt, "AMI Bios", - { DMI_MATCH(DMI_BIOS_VENDOR, "American Megatrends Inc."), - DMI_MATCH(DMI_BIOS_VERSION, "0AASNP05"), }, - }, { /* Handle problems with APM on Sony Vaio PCG-N505X(DE) */ swab_apm_power_in_minutes, "Sony VAIO", { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"), @@ -2390,14 +2181,6 @@ static int __init apm_init(void) if (misc_register(&apm_device)) printk(KERN_WARNING "apm: Could not register misc device.\n"); - if (HZ != 100) - idle_period = (idle_period * HZ) / 100; - if (idle_threshold < 100) { - original_pm_idle = pm_idle; - pm_idle = apm_cpu_idle; - set_pm_idle = 1; - } - return 0; } @@ -2405,15 +2188,6 @@ static void __exit apm_exit(void) { int error; - if (set_pm_idle) { - pm_idle = original_pm_idle; - /* - * We are about to unload the current idle thread pm callback - * (pm_idle), Wait for all processors to update cached/local - * copies of pm_idle before proceeding. - */ - cpu_idle_wait(); - } if (((apm_info.bios.flags & APM_BIOS_DISENGAGED) == 0) && (apm_info.connection_version > 0x0100)) { error = apm_engage_power_management(APM_DEVICE_ALL, 0); @@ -2451,12 +2225,6 @@ MODULE_PARM_DESC(broken_psr, "BIOS has a broken GetPowerStatus call"); module_param(realmode_power_off, bool, 0444); MODULE_PARM_DESC(realmode_power_off, "Switch to real mode before powering off"); -module_param(idle_threshold, int, 0444); -MODULE_PARM_DESC(idle_threshold, - "System idle percentage above which to make APM BIOS idle calls"); -module_param(idle_period, int, 0444); -MODULE_PARM_DESC(idle_period, - "Period (in sec/100) over which to caculate the idle percentage"); module_param(smp, bool, 0444); MODULE_PARM_DESC(smp, "Set this to enable APM use on an SMP platform. Use with caution on older systems");