Skip to content

Commit

Permalink
crypto: introduce crypto wait for async op
Browse files Browse the repository at this point in the history
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 <[email protected]>
CC: Eric Biggers <[email protected]>
CC: Jonathan Cameron <[email protected]>
Signed-off-by: Herbert Xu <[email protected]>
  • Loading branch information
gby authored and herbertx committed Nov 3, 2017
1 parent 3d549e3 commit ada69a1
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 0 deletions.
13 changes: 13 additions & 0 deletions crypto/api.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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");
40 changes: 40 additions & 0 deletions include/linux/crypto.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -467,6 +468,45 @@ struct crypto_alg {
struct module *cra_module;
} 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.
*/
Expand Down

0 comments on commit ada69a1

Please sign in to comment.