diff options
author | Jason A. Donenfeld <Jason@zx2c4.com> | 2018-06-19 15:41:40 +0200 |
---|---|---|
committer | Jason A. Donenfeld <Jason@zx2c4.com> | 2018-06-19 15:41:40 +0200 |
commit | cbd64bac2d156846c7f97ec6d9d047b48c4b6791 (patch) | |
tree | e911f67c181f4bd87eb943bdad3ae098d4fa88ee /src/ratelimiter.c | |
parent | 5d324c239c4f955261d4669afc85c46a94e8a58b (diff) |
ratelimiter: do not allow concurrent init and uninit
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Diffstat (limited to 'src/ratelimiter.c')
-rw-r--r-- | src/ratelimiter.c | 6 |
1 files changed, 6 insertions, 0 deletions
diff --git a/src/ratelimiter.c b/src/ratelimiter.c index 2107c8e..e1afcd6 100644 --- a/src/ratelimiter.c +++ b/src/ratelimiter.c @@ -12,6 +12,7 @@ static struct kmem_cache *entry_cache; static hsiphash_key_t key; static spinlock_t table_lock = __SPIN_LOCK_UNLOCKED("ratelimiter_table_lock"); +static DEFINE_MUTEX(init_lock); static atomic64_t refcnt = ATOMIC64_INIT(0); static atomic_t total_entries = ATOMIC_INIT(0); static unsigned int max_entries, table_size; @@ -146,6 +147,7 @@ int ratelimiter_init(void) if (atomic64_inc_return(&refcnt) != 1) return 0; + mutex_lock(&init_lock); entry_cache = KMEM_CACHE(ratelimiter_entry, 0); if (!entry_cache) goto err; @@ -172,12 +174,14 @@ int ratelimiter_init(void) queue_delayed_work(system_power_efficient_wq, &gc_work, HZ); get_random_bytes(&key, sizeof(key)); + mutex_unlock(&init_lock); return 0; err_kmemcache: kmem_cache_destroy(entry_cache); err: atomic64_dec(&refcnt); + mutex_unlock(&init_lock); return -ENOMEM; } @@ -186,6 +190,7 @@ void ratelimiter_uninit(void) if (atomic64_dec_if_positive(&refcnt)) return; + mutex_lock(&init_lock); cancel_delayed_work_sync(&gc_work); gc_entries(NULL); rcu_barrier(); @@ -194,6 +199,7 @@ void ratelimiter_uninit(void) kvfree(table_v6); #endif kmem_cache_destroy(entry_cache); + mutex_unlock(&init_lock); } #include "selftest/ratelimiter.h" |