Hi:

Here is the patch that makes the crypto layer use a tfm flag instead of
in_atomic() to determine whether sleeping is allowed.  I'll push this
into mm for testing.

[CRYPTO] Added CRYPTO_TFM_REQ_MAY_SLEEP flag

The crypto layer currently uses in_atomic() to determine whether it is
allowed to sleep.  This is incorrect since spin locks don't always cause
in_atomic() to return true.

Instead of that, this patch returns to an earlier idea of a per-tfm flag
which determines whether sleeping is allowed.  Unlike the earlier version,
the default is to not allow sleeping.  This ensures that no existing code
can break.

As usual, this flag may either be set through crypto_alloc_tfm(), or
just before a specific crypto operation.

Signed-off-by: Herbert Xu <[EMAIL PROTECTED]>

Cheers,
-- 
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <[EMAIL PROTECTED]>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
diff --git a/crypto/api.c b/crypto/api.c
--- a/crypto/api.c
+++ b/crypto/api.c
@@ -66,7 +66,8 @@ static inline struct crypto_alg *crypto_
 
 static int crypto_init_flags(struct crypto_tfm *tfm, u32 flags)
 {
-       tfm->crt_flags = 0;
+       tfm->crt_flags = flags & CRYPTO_TFM_REQ_MASK;
+       flags &= ~CRYPTO_TFM_REQ_MASK;
        
        switch (crypto_tfm_alg_type(tfm)) {
        case CRYPTO_ALG_TYPE_CIPHER:
diff --git a/crypto/cipher.c b/crypto/cipher.c
--- a/crypto/cipher.c
+++ b/crypto/cipher.c
@@ -377,11 +377,7 @@ static int nocrypt_iv(struct crypto_tfm 
 int crypto_init_cipher_flags(struct crypto_tfm *tfm, u32 flags)
 {
        u32 mode = flags & CRYPTO_TFM_MODE_MASK;
-       
        tfm->crt_cipher.cit_mode = mode ? mode : CRYPTO_TFM_MODE_ECB;
-       if (flags & CRYPTO_TFM_REQ_WEAK_KEY)
-               tfm->crt_flags = CRYPTO_TFM_REQ_WEAK_KEY;
-       
        return 0;
 }
 
diff --git a/crypto/internal.h b/crypto/internal.h
--- a/crypto/internal.h
+++ b/crypto/internal.h
@@ -17,6 +17,7 @@
 #include <linux/interrupt.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <asm/kmap_types.h>
 
 extern enum km_type crypto_km_types[];
@@ -38,7 +39,7 @@ static inline void crypto_kunmap(void *v
 
 static inline void crypto_yield(struct crypto_tfm *tfm)
 {
-       if (!in_atomic())
+       if (tfm->crt_flags & CRYPTO_TFM_REQ_MAY_SLEEP)
                cond_resched();
 }
 
diff --git a/include/linux/crypto.h b/include/linux/crypto.h
--- a/include/linux/crypto.h
+++ b/include/linux/crypto.h
@@ -45,6 +45,7 @@
 #define CRYPTO_TFM_MODE_CTR            0x00000008
 
 #define CRYPTO_TFM_REQ_WEAK_KEY                0x00000100
+#define CRYPTO_TFM_REQ_MAY_SLEEP       0x00000200
 #define CRYPTO_TFM_RES_WEAK_KEY                0x00100000
 #define CRYPTO_TFM_RES_BAD_KEY_LEN     0x00200000
 #define CRYPTO_TFM_RES_BAD_KEY_SCHED   0x00400000

Reply via email to