@@ -17,10 +17,10 @@
#include <crypto/internal/skcipher.h>
#include <linux/init.h>
#include <linux/module.h>
-#include <linux/mm.h>
+#include <linux/spinlock.h>
#include <linux/string.h>
-static DEFINE_MUTEX(crypto_default_null_skcipher_lock);
+static DEFINE_SPINLOCK(crypto_default_null_skcipher_lock);
static struct crypto_sync_skcipher *crypto_default_null_skcipher;
static int crypto_default_null_skcipher_refcnt;
@@ -152,23 +152,32 @@ MODULE_ALIAS_CRYPTO("cipher_null");
struct crypto_sync_skcipher *crypto_get_default_null_skcipher(void)
{
+ struct crypto_sync_skcipher *ntfm = NULL;
struct crypto_sync_skcipher *tfm;
- mutex_lock(&crypto_default_null_skcipher_lock);
+ spin_lock_bh(&crypto_default_null_skcipher_lock);
tfm = crypto_default_null_skcipher;
if (!tfm) {
- tfm = crypto_alloc_sync_skcipher("ecb(cipher_null)", 0, 0);
- if (IS_ERR(tfm))
- goto unlock;
+ spin_unlock_bh(&crypto_default_null_skcipher_lock);
- crypto_default_null_skcipher = tfm;
+ ntfm = crypto_alloc_sync_skcipher("ecb(cipher_null)", 0, 0);
+ if (IS_ERR(ntfm))
+ return ntfm;
+
+ spin_lock_bh(&crypto_default_null_skcipher_lock);
+ tfm = crypto_default_null_skcipher;
+ if (!tfm) {
+ tfm = ntfm;
+ ntfm = NULL;
+ crypto_default_null_skcipher = tfm;
+ }
}
crypto_default_null_skcipher_refcnt++;
+ spin_unlock_bh(&crypto_default_null_skcipher_lock);
-unlock:
- mutex_unlock(&crypto_default_null_skcipher_lock);
+ crypto_free_sync_skcipher(ntfm);
return tfm;
}
@@ -176,12 +185,16 @@ EXPORT_SYMBOL_GPL(crypto_get_default_null_skcipher);
void crypto_put_default_null_skcipher(void)
{
- mutex_lock(&crypto_default_null_skcipher_lock);
+ struct crypto_sync_skcipher *tfm = NULL;
+
+ spin_lock_bh(&crypto_default_null_skcipher_lock);
if (!--crypto_default_null_skcipher_refcnt) {
- crypto_free_sync_skcipher(crypto_default_null_skcipher);
+ tfm = crypto_default_null_skcipher;
crypto_default_null_skcipher = NULL;
}
- mutex_unlock(&crypto_default_null_skcipher_lock);
+ spin_unlock_bh(&crypto_default_null_skcipher_lock);
+
+ crypto_free_sync_skcipher(tfm);
}
EXPORT_SYMBOL_GPL(crypto_put_default_null_skcipher);