Skip to content

Commit 3b68086

Browse files
committed
Merge tag 'sched_urgent_for_v6.9_rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull scheduler fix from Borislav Petkov: - Add a missing memory barrier in the concurrency ID mm switching * tag 'sched_urgent_for_v6.9_rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: sched: Add missing memory barrier in switch_mm_cid
2 parents d07a0b8 + fe90f39 commit 3b68086

File tree

3 files changed

+25
-6
lines changed

3 files changed

+25
-6
lines changed

arch/x86/include/asm/barrier.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,9 @@ do { \
7979
#define __smp_mb__before_atomic() do { } while (0)
8080
#define __smp_mb__after_atomic() do { } while (0)
8181

82+
/* Writing to CR3 provides a full memory barrier in switch_mm(). */
83+
#define smp_mb__after_switch_mm() do { } while (0)
84+
8285
#include <asm-generic/barrier.h>
8386

8487
#endif /* _ASM_X86_BARRIER_H */

include/asm-generic/barrier.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,5 +294,13 @@ do { \
294294
#define io_stop_wc() do { } while (0)
295295
#endif
296296

297+
/*
298+
* Architectures that guarantee an implicit smp_mb() in switch_mm()
299+
* can override smp_mb__after_switch_mm.
300+
*/
301+
#ifndef smp_mb__after_switch_mm
302+
# define smp_mb__after_switch_mm() smp_mb()
303+
#endif
304+
297305
#endif /* !__ASSEMBLY__ */
298306
#endif /* __ASM_GENERIC_BARRIER_H */

kernel/sched/sched.h

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@
7979
# include <asm/paravirt_api_clock.h>
8080
#endif
8181

82+
#include <asm/barrier.h>
83+
8284
#include "cpupri.h"
8385
#include "cpudeadline.h"
8486

@@ -3445,13 +3447,19 @@ static inline void switch_mm_cid(struct rq *rq,
34453447
* between rq->curr store and load of {prev,next}->mm->pcpu_cid[cpu].
34463448
* Provide it here.
34473449
*/
3448-
if (!prev->mm) // from kernel
3450+
if (!prev->mm) { // from kernel
34493451
smp_mb();
3450-
/*
3451-
* user -> user transition guarantees a memory barrier through
3452-
* switch_mm() when current->mm changes. If current->mm is
3453-
* unchanged, no barrier is needed.
3454-
*/
3452+
} else { // from user
3453+
/*
3454+
* user->user transition relies on an implicit
3455+
* memory barrier in switch_mm() when
3456+
* current->mm changes. If the architecture
3457+
* switch_mm() does not have an implicit memory
3458+
* barrier, it is emitted here. If current->mm
3459+
* is unchanged, no barrier is needed.
3460+
*/
3461+
smp_mb__after_switch_mm();
3462+
}
34553463
}
34563464
if (prev->mm_cid_active) {
34573465
mm_cid_snapshot_time(rq, prev->mm);

0 commit comments

Comments
 (0)