s390/preempt: Add comments
authorHeiko Carstens <hca@linux.ibm.com>
Wed, 4 Dec 2024 11:31:00 +0000 (12:31 +0100)
committerAlexander Gordeev <agordeev@linux.ibm.com>
Sun, 15 Dec 2024 14:13:43 +0000 (15:13 +0100)
The s390 preempt_count implementation is more or less a copy of the x86
implementation using different instructions. For clarification how this
works also add all comments from x86 with some minor modifications.

Acked-by: Alexander Gordeev <agordeev@linux.ibm.com>
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>
arch/s390/include/asm/preempt.h

index 2c29bdf1212722e4996e7d56a16386aafb06c307..3e3f21385db9612f6aa8cee51f2514ee33c73703 100644 (file)
 
 /* We use the MSB mostly because its available */
 #define PREEMPT_NEED_RESCHED   0x80000000
+
+/*
+ * We use the PREEMPT_NEED_RESCHED bit as an inverted NEED_RESCHED such
+ * that a decrement hitting 0 means we can and should reschedule.
+ */
 #define PREEMPT_ENABLED        (0 + PREEMPT_NEED_RESCHED)
 
+/*
+ * We mask the PREEMPT_NEED_RESCHED bit so as not to confuse all current users
+ * that think a non-zero value indicates we cannot preempt.
+ */
 static __always_inline int preempt_count(void)
 {
        return READ_ONCE(get_lowcore()->preempt_count) & ~PREEMPT_NEED_RESCHED;
@@ -29,6 +38,15 @@ static __always_inline void preempt_count_set(int pc)
        } while (!arch_try_cmpxchg(&get_lowcore()->preempt_count, &old, new));
 }
 
+/*
+ * We fold the NEED_RESCHED bit into the preempt count such that
+ * preempt_enable() can decrement and test for needing to reschedule with a
+ * short instruction sequence.
+ *
+ * We invert the actual bit, so that when the decrement hits 0 we know we both
+ * need to resched (the bit is cleared) and can resched (no preempt count).
+ */
+
 static __always_inline void set_preempt_need_resched(void)
 {
        __atomic_and(~PREEMPT_NEED_RESCHED, &get_lowcore()->preempt_count);
@@ -64,11 +82,19 @@ static __always_inline void __preempt_count_sub(int val)
        __preempt_count_add(-val);
 }
 
+/*
+ * Because we keep PREEMPT_NEED_RESCHED set when we do _not_ need to reschedule
+ * a decrement which hits zero means we have no preempt_count and should
+ * reschedule.
+ */
 static __always_inline bool __preempt_count_dec_and_test(void)
 {
        return __atomic_add(-1, &get_lowcore()->preempt_count) == 1;
 }
 
+/*
+ * Returns true when we need to resched and can (barring IRQ state).
+ */
 static __always_inline bool should_resched(int preempt_offset)
 {
        return unlikely(READ_ONCE(get_lowcore()->preempt_count) ==