diff options
author | Gilad Ben-Yossef <gilad@benyossef.com> | 2017-10-18 03:00:38 -0400 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2017-11-03 10:11:18 -0400 |
commit | ada69a1639eca54ff74d839a6513c43db8d57d70 (patch) | |
tree | f22353657a65c0b90d9412224ee508898d9c874a | |
parent | 3d549e325e3c7dd294b96720f22cbc39ec2e02e9 (diff) |
crypto: introduce crypto wait for async op
Invoking a possibly async. crypto op and waiting for completion
while correctly handling backlog processing is a common task
in the crypto API implementation and outside users of it.
This patch adds a generic implementation for doing so in
preparation for using it across the board instead of hand
rolled versions.
Signed-off-by: Gilad Ben-Yossef <gilad@benyossef.com>
CC: Eric Biggers <ebiggers3@gmail.com>
CC: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
-rw-r--r-- | crypto/api.c | 13 | ||||
-rw-r--r-- | include/linux/crypto.h | 40 |
2 files changed, 53 insertions, 0 deletions
diff --git a/crypto/api.c b/crypto/api.c index 941cd4c6c7ec..2a2479d168aa 100644 --- a/crypto/api.c +++ b/crypto/api.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/sched/signal.h> | 24 | #include <linux/sched/signal.h> |
25 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
26 | #include <linux/string.h> | 26 | #include <linux/string.h> |
27 | #include <linux/completion.h> | ||
27 | #include "internal.h" | 28 | #include "internal.h" |
28 | 29 | ||
29 | LIST_HEAD(crypto_alg_list); | 30 | LIST_HEAD(crypto_alg_list); |
@@ -595,5 +596,17 @@ int crypto_has_alg(const char *name, u32 type, u32 mask) | |||
595 | } | 596 | } |
596 | EXPORT_SYMBOL_GPL(crypto_has_alg); | 597 | EXPORT_SYMBOL_GPL(crypto_has_alg); |
597 | 598 | ||
599 | void crypto_req_done(struct crypto_async_request *req, int err) | ||
600 | { | ||
601 | struct crypto_wait *wait = req->data; | ||
602 | |||
603 | if (err == -EINPROGRESS) | ||
604 | return; | ||
605 | |||
606 | wait->err = err; | ||
607 | complete(&wait->completion); | ||
608 | } | ||
609 | EXPORT_SYMBOL_GPL(crypto_req_done); | ||
610 | |||
598 | MODULE_DESCRIPTION("Cryptographic core API"); | 611 | MODULE_DESCRIPTION("Cryptographic core API"); |
599 | MODULE_LICENSE("GPL"); | 612 | MODULE_LICENSE("GPL"); |
diff --git a/include/linux/crypto.h b/include/linux/crypto.h index 84da9978e951..78508ca4b108 100644 --- a/include/linux/crypto.h +++ b/include/linux/crypto.h | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
25 | #include <linux/string.h> | 25 | #include <linux/string.h> |
26 | #include <linux/uaccess.h> | 26 | #include <linux/uaccess.h> |
27 | #include <linux/completion.h> | ||
27 | 28 | ||
28 | /* | 29 | /* |
29 | * Autoloaded crypto modules should only use a prefixed name to avoid allowing | 30 | * Autoloaded crypto modules should only use a prefixed name to avoid allowing |
@@ -468,6 +469,45 @@ struct crypto_alg { | |||
468 | } CRYPTO_MINALIGN_ATTR; | 469 | } CRYPTO_MINALIGN_ATTR; |
469 | 470 | ||
470 | /* | 471 | /* |
472 | * A helper struct for waiting for completion of async crypto ops | ||
473 | */ | ||
474 | struct crypto_wait { | ||
475 | struct completion completion; | ||
476 | int err; | ||
477 | }; | ||
478 | |||
479 | /* | ||
480 | * Macro for declaring a crypto op async wait object on stack | ||
481 | */ | ||
482 | #define DECLARE_CRYPTO_WAIT(_wait) \ | ||
483 | struct crypto_wait _wait = { \ | ||
484 | COMPLETION_INITIALIZER_ONSTACK((_wait).completion), 0 } | ||
485 | |||
486 | /* | ||
487 | * Async ops completion helper functioons | ||
488 | */ | ||
489 | void crypto_req_done(struct crypto_async_request *req, int err); | ||
490 | |||
491 | static inline int crypto_wait_req(int err, struct crypto_wait *wait) | ||
492 | { | ||
493 | switch (err) { | ||
494 | case -EINPROGRESS: | ||
495 | case -EBUSY: | ||
496 | wait_for_completion(&wait->completion); | ||
497 | reinit_completion(&wait->completion); | ||
498 | err = wait->err; | ||
499 | break; | ||
500 | }; | ||
501 | |||
502 | return err; | ||
503 | } | ||
504 | |||
505 | static inline void crypto_init_wait(struct crypto_wait *wait) | ||
506 | { | ||
507 | init_completion(&wait->completion); | ||
508 | } | ||
509 | |||
510 | /* | ||
471 | * Algorithm registration interface. | 511 | * Algorithm registration interface. |
472 | */ | 512 | */ |
473 | int crypto_register_alg(struct crypto_alg *alg); | 513 | int crypto_register_alg(struct crypto_alg *alg); |