From aeb834d95e771499cb0492d127aec3246d1595c8 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Tue, 27 Apr 2010 14:06:04 -0700 Subject: [PATCH 1/6] drivers/acpi: use kasprintf kasprintf combines kmalloc and sprintf, and takes care of the size calculation itself. The semantic patch that makes this change is as follows: (http://coccinelle.lip6.fr/) // @@ expression a,flag; expression list args; statement S; @@ a = - \(kmalloc\|kzalloc\)(...,flag) + kasprintf(flag,args) <... when != a if (a == NULL || ...) S ...> - sprintf(a,args); // [akpm@linux-foundation.org: don't change handling of `count'] Signed-off-by: Julia Lawall Signed-off-by: Andrew Morton Signed-off-by: Len Brown --- drivers/acpi/video.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index a0c93b321482..1a6b305006ef 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c @@ -1007,11 +1007,11 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device) result = acpi_video_init_brightness(device); if (result) return; - name = kzalloc(MAX_NAME_LEN, GFP_KERNEL); + name = kasprintf(GFP_KERNEL, "acpi_video%d", count); if (!name) return; + count++; - sprintf(name, "acpi_video%d", count++); memset(&props, 0, sizeof(struct backlight_properties)); props.max_brightness = device->brightness->count - 3; device->backlight = backlight_device_register(name, NULL, device, @@ -1067,10 +1067,10 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device) if (device->cap._DCS && device->cap._DSS) { static int count; char *name; - name = kzalloc(MAX_NAME_LEN, GFP_KERNEL); + name = kasprintf(GFP_KERNEL, "acpi_video%d", count); if (!name) return; - sprintf(name, "acpi_video%d", count++); + count++; device->output_dev = video_output_register(name, NULL, device, &acpi_output_properties); kfree(name); From d6bd535d88429b4804d6d917ab4f586306f9a855 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sat, 15 May 2010 23:16:21 +0200 Subject: [PATCH 2/6] ACPI: EC: Use kmemdup Use kmemdup when some other buffer is immediately copied into the allocated region. A simplified version of the semantic patch that makes this change is as follows: (http://coccinelle.lip6.fr/) // @@ expression from,to,size,flag; statement S; @@ - to = \(kmalloc\|kzalloc\)(size,flag); + to = kmemdup(from,size,flag); if (to==NULL || ...) S - memcpy(to, from, size); // Signed-off-by: Julia Lawall Acked-by: Alexey Starikovskiy Signed-off-by: Len Brown --- drivers/acpi/ec.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index f2234db85da0..e61d4f8e62a5 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -1027,10 +1027,9 @@ int __init acpi_ec_ecdt_probe(void) /* Don't trust ECDT, which comes from ASUSTek */ if (!EC_FLAGS_VALIDATE_ECDT) goto install; - saved_ec = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL); + saved_ec = kmemdup(boot_ec, sizeof(struct acpi_ec), GFP_KERNEL); if (!saved_ec) return -ENOMEM; - memcpy(saved_ec, boot_ec, sizeof(struct acpi_ec)); /* fall through */ } From 34a18d6fe5430184e4ca96eeb074ee671d89fe7b Mon Sep 17 00:00:00 2001 From: Len Brown Date: Fri, 21 May 2010 19:40:02 -0400 Subject: [PATCH 3/6] ACPI: delete unused c-state promotion/demotion data strucutures These were used before cpuidle by the native ACPI idle driver, which tracked promotion and demotion between states. The code was referenced by CONFIG_ACPI_PROCFS for /proc/acpi/processor/*/power, but as we no longer do promotion/demotion, that reference has been a NOP since the transition. Signed-off-by: Len Brown --- drivers/acpi/processor_idle.c | 14 ++------------ include/acpi/processor.h | 13 ------------- 2 files changed, 2 insertions(+), 25 deletions(-) diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index 5939e7f7d8e9..63a3d4b8c238 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c @@ -727,19 +727,9 @@ static int acpi_processor_power_seq_show(struct seq_file *seq, void *offset) break; } - if (pr->power.states[i].promotion.state) - seq_printf(seq, "promotion[C%zd] ", - (pr->power.states[i].promotion.state - - pr->power.states)); - else - seq_puts(seq, "promotion[--] "); + seq_puts(seq, "promotion[--] "); - if (pr->power.states[i].demotion.state) - seq_printf(seq, "demotion[C%zd] ", - (pr->power.states[i].demotion.state - - pr->power.states)); - else - seq_puts(seq, "demotion[--] "); + seq_puts(seq, "demotion[--] "); seq_printf(seq, "latency[%03d] usage[%08d] duration[%020llu]\n", pr->power.states[i].latency, diff --git a/include/acpi/processor.h b/include/acpi/processor.h index 86825ddbe14e..da565a48240e 100644 --- a/include/acpi/processor.h +++ b/include/acpi/processor.h @@ -52,17 +52,6 @@ struct acpi_power_register { u64 address; } __attribute__ ((packed)); -struct acpi_processor_cx_policy { - u32 count; - struct acpi_processor_cx *state; - struct { - u32 time; - u32 ticks; - u32 count; - u32 bm; - } threshold; -}; - struct acpi_processor_cx { u8 valid; u8 type; @@ -74,8 +63,6 @@ struct acpi_processor_cx { u32 power; u32 usage; u64 time; - struct acpi_processor_cx_policy promotion; - struct acpi_processor_cx_policy demotion; char desc[ACPI_CX_DESC_LEN]; }; From 2da513f582a96c053aacc2c92873978d2ea7abff Mon Sep 17 00:00:00 2001 From: Venkatesh Pallipadi Date: Thu, 22 Apr 2010 16:48:33 -0700 Subject: [PATCH 4/6] ACPI: Minor cleanup eliminating redundant PMTIMER_TICKS to NS conversion acpi_enter_[simple,bm] does idle timing in ns, convert it to timeval, then to us, then to pmtimer_ticks and then back to ns. This patch changes things to idle timing in ns, convert it to us, and then to pmtimer_ticks. Just saves an imul along this path, but makes the code cleaner. Signed-off-by: Venkatesh Pallipadi Signed-off-by: Len Brown --- drivers/acpi/processor_idle.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index 63a3d4b8c238..43fe52f9834b 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c @@ -859,6 +859,7 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev, struct acpi_processor *pr; struct acpi_processor_cx *cx = cpuidle_get_statedata(state); ktime_t kt1, kt2; + s64 idle_time_ns; s64 idle_time; s64 sleep_ticks = 0; @@ -900,12 +901,14 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev, sched_clock_idle_sleep_event(); acpi_idle_do_entry(cx); kt2 = ktime_get_real(); - idle_time = ktime_to_us(ktime_sub(kt2, kt1)); + idle_time_ns = ktime_to_ns(ktime_sub(kt2, kt1)); + idle_time = idle_time_ns; + do_div(idle_time, NSEC_PER_USEC); sleep_ticks = us_to_pm_timer_ticks(idle_time); /* Tell the scheduler how much we idled: */ - sched_clock_idle_wakeup_event(sleep_ticks*PM_TIMER_TICK_NS); + sched_clock_idle_wakeup_event(idle_time_ns); local_irq_enable(); current_thread_info()->status |= TS_POLLING; @@ -933,6 +936,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, struct acpi_processor *pr; struct acpi_processor_cx *cx = cpuidle_get_statedata(state); ktime_t kt1, kt2; + s64 idle_time_ns; s64 idle_time; s64 sleep_ticks = 0; @@ -1015,11 +1019,13 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, spin_unlock(&c3_lock); } kt2 = ktime_get_real(); - idle_time = ktime_to_us(ktime_sub(kt2, kt1)); + idle_time_ns = ktime_to_us(ktime_sub(kt2, kt1)); + idle_time = idle_time_ns; + do_div(idle_time, NSEC_PER_USEC); sleep_ticks = us_to_pm_timer_ticks(idle_time); /* Tell the scheduler how much we idled: */ - sched_clock_idle_wakeup_event(sleep_ticks*PM_TIMER_TICK_NS); + sched_clock_idle_wakeup_event(idle_time_ns); local_irq_enable(); current_thread_info()->status |= TS_POLLING; From b6fecaa8685a9922d11db2cd79e76f43c3edc970 Mon Sep 17 00:00:00 2001 From: Andrea Gelmini Date: Sat, 27 Feb 2010 17:51:42 +0100 Subject: [PATCH 5/6] drivers/acpi/sleep.h: Checkpatch cleanup drivers/acpi/sleep.h:3: WARNING: space prohibited between function name and open parenthesis '(' Signed-off-by: Andrea Gelmini Signed-off-by: Len Brown --- drivers/acpi/sleep.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/acpi/sleep.h b/drivers/acpi/sleep.h index 8a8f3b3382a6..25b8bd149284 100644 --- a/drivers/acpi/sleep.h +++ b/drivers/acpi/sleep.h @@ -1,6 +1,6 @@ extern u8 sleep_states[]; -extern int acpi_suspend (u32 state); +extern int acpi_suspend(u32 state); extern void acpi_enable_wakeup_device_prep(u8 sleep_state); extern void acpi_enable_wakeup_device(u8 sleep_state); From 0dc698b93f3eecdda43b22232131324eb41e510c Mon Sep 17 00:00:00 2001 From: Venkatesh Pallipadi Date: Tue, 18 May 2010 14:39:16 -0700 Subject: [PATCH 6/6] ACPI: Don't let acpi_pad needlessly mark TSC unstable acpi pad driver kind of aggressively marks TSC as unstable at init time, on mwait capable and non X86_FEATURE_NONSTOP_TSC systems. This is irrespective of whether pad driver is ever going to be used on the system or deep C-states are supported/used. This will affect every user who just happens to compile in (or get a kernel version which compiles in) acpi pad driver. Move mark_tsc_unstable() out of init to the actual idle invocation path of the pad driver. There is also another bug/missing_feature in the code that it does not support 'always running apic timer' and switches to broadcast mode unconditionally. Shaohua, can you take a look at that please. Signed-off-by: Venkatesh Pallipadi Signed-off-by: Len Brown --- drivers/acpi/acpi_pad.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/acpi/acpi_pad.c b/drivers/acpi/acpi_pad.c index 62122134693b..f169e516a1af 100644 --- a/drivers/acpi/acpi_pad.c +++ b/drivers/acpi/acpi_pad.c @@ -43,6 +43,10 @@ static DEFINE_MUTEX(isolated_cpus_lock); #define CPUID5_ECX_EXTENSIONS_SUPPORTED (0x1) #define CPUID5_ECX_INTERRUPT_BREAK (0x2) static unsigned long power_saving_mwait_eax; + +static unsigned char tsc_detected_unstable; +static unsigned char tsc_marked_unstable; + static void power_saving_mwait_init(void) { unsigned int eax, ebx, ecx, edx; @@ -87,8 +91,8 @@ static void power_saving_mwait_init(void) /*FALL THROUGH*/ default: - /* TSC could halt in idle, so notify users */ - mark_tsc_unstable("TSC halts in idle"); + /* TSC could halt in idle */ + tsc_detected_unstable = 1; } #endif } @@ -178,6 +182,11 @@ static int power_saving_thread(void *data) expire_time = jiffies + HZ * (100 - idle_pct) / 100; while (!need_resched()) { + if (tsc_detected_unstable && !tsc_marked_unstable) { + /* TSC could halt in idle, so notify users */ + mark_tsc_unstable("TSC halts in idle"); + tsc_marked_unstable = 1; + } local_irq_disable(); cpu = smp_processor_id(); clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER,