From 2fa00abdeb16e50dd3e98674784c9bd37a173926 Mon Sep 17 00:00:00 2001 From: Samuel Thibault Date: Wed, 15 Feb 2023 10:11:00 +0100 Subject: pmap: Fix busy loop waiting for pmap users We need to avoid the kernel optimizing away the read from pmap->cpus_using. Use a standard relaxing instruction for that. --- i386/i386/lock.h | 2 +- i386/i386/mp_desc.c | 4 ++-- i386/i386/smp.c | 14 ++++++-------- i386/i386/smp.h | 2 ++ i386/intel/pmap.c | 2 +- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/i386/i386/lock.h b/i386/i386/lock.h index 1450fe03..4b445ae4 100644 --- a/i386/i386/lock.h +++ b/i386/i386/lock.h @@ -62,7 +62,7 @@ ({ \ while(_simple_lock_xchg_(l, 1)) \ while (*(volatile int *)&(l)->lock_data) \ - __asm ("pause"); \ + cpu_pause(); \ 0; \ }) diff --git a/i386/i386/mp_desc.c b/i386/i386/mp_desc.c index e6fcbf62..4b5a78ea 100644 --- a/i386/i386/mp_desc.c +++ b/i386/i386/mp_desc.c @@ -269,7 +269,7 @@ cpu_ap_main() int cpu = apic_get_cpu_kernel_id(apic_id); do { - asm volatile ("pause" : : : "memory"); + cpu_pause(); } while (bspdone != cpu); __sync_synchronize(); @@ -319,7 +319,7 @@ start_other_cpus(void) bspdone++; do { - asm volatile ("pause" : : : "memory"); + cpu_pause(); } while (machine_slot[cpu].running == FALSE); __sync_synchronize(); diff --git a/i386/i386/smp.c b/i386/i386/smp.c index 7441ffbb..c0149a3b 100644 --- a/i386/i386/smp.c +++ b/i386/i386/smp.c @@ -29,8 +29,6 @@ #include -#define pause_memory asm volatile ("pause" : : : "memory") - /* * smp_data_init: initialize smp_data structure * Must be called after smp_init(), once all APIC structures @@ -56,13 +54,13 @@ void smp_pmap_update(unsigned apic_id) apic_send_ipi(NO_SHORTHAND, FIXED, PHYSICAL, ASSERT, EDGE, CALL_SINGLE_FUNCTION_BASE, apic_id); do { - pause_memory; + cpu_pause(); } while(lapic->icr_low.delivery_status == SEND_PENDING); apic_send_ipi(NO_SHORTHAND, FIXED, PHYSICAL, DE_ASSERT, EDGE, CALL_SINGLE_FUNCTION_BASE, apic_id); do { - pause_memory; + cpu_pause(); } while(lapic->icr_low.delivery_status == SEND_PENDING); cpu_intr_restore(flags); @@ -81,7 +79,7 @@ void smp_startup_cpu(unsigned apic_id, unsigned vector) /* Wait for delivery */ do { - pause_memory; + cpu_pause(); } while(lapic->icr_low.delivery_status == SEND_PENDING); /* Deassert INIT IPI */ @@ -89,7 +87,7 @@ void smp_startup_cpu(unsigned apic_id, unsigned vector) /* Wait for delivery */ do { - pause_memory; + cpu_pause(); } while(lapic->icr_low.delivery_status == SEND_PENDING); /* Wait 10 msec */ @@ -106,7 +104,7 @@ void smp_startup_cpu(unsigned apic_id, unsigned vector) /* Wait for delivery */ do { - pause_memory; + cpu_pause(); } while(lapic->icr_low.delivery_status == SEND_PENDING); /* Second StartUp IPI */ @@ -117,7 +115,7 @@ void smp_startup_cpu(unsigned apic_id, unsigned vector) /* Wait for delivery */ do { - pause_memory; + cpu_pause(); } while(lapic->icr_low.delivery_status == SEND_PENDING); printf("done\n"); diff --git a/i386/i386/smp.h b/i386/i386/smp.h index 79337022..1faa39cd 100644 --- a/i386/i386/smp.h +++ b/i386/i386/smp.h @@ -25,4 +25,6 @@ int smp_init(void); void smp_pmap_update(unsigned apic_id); void smp_startup_cpu(unsigned apic_id, unsigned vector); +#define cpu_pause() asm volatile ("pause" : : : "memory") + #endif diff --git a/i386/intel/pmap.c b/i386/intel/pmap.c index 129e600b..0387fa8d 100644 --- a/i386/intel/pmap.c +++ b/i386/intel/pmap.c @@ -300,7 +300,7 @@ lock_data_t pmap_system_lock; /* using the pmap */ \ signal_cpus(users, (pmap), (s), (e)); \ while ((pmap)->cpus_using & cpus_active & ~cpu_mask) \ - continue; \ + cpu_pause(); \ } \ \ /* invalidate our own TLB if pmap is in use */ \ -- cgit v1.2.3