diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/crc-t10dif.c | 11 |
1 files changed, 10 insertions, 1 deletions
diff --git a/lib/crc-t10dif.c b/lib/crc-t10dif.c index 43bc5b071f96..dfe6ec17c0a5 100644 --- a/lib/crc-t10dif.c +++ b/lib/crc-t10dif.c | |||
@@ -14,8 +14,10 @@ | |||
14 | #include <linux/err.h> | 14 | #include <linux/err.h> |
15 | #include <linux/init.h> | 15 | #include <linux/init.h> |
16 | #include <crypto/hash.h> | 16 | #include <crypto/hash.h> |
17 | #include <linux/static_key.h> | ||
17 | 18 | ||
18 | static struct crypto_shash *crct10dif_tfm; | 19 | static struct crypto_shash *crct10dif_tfm; |
20 | static struct static_key crct10dif_fallback __read_mostly; | ||
19 | 21 | ||
20 | __u16 crc_t10dif(const unsigned char *buffer, size_t len) | 22 | __u16 crc_t10dif(const unsigned char *buffer, size_t len) |
21 | { | 23 | { |
@@ -25,6 +27,9 @@ __u16 crc_t10dif(const unsigned char *buffer, size_t len) | |||
25 | } desc; | 27 | } desc; |
26 | int err; | 28 | int err; |
27 | 29 | ||
30 | if (static_key_false(&crct10dif_fallback)) | ||
31 | return crc_t10dif_generic(0, buffer, len); | ||
32 | |||
28 | desc.shash.tfm = crct10dif_tfm; | 33 | desc.shash.tfm = crct10dif_tfm; |
29 | desc.shash.flags = 0; | 34 | desc.shash.flags = 0; |
30 | *(__u16 *)desc.ctx = 0; | 35 | *(__u16 *)desc.ctx = 0; |
@@ -39,7 +44,11 @@ EXPORT_SYMBOL(crc_t10dif); | |||
39 | static int __init crc_t10dif_mod_init(void) | 44 | static int __init crc_t10dif_mod_init(void) |
40 | { | 45 | { |
41 | crct10dif_tfm = crypto_alloc_shash("crct10dif", 0, 0); | 46 | crct10dif_tfm = crypto_alloc_shash("crct10dif", 0, 0); |
42 | return PTR_RET(crct10dif_tfm); | 47 | if (IS_ERR(crct10dif_tfm)) { |
48 | static_key_slow_inc(&crct10dif_fallback); | ||
49 | crct10dif_tfm = NULL; | ||
50 | } | ||
51 | return 0; | ||
43 | } | 52 | } |
44 | 53 | ||
45 | static void __exit crc_t10dif_mod_fini(void) | 54 | static void __exit crc_t10dif_mod_fini(void) |