Revision 15f9850d3c2d46f5851a424d2990a18b5bb5ebfd authored by David S. Miller on 19 May 2005, 05:49:26 UTC, committed by David S. Miller on 19 May 2005, 05:49:26 UTC
Even though we do software interrupt mitigation via NAPI, it still helps to have some minimal hw assisted mitigation. This helps, particularly, on systems where register I/O overhead is much greater than the CPU horsepower. For example, it helps on NUMA systems. In such cases the PIO overhead to disable interrupts for NAPI accounts for the majority of the packet processing cost. The CPU is fast enough such that only a single packet is processed by each NAPI poll call. Thanks to Michael Chan for reviewing this patch. Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent fac9b83
smp.c
/*
* drivers/power/smp.c - Functions for stopping other CPUs.
*
* Copyright 2004 Pavel Machek <pavel@suse.cz>
* Copyright (C) 2002-2003 Nigel Cunningham <ncunningham@clear.net.nz>
*
* This file is released under the GPLv2.
*/
#undef DEBUG
#include <linux/smp_lock.h>
#include <linux/interrupt.h>
#include <linux/suspend.h>
#include <linux/module.h>
#include <asm/atomic.h>
#include <asm/tlbflush.h>
static atomic_t cpu_counter, freeze;
static void smp_pause(void * data)
{
struct saved_context ctxt;
__save_processor_state(&ctxt);
printk("Sleeping in:\n");
dump_stack();
atomic_inc(&cpu_counter);
while (atomic_read(&freeze)) {
/* FIXME: restore takes place at random piece inside this.
This should probably be written in assembly, and
preserve general-purpose registers, too
What about stack? We may need to move to new stack here.
This should better be ran with interrupts disabled.
*/
cpu_relax();
barrier();
}
atomic_dec(&cpu_counter);
__restore_processor_state(&ctxt);
}
static cpumask_t oldmask;
void disable_nonboot_cpus(void)
{
oldmask = current->cpus_allowed;
set_cpus_allowed(current, cpumask_of_cpu(0));
printk("Freezing CPUs (at %d)", _smp_processor_id());
current->state = TASK_INTERRUPTIBLE;
schedule_timeout(HZ);
printk("...");
BUG_ON(_smp_processor_id() != 0);
/* FIXME: for this to work, all the CPUs must be running
* "idle" thread (or we deadlock). Is that guaranteed? */
atomic_set(&cpu_counter, 0);
atomic_set(&freeze, 1);
smp_call_function(smp_pause, NULL, 0, 0);
while (atomic_read(&cpu_counter) < (num_online_cpus() - 1)) {
cpu_relax();
barrier();
}
printk("ok\n");
}
void enable_nonboot_cpus(void)
{
printk("Restarting CPUs");
atomic_set(&freeze, 0);
while (atomic_read(&cpu_counter)) {
cpu_relax();
barrier();
}
printk("...");
set_cpus_allowed(current, oldmask);
schedule();
printk("ok\n");
}
![swh spinner](/static/img/swh-spinner.gif)
Computing file changes ...