Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 37613
b: refs/heads/master
c: 5c87579
h: refs/heads/master
i:
  37611: d09fa25
v: v3
  • Loading branch information
Arjan van de Ven authored and Linus Torvalds committed Oct 1, 2006
1 parent 2ad3e4a commit 7814dee
Show file tree
Hide file tree
Showing 6 changed files with 350 additions and 6 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 130c6b98984a058068ea595c465fba2beb48b9ef
refs/heads/master: 5c87579e65ee4f419b2369407f82326d38b5d2d8
38 changes: 34 additions & 4 deletions trunk/drivers/acpi/processor_idle.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
#include <linux/dmi.h>
#include <linux/moduleparam.h>
#include <linux/sched.h> /* need_resched() */
#include <linux/latency.h>

#include <asm/io.h>
#include <asm/uaccess.h>
Expand Down Expand Up @@ -453,7 +454,8 @@ static void acpi_processor_idle(void)
*/
if (cx->promotion.state &&
((cx->promotion.state - pr->power.states) <= max_cstate)) {
if (sleep_ticks > cx->promotion.threshold.ticks) {
if (sleep_ticks > cx->promotion.threshold.ticks &&
cx->promotion.state->latency <= system_latency_constraint()) {
cx->promotion.count++;
cx->demotion.count = 0;
if (cx->promotion.count >=
Expand Down Expand Up @@ -494,8 +496,10 @@ static void acpi_processor_idle(void)
end:
/*
* Demote if current state exceeds max_cstate
* or if the latency of the current state is unacceptable
*/
if ((pr->power.state - pr->power.states) > max_cstate) {
if ((pr->power.state - pr->power.states) > max_cstate ||
pr->power.state->latency > system_latency_constraint()) {
if (cx->demotion.state)
next_state = cx->demotion.state;
}
Expand Down Expand Up @@ -1009,9 +1013,11 @@ static int acpi_processor_power_seq_show(struct seq_file *seq, void *offset)

seq_printf(seq, "active state: C%zd\n"
"max_cstate: C%d\n"
"bus master activity: %08x\n",
"bus master activity: %08x\n"
"maximum allowed latency: %d usec\n",
pr->power.state ? pr->power.state - pr->power.states : 0,
max_cstate, (unsigned)pr->power.bm_activity);
max_cstate, (unsigned)pr->power.bm_activity,
system_latency_constraint());

seq_puts(seq, "states:\n");

Expand Down Expand Up @@ -1077,6 +1083,28 @@ static const struct file_operations acpi_processor_power_fops = {
.release = single_release,
};

static void smp_callback(void *v)
{
/* we already woke the CPU up, nothing more to do */
}

/*
* This function gets called when a part of the kernel has a new latency
* requirement. This means we need to get all processors out of their C-state,
* and then recalculate a new suitable C-state. Just do a cross-cpu IPI; that
* wakes them all right up.
*/
static int acpi_processor_latency_notify(struct notifier_block *b,
unsigned long l, void *v)
{
smp_call_function(smp_callback, NULL, 0, 1);
return NOTIFY_OK;
}

static struct notifier_block acpi_processor_latency_notifier = {
.notifier_call = acpi_processor_latency_notify,
};

int acpi_processor_power_init(struct acpi_processor *pr,
struct acpi_device *device)
{
Expand All @@ -1093,6 +1121,7 @@ int acpi_processor_power_init(struct acpi_processor *pr,
"ACPI: processor limited to max C-state %d\n",
max_cstate);
first_run++;
register_latency_notifier(&acpi_processor_latency_notifier);
}

if (!pr)
Expand Down Expand Up @@ -1164,6 +1193,7 @@ int acpi_processor_power_exit(struct acpi_processor *pr,
* copies of pm_idle before proceeding.
*/
cpu_idle_wait();
unregister_latency_notifier(&acpi_processor_latency_notifier);
}

return 0;
Expand Down
10 changes: 10 additions & 0 deletions trunk/drivers/net/wireless/ipw2100.c
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ that only one external action is invoked at a time.
#include <linux/firmware.h>
#include <linux/acpi.h>
#include <linux/ctype.h>
#include <linux/latency.h>

#include "ipw2100.h"

Expand Down Expand Up @@ -1697,6 +1698,11 @@ static int ipw2100_up(struct ipw2100_priv *priv, int deferred)
return 0;
}

/* the ipw2100 hardware really doesn't want power management delays
* longer than 175usec
*/
modify_acceptable_latency("ipw2100", 175);

/* If the interrupt is enabled, turn it off... */
spin_lock_irqsave(&priv->low_lock, flags);
ipw2100_disable_interrupts(priv);
Expand Down Expand Up @@ -1849,6 +1855,8 @@ static void ipw2100_down(struct ipw2100_priv *priv)
ipw2100_disable_interrupts(priv);
spin_unlock_irqrestore(&priv->low_lock, flags);

modify_acceptable_latency("ipw2100", INFINITE_LATENCY);

#ifdef ACPI_CSTATE_LIMIT_DEFINED
if (priv->config & CFG_C3_DISABLED) {
IPW_DEBUG_INFO(": Resetting C3 transitions.\n");
Expand Down Expand Up @@ -6534,6 +6542,7 @@ static int __init ipw2100_init(void)

ret = pci_register_driver(&ipw2100_pci_driver);

set_acceptable_latency("ipw2100", INFINITE_LATENCY);
#ifdef CONFIG_IPW2100_DEBUG
ipw2100_debug_level = debug;
driver_create_file(&ipw2100_pci_driver.driver,
Expand All @@ -6554,6 +6563,7 @@ static void __exit ipw2100_exit(void)
&driver_attr_debug_level);
#endif
pci_unregister_driver(&ipw2100_pci_driver);
remove_acceptable_latency("ipw2100");
}

module_init(ipw2100_init);
Expand Down
25 changes: 25 additions & 0 deletions trunk/include/linux/latency.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* latency.h: Explicit system-wide latency-expectation infrastructure
*
* (C) Copyright 2006 Intel Corporation
* Author: Arjan van de Ven <arjan@linux.intel.com>
*
*/

#ifndef _INCLUDE_GUARD_LATENCY_H_
#define _INCLUDE_GUARD_LATENCY_H_

#include <linux/notifier.h>

void set_acceptable_latency(char *identifier, int usecs);
void modify_acceptable_latency(char *identifier, int usecs);
void remove_acceptable_latency(char *identifier);
void synchronize_acceptable_latency(void);
int system_latency_constraint(void);

int register_latency_notifier(struct notifier_block * nb);
int unregister_latency_notifier(struct notifier_block * nb);

#define INFINITE_LATENCY 1000000

#endif
2 changes: 1 addition & 1 deletion trunk/kernel/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ obj-y = sched.o fork.o exec_domain.o panic.o printk.o profile.o \
signal.o sys.o kmod.o workqueue.o pid.o \
rcupdate.o extable.o params.o posix-timers.o \
kthread.o wait.o kfifo.o sys_ni.o posix-cpu-timers.o mutex.o \
hrtimer.o rwsem.o
hrtimer.o rwsem.o latency.o

obj-$(CONFIG_STACKTRACE) += stacktrace.o
obj-y += time/
Expand Down
Loading

0 comments on commit 7814dee

Please sign in to comment.