From: NeilBrown <neilb@suse.de>
To: Ingo Molnar <mingo@redhat.com>,
Peter Zijlstra <peterz@infradead.org>,
Linus Torvalds <torvalds@linux-foundation.org>,
Jens Axboe <axboe@kernel.dk>
Cc: linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org,
linux-block@vger.kernel.org
Subject: [PATCH 5/7] sched: Add test_and_clear_wake_up_bit() and atomic_dec_and_wake_up()
Date: Mon, 26 Aug 2024 16:31:02 +1000 [thread overview]
Message-ID: <20240826063659.15327-6-neilb@suse.de> (raw)
In-Reply-To: <20240826063659.15327-1-neilb@suse.de>
There are common patterns in the kernel of using test_and_clear_bit()
before wake_up_bit(), and atomic_dec_and_test() before wake_up_var().
These combinations don't need extra barriers but sometimes include them
unnecessarily.
To help avoid the unnecessary barriers and to help discourage the
general use of wake_up_bit/var (which is a fragile interface) introduce
two combined functions which implement these patterns.
Also add store_release_wake_up() which support the parts of simply
setting a non-atomic variable as sending a wakeup. This pattern
requires barriers which are often omitted.
Signed-off-by: NeilBrown <neilb@suse.de>
---
include/linux/wait_bit.h | 61 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 61 insertions(+)
diff --git a/include/linux/wait_bit.h b/include/linux/wait_bit.h
index ca5c6e70f908..c1675457c077 100644
--- a/include/linux/wait_bit.h
+++ b/include/linux/wait_bit.h
@@ -419,4 +419,65 @@ static inline void clear_and_wake_up_bit(int bit, unsigned long *word)
wake_up_bit(word, bit);
}
+/**
+ * test_and_clear_wake_up_bit - clear a bit if it was set: wake up anyone waiting on that bit
+ *
+ * @bit: the bit of the word being waited on
+ * @word: the address of memory containing that bit
+ *
+ * If the bit is set and can be atomically cleared, any tasks waiting in
+ * wait_on_bit() or similar will be woken. This call has the same
+ * complete ordering semantics as test_and_clear_bit(). Any changes to
+ * memory made before this call are guaranteed to be visible after the
+ * corresponding wait_on_bit() completes.
+ *
+ * Returns %true if the bit was successfully set and the wake up was sent.
+ */
+static inline bool test_and_clear_wake_up_bit(int bit, unsigned long *word)
+{
+ if (!test_and_clear_bit(bit, word))
+ return false;
+ /* no extra barrier required */
+ wake_up_bit(word, bit);
+ return true;
+}
+
+/**
+ * atomic_dec_and_wake_up - decrement an atomic_t and if zero, wake up waiters
+ *
+ * @var: the variable to dec and test
+ *
+ * Decrements the atomic variable and if it reaches zero, send a wake_up to any
+ * processes waiting on the variable.
+ *
+ * This function has the same complete ordering semantics as atomic_dec_and_test.
+ *
+ * Returns %true is the variable reaches zero and the wake up was sent.
+ */
+
+static inline bool atomic_dec_and_wake_up(atomic_t *var)
+{
+ if (!atomic_dec_and_test(var))
+ return false;
+ wake_up_var(var);
+ return true;
+}
+
+/**
+ * store_release_wake_up - update a variable and send a wake_up
+ * @var: the address of the variable to be updated and woken
+ * @val: the value to store in the variable.
+ *
+ * Store the given value in the variable send a wake up to any tasks
+ * waiting on the variable. All necessary barriers are included to ensure
+ * the task calling wait_var_event() sees the new value and all values
+ * written to memory before this call.
+ */
+#define store_release_wake_up(var, val) \
+do { \
+ smp_store_release(var, val); \
+ smp_mb(); \
+ wake_up_var(var); \
+} while (0)
+
#endif /* _LINUX_WAIT_BIT_H */
--
2.44.0
next prev parent reply other threads:[~2024-08-26 6:37 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-08-26 6:30 [PATCH 0/7 v2 RFC] Make wake_up_{bit,var} less fragile NeilBrown
2024-08-26 6:30 ` [PATCH 1/7] block: change wait on bd_claiming to use a var_waitqueue, not a bit_waitqueue NeilBrown
2024-09-17 3:12 ` Jens Axboe
2024-09-17 21:54 ` NeilBrown
2024-09-17 3:13 ` (subset) " Jens Axboe
2024-08-26 6:30 ` [PATCH 2/7] sched: change wake_up_bit() and related function to expect unsigned long * NeilBrown
2024-09-16 11:28 ` Peter Zijlstra
2024-09-16 11:48 ` NeilBrown
2024-09-16 18:18 ` Peter Zijlstra
2024-09-16 20:37 ` NeilBrown
2024-08-26 6:31 ` [PATCH 3/7] sched: Improve documentation for wake_up_bit/wait_on_bit family of functions NeilBrown
2024-08-26 6:31 ` [PATCH 4/7] sched: Document wait_var_event() family of functions and wake_up_var() NeilBrown
2024-08-26 6:31 ` NeilBrown [this message]
2024-08-26 6:31 ` [PATCH 6/7] sched: Add wait/wake interface for variable updated under a lock NeilBrown
2024-08-26 6:31 ` [PATCH 7/7] Block: switch bd_prepare_to_claim to use wait_var_event_mutex() NeilBrown
2024-09-15 23:52 ` [PATCH 0/7 v2 RFC] Make wake_up_{bit,var} less fragile NeilBrown
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240826063659.15327-6-neilb@suse.de \
--to=neilb@suse.de \
--cc=axboe@kernel.dk \
--cc=linux-block@vger.kernel.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@redhat.com \
--cc=peterz@infradead.org \
--cc=torvalds@linux-foundation.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox