| From b6416e61012429e0277bd15a229222fd17afc1c1 Mon Sep 17 00:00:00 2001 |
| From: David Matlack <dmatlack@google.com> |
| Date: Fri, 16 Dec 2016 14:30:35 -0800 |
| Subject: jump_labels: API for flushing deferred jump label updates |
| |
| From: David Matlack <dmatlack@google.com> |
| |
| commit b6416e61012429e0277bd15a229222fd17afc1c1 upstream. |
| |
| Modules that use static_key_deferred need a way to synchronize with |
| any delayed work that is still pending when the module is unloaded. |
| Introduce static_key_deferred_flush() which flushes any pending |
| jump label updates. |
| |
| Signed-off-by: David Matlack <dmatlack@google.com> |
| Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org> |
| Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| include/linux/jump_label_ratelimit.h | 5 +++++ |
| kernel/jump_label.c | 7 +++++++ |
| 2 files changed, 12 insertions(+) |
| |
| --- a/include/linux/jump_label_ratelimit.h |
| +++ b/include/linux/jump_label_ratelimit.h |
| @@ -14,6 +14,7 @@ struct static_key_deferred { |
| |
| #ifdef HAVE_JUMP_LABEL |
| extern void static_key_slow_dec_deferred(struct static_key_deferred *key); |
| +extern void static_key_deferred_flush(struct static_key_deferred *key); |
| extern void |
| jump_label_rate_limit(struct static_key_deferred *key, unsigned long rl); |
| |
| @@ -26,6 +27,10 @@ static inline void static_key_slow_dec_d |
| STATIC_KEY_CHECK_USE(); |
| static_key_slow_dec(&key->key); |
| } |
| +static inline void static_key_deferred_flush(struct static_key_deferred *key) |
| +{ |
| + STATIC_KEY_CHECK_USE(); |
| +} |
| static inline void |
| jump_label_rate_limit(struct static_key_deferred *key, |
| unsigned long rl) |
| --- a/kernel/jump_label.c |
| +++ b/kernel/jump_label.c |
| @@ -138,6 +138,13 @@ void static_key_slow_dec_deferred(struct |
| } |
| EXPORT_SYMBOL_GPL(static_key_slow_dec_deferred); |
| |
| +void static_key_deferred_flush(struct static_key_deferred *key) |
| +{ |
| + STATIC_KEY_CHECK_USE(); |
| + flush_delayed_work(&key->work); |
| +} |
| +EXPORT_SYMBOL_GPL(static_key_deferred_flush); |
| + |
| void jump_label_rate_limit(struct static_key_deferred *key, |
| unsigned long rl) |
| { |