OSDN Git Service

crypto: introduce crypto wait for async op
authorGilad Ben-Yossef <gilad@benyossef.com>
Wed, 18 Oct 2017 07:00:38 +0000 (08:00 +0100)
committerHerbert Xu <herbert@gondor.apana.org.au>
Fri, 3 Nov 2017 14:11:18 +0000 (22:11 +0800)
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>
crypto/api.c
include/linux/crypto.h

index 941cd4c..2a2479d 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/sched/signal.h>
 #include <linux/slab.h>
 #include <linux/string.h>
+#include <linux/completion.h>
 #include "internal.h"
 
 LIST_HEAD(crypto_alg_list);
@@ -595,5 +596,17 @@ int crypto_has_alg(const char *name, u32 type, u32 mask)
 }
 EXPORT_SYMBOL_GPL(crypto_has_alg);
 
+void crypto_req_done(struct crypto_async_request *req, int err)
+{
+       struct crypto_wait *wait = req->data;
+
+       if (err == -EINPROGRESS)
+               return;
+
+       wait->err = err;
+       complete(&wait->completion);
+}
+EXPORT_SYMBOL_GPL(crypto_req_done);
+
 MODULE_DESCRIPTION("Cryptographic core API");
 MODULE_LICENSE("GPL");
index 84da997..78508ca 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/uaccess.h>
+#include <linux/completion.h>
 
 /*
  * Autoloaded crypto modules should only use a prefixed name to avoid allowing
@@ -468,6 +469,45 @@ struct crypto_alg {
 } CRYPTO_MINALIGN_ATTR;
 
 /*
+ * A helper struct for waiting for completion of async crypto ops
+ */
+struct crypto_wait {
+       struct completion completion;
+       int err;
+};
+
+/*
+ * Macro for declaring a crypto op async wait object on stack
+ */
+#define DECLARE_CRYPTO_WAIT(_wait) \
+       struct crypto_wait _wait = { \
+               COMPLETION_INITIALIZER_ONSTACK((_wait).completion), 0 }
+
+/*
+ * Async ops completion helper functioons
+ */
+void crypto_req_done(struct crypto_async_request *req, int err);
+
+static inline int crypto_wait_req(int err, struct crypto_wait *wait)
+{
+       switch (err) {
+       case -EINPROGRESS:
+       case -EBUSY:
+               wait_for_completion(&wait->completion);
+               reinit_completion(&wait->completion);
+               err = wait->err;
+               break;
+       };
+
+       return err;
+}
+
+static inline void crypto_init_wait(struct crypto_wait *wait)
+{
+       init_completion(&wait->completion);
+}
+
+/*
  * Algorithm registration interface.
  */
 int crypto_register_alg(struct crypto_alg *alg);