aboutsummaryrefslogtreecommitdiffstats
path: root/arch/i386
diff options
context:
space:
mode:
authorJohn M. Calandrino <jmc@jupiter-cs.cs.unc.edu>2007-02-07 11:50:15 -0500
committerJohn M. Calandrino <jmc@jupiter-cs.cs.unc.edu>2007-02-07 11:50:15 -0500
commit8a3cb25f615be35df14df9b224d90c464bb7afa4 (patch)
tree779c3d6113c9a2011844fea1f2b999421543358e /arch/i386
parenteb2ba33041b84cf15367288367494c6aec1da25a (diff)
Modified apic.c to fix barrier-related issues with timer sync, now
use global timer (jiffies) to determine when sync occurs. Still broken though, this is just a local checkpoint.
Diffstat (limited to 'arch/i386')
-rw-r--r--arch/i386/kernel/apic.c51
1 files changed, 40 insertions, 11 deletions
diff --git a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c
index 268a32870c..13a08e8198 100644
--- a/arch/i386/kernel/apic.c
+++ b/arch/i386/kernel/apic.c
@@ -1198,13 +1198,20 @@ EXPORT_SYMBOL(switch_ipi_to_APIC_timer);
1198#undef APIC_DIVISOR 1198#undef APIC_DIVISOR
1199 1199
1200/* JOHN: Begin added code, starting with quantum sync function. */ 1200/* JOHN: Begin added code, starting with quantum sync function. */
1201#define STAGGER 0 1201#define STAGGER 1
1202#define WARM_UP_INTRS 10000 1202#define WAIT_TO_SYNC 30000 // 30s after boot (later: between syncs?)
1203 // later, define per-cpu variable and re-synch when intr_count % WARM_UP_INTRS == 0 1203#define QSYNC_TIME (INITIAL_JIFFIES+msecs_to_jiffies(WAIT_TO_SYNC))
1204static atomic_t quantum_sync_barrier = ATOMIC_INIT(0); // used to implement simple barrier 1204 // later: re-synch when intr_count % WARM_UP_INTRS == 0
1205static atomic_t quantum_sync_barrier = ATOMIC_INIT(0);
1206 // used to implement simple barrier
1205static DEFINE_PER_CPU(int, synched) = 0; 1207static DEFINE_PER_CPU(int, synched) = 0;
1208static DEFINE_PER_CPU(int, intr_count) = 0;
1206 1209
1207/* This function is called to align all quanta, and to stagger quanta if necessary. */ 1210/*
1211 * This function is called to align all quanta, and to stagger quanta if
1212 * necessary. It relies on a barrier to synchronize all processors, so
1213 * that they all reset their APIC timers at the same time.
1214 */
1208void synchronize_quanta(void) 1215void synchronize_quanta(void)
1209{ 1216{
1210 int cpu = smp_processor_id(); 1217 int cpu = smp_processor_id();
@@ -1217,7 +1224,13 @@ void synchronize_quanta(void)
1217 */ 1224 */
1218 disable_APIC_timer(); 1225 disable_APIC_timer();
1219 atomic_inc(&quantum_sync_barrier); 1226 atomic_inc(&quantum_sync_barrier);
1220 while (atomic_read(&quantum_sync_barrier) < total_cpus); 1227
1228 //debugging this...
1229 while (atomic_read(&quantum_sync_barrier) < total_cpus)//;
1230 {
1231// printk("cpu %d, barrier = %d\n", cpu, atomic_read(&quantum_sync_barrier));
1232 }
1233
1221 __setup_APIC_LVTT(calibration_result); 1234 __setup_APIC_LVTT(calibration_result);
1222 enable_APIC_timer(); 1235 enable_APIC_timer();
1223 1236
@@ -1258,13 +1271,29 @@ inline void smp_local_timer_interrupt(void)
1258 1271
1259 // JOHN: begin added code. 1272 // JOHN: begin added code.
1260 /* 1273 /*
1261 * Time to synchronize quanta, if it hasn't been done already. To avoid 1274 * Synchronize quanta, if it hasn't been done already.
1262 * placing a lot of code in an inline function, the actual sync code is 1275 * To keep the interrupt handler code as efficient as possible
1263 * placed in its own (non-inline) function - the majority of the time 1276 * in the common case, we check a flag and only check the
1264 * we won't even call it. 1277 * jiffy count (indicating the approximate system uptime after
1278 * which all processors should synch interrupts -- this jiffy count
1279 * needs to be high enough to ensure that all local APIC timers are
1280 * up and running) if the flag has not yet been set
1281 * (indicating that timers have not yet been synchronized).
1282 * An additional comparison is performed to see if the jiffy
1283 * count has exceeded QSYNC_TIME, at which point
1284 * the synchronization occurs, and the flag is set so we never enter
1285 * this code again (unless this is changed so that quanta are
1286 * periodically re-synchronized).
1287 * The synchronization code itself is placed in its own
1288 * (non-inline) function, to avoid issues with creating an inline
1289 * function that is too large.
1265 */ 1290 */
1266 if (unlikely(!per_cpu(synched, cpu))) { 1291 if (unlikely(!per_cpu(synched, cpu))) {
1267 synchronize_quanta(); 1292// per_cpu(intr_count, cpu)++;
1293// if (unlikely(per_cpu(intr_count, cpu) > WARM_UP_INTRS)) {
1294 if (jiffies > QSYNC_TIME) {
1295 synchronize_quanta();
1296 }
1268 } 1297 }
1269 // JOHN: end added code. 1298 // JOHN: end added code.
1270 1299