summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSamuel Thibault <samuel.thibault@ens-lyon.org>2023-02-15 10:59:42 +0100
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2023-02-15 10:59:42 +0100
commitca7b8ae031d9ce12139d96caedc5d1bd369feeca (patch)
tree5506dc516c95c7f6c065dd0d4e00ee69cd53eb3b
parentd3ef1ba20f7b6e1af5387c48d58da38cc55d3b79 (diff)
smp: Fix more busy loops
We need to avoid the kernel optimizing away the reads from memory. Use a standard relaxing instruction for that.
-rw-r--r--i386/i386/lock.h1
-rw-r--r--i386/intel/pmap.c6
-rw-r--r--kern/eventcount.c2
-rw-r--r--kern/lock.c12
-rw-r--r--kern/machine.c2
5 files changed, 13 insertions, 10 deletions
diff --git a/i386/i386/lock.h b/i386/i386/lock.h
index 4b445ae4..b189a559 100644
--- a/i386/i386/lock.h
+++ b/i386/i386/lock.h
@@ -30,6 +30,7 @@
#define _I386_LOCK_H_
#if NCPUS > 1
+#include <i386/smp.h>
/*
* All of the locking routines are built from calls on
diff --git a/i386/intel/pmap.c b/i386/intel/pmap.c
index 3b52deb3..3605d120 100644
--- a/i386/intel/pmap.c
+++ b/i386/intel/pmap.c
@@ -3093,9 +3093,9 @@ void pmap_update_interrupt(void)
* Wait for any pmap updates in progress, on either user
* or kernel pmap.
*/
- while (*(volatile int *)&my_pmap->lock.lock_data ||
- *(volatile int *)&kernel_pmap->lock.lock_data)
- continue;
+ while (my_pmap->lock.lock_data ||
+ kernel_pmap->lock.lock_data)
+ cpu_pause();
process_pmap_updates(my_pmap);
diff --git a/kern/eventcount.c b/kern/eventcount.c
index a9d7bd41..3a96b4fb 100644
--- a/kern/eventcount.c
+++ b/kern/eventcount.c
@@ -244,7 +244,7 @@ evc_signal(evc_t ev)
#if (NCPUS > 1)
retry:
while((thread->state & TH_RUN) || thread->lock.lock_data)
- ;
+ cpu_pause();
#endif
thread_lock(thread);
diff --git a/kern/lock.c b/kern/lock.c
index a4b82522..81c6a129 100644
--- a/kern/lock.c
+++ b/kern/lock.c
@@ -36,6 +36,8 @@
#include <string.h>
+#include <machine/smp.h>
+
#include <kern/debug.h>
#include <kern/lock.h>
#include <kern/thread.h>
@@ -88,7 +90,7 @@ void simple_lock_init(simple_lock_t l)
void simple_lock(simple_lock_t l)
{
while (test_and_set((boolean_t *)l))
- continue;
+ cpu_pause();
}
void simple_unlock(simple_lock_t l)
@@ -290,7 +292,7 @@ void lock_write(
if ((i = lock_wait_time) > 0) {
simple_unlock(&l->interlock);
while (--i > 0 && l->want_write)
- continue;
+ cpu_pause();
simple_lock(&l->interlock);
}
@@ -310,7 +312,7 @@ void lock_write(
simple_unlock(&l->interlock);
while (--i > 0 && (l->read_count != 0 ||
l->want_upgrade))
- continue;
+ cpu_pause();
simple_lock(&l->interlock);
}
@@ -384,7 +386,7 @@ void lock_read(
if ((i = lock_wait_time) > 0) {
simple_unlock(&l->interlock);
while (--i > 0 && (l->want_write || l->want_upgrade))
- continue;
+ cpu_pause();
simple_lock(&l->interlock);
}
@@ -450,7 +452,7 @@ boolean_t lock_read_to_write(
if ((i = lock_wait_time) > 0) {
simple_unlock(&l->interlock);
while (--i > 0 && l->read_count != 0)
- continue;
+ cpu_pause();
simple_lock(&l->interlock);
}
diff --git a/kern/machine.c b/kern/machine.c
index e8c9912e..bf9677c9 100644
--- a/kern/machine.c
+++ b/kern/machine.c
@@ -172,7 +172,7 @@ processor_request_action(
* state to running very soon.
*/
while (*(volatile int *)&processor->state == PROCESSOR_DISPATCHING)
- continue;
+ cpu_pause();
/*
* Now lock the action queue and do the dirty work.