summaryrefslogtreecommitdiffstats
path: root/arch/i386
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1999-06-22 23:05:57 +0000
committerRalf Baechle <ralf@linux-mips.org>1999-06-22 23:05:57 +0000
commit51d3b7814cdccef9188240fe0cbd8d97ff2c7470 (patch)
tree5cbb01d0323d4f63ade66bdf48ba4a91aaa6df16 /arch/i386
parent52273a23c9a84336b93a35e4847fc88fac7eb0e4 (diff)
Merge with Linux 2.3.7.
WARNING: 2.3.7 is known to eat filesystems for breakfast and little children for lunch, so if you try this on your machine make backups first ...
Diffstat (limited to 'arch/i386')
-rw-r--r--arch/i386/defconfig4
-rw-r--r--arch/i386/kernel/mca.c1
-rw-r--r--arch/i386/kernel/smp.c51
-rw-r--r--arch/i386/mm/init.c12
4 files changed, 39 insertions, 29 deletions
diff --git a/arch/i386/defconfig b/arch/i386/defconfig
index 49be2fe7b..b5ede6508 100644
--- a/arch/i386/defconfig
+++ b/arch/i386/defconfig
@@ -95,10 +95,9 @@ CONFIG_BLK_DEV_CMD640=y
# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
CONFIG_BLK_DEV_RZ1000=y
CONFIG_BLK_DEV_IDEPCI=y
-CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_BLK_DEV_IDEDMA_PCI is not set
# CONFIG_BLK_DEV_OFFBOARD is not set
# CONFIG_BLK_DEV_AEC6210 is not set
-CONFIG_IDEDMA_AUTO=y
# CONFIG_IDE_CHIPSETS is not set
#
@@ -355,7 +354,6 @@ CONFIG_EXT2_FS=y
#
# CONFIG_CODA_FS is not set
CONFIG_NFS_FS=y
-# CONFIG_NFSD_SUN is not set
CONFIG_SUNRPC=y
CONFIG_LOCKD=y
# CONFIG_SMB_FS is not set
diff --git a/arch/i386/kernel/mca.c b/arch/i386/kernel/mca.c
index 9c6948c60..ae1980a42 100644
--- a/arch/i386/kernel/mca.c
+++ b/arch/i386/kernel/mca.c
@@ -148,7 +148,6 @@ static struct inode_operations proc_mca_inode_operations = {
NULL, /* truncate */
NULL, /* permission */
NULL, /* smap */
- NULL, /* updatepage */
NULL /* revalidate */
};
#endif
diff --git a/arch/i386/kernel/smp.c b/arch/i386/kernel/smp.c
index 5588f5ca8..9d3a8b4b5 100644
--- a/arch/i386/kernel/smp.c
+++ b/arch/i386/kernel/smp.c
@@ -1164,6 +1164,7 @@ static void smp_tune_scheduling (void)
}
unsigned int prof_multiplier[NR_CPUS];
+unsigned int prof_old_multiplier[NR_CPUS];
unsigned int prof_counter[NR_CPUS];
/*
@@ -1187,6 +1188,7 @@ void __init smp_boot_cpus(void)
for (i = 0; i < NR_CPUS; i++) {
cpu_number_map[i] = -1;
prof_counter[i] = 1;
+ prof_old_multiplier[i] = 1;
prof_multiplier[i] = 1;
}
@@ -1733,6 +1735,10 @@ int smp_call_function (void (*func) (void *info), void *info, int retry,
return 0;
}
+static unsigned int calibration_result;
+
+void setup_APIC_timer(unsigned int clocks);
+
/*
* Local timer interrupt handler. It does both profiling and
* process statistics/rescheduling.
@@ -1745,6 +1751,7 @@ int smp_call_function (void (*func) (void *info), void *info, int retry,
void smp_local_timer_interrupt(struct pt_regs * regs)
{
+ int user = (user_mode(regs) != 0);
int cpu = smp_processor_id();
/*
@@ -1753,25 +1760,34 @@ void smp_local_timer_interrupt(struct pt_regs * regs)
* updated with atomic operations). This is especially
* useful with a profiling multiplier != 1
*/
- if (!user_mode(regs))
+ if (!user)
x86_do_profile(regs->eip);
if (!--prof_counter[cpu]) {
- int user=0,system=0;
+ int system = 1 - user;
struct task_struct * p = current;
/*
+ * The multiplier may have changed since the last time we got
+ * to this point as a result of the user writing to
+ * /proc/profile. In this case we need to adjust the APIC
+ * timer accordingly.
+ *
+ * Interrupts are already masked off at this point.
+ */
+ prof_counter[cpu] = prof_multiplier[cpu];
+ if (prof_counter[cpu] != prof_old_multiplier[cpu]) {
+ setup_APIC_timer(calibration_result/prof_counter[cpu]);
+ prof_old_multiplier[cpu] = prof_counter[cpu];
+ }
+
+ /*
* After doing the above, we need to make like
* a normal interrupt - otherwise timer interrupts
* ignore the global interrupt lock, which is the
* WrongThing (tm) to do.
*/
- if (user_mode(regs))
- user=1;
- else
- system=1;
-
irq_enter(cpu, 0);
update_one_process(p, 1, user, system, cpu);
if (p->pid) {
@@ -1791,7 +1807,6 @@ void smp_local_timer_interrupt(struct pt_regs * regs)
kstat.per_cpu_system[cpu] += system;
}
- prof_counter[cpu]=prof_multiplier[cpu];
irq_exit(cpu, 0);
}
@@ -2064,8 +2079,6 @@ int __init calibrate_APIC_clock(void)
return calibration_result;
}
-static unsigned int calibration_result;
-
void __init setup_APIC_clock(void)
{
unsigned long flags;
@@ -2117,13 +2130,10 @@ void __init setup_APIC_clock(void)
/*
* the frequency of the profiling timer can be changed
* by writing a multiplier value into /proc/profile.
- *
- * usually you want to run this on all CPUs ;)
*/
int setup_profiling_timer(unsigned int multiplier)
{
- int cpu = smp_processor_id();
- unsigned long flags;
+ int i;
/*
* Sanity check. [at least 500 APIC cycles should be
@@ -2133,11 +2143,14 @@ int setup_profiling_timer(unsigned int multiplier)
if ( (!multiplier) || (calibration_result/multiplier < 500))
return -EINVAL;
- save_flags(flags);
- cli();
- setup_APIC_timer(calibration_result/multiplier);
- prof_multiplier[cpu]=multiplier;
- restore_flags(flags);
+ /*
+ * Set the new multiplier for each CPU. CPUs don't start using the
+ * new values until the next timer interrupt in which they do process
+ * accounting. At that time they also adjust their APIC timers
+ * accordingly.
+ */
+ for (i = 0; i < NR_CPUS; ++i)
+ prof_multiplier[i] = multiplier;
return 0;
}
diff --git a/arch/i386/mm/init.c b/arch/i386/mm/init.c
index 22ebf7a10..bef9ea2fe 100644
--- a/arch/i386/mm/init.c
+++ b/arch/i386/mm/init.c
@@ -159,10 +159,10 @@ void show_mem(void)
reserved++;
else if (PageSwapCache(mem_map+i))
cached++;
- else if (!atomic_read(&mem_map[i].count))
+ else if (!page_count(mem_map+i))
free++;
else
- shared += atomic_read(&mem_map[i].count) - 1;
+ shared += page_count(mem_map+i) - 1;
}
printk("%d pages of RAM\n",total);
printk("%d reserved pages\n",reserved);
@@ -449,7 +449,7 @@ __initfunc(void mem_init(unsigned long start_mem, unsigned long end_mem))
reservedpages++;
continue;
}
- atomic_set(&mem_map[MAP_NR(tmp)].count, 1);
+ set_page_count(mem_map+MAP_NR(tmp), 1);
#ifdef CONFIG_BLK_DEV_INITRD
if (!initrd_start || (tmp < initrd_start || tmp >=
initrd_end))
@@ -475,7 +475,7 @@ void free_initmem(void)
addr = (unsigned long)(&__init_begin);
for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) {
mem_map[MAP_NR(addr)].flags &= ~(1 << PG_reserved);
- atomic_set(&mem_map[MAP_NR(addr)].count, 1);
+ set_page_count(mem_map+MAP_NR(addr), 1);
free_page(addr);
}
printk ("Freeing unused kernel memory: %dk freed\n", (&__init_end - &__init_begin) >> 10);
@@ -494,9 +494,9 @@ void si_meminfo(struct sysinfo *val)
if (PageReserved(mem_map+i))
continue;
val->totalram++;
- if (!atomic_read(&mem_map[i].count))
+ if (!page_count(mem_map+i))
continue;
- val->sharedram += atomic_read(&mem_map[i].count) - 1;
+ val->sharedram += page_count(mem_map+i) - 1;
}
val->totalram <<= PAGE_SHIFT;
val->sharedram <<= PAGE_SHIFT;