Linux RAID subsystem development
 help / color / mirror / Atom feed
  • * [PATCH v5 01/19] crypto: change transient busy return code to -EAGAIN
           [not found] <1502724094-23305-1-git-send-email-gilad@benyossef.com>
           [not found] ` <1502724094-23305-1-git-send-email-gilad-6S/DczAoZh3WXxRugSxzZg@public.gmane.org>
    @ 2017-08-14 15:21 ` Gilad Ben-Yossef
      2017-08-14 15:21 ` Gilad Ben-Yossef
                       ` (38 subsequent siblings)
      40 siblings, 0 replies; 58+ messages in thread
    From: Gilad Ben-Yossef @ 2017-08-14 15:21 UTC (permalink / raw)
      To: Herbert Xu, David S. Miller, Jonathan Corbet, David Howells,
    	Tom Lendacky, Gary Hook, Boris Brezillon, Arnaud Ebalard,
    	Matthias Brugger, Alasdair Kergon, Mike Snitzer, dm-devel,
    	Shaohua Li, Steve French, Theodore Y. Ts'o, Jaegeuk Kim,
    	Mimi Zohar, Dmitry Kasatkin, James Morris, Serge E. Hallyn,
    	linux-crypto
      Cc: Ofir Drang
    
    The crypto API was using the -EBUSY return value to indicate
    both a hard failure to submit a crypto operation into a
    transformation provider when the latter was busy and the backlog
    mechanism was not enabled as well as a notification that the
    operation was queued into the backlog when the backlog mechanism
    was enabled.
    
    Having the same return code indicate two very different conditions
    depending on a flag is both error prone and requires extra runtime
    check like the following to discern between the cases:
    
    	if (err == -EINPROGRESS ||
    	    (err == -EBUSY && (ahash_request_flags(req) &
    			       CRYPTO_TFM_REQ_MAY_BACKLOG)))
    
    This patch changes the return code used to indicate a crypto op
    failed due to the transformation provider being transiently busy
    to -EAGAIN.
    
    Signed-off-by: Gilad Ben-Yossef <gilad@benyossef.com>
    ---
     crypto/algapi.c     |  6 ++++--
     crypto/algif_hash.c | 20 +++++++++++++++++---
     crypto/cryptd.c     |  4 +---
     3 files changed, 22 insertions(+), 8 deletions(-)
    
    diff --git a/crypto/algapi.c b/crypto/algapi.c
    index aa699ff..916bee3 100644
    --- a/crypto/algapi.c
    +++ b/crypto/algapi.c
    @@ -897,9 +897,11 @@ int crypto_enqueue_request(struct crypto_queue *queue,
     	int err = -EINPROGRESS;
     
     	if (unlikely(queue->qlen >= queue->max_qlen)) {
    -		err = -EBUSY;
    -		if (!(request->flags & CRYPTO_TFM_REQ_MAY_BACKLOG))
    +		if (!(request->flags & CRYPTO_TFM_REQ_MAY_BACKLOG)) {
    +			err = -EAGAIN;
     			goto out;
    +		}
    +		err = -EBUSY;
     		if (queue->backlog == &queue->list)
     			queue->backlog = &request->list;
     	}
    diff --git a/crypto/algif_hash.c b/crypto/algif_hash.c
    index 5e92bd2..3b3c154 100644
    --- a/crypto/algif_hash.c
    +++ b/crypto/algif_hash.c
    @@ -39,6 +39,20 @@ struct algif_hash_tfm {
     	bool has_key;
     };
     
    +/* Previous versions of crypto_* ops used to return -EBUSY
    + * rather than -EAGAIN to indicate being tied up. The in
    + * kernel API changed but we don't want to break the user
    + * space API. As only the hash user interface exposed this
    + * error ever to the user, do the translation here.
    + */
    +static inline int crypto_user_err(int err)
    +{
    +	if (err == -EAGAIN)
    +		return -EBUSY;
    +
    +	return err;
    +}
    +
     static int hash_alloc_result(struct sock *sk, struct hash_ctx *ctx)
     {
     	unsigned ds;
    @@ -136,7 +150,7 @@ static int hash_sendmsg(struct socket *sock, struct msghdr *msg,
     unlock:
     	release_sock(sk);
     
    -	return err ?: copied;
    +	return err ? crypto_user_err(err) : copied;
     }
     
     static ssize_t hash_sendpage(struct socket *sock, struct page *page,
    @@ -188,7 +202,7 @@ static ssize_t hash_sendpage(struct socket *sock, struct page *page,
     unlock:
     	release_sock(sk);
     
    -	return err ?: size;
    +	return err ? crypto_user_err(err) : size;
     }
     
     static int hash_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
    @@ -236,7 +250,7 @@ static int hash_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
     	hash_free_result(sk, ctx);
     	release_sock(sk);
     
    -	return err ?: len;
    +	return err ? crypto_user_err(err) : len;
     }
     
     static int hash_accept(struct socket *sock, struct socket *newsock, int flags,
    diff --git a/crypto/cryptd.c b/crypto/cryptd.c
    index 0508c48..d1dbdce 100644
    --- a/crypto/cryptd.c
    +++ b/crypto/cryptd.c
    @@ -137,16 +137,14 @@ static int cryptd_enqueue_request(struct cryptd_queue *queue,
     	int cpu, err;
     	struct cryptd_cpu_queue *cpu_queue;
     	atomic_t *refcnt;
    -	bool may_backlog;
     
     	cpu = get_cpu();
     	cpu_queue = this_cpu_ptr(queue->cpu_queue);
     	err = crypto_enqueue_request(&cpu_queue->queue, request);
     
     	refcnt = crypto_tfm_ctx(request->tfm);
    -	may_backlog = request->flags & CRYPTO_TFM_REQ_MAY_BACKLOG;
     
    -	if (err == -EBUSY && !may_backlog)
    +	if (err == -EAGAIN)
     		goto out_put_cpu;
     
     	queue_work_on(cpu, kcrypto_wq, &cpu_queue->work);
    -- 
    2.1.4
    
    
    ^ permalink raw reply related	[flat|nested] 58+ messages in thread
  • * [PATCH v5 01/19] crypto: change transient busy return code to -EAGAIN
           [not found] <1502724094-23305-1-git-send-email-gilad@benyossef.com>
           [not found] ` <1502724094-23305-1-git-send-email-gilad-6S/DczAoZh3WXxRugSxzZg@public.gmane.org>
      2017-08-14 15:21 ` [PATCH v5 01/19] crypto: change transient busy return code to -EAGAIN Gilad Ben-Yossef
    @ 2017-08-14 15:21 ` Gilad Ben-Yossef
      2017-08-14 15:21 ` [PATCH v5 02/19] crypto: ccp: use -EAGAIN for transient busy indication Gilad Ben-Yossef
                       ` (37 subsequent siblings)
      40 siblings, 0 replies; 58+ messages in thread
    From: Gilad Ben-Yossef @ 2017-08-14 15:21 UTC (permalink / raw)
      To: Herbert Xu, David S. Miller, Jonathan Corbet, David Howells,
    	Tom Lendacky, Gary Hook, Boris Brezillon, Arnaud Ebalard,
    	Matthias Brugger, Alasdair Kergon, Mike Snitzer, dm-devel,
    	Shaohua Li, Steve French, Theodore Y. Ts'o, Jaegeuk Kim,
    	Mimi Zohar, Dmitry Kasatkin, James Morris, Serge E. Hallyn,
    	linux-crypto, linux-doc, linux-kernel, keyrings, linux-arm-kernel
      Cc: Ofir Drang
    
    The crypto API was using the -EBUSY return value to indicate
    both a hard failure to submit a crypto operation into a
    transformation provider when the latter was busy and the backlog
    mechanism was not enabled as well as a notification that the
    operation was queued into the backlog when the backlog mechanism
    was enabled.
    
    Having the same return code indicate two very different conditions
    depending on a flag is both error prone and requires extra runtime
    check like the following to discern between the cases:
    
    	if (err == -EINPROGRESS ||
    	    (err == -EBUSY && (ahash_request_flags(req) &
    			       CRYPTO_TFM_REQ_MAY_BACKLOG)))
    
    This patch changes the return code used to indicate a crypto op
    failed due to the transformation provider being transiently busy
    to -EAGAIN.
    
    Signed-off-by: Gilad Ben-Yossef <gilad@benyossef.com>
    ---
     crypto/algapi.c     |  6 ++++--
     crypto/algif_hash.c | 20 +++++++++++++++++---
     crypto/cryptd.c     |  4 +---
     3 files changed, 22 insertions(+), 8 deletions(-)
    
    diff --git a/crypto/algapi.c b/crypto/algapi.c
    index aa699ff..916bee3 100644
    --- a/crypto/algapi.c
    +++ b/crypto/algapi.c
    @@ -897,9 +897,11 @@ int crypto_enqueue_request(struct crypto_queue *queue,
     	int err = -EINPROGRESS;
     
     	if (unlikely(queue->qlen >= queue->max_qlen)) {
    -		err = -EBUSY;
    -		if (!(request->flags & CRYPTO_TFM_REQ_MAY_BACKLOG))
    +		if (!(request->flags & CRYPTO_TFM_REQ_MAY_BACKLOG)) {
    +			err = -EAGAIN;
     			goto out;
    +		}
    +		err = -EBUSY;
     		if (queue->backlog == &queue->list)
     			queue->backlog = &request->list;
     	}
    diff --git a/crypto/algif_hash.c b/crypto/algif_hash.c
    index 5e92bd2..3b3c154 100644
    --- a/crypto/algif_hash.c
    +++ b/crypto/algif_hash.c
    @@ -39,6 +39,20 @@ struct algif_hash_tfm {
     	bool has_key;
     };
     
    +/* Previous versions of crypto_* ops used to return -EBUSY
    + * rather than -EAGAIN to indicate being tied up. The in
    + * kernel API changed but we don't want to break the user
    + * space API. As only the hash user interface exposed this
    + * error ever to the user, do the translation here.
    + */
    +static inline int crypto_user_err(int err)
    +{
    +	if (err == -EAGAIN)
    +		return -EBUSY;
    +
    +	return err;
    +}
    +
     static int hash_alloc_result(struct sock *sk, struct hash_ctx *ctx)
     {
     	unsigned ds;
    @@ -136,7 +150,7 @@ static int hash_sendmsg(struct socket *sock, struct msghdr *msg,
     unlock:
     	release_sock(sk);
     
    -	return err ?: copied;
    +	return err ? crypto_user_err(err) : copied;
     }
     
     static ssize_t hash_sendpage(struct socket *sock, struct page *page,
    @@ -188,7 +202,7 @@ static ssize_t hash_sendpage(struct socket *sock, struct page *page,
     unlock:
     	release_sock(sk);
     
    -	return err ?: size;
    +	return err ? crypto_user_err(err) : size;
     }
     
     static int hash_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
    @@ -236,7 +250,7 @@ static int hash_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
     	hash_free_result(sk, ctx);
     	release_sock(sk);
     
    -	return err ?: len;
    +	return err ? crypto_user_err(err) : len;
     }
     
     static int hash_accept(struct socket *sock, struct socket *newsock, int flags,
    diff --git a/crypto/cryptd.c b/crypto/cryptd.c
    index 0508c48..d1dbdce 100644
    --- a/crypto/cryptd.c
    +++ b/crypto/cryptd.c
    @@ -137,16 +137,14 @@ static int cryptd_enqueue_request(struct cryptd_queue *queue,
     	int cpu, err;
     	struct cryptd_cpu_queue *cpu_queue;
     	atomic_t *refcnt;
    -	bool may_backlog;
     
     	cpu = get_cpu();
     	cpu_queue = this_cpu_ptr(queue->cpu_queue);
     	err = crypto_enqueue_request(&cpu_queue->queue, request);
     
     	refcnt = crypto_tfm_ctx(request->tfm);
    -	may_backlog = request->flags & CRYPTO_TFM_REQ_MAY_BACKLOG;
     
    -	if (err == -EBUSY && !may_backlog)
    +	if (err == -EAGAIN)
     		goto out_put_cpu;
     
     	queue_work_on(cpu, kcrypto_wq, &cpu_queue->work);
    -- 
    2.1.4
    
    ^ permalink raw reply related	[flat|nested] 58+ messages in thread
  • * [PATCH v5 02/19] crypto: ccp: use -EAGAIN for transient busy indication
           [not found] <1502724094-23305-1-git-send-email-gilad@benyossef.com>
                       ` (2 preceding siblings ...)
      2017-08-14 15:21 ` Gilad Ben-Yossef
    @ 2017-08-14 15:21 ` Gilad Ben-Yossef
      2017-08-14 15:21 ` Gilad Ben-Yossef
                       ` (36 subsequent siblings)
      40 siblings, 0 replies; 58+ messages in thread
    From: Gilad Ben-Yossef @ 2017-08-14 15:21 UTC (permalink / raw)
      To: Herbert Xu, David S. Miller, Jonathan Corbet, David Howells,
    	Tom Lendacky, Gary Hook, Boris Brezillon, Arnaud Ebalard,
    	Matthias Brugger, Alasdair Kergon, Mike Snitzer, dm-devel,
    	Shaohua Li, Steve French, Theodore Y. Ts'o, Jaegeuk Kim,
    	Mimi Zohar, Dmitry Kasatkin, James Morris, Serge E. Hallyn,
    	linux-crypto, linux-doc, linux-kernel, keyrings, linux-arm-kernel
      Cc: Ofir Drang
    
    Replace -EBUSY with -EAGAIN when reporting transient busy
    indication in the absence of backlog.
    
    Signed-off-by: Gilad Ben-Yossef <gilad@benyossef.com>
    ---
     drivers/crypto/ccp/ccp-crypto-main.c | 8 +++-----
     drivers/crypto/ccp/ccp-dev.c         | 7 +++++--
     2 files changed, 8 insertions(+), 7 deletions(-)
    
    diff --git a/drivers/crypto/ccp/ccp-crypto-main.c b/drivers/crypto/ccp/ccp-crypto-main.c
    index 35a9de7..403ff0a 100644
    --- a/drivers/crypto/ccp/ccp-crypto-main.c
    +++ b/drivers/crypto/ccp/ccp-crypto-main.c
    @@ -222,9 +222,10 @@ static int ccp_crypto_enqueue_cmd(struct ccp_crypto_cmd *crypto_cmd)
     
     	/* Check if the cmd can/should be queued */
     	if (req_queue.cmd_count >= CCP_CRYPTO_MAX_QLEN) {
    -		ret = -EBUSY;
    -		if (!(crypto_cmd->cmd->flags & CCP_CMD_MAY_BACKLOG))
    +		if (!(crypto_cmd->cmd->flags & CCP_CMD_MAY_BACKLOG)) {
    +			ret = -EAGAIN;
     			goto e_lock;
    +		}
     	}
     
     	/* Look for an entry with the same tfm.  If there is a cmd
    @@ -243,9 +244,6 @@ static int ccp_crypto_enqueue_cmd(struct ccp_crypto_cmd *crypto_cmd)
     		ret = ccp_enqueue_cmd(crypto_cmd->cmd);
     		if (!ccp_crypto_success(ret))
     			goto e_lock;	/* Error, don't queue it */
    -		if ((ret == -EBUSY) &&
    -		    !(crypto_cmd->cmd->flags & CCP_CMD_MAY_BACKLOG))
    -			goto e_lock;	/* Not backlogging, don't queue it */
     	}
     
     	if (req_queue.cmd_count >= CCP_CRYPTO_MAX_QLEN) {
    diff --git a/drivers/crypto/ccp/ccp-dev.c b/drivers/crypto/ccp/ccp-dev.c
    index 4e029b1..3d637e3 100644
    --- a/drivers/crypto/ccp/ccp-dev.c
    +++ b/drivers/crypto/ccp/ccp-dev.c
    @@ -292,9 +292,12 @@ int ccp_enqueue_cmd(struct ccp_cmd *cmd)
     	i = ccp->cmd_q_count;
     
     	if (ccp->cmd_count >= MAX_CMD_QLEN) {
    -		ret = -EBUSY;
    -		if (cmd->flags & CCP_CMD_MAY_BACKLOG)
    +		if (cmd->flags & CCP_CMD_MAY_BACKLOG) {
    +			ret = -EBUSY;
     			list_add_tail(&cmd->entry, &ccp->backlog);
    +		} else {
    +			ret = -EAGAIN;
    +		}
     	} else {
     		ret = -EINPROGRESS;
     		ccp->cmd_count++;
    -- 
    2.1.4
    
    ^ permalink raw reply related	[flat|nested] 58+ messages in thread
  • * [PATCH v5 02/19] crypto: ccp: use -EAGAIN for transient busy indication
           [not found] <1502724094-23305-1-git-send-email-gilad@benyossef.com>
                       ` (3 preceding siblings ...)
      2017-08-14 15:21 ` [PATCH v5 02/19] crypto: ccp: use -EAGAIN for transient busy indication Gilad Ben-Yossef
    @ 2017-08-14 15:21 ` Gilad Ben-Yossef
      2017-08-14 15:21 ` [PATCH v5 03/19] crypto: remove redundant backlog checks on EBUSY Gilad Ben-Yossef
                       ` (35 subsequent siblings)
      40 siblings, 0 replies; 58+ messages in thread
    From: Gilad Ben-Yossef @ 2017-08-14 15:21 UTC (permalink / raw)
      To: Herbert Xu, David S. Miller, Jonathan Corbet, David Howells,
    	Tom Lendacky, Gary Hook, Boris Brezillon, Arnaud Ebalard,
    	Matthias Brugger, Alasdair Kergon, Mike Snitzer, dm-devel,
    	Shaohua Li, Steve French, Theodore Y. Ts'o, Jaegeuk Kim,
    	Mimi Zohar, Dmitry Kasatkin, James Morris, Serge E. Hallyn,
    	linux-crypto
      Cc: Ofir Drang
    
    Replace -EBUSY with -EAGAIN when reporting transient busy
    indication in the absence of backlog.
    
    Signed-off-by: Gilad Ben-Yossef <gilad@benyossef.com>
    ---
     drivers/crypto/ccp/ccp-crypto-main.c | 8 +++-----
     drivers/crypto/ccp/ccp-dev.c         | 7 +++++--
     2 files changed, 8 insertions(+), 7 deletions(-)
    
    diff --git a/drivers/crypto/ccp/ccp-crypto-main.c b/drivers/crypto/ccp/ccp-crypto-main.c
    index 35a9de7..403ff0a 100644
    --- a/drivers/crypto/ccp/ccp-crypto-main.c
    +++ b/drivers/crypto/ccp/ccp-crypto-main.c
    @@ -222,9 +222,10 @@ static int ccp_crypto_enqueue_cmd(struct ccp_crypto_cmd *crypto_cmd)
     
     	/* Check if the cmd can/should be queued */
     	if (req_queue.cmd_count >= CCP_CRYPTO_MAX_QLEN) {
    -		ret = -EBUSY;
    -		if (!(crypto_cmd->cmd->flags & CCP_CMD_MAY_BACKLOG))
    +		if (!(crypto_cmd->cmd->flags & CCP_CMD_MAY_BACKLOG)) {
    +			ret = -EAGAIN;
     			goto e_lock;
    +		}
     	}
     
     	/* Look for an entry with the same tfm.  If there is a cmd
    @@ -243,9 +244,6 @@ static int ccp_crypto_enqueue_cmd(struct ccp_crypto_cmd *crypto_cmd)
     		ret = ccp_enqueue_cmd(crypto_cmd->cmd);
     		if (!ccp_crypto_success(ret))
     			goto e_lock;	/* Error, don't queue it */
    -		if ((ret == -EBUSY) &&
    -		    !(crypto_cmd->cmd->flags & CCP_CMD_MAY_BACKLOG))
    -			goto e_lock;	/* Not backlogging, don't queue it */
     	}
     
     	if (req_queue.cmd_count >= CCP_CRYPTO_MAX_QLEN) {
    diff --git a/drivers/crypto/ccp/ccp-dev.c b/drivers/crypto/ccp/ccp-dev.c
    index 4e029b1..3d637e3 100644
    --- a/drivers/crypto/ccp/ccp-dev.c
    +++ b/drivers/crypto/ccp/ccp-dev.c
    @@ -292,9 +292,12 @@ int ccp_enqueue_cmd(struct ccp_cmd *cmd)
     	i = ccp->cmd_q_count;
     
     	if (ccp->cmd_count >= MAX_CMD_QLEN) {
    -		ret = -EBUSY;
    -		if (cmd->flags & CCP_CMD_MAY_BACKLOG)
    +		if (cmd->flags & CCP_CMD_MAY_BACKLOG) {
    +			ret = -EBUSY;
     			list_add_tail(&cmd->entry, &ccp->backlog);
    +		} else {
    +			ret = -EAGAIN;
    +		}
     	} else {
     		ret = -EINPROGRESS;
     		ccp->cmd_count++;
    -- 
    2.1.4
    
    
    ^ permalink raw reply related	[flat|nested] 58+ messages in thread
  • * [PATCH v5 03/19] crypto: remove redundant backlog checks on EBUSY
           [not found] <1502724094-23305-1-git-send-email-gilad@benyossef.com>
                       ` (4 preceding siblings ...)
      2017-08-14 15:21 ` Gilad Ben-Yossef
    @ 2017-08-14 15:21 ` Gilad Ben-Yossef
      2017-08-14 15:21 ` Gilad Ben-Yossef
                       ` (34 subsequent siblings)
      40 siblings, 0 replies; 58+ messages in thread
    From: Gilad Ben-Yossef @ 2017-08-14 15:21 UTC (permalink / raw)
      To: Herbert Xu, David S. Miller, Jonathan Corbet, David Howells,
    	Tom Lendacky, Gary Hook, Boris Brezillon, Arnaud Ebalard,
    	Matthias Brugger, Alasdair Kergon, Mike Snitzer, dm-devel,
    	Shaohua Li, Steve French, Theodore Y. Ts'o, Jaegeuk Kim,
    	Mimi Zohar, Dmitry Kasatkin, James Morris, Serge E. Hallyn,
    	linux-crypto
      Cc: Ofir Drang
    
    Now that -EBUSY return code only indicates backlog queueing
    we can safely remove the now redundant check for the
    CRYPTO_TFM_REQ_MAY_BACKLOG flag when -EBUSY is returned.
    
    Signed-off-by: Gilad Ben-Yossef <gilad@benyossef.com>
    ---
     crypto/ahash.c        | 12 +++---------
     crypto/cts.c          |  6 ++----
     crypto/lrw.c          |  8 ++------
     crypto/rsa-pkcs1pad.c | 16 ++++------------
     crypto/xts.c          |  8 ++------
     5 files changed, 13 insertions(+), 37 deletions(-)
    
    diff --git a/crypto/ahash.c b/crypto/ahash.c
    index 826cd7a..d63eeef 100644
    --- a/crypto/ahash.c
    +++ b/crypto/ahash.c
    @@ -334,9 +334,7 @@ static int ahash_op_unaligned(struct ahash_request *req,
     		return err;
     
     	err = op(req);
    -	if (err == -EINPROGRESS ||
    -	    (err == -EBUSY && (ahash_request_flags(req) &
    -			       CRYPTO_TFM_REQ_MAY_BACKLOG)))
    +	if (err == -EINPROGRESS || err == -EBUSY)
     		return err;
     
     	ahash_restore_req(req, err);
    @@ -394,9 +392,7 @@ static int ahash_def_finup_finish1(struct ahash_request *req, int err)
     	req->base.complete = ahash_def_finup_done2;
     
     	err = crypto_ahash_reqtfm(req)->final(req);
    -	if (err == -EINPROGRESS ||
    -	    (err == -EBUSY && (ahash_request_flags(req) &
    -			       CRYPTO_TFM_REQ_MAY_BACKLOG)))
    +	if (err == -EINPROGRESS || err == -EBUSY)
     		return err;
     
     out:
    @@ -432,9 +428,7 @@ static int ahash_def_finup(struct ahash_request *req)
     		return err;
     
     	err = tfm->update(req);
    -	if (err == -EINPROGRESS ||
    -	    (err == -EBUSY && (ahash_request_flags(req) &
    -			       CRYPTO_TFM_REQ_MAY_BACKLOG)))
    +	if (err == -EINPROGRESS || err == -EBUSY)
     		return err;
     
     	return ahash_def_finup_finish1(req, err);
    diff --git a/crypto/cts.c b/crypto/cts.c
    index 243f591..4773c18 100644
    --- a/crypto/cts.c
    +++ b/crypto/cts.c
    @@ -136,8 +136,7 @@ static void crypto_cts_encrypt_done(struct crypto_async_request *areq, int err)
     		goto out;
     
     	err = cts_cbc_encrypt(req);
    -	if (err == -EINPROGRESS ||
    -	    (err == -EBUSY && req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG))
    +	if (err == -EINPROGRESS || err == -EBUSY)
     		return;
     
     out:
    @@ -229,8 +228,7 @@ static void crypto_cts_decrypt_done(struct crypto_async_request *areq, int err)
     		goto out;
     
     	err = cts_cbc_decrypt(req);
    -	if (err == -EINPROGRESS ||
    -	    (err == -EBUSY && req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG))
    +	if (err == -EINPROGRESS || err == -EBUSY)
     		return;
     
     out:
    diff --git a/crypto/lrw.c b/crypto/lrw.c
    index a8bfae4..695cea9 100644
    --- a/crypto/lrw.c
    +++ b/crypto/lrw.c
    @@ -328,9 +328,7 @@ static int do_encrypt(struct skcipher_request *req, int err)
     		      crypto_skcipher_encrypt(subreq) ?:
     		      post_crypt(req);
     
    -		if (err == -EINPROGRESS ||
    -		    (err == -EBUSY &&
    -		     req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG))
    +		if (err == -EINPROGRESS || err == -EBUSY)
     			return err;
     	}
     
    @@ -380,9 +378,7 @@ static int do_decrypt(struct skcipher_request *req, int err)
     		      crypto_skcipher_decrypt(subreq) ?:
     		      post_crypt(req);
     
    -		if (err == -EINPROGRESS ||
    -		    (err == -EBUSY &&
    -		     req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG))
    +		if (err == -EINPROGRESS || err == -EBUSY)
     			return err;
     	}
     
    diff --git a/crypto/rsa-pkcs1pad.c b/crypto/rsa-pkcs1pad.c
    index 407c64b..2908f93 100644
    --- a/crypto/rsa-pkcs1pad.c
    +++ b/crypto/rsa-pkcs1pad.c
    @@ -279,9 +279,7 @@ static int pkcs1pad_encrypt(struct akcipher_request *req)
     				   req->dst, ctx->key_size - 1, req->dst_len);
     
     	err = crypto_akcipher_encrypt(&req_ctx->child_req);
    -	if (err != -EINPROGRESS &&
    -			(err != -EBUSY ||
    -			 !(req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG)))
    +	if (err != -EINPROGRESS && err != -EBUSY)
     		return pkcs1pad_encrypt_sign_complete(req, err);
     
     	return err;
    @@ -383,9 +381,7 @@ static int pkcs1pad_decrypt(struct akcipher_request *req)
     				   ctx->key_size);
     
     	err = crypto_akcipher_decrypt(&req_ctx->child_req);
    -	if (err != -EINPROGRESS &&
    -			(err != -EBUSY ||
    -			 !(req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG)))
    +	if (err != -EINPROGRESS && err != -EBUSY)
     		return pkcs1pad_decrypt_complete(req, err);
     
     	return err;
    @@ -440,9 +436,7 @@ static int pkcs1pad_sign(struct akcipher_request *req)
     				   req->dst, ctx->key_size - 1, req->dst_len);
     
     	err = crypto_akcipher_sign(&req_ctx->child_req);
    -	if (err != -EINPROGRESS &&
    -			(err != -EBUSY ||
    -			 !(req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG)))
    +	if (err != -EINPROGRESS && err != -EBUSY)
     		return pkcs1pad_encrypt_sign_complete(req, err);
     
     	return err;
    @@ -561,9 +555,7 @@ static int pkcs1pad_verify(struct akcipher_request *req)
     				   ctx->key_size);
     
     	err = crypto_akcipher_verify(&req_ctx->child_req);
    -	if (err != -EINPROGRESS &&
    -			(err != -EBUSY ||
    -			 !(req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG)))
    +	if (err != -EINPROGRESS && err != -EBUSY)
     		return pkcs1pad_verify_complete(req, err);
     
     	return err;
    diff --git a/crypto/xts.c b/crypto/xts.c
    index d86c11a..af68012 100644
    --- a/crypto/xts.c
    +++ b/crypto/xts.c
    @@ -269,9 +269,7 @@ static int do_encrypt(struct skcipher_request *req, int err)
     		      crypto_skcipher_encrypt(subreq) ?:
     		      post_crypt(req);
     
    -		if (err == -EINPROGRESS ||
    -		    (err == -EBUSY &&
    -		     req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG))
    +		if (err == -EINPROGRESS || err == -EBUSY)
     			return err;
     	}
     
    @@ -321,9 +319,7 @@ static int do_decrypt(struct skcipher_request *req, int err)
     		      crypto_skcipher_decrypt(subreq) ?:
     		      post_crypt(req);
     
    -		if (err == -EINPROGRESS ||
    -		    (err == -EBUSY &&
    -		     req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG))
    +		if (err == -EINPROGRESS || err == -EBUSY)
     			return err;
     	}
     
    -- 
    2.1.4
    
    
    ^ permalink raw reply related	[flat|nested] 58+ messages in thread
  • * [PATCH v5 03/19] crypto: remove redundant backlog checks on EBUSY
           [not found] <1502724094-23305-1-git-send-email-gilad@benyossef.com>
                       ` (5 preceding siblings ...)
      2017-08-14 15:21 ` [PATCH v5 03/19] crypto: remove redundant backlog checks on EBUSY Gilad Ben-Yossef
    @ 2017-08-14 15:21 ` Gilad Ben-Yossef
      2017-08-14 15:21 ` [PATCH v5 04/19] crypto: marvell/cesa: " Gilad Ben-Yossef
                       ` (33 subsequent siblings)
      40 siblings, 0 replies; 58+ messages in thread
    From: Gilad Ben-Yossef @ 2017-08-14 15:21 UTC (permalink / raw)
      To: Herbert Xu, David S. Miller, Jonathan Corbet, David Howells,
    	Tom Lendacky, Gary Hook, Boris Brezillon, Arnaud Ebalard,
    	Matthias Brugger, Alasdair Kergon, Mike Snitzer, dm-devel,
    	Shaohua Li, Steve French, Theodore Y. Ts'o, Jaegeuk Kim,
    	Mimi Zohar, Dmitry Kasatkin, James Morris, Serge E. Hallyn,
    	linux-crypto, linux-doc, linux-kernel, keyrings, linux-arm-kernel
      Cc: Ofir Drang
    
    Now that -EBUSY return code only indicates backlog queueing
    we can safely remove the now redundant check for the
    CRYPTO_TFM_REQ_MAY_BACKLOG flag when -EBUSY is returned.
    
    Signed-off-by: Gilad Ben-Yossef <gilad@benyossef.com>
    ---
     crypto/ahash.c        | 12 +++---------
     crypto/cts.c          |  6 ++----
     crypto/lrw.c          |  8 ++------
     crypto/rsa-pkcs1pad.c | 16 ++++------------
     crypto/xts.c          |  8 ++------
     5 files changed, 13 insertions(+), 37 deletions(-)
    
    diff --git a/crypto/ahash.c b/crypto/ahash.c
    index 826cd7a..d63eeef 100644
    --- a/crypto/ahash.c
    +++ b/crypto/ahash.c
    @@ -334,9 +334,7 @@ static int ahash_op_unaligned(struct ahash_request *req,
     		return err;
     
     	err = op(req);
    -	if (err == -EINPROGRESS ||
    -	    (err == -EBUSY && (ahash_request_flags(req) &
    -			       CRYPTO_TFM_REQ_MAY_BACKLOG)))
    +	if (err == -EINPROGRESS || err == -EBUSY)
     		return err;
     
     	ahash_restore_req(req, err);
    @@ -394,9 +392,7 @@ static int ahash_def_finup_finish1(struct ahash_request *req, int err)
     	req->base.complete = ahash_def_finup_done2;
     
     	err = crypto_ahash_reqtfm(req)->final(req);
    -	if (err == -EINPROGRESS ||
    -	    (err == -EBUSY && (ahash_request_flags(req) &
    -			       CRYPTO_TFM_REQ_MAY_BACKLOG)))
    +	if (err == -EINPROGRESS || err == -EBUSY)
     		return err;
     
     out:
    @@ -432,9 +428,7 @@ static int ahash_def_finup(struct ahash_request *req)
     		return err;
     
     	err = tfm->update(req);
    -	if (err == -EINPROGRESS ||
    -	    (err == -EBUSY && (ahash_request_flags(req) &
    -			       CRYPTO_TFM_REQ_MAY_BACKLOG)))
    +	if (err == -EINPROGRESS || err == -EBUSY)
     		return err;
     
     	return ahash_def_finup_finish1(req, err);
    diff --git a/crypto/cts.c b/crypto/cts.c
    index 243f591..4773c18 100644
    --- a/crypto/cts.c
    +++ b/crypto/cts.c
    @@ -136,8 +136,7 @@ static void crypto_cts_encrypt_done(struct crypto_async_request *areq, int err)
     		goto out;
     
     	err = cts_cbc_encrypt(req);
    -	if (err == -EINPROGRESS ||
    -	    (err == -EBUSY && req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG))
    +	if (err == -EINPROGRESS || err == -EBUSY)
     		return;
     
     out:
    @@ -229,8 +228,7 @@ static void crypto_cts_decrypt_done(struct crypto_async_request *areq, int err)
     		goto out;
     
     	err = cts_cbc_decrypt(req);
    -	if (err == -EINPROGRESS ||
    -	    (err == -EBUSY && req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG))
    +	if (err == -EINPROGRESS || err == -EBUSY)
     		return;
     
     out:
    diff --git a/crypto/lrw.c b/crypto/lrw.c
    index a8bfae4..695cea9 100644
    --- a/crypto/lrw.c
    +++ b/crypto/lrw.c
    @@ -328,9 +328,7 @@ static int do_encrypt(struct skcipher_request *req, int err)
     		      crypto_skcipher_encrypt(subreq) ?:
     		      post_crypt(req);
     
    -		if (err == -EINPROGRESS ||
    -		    (err == -EBUSY &&
    -		     req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG))
    +		if (err == -EINPROGRESS || err == -EBUSY)
     			return err;
     	}
     
    @@ -380,9 +378,7 @@ static int do_decrypt(struct skcipher_request *req, int err)
     		      crypto_skcipher_decrypt(subreq) ?:
     		      post_crypt(req);
     
    -		if (err == -EINPROGRESS ||
    -		    (err == -EBUSY &&
    -		     req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG))
    +		if (err == -EINPROGRESS || err == -EBUSY)
     			return err;
     	}
     
    diff --git a/crypto/rsa-pkcs1pad.c b/crypto/rsa-pkcs1pad.c
    index 407c64b..2908f93 100644
    --- a/crypto/rsa-pkcs1pad.c
    +++ b/crypto/rsa-pkcs1pad.c
    @@ -279,9 +279,7 @@ static int pkcs1pad_encrypt(struct akcipher_request *req)
     				   req->dst, ctx->key_size - 1, req->dst_len);
     
     	err = crypto_akcipher_encrypt(&req_ctx->child_req);
    -	if (err != -EINPROGRESS &&
    -			(err != -EBUSY ||
    -			 !(req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG)))
    +	if (err != -EINPROGRESS && err != -EBUSY)
     		return pkcs1pad_encrypt_sign_complete(req, err);
     
     	return err;
    @@ -383,9 +381,7 @@ static int pkcs1pad_decrypt(struct akcipher_request *req)
     				   ctx->key_size);
     
     	err = crypto_akcipher_decrypt(&req_ctx->child_req);
    -	if (err != -EINPROGRESS &&
    -			(err != -EBUSY ||
    -			 !(req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG)))
    +	if (err != -EINPROGRESS && err != -EBUSY)
     		return pkcs1pad_decrypt_complete(req, err);
     
     	return err;
    @@ -440,9 +436,7 @@ static int pkcs1pad_sign(struct akcipher_request *req)
     				   req->dst, ctx->key_size - 1, req->dst_len);
     
     	err = crypto_akcipher_sign(&req_ctx->child_req);
    -	if (err != -EINPROGRESS &&
    -			(err != -EBUSY ||
    -			 !(req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG)))
    +	if (err != -EINPROGRESS && err != -EBUSY)
     		return pkcs1pad_encrypt_sign_complete(req, err);
     
     	return err;
    @@ -561,9 +555,7 @@ static int pkcs1pad_verify(struct akcipher_request *req)
     				   ctx->key_size);
     
     	err = crypto_akcipher_verify(&req_ctx->child_req);
    -	if (err != -EINPROGRESS &&
    -			(err != -EBUSY ||
    -			 !(req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG)))
    +	if (err != -EINPROGRESS && err != -EBUSY)
     		return pkcs1pad_verify_complete(req, err);
     
     	return err;
    diff --git a/crypto/xts.c b/crypto/xts.c
    index d86c11a..af68012 100644
    --- a/crypto/xts.c
    +++ b/crypto/xts.c
    @@ -269,9 +269,7 @@ static int do_encrypt(struct skcipher_request *req, int err)
     		      crypto_skcipher_encrypt(subreq) ?:
     		      post_crypt(req);
     
    -		if (err == -EINPROGRESS ||
    -		    (err == -EBUSY &&
    -		     req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG))
    +		if (err == -EINPROGRESS || err == -EBUSY)
     			return err;
     	}
     
    @@ -321,9 +319,7 @@ static int do_decrypt(struct skcipher_request *req, int err)
     		      crypto_skcipher_decrypt(subreq) ?:
     		      post_crypt(req);
     
    -		if (err == -EINPROGRESS ||
    -		    (err == -EBUSY &&
    -		     req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG))
    +		if (err == -EINPROGRESS || err == -EBUSY)
     			return err;
     	}
     
    -- 
    2.1.4
    
    ^ permalink raw reply related	[flat|nested] 58+ messages in thread
  • * [PATCH v5 04/19] crypto: marvell/cesa: remove redundant backlog checks on EBUSY
           [not found] <1502724094-23305-1-git-send-email-gilad@benyossef.com>
                       ` (6 preceding siblings ...)
      2017-08-14 15:21 ` Gilad Ben-Yossef
    @ 2017-08-14 15:21 ` Gilad Ben-Yossef
      2017-08-14 15:21 ` Gilad Ben-Yossef
                       ` (32 subsequent siblings)
      40 siblings, 0 replies; 58+ messages in thread
    From: Gilad Ben-Yossef @ 2017-08-14 15:21 UTC (permalink / raw)
      To: Herbert Xu, David S. Miller, Jonathan Corbet, David Howells,
    	Tom Lendacky, Gary Hook, Boris Brezillon, Arnaud Ebalard,
    	Matthias Brugger, Alasdair Kergon, Mike Snitzer, dm-devel,
    	Shaohua Li, Steve French, Theodore Y. Ts'o, Jaegeuk Kim,
    	Mimi Zohar, Dmitry Kasatkin, James Morris, Serge E. Hallyn,
    	linux-crypto, linux-doc, linux-kernel, keyrings, linux-arm-kernel
      Cc: Ofir Drang
    
    Now that -EBUSY return code only indicates backlog queueing
    we can safely remove the now redundant check for the
    CRYPTO_TFM_REQ_MAY_BACKLOG flag when -EBUSY is returned.
    
    Signed-off-by: Gilad Ben-Yossef <gilad@benyossef.com>
    ---
     drivers/crypto/marvell/cesa.c | 3 +--
     drivers/crypto/marvell/cesa.h | 2 +-
     2 files changed, 2 insertions(+), 3 deletions(-)
    
    diff --git a/drivers/crypto/marvell/cesa.c b/drivers/crypto/marvell/cesa.c
    index 6e7a5c7..269737f 100644
    --- a/drivers/crypto/marvell/cesa.c
    +++ b/drivers/crypto/marvell/cesa.c
    @@ -183,8 +183,7 @@ int mv_cesa_queue_req(struct crypto_async_request *req,
     	spin_lock_bh(&engine->lock);
     	ret = crypto_enqueue_request(&engine->queue, req);
     	if ((mv_cesa_req_get_type(creq) == CESA_DMA_REQ) &&
    -	    (ret == -EINPROGRESS ||
    -	    (ret == -EBUSY && req->flags & CRYPTO_TFM_REQ_MAY_BACKLOG)))
    +	    (ret == -EINPROGRESS || ret == -EBUSY)
     		mv_cesa_tdma_chain(engine, creq);
     	spin_unlock_bh(&engine->lock);
     
    diff --git a/drivers/crypto/marvell/cesa.h b/drivers/crypto/marvell/cesa.h
    index b7872f6..63c8457 100644
    --- a/drivers/crypto/marvell/cesa.h
    +++ b/drivers/crypto/marvell/cesa.h
    @@ -763,7 +763,7 @@ static inline int mv_cesa_req_needs_cleanup(struct crypto_async_request *req,
     	 * the backlog and will be processed later. There's no need to
     	 * clean it up.
     	 */
    -	if (ret == -EBUSY && req->flags & CRYPTO_TFM_REQ_MAY_BACKLOG)
    +	if (ret == -EBUSY)
     		return false;
     
     	/* Request wasn't queued, we need to clean it up */
    -- 
    2.1.4
    
    ^ permalink raw reply related	[flat|nested] 58+ messages in thread
  • * [PATCH v5 04/19] crypto: marvell/cesa: remove redundant backlog checks on EBUSY
           [not found] <1502724094-23305-1-git-send-email-gilad@benyossef.com>
                       ` (7 preceding siblings ...)
      2017-08-14 15:21 ` [PATCH v5 04/19] crypto: marvell/cesa: " Gilad Ben-Yossef
    @ 2017-08-14 15:21 ` Gilad Ben-Yossef
      2017-08-14 15:21 ` [PATCH v5 05/19] crypto: introduce crypto wait for async op Gilad Ben-Yossef
                       ` (31 subsequent siblings)
      40 siblings, 0 replies; 58+ messages in thread
    From: Gilad Ben-Yossef @ 2017-08-14 15:21 UTC (permalink / raw)
      To: Herbert Xu, David S. Miller, Jonathan Corbet, David Howells,
    	Tom Lendacky, Gary Hook, Boris Brezillon, Arnaud Ebalard,
    	Matthias Brugger, Alasdair Kergon, Mike Snitzer, dm-devel,
    	Shaohua Li, Steve French, Theodore Y. Ts'o, Jaegeuk Kim,
    	Mimi Zohar, Dmitry Kasatkin, James Morris, Serge E. Hallyn,
    	linux-crypto
      Cc: Ofir Drang
    
    Now that -EBUSY return code only indicates backlog queueing
    we can safely remove the now redundant check for the
    CRYPTO_TFM_REQ_MAY_BACKLOG flag when -EBUSY is returned.
    
    Signed-off-by: Gilad Ben-Yossef <gilad@benyossef.com>
    ---
     drivers/crypto/marvell/cesa.c | 3 +--
     drivers/crypto/marvell/cesa.h | 2 +-
     2 files changed, 2 insertions(+), 3 deletions(-)
    
    diff --git a/drivers/crypto/marvell/cesa.c b/drivers/crypto/marvell/cesa.c
    index 6e7a5c7..269737f 100644
    --- a/drivers/crypto/marvell/cesa.c
    +++ b/drivers/crypto/marvell/cesa.c
    @@ -183,8 +183,7 @@ int mv_cesa_queue_req(struct crypto_async_request *req,
     	spin_lock_bh(&engine->lock);
     	ret = crypto_enqueue_request(&engine->queue, req);
     	if ((mv_cesa_req_get_type(creq) == CESA_DMA_REQ) &&
    -	    (ret == -EINPROGRESS ||
    -	    (ret == -EBUSY && req->flags & CRYPTO_TFM_REQ_MAY_BACKLOG)))
    +	    (ret == -EINPROGRESS || ret == -EBUSY)
     		mv_cesa_tdma_chain(engine, creq);
     	spin_unlock_bh(&engine->lock);
     
    diff --git a/drivers/crypto/marvell/cesa.h b/drivers/crypto/marvell/cesa.h
    index b7872f6..63c8457 100644
    --- a/drivers/crypto/marvell/cesa.h
    +++ b/drivers/crypto/marvell/cesa.h
    @@ -763,7 +763,7 @@ static inline int mv_cesa_req_needs_cleanup(struct crypto_async_request *req,
     	 * the backlog and will be processed later. There's no need to
     	 * clean it up.
     	 */
    -	if (ret == -EBUSY && req->flags & CRYPTO_TFM_REQ_MAY_BACKLOG)
    +	if (ret == -EBUSY)
     		return false;
     
     	/* Request wasn't queued, we need to clean it up */
    -- 
    2.1.4
    
    
    ^ permalink raw reply related	[flat|nested] 58+ messages in thread
  • * [PATCH v5 05/19] crypto: introduce crypto wait for async op
           [not found] <1502724094-23305-1-git-send-email-gilad@benyossef.com>
                       ` (8 preceding siblings ...)
      2017-08-14 15:21 ` Gilad Ben-Yossef
    @ 2017-08-14 15:21 ` Gilad Ben-Yossef
      2017-08-14 15:21 ` Gilad Ben-Yossef
                       ` (30 subsequent siblings)
      40 siblings, 0 replies; 58+ messages in thread
    From: Gilad Ben-Yossef @ 2017-08-14 15:21 UTC (permalink / raw)
      To: Herbert Xu, David S. Miller, Jonathan Corbet, David Howells,
    	Tom Lendacky, Gary Hook, Boris Brezillon, Arnaud Ebalard,
    	Matthias Brugger, Alasdair Kergon, Mike Snitzer, dm-devel,
    	Shaohua Li, Steve French, Theodore Y. Ts'o, Jaegeuk Kim,
    	Mimi Zohar, Dmitry Kasatkin, James Morris, Serge E. Hallyn,
    	linux-crypto
      Cc: Ofir Drang, Eric Biggers
    
    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>
    ---
     crypto/api.c           | 13 +++++++++++++
     include/linux/crypto.h | 41 +++++++++++++++++++++++++++++++++++++++++
     2 files changed, 54 insertions(+)
    
    diff --git a/crypto/api.c b/crypto/api.c
    index 941cd4c..2a2479d 100644
    --- a/crypto/api.c
    +++ b/crypto/api.c
    @@ -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");
    diff --git a/include/linux/crypto.h b/include/linux/crypto.h
    index 84da997..bb00186 100644
    --- a/include/linux/crypto.h
    +++ b/include/linux/crypto.h
    @@ -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);
    @@ -1604,5 +1644,6 @@ static inline int crypto_comp_decompress(struct crypto_comp *tfm,
     						    src, slen, dst, dlen);
     }
     
    +
     #endif	/* _LINUX_CRYPTO_H */
     
    -- 
    2.1.4
    
    
    ^ permalink raw reply related	[flat|nested] 58+ messages in thread
  • * [PATCH v5 05/19] crypto: introduce crypto wait for async op
           [not found] <1502724094-23305-1-git-send-email-gilad@benyossef.com>
                       ` (9 preceding siblings ...)
      2017-08-14 15:21 ` [PATCH v5 05/19] crypto: introduce crypto wait for async op Gilad Ben-Yossef
    @ 2017-08-14 15:21 ` Gilad Ben-Yossef
      2017-08-14 15:21 ` [PATCH v5 06/19] crypto: move algif to generic async completion Gilad Ben-Yossef
                       ` (29 subsequent siblings)
      40 siblings, 0 replies; 58+ messages in thread
    From: Gilad Ben-Yossef @ 2017-08-14 15:21 UTC (permalink / raw)
      To: Herbert Xu, David S. Miller, Jonathan Corbet, David Howells,
    	Tom Lendacky, Gary Hook, Boris Brezillon, Arnaud Ebalard,
    	Matthias Brugger, Alasdair Kergon, Mike Snitzer, dm-devel,
    	Shaohua Li, Steve French, Theodore Y. Ts'o, Jaegeuk Kim,
    	Mimi Zohar, Dmitry Kasatkin, James Morris, Serge E. Hallyn,
    	linux-crypto, linux-doc, linux-kernel, keyrings, linux-arm-kernel
      Cc: Eric Biggers, Ofir Drang
    
    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>
    ---
     crypto/api.c           | 13 +++++++++++++
     include/linux/crypto.h | 41 +++++++++++++++++++++++++++++++++++++++++
     2 files changed, 54 insertions(+)
    
    diff --git a/crypto/api.c b/crypto/api.c
    index 941cd4c..2a2479d 100644
    --- a/crypto/api.c
    +++ b/crypto/api.c
    @@ -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");
    diff --git a/include/linux/crypto.h b/include/linux/crypto.h
    index 84da997..bb00186 100644
    --- a/include/linux/crypto.h
    +++ b/include/linux/crypto.h
    @@ -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);
    @@ -1604,5 +1644,6 @@ static inline int crypto_comp_decompress(struct crypto_comp *tfm,
     						    src, slen, dst, dlen);
     }
     
    +
     #endif	/* _LINUX_CRYPTO_H */
     
    -- 
    2.1.4
    
    ^ permalink raw reply related	[flat|nested] 58+ messages in thread
  • * [PATCH v5 06/19] crypto: move algif to generic async completion
           [not found] <1502724094-23305-1-git-send-email-gilad@benyossef.com>
                       ` (10 preceding siblings ...)
      2017-08-14 15:21 ` Gilad Ben-Yossef
    @ 2017-08-14 15:21 ` Gilad Ben-Yossef
      2017-08-14 15:21 ` [PATCH v5 07/19] crypto: move pub key " Gilad Ben-Yossef
                       ` (28 subsequent siblings)
      40 siblings, 0 replies; 58+ messages in thread
    From: Gilad Ben-Yossef @ 2017-08-14 15:21 UTC (permalink / raw)
      To: Herbert Xu, David S. Miller, Jonathan Corbet, David Howells,
    	Tom Lendacky, Gary Hook, Boris Brezillon, Arnaud Ebalard,
    	Matthias Brugger, Alasdair Kergon, Mike Snitzer, dm-devel,
    	Shaohua Li, Steve French, Theodore Y. Ts'o, Jaegeuk Kim,
    	Mimi Zohar, Dmitry Kasatkin, James Morris, Serge E. Hallyn,
    	linux-crypto, linux-doc, linux-kernel, keyrings, linux-arm-kernel
      Cc: Ofir Drang
    
    algif starts several async crypto ops and waits for their completion.
    Move it over to generic code doing the same.
    
    Signed-off-by: Gilad Ben-Yossef <gilad@benyossef.com>
    ---
     crypto/af_alg.c         | 27 ---------------------------
     crypto/algif_aead.c     |  8 ++++----
     crypto/algif_hash.c     | 30 ++++++++++++++----------------
     crypto/algif_skcipher.c |  9 ++++-----
     include/crypto/if_alg.h | 15 +--------------
     5 files changed, 23 insertions(+), 66 deletions(-)
    
    diff --git a/crypto/af_alg.c b/crypto/af_alg.c
    index d6936c0..f8917e7 100644
    --- a/crypto/af_alg.c
    +++ b/crypto/af_alg.c
    @@ -481,33 +481,6 @@ int af_alg_cmsg_send(struct msghdr *msg, struct af_alg_control *con)
     }
     EXPORT_SYMBOL_GPL(af_alg_cmsg_send);
     
    -int af_alg_wait_for_completion(int err, struct af_alg_completion *completion)
    -{
    -	switch (err) {
    -	case -EINPROGRESS:
    -	case -EBUSY:
    -		wait_for_completion(&completion->completion);
    -		reinit_completion(&completion->completion);
    -		err = completion->err;
    -		break;
    -	};
    -
    -	return err;
    -}
    -EXPORT_SYMBOL_GPL(af_alg_wait_for_completion);
    -
    -void af_alg_complete(struct crypto_async_request *req, int err)
    -{
    -	struct af_alg_completion *completion = req->data;
    -
    -	if (err == -EINPROGRESS)
    -		return;
    -
    -	completion->err = err;
    -	complete(&completion->completion);
    -}
    -EXPORT_SYMBOL_GPL(af_alg_complete);
    -
     /**
      * af_alg_alloc_tsgl - allocate the TX SGL
      *
    diff --git a/crypto/algif_aead.c b/crypto/algif_aead.c
    index 48d46e7..abbac8a 100644
    --- a/crypto/algif_aead.c
    +++ b/crypto/algif_aead.c
    @@ -278,11 +278,11 @@ static int _aead_recvmsg(struct socket *sock, struct msghdr *msg,
     		/* Synchronous operation */
     		aead_request_set_callback(&areq->cra_u.aead_req,
     					  CRYPTO_TFM_REQ_MAY_BACKLOG,
    -					  af_alg_complete, &ctx->completion);
    -		err = af_alg_wait_for_completion(ctx->enc ?
    +					  crypto_req_done, &ctx->wait);
    +		err = crypto_wait_req(ctx->enc ?
     				crypto_aead_encrypt(&areq->cra_u.aead_req) :
     				crypto_aead_decrypt(&areq->cra_u.aead_req),
    -						 &ctx->completion);
    +				&ctx->wait);
     	}
     
     	/* AIO operation in progress */
    @@ -554,7 +554,7 @@ static int aead_accept_parent_nokey(void *private, struct sock *sk)
     	ctx->merge = 0;
     	ctx->enc = 0;
     	ctx->aead_assoclen = 0;
    -	af_alg_init_completion(&ctx->completion);
    +	crypto_init_wait(&ctx->wait);
     
     	ask->private = ctx;
     
    diff --git a/crypto/algif_hash.c b/crypto/algif_hash.c
    index 3b3c154..d2ab8de 100644
    --- a/crypto/algif_hash.c
    +++ b/crypto/algif_hash.c
    @@ -26,7 +26,7 @@ struct hash_ctx {
     
     	u8 *result;
     
    -	struct af_alg_completion completion;
    +	struct crypto_wait wait;
     
     	unsigned int len;
     	bool more;
    @@ -102,8 +102,7 @@ static int hash_sendmsg(struct socket *sock, struct msghdr *msg,
     		if ((msg->msg_flags & MSG_MORE))
     			hash_free_result(sk, ctx);
     
    -		err = af_alg_wait_for_completion(crypto_ahash_init(&ctx->req),
    -						&ctx->completion);
    +		err = crypto_wait_req(crypto_ahash_init(&ctx->req), &ctx->wait);
     		if (err)
     			goto unlock;
     	}
    @@ -124,8 +123,8 @@ static int hash_sendmsg(struct socket *sock, struct msghdr *msg,
     
     		ahash_request_set_crypt(&ctx->req, ctx->sgl.sg, NULL, len);
     
    -		err = af_alg_wait_for_completion(crypto_ahash_update(&ctx->req),
    -						 &ctx->completion);
    +		err = crypto_wait_req(crypto_ahash_update(&ctx->req),
    +				      &ctx->wait);
     		af_alg_free_sg(&ctx->sgl);
     		if (err)
     			goto unlock;
    @@ -143,8 +142,8 @@ static int hash_sendmsg(struct socket *sock, struct msghdr *msg,
     			goto unlock;
     
     		ahash_request_set_crypt(&ctx->req, NULL, ctx->result, 0);
    -		err = af_alg_wait_for_completion(crypto_ahash_final(&ctx->req),
    -						 &ctx->completion);
    +		err = crypto_wait_req(crypto_ahash_final(&ctx->req),
    +				      &ctx->wait);
     	}
     
     unlock:
    @@ -185,7 +184,7 @@ static ssize_t hash_sendpage(struct socket *sock, struct page *page,
     	} else {
     		if (!ctx->more) {
     			err = crypto_ahash_init(&ctx->req);
    -			err = af_alg_wait_for_completion(err, &ctx->completion);
    +			err = crypto_wait_req(err, &ctx->wait);
     			if (err)
     				goto unlock;
     		}
    @@ -193,7 +192,7 @@ static ssize_t hash_sendpage(struct socket *sock, struct page *page,
     		err = crypto_ahash_update(&ctx->req);
     	}
     
    -	err = af_alg_wait_for_completion(err, &ctx->completion);
    +	err = crypto_wait_req(err, &ctx->wait);
     	if (err)
     		goto unlock;
     
    @@ -229,17 +228,16 @@ static int hash_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
     	ahash_request_set_crypt(&ctx->req, NULL, ctx->result, 0);
     
     	if (!result && !ctx->more) {
    -		err = af_alg_wait_for_completion(
    -				crypto_ahash_init(&ctx->req),
    -				&ctx->completion);
    +		err = crypto_wait_req(crypto_ahash_init(&ctx->req),
    +				      &ctx->wait);
     		if (err)
     			goto unlock;
     	}
     
     	if (!result || ctx->more) {
     		ctx->more = 0;
    -		err = af_alg_wait_for_completion(crypto_ahash_final(&ctx->req),
    -						 &ctx->completion);
    +		err = crypto_wait_req(crypto_ahash_final(&ctx->req),
    +				      &ctx->wait);
     		if (err)
     			goto unlock;
     	}
    @@ -490,13 +488,13 @@ static int hash_accept_parent_nokey(void *private, struct sock *sk)
     	ctx->result = NULL;
     	ctx->len = len;
     	ctx->more = 0;
    -	af_alg_init_completion(&ctx->completion);
    +	crypto_init_wait(&ctx->wait);
     
     	ask->private = ctx;
     
     	ahash_request_set_tfm(&ctx->req, hash);
     	ahash_request_set_callback(&ctx->req, CRYPTO_TFM_REQ_MAY_BACKLOG,
    -				   af_alg_complete, &ctx->completion);
    +				   crypto_req_done, &ctx->wait);
     
     	sk->sk_destruct = hash_sock_destruct;
     
    diff --git a/crypto/algif_skcipher.c b/crypto/algif_skcipher.c
    index 8ae4170..9954b07 100644
    --- a/crypto/algif_skcipher.c
    +++ b/crypto/algif_skcipher.c
    @@ -129,12 +129,11 @@ static int _skcipher_recvmsg(struct socket *sock, struct msghdr *msg,
     		skcipher_request_set_callback(&areq->cra_u.skcipher_req,
     					      CRYPTO_TFM_REQ_MAY_SLEEP |
     					      CRYPTO_TFM_REQ_MAY_BACKLOG,
    -					      af_alg_complete,
    -					      &ctx->completion);
    -		err = af_alg_wait_for_completion(ctx->enc ?
    +					      crypto_req_done, &ctx->wait);
    +		err = crypto_wait_req(ctx->enc ?
     			crypto_skcipher_encrypt(&areq->cra_u.skcipher_req) :
     			crypto_skcipher_decrypt(&areq->cra_u.skcipher_req),
    -						 &ctx->completion);
    +						 &ctx->wait);
     	}
     
     	/* AIO operation in progress */
    @@ -388,7 +387,7 @@ static int skcipher_accept_parent_nokey(void *private, struct sock *sk)
     	ctx->more = 0;
     	ctx->merge = 0;
     	ctx->enc = 0;
    -	af_alg_init_completion(&ctx->completion);
    +	crypto_init_wait(&ctx->wait);
     
     	ask->private = ctx;
     
    diff --git a/include/crypto/if_alg.h b/include/crypto/if_alg.h
    index 75ec9c6..6abf0a3 100644
    --- a/include/crypto/if_alg.h
    +++ b/include/crypto/if_alg.h
    @@ -40,11 +40,6 @@ struct alg_sock {
     	void *private;
     };
     
    -struct af_alg_completion {
    -	struct completion completion;
    -	int err;
    -};
    -
     struct af_alg_control {
     	struct af_alg_iv *iv;
     	int op;
    @@ -152,7 +147,7 @@ struct af_alg_ctx {
     	void *iv;
     	size_t aead_assoclen;
     
    -	struct af_alg_completion completion;
    +	struct crypto_wait wait;
     
     	size_t used;
     	size_t rcvused;
    @@ -177,19 +172,11 @@ void af_alg_link_sg(struct af_alg_sgl *sgl_prev, struct af_alg_sgl *sgl_new);
     
     int af_alg_cmsg_send(struct msghdr *msg, struct af_alg_control *con);
     
    -int af_alg_wait_for_completion(int err, struct af_alg_completion *completion);
    -void af_alg_complete(struct crypto_async_request *req, int err);
    -
     static inline struct alg_sock *alg_sk(struct sock *sk)
     {
     	return (struct alg_sock *)sk;
     }
     
    -static inline void af_alg_init_completion(struct af_alg_completion *completion)
    -{
    -	init_completion(&completion->completion);
    -}
    -
     /**
      * Size of available buffer for sending data from user space to kernel.
      *
    -- 
    2.1.4
    
    ^ permalink raw reply related	[flat|nested] 58+ messages in thread
  • * [PATCH v5 07/19] crypto: move pub key to generic async completion
           [not found] <1502724094-23305-1-git-send-email-gilad@benyossef.com>
                       ` (11 preceding siblings ...)
      2017-08-14 15:21 ` [PATCH v5 06/19] crypto: move algif to generic async completion Gilad Ben-Yossef
    @ 2017-08-14 15:21 ` Gilad Ben-Yossef
      2017-08-14 15:21 ` [PATCH v5 08/19] crypto: move drbg " Gilad Ben-Yossef
                       ` (27 subsequent siblings)
      40 siblings, 0 replies; 58+ messages in thread
    From: Gilad Ben-Yossef @ 2017-08-14 15:21 UTC (permalink / raw)
      To: Herbert Xu, David S. Miller, Jonathan Corbet, David Howells,
    	Tom Lendacky, Gary Hook, Boris Brezillon, Arnaud Ebalard,
    	Matthias Brugger, Alasdair Kergon, Mike Snitzer, dm-devel,
    	Shaohua Li, Steve French, Theodore Y. Ts'o, Jaegeuk Kim,
    	Mimi Zohar, Dmitry Kasatkin, James Morris, Serge E. Hallyn,
    	linux-crypto, linux-doc, linux-kernel, keyrings, linux-arm-kernel
      Cc: Ofir Drang
    
    public_key_verify_signature() is starting an async crypto op and
    waiting for it to complete. Move it over to generic code doing
    the same.
    
    Signed-off-by: Gilad Ben-Yossef <gilad@benyossef.com>
    ---
     crypto/asymmetric_keys/public_key.c | 28 ++++------------------------
     1 file changed, 4 insertions(+), 24 deletions(-)
    
    diff --git a/crypto/asymmetric_keys/public_key.c b/crypto/asymmetric_keys/public_key.c
    index 3cd6e12..d916235 100644
    --- a/crypto/asymmetric_keys/public_key.c
    +++ b/crypto/asymmetric_keys/public_key.c
    @@ -57,29 +57,13 @@ static void public_key_destroy(void *payload0, void *payload3)
     	public_key_signature_free(payload3);
     }
     
    -struct public_key_completion {
    -	struct completion completion;
    -	int err;
    -};
    -
    -static void public_key_verify_done(struct crypto_async_request *req, int err)
    -{
    -	struct public_key_completion *compl = req->data;
    -
    -	if (err == -EINPROGRESS)
    -		return;
    -
    -	compl->err = err;
    -	complete(&compl->completion);
    -}
    -
     /*
      * Verify a signature using a public key.
      */
     int public_key_verify_signature(const struct public_key *pkey,
     				const struct public_key_signature *sig)
     {
    -	struct public_key_completion compl;
    +	struct crypto_wait cwait;
     	struct crypto_akcipher *tfm;
     	struct akcipher_request *req;
     	struct scatterlist sig_sg, digest_sg;
    @@ -131,20 +115,16 @@ int public_key_verify_signature(const struct public_key *pkey,
     	sg_init_one(&digest_sg, output, outlen);
     	akcipher_request_set_crypt(req, &sig_sg, &digest_sg, sig->s_size,
     				   outlen);
    -	init_completion(&compl.completion);
    +	crypto_init_wait(&cwait);
     	akcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG |
     				      CRYPTO_TFM_REQ_MAY_SLEEP,
    -				      public_key_verify_done, &compl);
    +				      crypto_req_done, &cwait);
     
     	/* Perform the verification calculation.  This doesn't actually do the
     	 * verification, but rather calculates the hash expected by the
     	 * signature and returns that to us.
     	 */
    -	ret = crypto_akcipher_verify(req);
    -	if ((ret == -EINPROGRESS) || (ret == -EBUSY)) {
    -		wait_for_completion(&compl.completion);
    -		ret = compl.err;
    -	}
    +	ret = crypto_wait_req(crypto_akcipher_verify(req), &cwait);
     	if (ret < 0)
     		goto out_free_output;
     
    -- 
    2.1.4
    
    ^ permalink raw reply related	[flat|nested] 58+ messages in thread
  • * [PATCH v5 08/19] crypto: move drbg to generic async completion
           [not found] <1502724094-23305-1-git-send-email-gilad@benyossef.com>
                       ` (12 preceding siblings ...)
      2017-08-14 15:21 ` [PATCH v5 07/19] crypto: move pub key " Gilad Ben-Yossef
    @ 2017-08-14 15:21 ` Gilad Ben-Yossef
      2017-08-14 15:21 ` Gilad Ben-Yossef
                       ` (26 subsequent siblings)
      40 siblings, 0 replies; 58+ messages in thread
    From: Gilad Ben-Yossef @ 2017-08-14 15:21 UTC (permalink / raw)
      To: Herbert Xu, David S. Miller, Jonathan Corbet, David Howells,
    	Tom Lendacky, Gary Hook, Boris Brezillon, Arnaud Ebalard,
    	Matthias Brugger, Alasdair Kergon, Mike Snitzer, dm-devel,
    	Shaohua Li, Steve French, Theodore Y. Ts'o, Jaegeuk Kim,
    	Mimi Zohar, Dmitry Kasatkin, James Morris, Serge E. Hallyn,
    	linux-crypto, linux-doc, linux-kernel, keyrings, linux-arm-kernel
      Cc: Ofir Drang
    
    DRBG is starting an async. crypto op and waiting for it complete.
    Move it over to generic code doing the same.
    
    The code now also passes CRYPTO_TFM_REQ_MAY_SLEEP flag indicating
    crypto request memory allocation may use GFP_KERNEL which should
    be perfectly fine as the code is obviously sleeping for the
    completion of the request any way.
    
    Signed-off-by: Gilad Ben-Yossef <gilad@benyossef.com>
    ---
     crypto/drbg.c         | 36 +++++++++---------------------------
     include/crypto/drbg.h |  3 +--
     2 files changed, 10 insertions(+), 29 deletions(-)
    
    diff --git a/crypto/drbg.c b/crypto/drbg.c
    index 633a88e..c522251 100644
    --- a/crypto/drbg.c
    +++ b/crypto/drbg.c
    @@ -1651,16 +1651,6 @@ static int drbg_fini_sym_kernel(struct drbg_state *drbg)
     	return 0;
     }
     
    -static void drbg_skcipher_cb(struct crypto_async_request *req, int error)
    -{
    -	struct drbg_state *drbg = req->data;
    -
    -	if (error == -EINPROGRESS)
    -		return;
    -	drbg->ctr_async_err = error;
    -	complete(&drbg->ctr_completion);
    -}
    -
     static int drbg_init_sym_kernel(struct drbg_state *drbg)
     {
     	struct crypto_cipher *tfm;
    @@ -1691,7 +1681,7 @@ static int drbg_init_sym_kernel(struct drbg_state *drbg)
     		return PTR_ERR(sk_tfm);
     	}
     	drbg->ctr_handle = sk_tfm;
    -	init_completion(&drbg->ctr_completion);
    +	crypto_init_wait(&drbg->ctr_wait);
     
     	req = skcipher_request_alloc(sk_tfm, GFP_KERNEL);
     	if (!req) {
    @@ -1700,8 +1690,9 @@ static int drbg_init_sym_kernel(struct drbg_state *drbg)
     		return -ENOMEM;
     	}
     	drbg->ctr_req = req;
    -	skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
    -					drbg_skcipher_cb, drbg);
    +	skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG |
    +						CRYPTO_TFM_REQ_MAY_SLEEP,
    +					crypto_req_done, &drbg->ctr_wait);
     
     	alignmask = crypto_skcipher_alignmask(sk_tfm);
     	drbg->ctr_null_value_buf = kzalloc(DRBG_CTR_NULL_LEN + alignmask,
    @@ -1762,21 +1753,12 @@ static int drbg_kcapi_sym_ctr(struct drbg_state *drbg,
     		/* Output buffer may not be valid for SGL, use scratchpad */
     		skcipher_request_set_crypt(drbg->ctr_req, &sg_in, &sg_out,
     					   cryptlen, drbg->V);
    -		ret = crypto_skcipher_encrypt(drbg->ctr_req);
    -		switch (ret) {
    -		case 0:
    -			break;
    -		case -EINPROGRESS:
    -		case -EBUSY:
    -			wait_for_completion(&drbg->ctr_completion);
    -			if (!drbg->ctr_async_err) {
    -				reinit_completion(&drbg->ctr_completion);
    -				break;
    -			}
    -		default:
    +		ret = crypto_wait_req(crypto_skcipher_encrypt(drbg->ctr_req),
    +					&drbg->ctr_wait);
    +		if (ret)
     			goto out;
    -		}
    -		init_completion(&drbg->ctr_completion);
    +
    +		crypto_init_wait(&drbg->ctr_wait);
     
     		memcpy(outbuf, drbg->outscratchpad, cryptlen);
     
    diff --git a/include/crypto/drbg.h b/include/crypto/drbg.h
    index 22f884c..8f94110 100644
    --- a/include/crypto/drbg.h
    +++ b/include/crypto/drbg.h
    @@ -126,8 +126,7 @@ struct drbg_state {
     	__u8 *ctr_null_value;			/* CTR mode aligned zero buf */
     	__u8 *outscratchpadbuf;			/* CTR mode output scratchpad */
             __u8 *outscratchpad;			/* CTR mode aligned outbuf */
    -	struct completion ctr_completion;	/* CTR mode async handler */
    -	int ctr_async_err;			/* CTR mode async error */
    +	struct crypto_wait ctr_wait;		/* CTR mode async wait obj */
     
     	bool seeded;		/* DRBG fully seeded? */
     	bool pr;		/* Prediction resistance enabled? */
    -- 
    2.1.4
    
    ^ permalink raw reply related	[flat|nested] 58+ messages in thread
  • * [PATCH v5 08/19] crypto: move drbg to generic async completion
           [not found] <1502724094-23305-1-git-send-email-gilad@benyossef.com>
                       ` (13 preceding siblings ...)
      2017-08-14 15:21 ` [PATCH v5 08/19] crypto: move drbg " Gilad Ben-Yossef
    @ 2017-08-14 15:21 ` Gilad Ben-Yossef
      2017-08-14 15:21 ` [PATCH v5 09/19] crypto: move gcm " Gilad Ben-Yossef
                       ` (25 subsequent siblings)
      40 siblings, 0 replies; 58+ messages in thread
    From: Gilad Ben-Yossef @ 2017-08-14 15:21 UTC (permalink / raw)
      To: Herbert Xu, David S. Miller, Jonathan Corbet, David Howells,
    	Tom Lendacky, Gary Hook, Boris Brezillon, Arnaud Ebalard,
    	Matthias Brugger, Alasdair Kergon, Mike Snitzer, dm-devel,
    	Shaohua Li, Steve French, Theodore Y. Ts'o, Jaegeuk Kim,
    	Mimi Zohar, Dmitry Kasatkin, James Morris, Serge E. Hallyn,
    	linux-crypto
      Cc: Ofir Drang
    
    DRBG is starting an async. crypto op and waiting for it complete.
    Move it over to generic code doing the same.
    
    The code now also passes CRYPTO_TFM_REQ_MAY_SLEEP flag indicating
    crypto request memory allocation may use GFP_KERNEL which should
    be perfectly fine as the code is obviously sleeping for the
    completion of the request any way.
    
    Signed-off-by: Gilad Ben-Yossef <gilad@benyossef.com>
    ---
     crypto/drbg.c         | 36 +++++++++---------------------------
     include/crypto/drbg.h |  3 +--
     2 files changed, 10 insertions(+), 29 deletions(-)
    
    diff --git a/crypto/drbg.c b/crypto/drbg.c
    index 633a88e..c522251 100644
    --- a/crypto/drbg.c
    +++ b/crypto/drbg.c
    @@ -1651,16 +1651,6 @@ static int drbg_fini_sym_kernel(struct drbg_state *drbg)
     	return 0;
     }
     
    -static void drbg_skcipher_cb(struct crypto_async_request *req, int error)
    -{
    -	struct drbg_state *drbg = req->data;
    -
    -	if (error == -EINPROGRESS)
    -		return;
    -	drbg->ctr_async_err = error;
    -	complete(&drbg->ctr_completion);
    -}
    -
     static int drbg_init_sym_kernel(struct drbg_state *drbg)
     {
     	struct crypto_cipher *tfm;
    @@ -1691,7 +1681,7 @@ static int drbg_init_sym_kernel(struct drbg_state *drbg)
     		return PTR_ERR(sk_tfm);
     	}
     	drbg->ctr_handle = sk_tfm;
    -	init_completion(&drbg->ctr_completion);
    +	crypto_init_wait(&drbg->ctr_wait);
     
     	req = skcipher_request_alloc(sk_tfm, GFP_KERNEL);
     	if (!req) {
    @@ -1700,8 +1690,9 @@ static int drbg_init_sym_kernel(struct drbg_state *drbg)
     		return -ENOMEM;
     	}
     	drbg->ctr_req = req;
    -	skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
    -					drbg_skcipher_cb, drbg);
    +	skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG |
    +						CRYPTO_TFM_REQ_MAY_SLEEP,
    +					crypto_req_done, &drbg->ctr_wait);
     
     	alignmask = crypto_skcipher_alignmask(sk_tfm);
     	drbg->ctr_null_value_buf = kzalloc(DRBG_CTR_NULL_LEN + alignmask,
    @@ -1762,21 +1753,12 @@ static int drbg_kcapi_sym_ctr(struct drbg_state *drbg,
     		/* Output buffer may not be valid for SGL, use scratchpad */
     		skcipher_request_set_crypt(drbg->ctr_req, &sg_in, &sg_out,
     					   cryptlen, drbg->V);
    -		ret = crypto_skcipher_encrypt(drbg->ctr_req);
    -		switch (ret) {
    -		case 0:
    -			break;
    -		case -EINPROGRESS:
    -		case -EBUSY:
    -			wait_for_completion(&drbg->ctr_completion);
    -			if (!drbg->ctr_async_err) {
    -				reinit_completion(&drbg->ctr_completion);
    -				break;
    -			}
    -		default:
    +		ret = crypto_wait_req(crypto_skcipher_encrypt(drbg->ctr_req),
    +					&drbg->ctr_wait);
    +		if (ret)
     			goto out;
    -		}
    -		init_completion(&drbg->ctr_completion);
    +
    +		crypto_init_wait(&drbg->ctr_wait);
     
     		memcpy(outbuf, drbg->outscratchpad, cryptlen);
     
    diff --git a/include/crypto/drbg.h b/include/crypto/drbg.h
    index 22f884c..8f94110 100644
    --- a/include/crypto/drbg.h
    +++ b/include/crypto/drbg.h
    @@ -126,8 +126,7 @@ struct drbg_state {
     	__u8 *ctr_null_value;			/* CTR mode aligned zero buf */
     	__u8 *outscratchpadbuf;			/* CTR mode output scratchpad */
             __u8 *outscratchpad;			/* CTR mode aligned outbuf */
    -	struct completion ctr_completion;	/* CTR mode async handler */
    -	int ctr_async_err;			/* CTR mode async error */
    +	struct crypto_wait ctr_wait;		/* CTR mode async wait obj */
     
     	bool seeded;		/* DRBG fully seeded? */
     	bool pr;		/* Prediction resistance enabled? */
    -- 
    2.1.4
    
    
    ^ permalink raw reply related	[flat|nested] 58+ messages in thread
  • * [PATCH v5 09/19] crypto: move gcm to generic async completion
           [not found] <1502724094-23305-1-git-send-email-gilad@benyossef.com>
                       ` (14 preceding siblings ...)
      2017-08-14 15:21 ` Gilad Ben-Yossef
    @ 2017-08-14 15:21 ` Gilad Ben-Yossef
      2017-08-14 15:21 ` Gilad Ben-Yossef
                       ` (24 subsequent siblings)
      40 siblings, 0 replies; 58+ messages in thread
    From: Gilad Ben-Yossef @ 2017-08-14 15:21 UTC (permalink / raw)
      To: Herbert Xu, David S. Miller, Jonathan Corbet, David Howells,
    	Tom Lendacky, Gary Hook, Boris Brezillon, Arnaud Ebalard,
    	Matthias Brugger, Alasdair Kergon, Mike Snitzer, dm-devel,
    	Shaohua Li, Steve French, Theodore Y. Ts'o, Jaegeuk Kim,
    	Mimi Zohar, Dmitry Kasatkin, James Morris, Serge E. Hallyn,
    	linux-crypto
      Cc: Ofir Drang
    
    gcm is starting an async. crypto op and waiting for it complete.
    Move it over to generic code doing the same.
    
    Signed-off-by: Gilad Ben-Yossef <gilad@benyossef.com>
    ---
     crypto/gcm.c | 32 ++++++--------------------------
     1 file changed, 6 insertions(+), 26 deletions(-)
    
    diff --git a/crypto/gcm.c b/crypto/gcm.c
    index 3841b5e..fb923a5 100644
    --- a/crypto/gcm.c
    +++ b/crypto/gcm.c
    @@ -16,7 +16,6 @@
     #include <crypto/scatterwalk.h>
     #include <crypto/hash.h>
     #include "internal.h"
    -#include <linux/completion.h>
     #include <linux/err.h>
     #include <linux/init.h>
     #include <linux/kernel.h>
    @@ -78,11 +77,6 @@ struct crypto_gcm_req_priv_ctx {
     	} u;
     };
     
    -struct crypto_gcm_setkey_result {
    -	int err;
    -	struct completion completion;
    -};
    -
     static struct {
     	u8 buf[16];
     	struct scatterlist sg;
    @@ -98,17 +92,6 @@ static inline struct crypto_gcm_req_priv_ctx *crypto_gcm_reqctx(
     	return (void *)PTR_ALIGN((u8 *)aead_request_ctx(req), align + 1);
     }
     
    -static void crypto_gcm_setkey_done(struct crypto_async_request *req, int err)
    -{
    -	struct crypto_gcm_setkey_result *result = req->data;
    -
    -	if (err == -EINPROGRESS)
    -		return;
    -
    -	result->err = err;
    -	complete(&result->completion);
    -}
    -
     static int crypto_gcm_setkey(struct crypto_aead *aead, const u8 *key,
     			     unsigned int keylen)
     {
    @@ -119,7 +102,7 @@ static int crypto_gcm_setkey(struct crypto_aead *aead, const u8 *key,
     		be128 hash;
     		u8 iv[16];
     
    -		struct crypto_gcm_setkey_result result;
    +		struct crypto_wait wait;
     
     		struct scatterlist sg[1];
     		struct skcipher_request req;
    @@ -140,21 +123,18 @@ static int crypto_gcm_setkey(struct crypto_aead *aead, const u8 *key,
     	if (!data)
     		return -ENOMEM;
     
    -	init_completion(&data->result.completion);
    +	crypto_init_wait(&data->wait);
     	sg_init_one(data->sg, &data->hash, sizeof(data->hash));
     	skcipher_request_set_tfm(&data->req, ctr);
     	skcipher_request_set_callback(&data->req, CRYPTO_TFM_REQ_MAY_SLEEP |
     						  CRYPTO_TFM_REQ_MAY_BACKLOG,
    -				      crypto_gcm_setkey_done,
    -				      &data->result);
    +				      crypto_req_done,
    +				      &data->wait);
     	skcipher_request_set_crypt(&data->req, data->sg, data->sg,
     				   sizeof(data->hash), data->iv);
     
    -	err = crypto_skcipher_encrypt(&data->req);
    -	if (err == -EINPROGRESS || err == -EBUSY) {
    -		wait_for_completion(&data->result.completion);
    -		err = data->result.err;
    -	}
    +	err = crypto_wait_req(crypto_skcipher_encrypt(&data->req),
    +							&data->wait);
     
     	if (err)
     		goto out;
    -- 
    2.1.4
    
    
    ^ permalink raw reply related	[flat|nested] 58+ messages in thread
  • * [PATCH v5 09/19] crypto: move gcm to generic async completion
           [not found] <1502724094-23305-1-git-send-email-gilad@benyossef.com>
                       ` (15 preceding siblings ...)
      2017-08-14 15:21 ` [PATCH v5 09/19] crypto: move gcm " Gilad Ben-Yossef
    @ 2017-08-14 15:21 ` Gilad Ben-Yossef
      2017-08-14 15:21 ` [PATCH v5 10/19] crypto: move testmgr " Gilad Ben-Yossef
                       ` (23 subsequent siblings)
      40 siblings, 0 replies; 58+ messages in thread
    From: Gilad Ben-Yossef @ 2017-08-14 15:21 UTC (permalink / raw)
      To: Herbert Xu, David S. Miller, Jonathan Corbet, David Howells,
    	Tom Lendacky, Gary Hook, Boris Brezillon, Arnaud Ebalard,
    	Matthias Brugger, Alasdair Kergon, Mike Snitzer, dm-devel,
    	Shaohua Li, Steve French, Theodore Y. Ts'o, Jaegeuk Kim,
    	Mimi Zohar, Dmitry Kasatkin, James Morris, Serge E. Hallyn,
    	linux-crypto, linux-doc, linux-kernel, keyrings, linux-arm-kernel
      Cc: Ofir Drang
    
    gcm is starting an async. crypto op and waiting for it complete.
    Move it over to generic code doing the same.
    
    Signed-off-by: Gilad Ben-Yossef <gilad@benyossef.com>
    ---
     crypto/gcm.c | 32 ++++++--------------------------
     1 file changed, 6 insertions(+), 26 deletions(-)
    
    diff --git a/crypto/gcm.c b/crypto/gcm.c
    index 3841b5e..fb923a5 100644
    --- a/crypto/gcm.c
    +++ b/crypto/gcm.c
    @@ -16,7 +16,6 @@
     #include <crypto/scatterwalk.h>
     #include <crypto/hash.h>
     #include "internal.h"
    -#include <linux/completion.h>
     #include <linux/err.h>
     #include <linux/init.h>
     #include <linux/kernel.h>
    @@ -78,11 +77,6 @@ struct crypto_gcm_req_priv_ctx {
     	} u;
     };
     
    -struct crypto_gcm_setkey_result {
    -	int err;
    -	struct completion completion;
    -};
    -
     static struct {
     	u8 buf[16];
     	struct scatterlist sg;
    @@ -98,17 +92,6 @@ static inline struct crypto_gcm_req_priv_ctx *crypto_gcm_reqctx(
     	return (void *)PTR_ALIGN((u8 *)aead_request_ctx(req), align + 1);
     }
     
    -static void crypto_gcm_setkey_done(struct crypto_async_request *req, int err)
    -{
    -	struct crypto_gcm_setkey_result *result = req->data;
    -
    -	if (err == -EINPROGRESS)
    -		return;
    -
    -	result->err = err;
    -	complete(&result->completion);
    -}
    -
     static int crypto_gcm_setkey(struct crypto_aead *aead, const u8 *key,
     			     unsigned int keylen)
     {
    @@ -119,7 +102,7 @@ static int crypto_gcm_setkey(struct crypto_aead *aead, const u8 *key,
     		be128 hash;
     		u8 iv[16];
     
    -		struct crypto_gcm_setkey_result result;
    +		struct crypto_wait wait;
     
     		struct scatterlist sg[1];
     		struct skcipher_request req;
    @@ -140,21 +123,18 @@ static int crypto_gcm_setkey(struct crypto_aead *aead, const u8 *key,
     	if (!data)
     		return -ENOMEM;
     
    -	init_completion(&data->result.completion);
    +	crypto_init_wait(&data->wait);
     	sg_init_one(data->sg, &data->hash, sizeof(data->hash));
     	skcipher_request_set_tfm(&data->req, ctr);
     	skcipher_request_set_callback(&data->req, CRYPTO_TFM_REQ_MAY_SLEEP |
     						  CRYPTO_TFM_REQ_MAY_BACKLOG,
    -				      crypto_gcm_setkey_done,
    -				      &data->result);
    +				      crypto_req_done,
    +				      &data->wait);
     	skcipher_request_set_crypt(&data->req, data->sg, data->sg,
     				   sizeof(data->hash), data->iv);
     
    -	err = crypto_skcipher_encrypt(&data->req);
    -	if (err == -EINPROGRESS || err == -EBUSY) {
    -		wait_for_completion(&data->result.completion);
    -		err = data->result.err;
    -	}
    +	err = crypto_wait_req(crypto_skcipher_encrypt(&data->req),
    +							&data->wait);
     
     	if (err)
     		goto out;
    -- 
    2.1.4
    
    ^ permalink raw reply related	[flat|nested] 58+ messages in thread
  • * [PATCH v5 10/19] crypto: move testmgr to generic async completion
           [not found] <1502724094-23305-1-git-send-email-gilad@benyossef.com>
                       ` (16 preceding siblings ...)
      2017-08-14 15:21 ` Gilad Ben-Yossef
    @ 2017-08-14 15:21 ` Gilad Ben-Yossef
      2017-08-14 15:21 ` Gilad Ben-Yossef
                       ` (22 subsequent siblings)
      40 siblings, 0 replies; 58+ messages in thread
    From: Gilad Ben-Yossef @ 2017-08-14 15:21 UTC (permalink / raw)
      To: Herbert Xu, David S. Miller, Jonathan Corbet, David Howells,
    	Tom Lendacky, Gary Hook, Boris Brezillon, Arnaud Ebalard,
    	Matthias Brugger, Alasdair Kergon, Mike Snitzer, dm-devel,
    	Shaohua Li, Steve French, Theodore Y. Ts'o, Jaegeuk Kim,
    	Mimi Zohar, Dmitry Kasatkin, James Morris, Serge E. Hallyn,
    	linux-crypto
      Cc: Ofir Drang
    
    testmgr is starting async. crypto ops and waiting for them to complete.
    Move it over to generic code doing the same.
    
    This also provides a test of the generic crypto async. wait code.
    
    Signed-off-by: Gilad Ben-Yossef <gilad@benyossef.com>
    ---
     crypto/testmgr.c | 204 ++++++++++++++++++-------------------------------------
     1 file changed, 66 insertions(+), 138 deletions(-)
    
    diff --git a/crypto/testmgr.c b/crypto/testmgr.c
    index 7125ba3..a65b4d5 100644
    --- a/crypto/testmgr.c
    +++ b/crypto/testmgr.c
    @@ -76,11 +76,6 @@ int alg_test(const char *driver, const char *alg, u32 type, u32 mask)
     #define ENCRYPT 1
     #define DECRYPT 0
     
    -struct tcrypt_result {
    -	struct completion completion;
    -	int err;
    -};
    -
     struct aead_test_suite {
     	struct {
     		const struct aead_testvec *vecs;
    @@ -155,17 +150,6 @@ static void hexdump(unsigned char *buf, unsigned int len)
     			buf, len, false);
     }
     
    -static void tcrypt_complete(struct crypto_async_request *req, int err)
    -{
    -	struct tcrypt_result *res = req->data;
    -
    -	if (err == -EINPROGRESS)
    -		return;
    -
    -	res->err = err;
    -	complete(&res->completion);
    -}
    -
     static int testmgr_alloc_buf(char *buf[XBUFSIZE])
     {
     	int i;
    @@ -193,20 +177,10 @@ static void testmgr_free_buf(char *buf[XBUFSIZE])
     		free_page((unsigned long)buf[i]);
     }
     
    -static int wait_async_op(struct tcrypt_result *tr, int ret)
    -{
    -	if (ret == -EINPROGRESS || ret == -EBUSY) {
    -		wait_for_completion(&tr->completion);
    -		reinit_completion(&tr->completion);
    -		ret = tr->err;
    -	}
    -	return ret;
    -}
    -
     static int ahash_partial_update(struct ahash_request **preq,
     	struct crypto_ahash *tfm, const struct hash_testvec *template,
     	void *hash_buff, int k, int temp, struct scatterlist *sg,
    -	const char *algo, char *result, struct tcrypt_result *tresult)
    +	const char *algo, char *result, struct crypto_wait *wait)
     {
     	char *state;
     	struct ahash_request *req;
    @@ -236,7 +210,7 @@ static int ahash_partial_update(struct ahash_request **preq,
     	}
     	ahash_request_set_callback(req,
     		CRYPTO_TFM_REQ_MAY_BACKLOG,
    -		tcrypt_complete, tresult);
    +		crypto_req_done, wait);
     
     	memcpy(hash_buff, template->plaintext + temp,
     		template->tap[k]);
    @@ -247,7 +221,7 @@ static int ahash_partial_update(struct ahash_request **preq,
     		pr_err("alg: hash: Failed to import() for %s\n", algo);
     		goto out;
     	}
    -	ret = wait_async_op(tresult, crypto_ahash_update(req));
    +	ret = crypto_wait_req(crypto_ahash_update(req), wait);
     	if (ret)
     		goto out;
     	*preq = req;
    @@ -272,7 +246,7 @@ static int __test_hash(struct crypto_ahash *tfm,
     	char *result;
     	char *key;
     	struct ahash_request *req;
    -	struct tcrypt_result tresult;
    +	struct crypto_wait wait;
     	void *hash_buff;
     	char *xbuf[XBUFSIZE];
     	int ret = -ENOMEM;
    @@ -286,7 +260,7 @@ static int __test_hash(struct crypto_ahash *tfm,
     	if (testmgr_alloc_buf(xbuf))
     		goto out_nobuf;
     
    -	init_completion(&tresult.completion);
    +	crypto_init_wait(&wait);
     
     	req = ahash_request_alloc(tfm, GFP_KERNEL);
     	if (!req) {
    @@ -295,7 +269,7 @@ static int __test_hash(struct crypto_ahash *tfm,
     		goto out_noreq;
     	}
     	ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
    -				   tcrypt_complete, &tresult);
    +				   crypto_req_done, &wait);
     
     	j = 0;
     	for (i = 0; i < tcount; i++) {
    @@ -335,26 +309,26 @@ static int __test_hash(struct crypto_ahash *tfm,
     
     		ahash_request_set_crypt(req, sg, result, template[i].psize);
     		if (use_digest) {
    -			ret = wait_async_op(&tresult, crypto_ahash_digest(req));
    +			ret = crypto_wait_req(crypto_ahash_digest(req), &wait);
     			if (ret) {
     				pr_err("alg: hash: digest failed on test %d "
     				       "for %s: ret=%d\n", j, algo, -ret);
     				goto out;
     			}
     		} else {
    -			ret = wait_async_op(&tresult, crypto_ahash_init(req));
    +			ret = crypto_wait_req(crypto_ahash_init(req), &wait);
     			if (ret) {
     				pr_err("alg: hash: init failed on test %d "
     				       "for %s: ret=%d\n", j, algo, -ret);
     				goto out;
     			}
    -			ret = wait_async_op(&tresult, crypto_ahash_update(req));
    +			ret = crypto_wait_req(crypto_ahash_update(req), &wait);
     			if (ret) {
     				pr_err("alg: hash: update failed on test %d "
     				       "for %s: ret=%d\n", j, algo, -ret);
     				goto out;
     			}
    -			ret = wait_async_op(&tresult, crypto_ahash_final(req));
    +			ret = crypto_wait_req(crypto_ahash_final(req), &wait);
     			if (ret) {
     				pr_err("alg: hash: final failed on test %d "
     				       "for %s: ret=%d\n", j, algo, -ret);
    @@ -420,22 +394,10 @@ static int __test_hash(struct crypto_ahash *tfm,
     		}
     
     		ahash_request_set_crypt(req, sg, result, template[i].psize);
    -		ret = crypto_ahash_digest(req);
    -		switch (ret) {
    -		case 0:
    -			break;
    -		case -EINPROGRESS:
    -		case -EBUSY:
    -			wait_for_completion(&tresult.completion);
    -			reinit_completion(&tresult.completion);
    -			ret = tresult.err;
    -			if (!ret)
    -				break;
    -			/* fall through */
    -		default:
    -			printk(KERN_ERR "alg: hash: digest failed "
    -			       "on chunking test %d for %s: "
    -			       "ret=%d\n", j, algo, -ret);
    +		ret = crypto_wait_req(crypto_ahash_digest(req), &wait);
    +		if (ret) {
    +			pr_err("alg: hash: digest failed on chunking test %d for %s: ret=%d\n",
    +			       j, algo, -ret);
     			goto out;
     		}
     
    @@ -486,13 +448,13 @@ static int __test_hash(struct crypto_ahash *tfm,
     		}
     
     		ahash_request_set_crypt(req, sg, result, template[i].tap[0]);
    -		ret = wait_async_op(&tresult, crypto_ahash_init(req));
    +		ret = crypto_wait_req(crypto_ahash_init(req), &wait);
     		if (ret) {
     			pr_err("alg: hash: init failed on test %d for %s: ret=%d\n",
     				j, algo, -ret);
     			goto out;
     		}
    -		ret = wait_async_op(&tresult, crypto_ahash_update(req));
    +		ret = crypto_wait_req(crypto_ahash_update(req), &wait);
     		if (ret) {
     			pr_err("alg: hash: update failed on test %d for %s: ret=%d\n",
     				j, algo, -ret);
    @@ -503,7 +465,7 @@ static int __test_hash(struct crypto_ahash *tfm,
     		for (k = 1; k < template[i].np; k++) {
     			ret = ahash_partial_update(&req, tfm, &template[i],
     				hash_buff, k, temp, &sg[0], algo, result,
    -				&tresult);
    +				&wait);
     			if (ret) {
     				pr_err("alg: hash: partial update failed on test %d for %s: ret=%d\n",
     					j, algo, -ret);
    @@ -511,7 +473,7 @@ static int __test_hash(struct crypto_ahash *tfm,
     			}
     			temp += template[i].tap[k];
     		}
    -		ret = wait_async_op(&tresult, crypto_ahash_final(req));
    +		ret = crypto_wait_req(crypto_ahash_final(req), &wait);
     		if (ret) {
     			pr_err("alg: hash: final failed on test %d for %s: ret=%d\n",
     				j, algo, -ret);
    @@ -580,7 +542,7 @@ static int __test_aead(struct crypto_aead *tfm, int enc,
     	struct scatterlist *sg;
     	struct scatterlist *sgout;
     	const char *e, *d;
    -	struct tcrypt_result result;
    +	struct crypto_wait wait;
     	unsigned int authsize, iv_len;
     	void *input;
     	void *output;
    @@ -619,7 +581,7 @@ static int __test_aead(struct crypto_aead *tfm, int enc,
     	else
     		e = "decryption";
     
    -	init_completion(&result.completion);
    +	crypto_init_wait(&wait);
     
     	req = aead_request_alloc(tfm, GFP_KERNEL);
     	if (!req) {
    @@ -629,7 +591,7 @@ static int __test_aead(struct crypto_aead *tfm, int enc,
     	}
     
     	aead_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
    -				  tcrypt_complete, &result);
    +				  crypto_req_done, &wait);
     
     	iv_len = crypto_aead_ivsize(tfm);
     
    @@ -709,7 +671,8 @@ static int __test_aead(struct crypto_aead *tfm, int enc,
     
     		aead_request_set_ad(req, template[i].alen);
     
    -		ret = enc ? crypto_aead_encrypt(req) : crypto_aead_decrypt(req);
    +		ret = crypto_wait_req(enc ? crypto_aead_encrypt(req)
    +				      : crypto_aead_decrypt(req), &wait);
     
     		switch (ret) {
     		case 0:
    @@ -722,13 +685,6 @@ static int __test_aead(struct crypto_aead *tfm, int enc,
     				goto out;
     			}
     			break;
    -		case -EINPROGRESS:
    -		case -EBUSY:
    -			wait_for_completion(&result.completion);
    -			reinit_completion(&result.completion);
    -			ret = result.err;
    -			if (!ret)
    -				break;
     		case -EBADMSG:
     			if (template[i].novrfy)
     				/* verification failure was expected */
    @@ -866,7 +822,8 @@ static int __test_aead(struct crypto_aead *tfm, int enc,
     
     		aead_request_set_ad(req, template[i].alen);
     
    -		ret = enc ? crypto_aead_encrypt(req) : crypto_aead_decrypt(req);
    +		ret = crypto_wait_req(enc ? crypto_aead_encrypt(req)
    +				      : crypto_aead_decrypt(req), &wait);
     
     		switch (ret) {
     		case 0:
    @@ -879,13 +836,6 @@ static int __test_aead(struct crypto_aead *tfm, int enc,
     				goto out;
     			}
     			break;
    -		case -EINPROGRESS:
    -		case -EBUSY:
    -			wait_for_completion(&result.completion);
    -			reinit_completion(&result.completion);
    -			ret = result.err;
    -			if (!ret)
    -				break;
     		case -EBADMSG:
     			if (template[i].novrfy)
     				/* verification failure was expected */
    @@ -1083,7 +1033,7 @@ static int __test_skcipher(struct crypto_skcipher *tfm, int enc,
     	struct scatterlist sg[8];
     	struct scatterlist sgout[8];
     	const char *e, *d;
    -	struct tcrypt_result result;
    +	struct crypto_wait wait;
     	void *data;
     	char iv[MAX_IVLEN];
     	char *xbuf[XBUFSIZE];
    @@ -1107,7 +1057,7 @@ static int __test_skcipher(struct crypto_skcipher *tfm, int enc,
     	else
     		e = "decryption";
     
    -	init_completion(&result.completion);
    +	crypto_init_wait(&wait);
     
     	req = skcipher_request_alloc(tfm, GFP_KERNEL);
     	if (!req) {
    @@ -1117,7 +1067,7 @@ static int __test_skcipher(struct crypto_skcipher *tfm, int enc,
     	}
     
     	skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
    -				      tcrypt_complete, &result);
    +				      crypto_req_done, &wait);
     
     	j = 0;
     	for (i = 0; i < tcount; i++) {
    @@ -1164,21 +1114,10 @@ static int __test_skcipher(struct crypto_skcipher *tfm, int enc,
     
     		skcipher_request_set_crypt(req, sg, (diff_dst) ? sgout : sg,
     					   template[i].ilen, iv);
    -		ret = enc ? crypto_skcipher_encrypt(req) :
    -			    crypto_skcipher_decrypt(req);
    +		ret = crypto_wait_req(enc ? crypto_skcipher_encrypt(req) :
    +				      crypto_skcipher_decrypt(req), &wait);
     
    -		switch (ret) {
    -		case 0:
    -			break;
    -		case -EINPROGRESS:
    -		case -EBUSY:
    -			wait_for_completion(&result.completion);
    -			reinit_completion(&result.completion);
    -			ret = result.err;
    -			if (!ret)
    -				break;
    -			/* fall through */
    -		default:
    +		if (ret) {
     			pr_err("alg: skcipher%s: %s failed on test %d for %s: ret=%d\n",
     			       d, e, j, algo, -ret);
     			goto out;
    @@ -1272,21 +1211,10 @@ static int __test_skcipher(struct crypto_skcipher *tfm, int enc,
     		skcipher_request_set_crypt(req, sg, (diff_dst) ? sgout : sg,
     					   template[i].ilen, iv);
     
    -		ret = enc ? crypto_skcipher_encrypt(req) :
    -			    crypto_skcipher_decrypt(req);
    +		ret = crypto_wait_req(enc ? crypto_skcipher_encrypt(req) :
    +				      crypto_skcipher_decrypt(req), &wait);
     
    -		switch (ret) {
    -		case 0:
    -			break;
    -		case -EINPROGRESS:
    -		case -EBUSY:
    -			wait_for_completion(&result.completion);
    -			reinit_completion(&result.completion);
    -			ret = result.err;
    -			if (!ret)
    -				break;
    -			/* fall through */
    -		default:
    +		if (ret) {
     			pr_err("alg: skcipher%s: %s failed on chunk test %d for %s: ret=%d\n",
     			       d, e, j, algo, -ret);
     			goto out;
    @@ -1462,7 +1390,7 @@ static int test_acomp(struct crypto_acomp *tfm,
     	int ret;
     	struct scatterlist src, dst;
     	struct acomp_req *req;
    -	struct tcrypt_result result;
    +	struct crypto_wait wait;
     
     	output = kmalloc(COMP_BUF_SIZE, GFP_KERNEL);
     	if (!output)
    @@ -1486,7 +1414,7 @@ static int test_acomp(struct crypto_acomp *tfm,
     		}
     
     		memset(output, 0, dlen);
    -		init_completion(&result.completion);
    +		crypto_init_wait(&wait);
     		sg_init_one(&src, input_vec, ilen);
     		sg_init_one(&dst, output, dlen);
     
    @@ -1501,9 +1429,9 @@ static int test_acomp(struct crypto_acomp *tfm,
     
     		acomp_request_set_params(req, &src, &dst, ilen, dlen);
     		acomp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
    -					   tcrypt_complete, &result);
    +					   crypto_req_done, &wait);
     
    -		ret = wait_async_op(&result, crypto_acomp_compress(req));
    +		ret = crypto_wait_req(crypto_acomp_compress(req), &wait);
     		if (ret) {
     			pr_err("alg: acomp: compression failed on test %d for %s: ret=%d\n",
     			       i + 1, algo, -ret);
    @@ -1516,10 +1444,10 @@ static int test_acomp(struct crypto_acomp *tfm,
     		dlen = COMP_BUF_SIZE;
     		sg_init_one(&src, output, ilen);
     		sg_init_one(&dst, decomp_out, dlen);
    -		init_completion(&result.completion);
    +		crypto_init_wait(&wait);
     		acomp_request_set_params(req, &src, &dst, ilen, dlen);
     
    -		ret = wait_async_op(&result, crypto_acomp_decompress(req));
    +		ret = crypto_wait_req(crypto_acomp_decompress(req), &wait);
     		if (ret) {
     			pr_err("alg: acomp: compression failed on test %d for %s: ret=%d\n",
     			       i + 1, algo, -ret);
    @@ -1563,7 +1491,7 @@ static int test_acomp(struct crypto_acomp *tfm,
     		}
     
     		memset(output, 0, dlen);
    -		init_completion(&result.completion);
    +		crypto_init_wait(&wait);
     		sg_init_one(&src, input_vec, ilen);
     		sg_init_one(&dst, output, dlen);
     
    @@ -1578,9 +1506,9 @@ static int test_acomp(struct crypto_acomp *tfm,
     
     		acomp_request_set_params(req, &src, &dst, ilen, dlen);
     		acomp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
    -					   tcrypt_complete, &result);
    +					   crypto_req_done, &wait);
     
    -		ret = wait_async_op(&result, crypto_acomp_decompress(req));
    +		ret = crypto_wait_req(crypto_acomp_decompress(req), &wait);
     		if (ret) {
     			pr_err("alg: acomp: decompression failed on test %d for %s: ret=%d\n",
     			       i + 1, algo, -ret);
    @@ -2000,7 +1928,7 @@ static int do_test_kpp(struct crypto_kpp *tfm, const struct kpp_testvec *vec,
     	void *a_public = NULL;
     	void *a_ss = NULL;
     	void *shared_secret = NULL;
    -	struct tcrypt_result result;
    +	struct crypto_wait wait;
     	unsigned int out_len_max;
     	int err = -ENOMEM;
     	struct scatterlist src, dst;
    @@ -2009,7 +1937,7 @@ static int do_test_kpp(struct crypto_kpp *tfm, const struct kpp_testvec *vec,
     	if (!req)
     		return err;
     
    -	init_completion(&result.completion);
    +	crypto_init_wait(&wait);
     
     	err = crypto_kpp_set_secret(tfm, vec->secret, vec->secret_size);
     	if (err < 0)
    @@ -2027,10 +1955,10 @@ static int do_test_kpp(struct crypto_kpp *tfm, const struct kpp_testvec *vec,
     	sg_init_one(&dst, output_buf, out_len_max);
     	kpp_request_set_output(req, &dst, out_len_max);
     	kpp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
    -				 tcrypt_complete, &result);
    +				 crypto_req_done, &wait);
     
     	/* Compute party A's public key */
    -	err = wait_async_op(&result, crypto_kpp_generate_public_key(req));
    +	err = crypto_wait_req(crypto_kpp_generate_public_key(req), &wait);
     	if (err) {
     		pr_err("alg: %s: Party A: generate public key test failed. err %d\n",
     		       alg, err);
    @@ -2069,8 +1997,8 @@ static int do_test_kpp(struct crypto_kpp *tfm, const struct kpp_testvec *vec,
     	kpp_request_set_input(req, &src, vec->b_public_size);
     	kpp_request_set_output(req, &dst, out_len_max);
     	kpp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
    -				 tcrypt_complete, &result);
    -	err = wait_async_op(&result, crypto_kpp_compute_shared_secret(req));
    +				 crypto_req_done, &wait);
    +	err = crypto_wait_req(crypto_kpp_compute_shared_secret(req), &wait);
     	if (err) {
     		pr_err("alg: %s: Party A: compute shared secret test failed. err %d\n",
     		       alg, err);
    @@ -2100,9 +2028,9 @@ static int do_test_kpp(struct crypto_kpp *tfm, const struct kpp_testvec *vec,
     		kpp_request_set_input(req, &src, vec->expected_a_public_size);
     		kpp_request_set_output(req, &dst, out_len_max);
     		kpp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
    -					 tcrypt_complete, &result);
    -		err = wait_async_op(&result,
    -				    crypto_kpp_compute_shared_secret(req));
    +					 crypto_req_done, &wait);
    +		err = crypto_wait_req(crypto_kpp_compute_shared_secret(req),
    +				      &wait);
     		if (err) {
     			pr_err("alg: %s: Party B: compute shared secret failed. err %d\n",
     			       alg, err);
    @@ -2179,7 +2107,7 @@ static int test_akcipher_one(struct crypto_akcipher *tfm,
     	struct akcipher_request *req;
     	void *outbuf_enc = NULL;
     	void *outbuf_dec = NULL;
    -	struct tcrypt_result result;
    +	struct crypto_wait wait;
     	unsigned int out_len_max, out_len = 0;
     	int err = -ENOMEM;
     	struct scatterlist src, dst, src_tab[2];
    @@ -2191,7 +2119,7 @@ static int test_akcipher_one(struct crypto_akcipher *tfm,
     	if (!req)
     		goto free_xbuf;
     
    -	init_completion(&result.completion);
    +	crypto_init_wait(&wait);
     
     	if (vecs->public_key_vec)
     		err = crypto_akcipher_set_pub_key(tfm, vecs->key,
    @@ -2220,13 +2148,13 @@ static int test_akcipher_one(struct crypto_akcipher *tfm,
     	akcipher_request_set_crypt(req, src_tab, &dst, vecs->m_size,
     				   out_len_max);
     	akcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
    -				      tcrypt_complete, &result);
    +				      crypto_req_done, &wait);
     
    -	err = wait_async_op(&result, vecs->siggen_sigver_test ?
    -				     /* Run asymmetric signature generation */
    -				     crypto_akcipher_sign(req) :
    -				     /* Run asymmetric encrypt */
    -				     crypto_akcipher_encrypt(req));
    +	err = crypto_wait_req(vecs->siggen_sigver_test ?
    +			      /* Run asymmetric signature generation */
    +			      crypto_akcipher_sign(req) :
    +			      /* Run asymmetric encrypt */
    +			      crypto_akcipher_encrypt(req), &wait);
     	if (err) {
     		pr_err("alg: akcipher: encrypt test failed. err %d\n", err);
     		goto free_all;
    @@ -2261,14 +2189,14 @@ static int test_akcipher_one(struct crypto_akcipher *tfm,
     
     	sg_init_one(&src, xbuf[0], vecs->c_size);
     	sg_init_one(&dst, outbuf_dec, out_len_max);
    -	init_completion(&result.completion);
    +	crypto_init_wait(&wait);
     	akcipher_request_set_crypt(req, &src, &dst, vecs->c_size, out_len_max);
     
    -	err = wait_async_op(&result, vecs->siggen_sigver_test ?
    -				     /* Run asymmetric signature verification */
    -				     crypto_akcipher_verify(req) :
    -				     /* Run asymmetric decrypt */
    -				     crypto_akcipher_decrypt(req));
    +	err = crypto_wait_req(vecs->siggen_sigver_test ?
    +			      /* Run asymmetric signature verification */
    +			      crypto_akcipher_verify(req) :
    +			      /* Run asymmetric decrypt */
    +			      crypto_akcipher_decrypt(req), &wait);
     	if (err) {
     		pr_err("alg: akcipher: decrypt test failed. err %d\n", err);
     		goto free_all;
    -- 
    2.1.4
    
    
    ^ permalink raw reply related	[flat|nested] 58+ messages in thread
  • * [PATCH v5 10/19] crypto: move testmgr to generic async completion
           [not found] <1502724094-23305-1-git-send-email-gilad@benyossef.com>
                       ` (17 preceding siblings ...)
      2017-08-14 15:21 ` [PATCH v5 10/19] crypto: move testmgr " Gilad Ben-Yossef
    @ 2017-08-14 15:21 ` Gilad Ben-Yossef
      2017-08-14 15:21 ` [PATCH v5 11/19] fscrypt: move " Gilad Ben-Yossef
                       ` (21 subsequent siblings)
      40 siblings, 0 replies; 58+ messages in thread
    From: Gilad Ben-Yossef @ 2017-08-14 15:21 UTC (permalink / raw)
      To: Herbert Xu, David S. Miller, Jonathan Corbet, David Howells,
    	Tom Lendacky, Gary Hook, Boris Brezillon, Arnaud Ebalard,
    	Matthias Brugger, Alasdair Kergon, Mike Snitzer, dm-devel,
    	Shaohua Li, Steve French, Theodore Y. Ts'o, Jaegeuk Kim,
    	Mimi Zohar, Dmitry Kasatkin, James Morris, Serge E. Hallyn,
    	linux-crypto, linux-doc, linux-kernel, keyrings, linux-arm-kernel
      Cc: Ofir Drang
    
    testmgr is starting async. crypto ops and waiting for them to complete.
    Move it over to generic code doing the same.
    
    This also provides a test of the generic crypto async. wait code.
    
    Signed-off-by: Gilad Ben-Yossef <gilad@benyossef.com>
    ---
     crypto/testmgr.c | 204 ++++++++++++++++++-------------------------------------
     1 file changed, 66 insertions(+), 138 deletions(-)
    
    diff --git a/crypto/testmgr.c b/crypto/testmgr.c
    index 7125ba3..a65b4d5 100644
    --- a/crypto/testmgr.c
    +++ b/crypto/testmgr.c
    @@ -76,11 +76,6 @@ int alg_test(const char *driver, const char *alg, u32 type, u32 mask)
     #define ENCRYPT 1
     #define DECRYPT 0
     
    -struct tcrypt_result {
    -	struct completion completion;
    -	int err;
    -};
    -
     struct aead_test_suite {
     	struct {
     		const struct aead_testvec *vecs;
    @@ -155,17 +150,6 @@ static void hexdump(unsigned char *buf, unsigned int len)
     			buf, len, false);
     }
     
    -static void tcrypt_complete(struct crypto_async_request *req, int err)
    -{
    -	struct tcrypt_result *res = req->data;
    -
    -	if (err == -EINPROGRESS)
    -		return;
    -
    -	res->err = err;
    -	complete(&res->completion);
    -}
    -
     static int testmgr_alloc_buf(char *buf[XBUFSIZE])
     {
     	int i;
    @@ -193,20 +177,10 @@ static void testmgr_free_buf(char *buf[XBUFSIZE])
     		free_page((unsigned long)buf[i]);
     }
     
    -static int wait_async_op(struct tcrypt_result *tr, int ret)
    -{
    -	if (ret == -EINPROGRESS || ret == -EBUSY) {
    -		wait_for_completion(&tr->completion);
    -		reinit_completion(&tr->completion);
    -		ret = tr->err;
    -	}
    -	return ret;
    -}
    -
     static int ahash_partial_update(struct ahash_request **preq,
     	struct crypto_ahash *tfm, const struct hash_testvec *template,
     	void *hash_buff, int k, int temp, struct scatterlist *sg,
    -	const char *algo, char *result, struct tcrypt_result *tresult)
    +	const char *algo, char *result, struct crypto_wait *wait)
     {
     	char *state;
     	struct ahash_request *req;
    @@ -236,7 +210,7 @@ static int ahash_partial_update(struct ahash_request **preq,
     	}
     	ahash_request_set_callback(req,
     		CRYPTO_TFM_REQ_MAY_BACKLOG,
    -		tcrypt_complete, tresult);
    +		crypto_req_done, wait);
     
     	memcpy(hash_buff, template->plaintext + temp,
     		template->tap[k]);
    @@ -247,7 +221,7 @@ static int ahash_partial_update(struct ahash_request **preq,
     		pr_err("alg: hash: Failed to import() for %s\n", algo);
     		goto out;
     	}
    -	ret = wait_async_op(tresult, crypto_ahash_update(req));
    +	ret = crypto_wait_req(crypto_ahash_update(req), wait);
     	if (ret)
     		goto out;
     	*preq = req;
    @@ -272,7 +246,7 @@ static int __test_hash(struct crypto_ahash *tfm,
     	char *result;
     	char *key;
     	struct ahash_request *req;
    -	struct tcrypt_result tresult;
    +	struct crypto_wait wait;
     	void *hash_buff;
     	char *xbuf[XBUFSIZE];
     	int ret = -ENOMEM;
    @@ -286,7 +260,7 @@ static int __test_hash(struct crypto_ahash *tfm,
     	if (testmgr_alloc_buf(xbuf))
     		goto out_nobuf;
     
    -	init_completion(&tresult.completion);
    +	crypto_init_wait(&wait);
     
     	req = ahash_request_alloc(tfm, GFP_KERNEL);
     	if (!req) {
    @@ -295,7 +269,7 @@ static int __test_hash(struct crypto_ahash *tfm,
     		goto out_noreq;
     	}
     	ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
    -				   tcrypt_complete, &tresult);
    +				   crypto_req_done, &wait);
     
     	j = 0;
     	for (i = 0; i < tcount; i++) {
    @@ -335,26 +309,26 @@ static int __test_hash(struct crypto_ahash *tfm,
     
     		ahash_request_set_crypt(req, sg, result, template[i].psize);
     		if (use_digest) {
    -			ret = wait_async_op(&tresult, crypto_ahash_digest(req));
    +			ret = crypto_wait_req(crypto_ahash_digest(req), &wait);
     			if (ret) {
     				pr_err("alg: hash: digest failed on test %d "
     				       "for %s: ret=%d\n", j, algo, -ret);
     				goto out;
     			}
     		} else {
    -			ret = wait_async_op(&tresult, crypto_ahash_init(req));
    +			ret = crypto_wait_req(crypto_ahash_init(req), &wait);
     			if (ret) {
     				pr_err("alg: hash: init failed on test %d "
     				       "for %s: ret=%d\n", j, algo, -ret);
     				goto out;
     			}
    -			ret = wait_async_op(&tresult, crypto_ahash_update(req));
    +			ret = crypto_wait_req(crypto_ahash_update(req), &wait);
     			if (ret) {
     				pr_err("alg: hash: update failed on test %d "
     				       "for %s: ret=%d\n", j, algo, -ret);
     				goto out;
     			}
    -			ret = wait_async_op(&tresult, crypto_ahash_final(req));
    +			ret = crypto_wait_req(crypto_ahash_final(req), &wait);
     			if (ret) {
     				pr_err("alg: hash: final failed on test %d "
     				       "for %s: ret=%d\n", j, algo, -ret);
    @@ -420,22 +394,10 @@ static int __test_hash(struct crypto_ahash *tfm,
     		}
     
     		ahash_request_set_crypt(req, sg, result, template[i].psize);
    -		ret = crypto_ahash_digest(req);
    -		switch (ret) {
    -		case 0:
    -			break;
    -		case -EINPROGRESS:
    -		case -EBUSY:
    -			wait_for_completion(&tresult.completion);
    -			reinit_completion(&tresult.completion);
    -			ret = tresult.err;
    -			if (!ret)
    -				break;
    -			/* fall through */
    -		default:
    -			printk(KERN_ERR "alg: hash: digest failed "
    -			       "on chunking test %d for %s: "
    -			       "ret=%d\n", j, algo, -ret);
    +		ret = crypto_wait_req(crypto_ahash_digest(req), &wait);
    +		if (ret) {
    +			pr_err("alg: hash: digest failed on chunking test %d for %s: ret=%d\n",
    +			       j, algo, -ret);
     			goto out;
     		}
     
    @@ -486,13 +448,13 @@ static int __test_hash(struct crypto_ahash *tfm,
     		}
     
     		ahash_request_set_crypt(req, sg, result, template[i].tap[0]);
    -		ret = wait_async_op(&tresult, crypto_ahash_init(req));
    +		ret = crypto_wait_req(crypto_ahash_init(req), &wait);
     		if (ret) {
     			pr_err("alg: hash: init failed on test %d for %s: ret=%d\n",
     				j, algo, -ret);
     			goto out;
     		}
    -		ret = wait_async_op(&tresult, crypto_ahash_update(req));
    +		ret = crypto_wait_req(crypto_ahash_update(req), &wait);
     		if (ret) {
     			pr_err("alg: hash: update failed on test %d for %s: ret=%d\n",
     				j, algo, -ret);
    @@ -503,7 +465,7 @@ static int __test_hash(struct crypto_ahash *tfm,
     		for (k = 1; k < template[i].np; k++) {
     			ret = ahash_partial_update(&req, tfm, &template[i],
     				hash_buff, k, temp, &sg[0], algo, result,
    -				&tresult);
    +				&wait);
     			if (ret) {
     				pr_err("alg: hash: partial update failed on test %d for %s: ret=%d\n",
     					j, algo, -ret);
    @@ -511,7 +473,7 @@ static int __test_hash(struct crypto_ahash *tfm,
     			}
     			temp += template[i].tap[k];
     		}
    -		ret = wait_async_op(&tresult, crypto_ahash_final(req));
    +		ret = crypto_wait_req(crypto_ahash_final(req), &wait);
     		if (ret) {
     			pr_err("alg: hash: final failed on test %d for %s: ret=%d\n",
     				j, algo, -ret);
    @@ -580,7 +542,7 @@ static int __test_aead(struct crypto_aead *tfm, int enc,
     	struct scatterlist *sg;
     	struct scatterlist *sgout;
     	const char *e, *d;
    -	struct tcrypt_result result;
    +	struct crypto_wait wait;
     	unsigned int authsize, iv_len;
     	void *input;
     	void *output;
    @@ -619,7 +581,7 @@ static int __test_aead(struct crypto_aead *tfm, int enc,
     	else
     		e = "decryption";
     
    -	init_completion(&result.completion);
    +	crypto_init_wait(&wait);
     
     	req = aead_request_alloc(tfm, GFP_KERNEL);
     	if (!req) {
    @@ -629,7 +591,7 @@ static int __test_aead(struct crypto_aead *tfm, int enc,
     	}
     
     	aead_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
    -				  tcrypt_complete, &result);
    +				  crypto_req_done, &wait);
     
     	iv_len = crypto_aead_ivsize(tfm);
     
    @@ -709,7 +671,8 @@ static int __test_aead(struct crypto_aead *tfm, int enc,
     
     		aead_request_set_ad(req, template[i].alen);
     
    -		ret = enc ? crypto_aead_encrypt(req) : crypto_aead_decrypt(req);
    +		ret = crypto_wait_req(enc ? crypto_aead_encrypt(req)
    +				      : crypto_aead_decrypt(req), &wait);
     
     		switch (ret) {
     		case 0:
    @@ -722,13 +685,6 @@ static int __test_aead(struct crypto_aead *tfm, int enc,
     				goto out;
     			}
     			break;
    -		case -EINPROGRESS:
    -		case -EBUSY:
    -			wait_for_completion(&result.completion);
    -			reinit_completion(&result.completion);
    -			ret = result.err;
    -			if (!ret)
    -				break;
     		case -EBADMSG:
     			if (template[i].novrfy)
     				/* verification failure was expected */
    @@ -866,7 +822,8 @@ static int __test_aead(struct crypto_aead *tfm, int enc,
     
     		aead_request_set_ad(req, template[i].alen);
     
    -		ret = enc ? crypto_aead_encrypt(req) : crypto_aead_decrypt(req);
    +		ret = crypto_wait_req(enc ? crypto_aead_encrypt(req)
    +				      : crypto_aead_decrypt(req), &wait);
     
     		switch (ret) {
     		case 0:
    @@ -879,13 +836,6 @@ static int __test_aead(struct crypto_aead *tfm, int enc,
     				goto out;
     			}
     			break;
    -		case -EINPROGRESS:
    -		case -EBUSY:
    -			wait_for_completion(&result.completion);
    -			reinit_completion(&result.completion);
    -			ret = result.err;
    -			if (!ret)
    -				break;
     		case -EBADMSG:
     			if (template[i].novrfy)
     				/* verification failure was expected */
    @@ -1083,7 +1033,7 @@ static int __test_skcipher(struct crypto_skcipher *tfm, int enc,
     	struct scatterlist sg[8];
     	struct scatterlist sgout[8];
     	const char *e, *d;
    -	struct tcrypt_result result;
    +	struct crypto_wait wait;
     	void *data;
     	char iv[MAX_IVLEN];
     	char *xbuf[XBUFSIZE];
    @@ -1107,7 +1057,7 @@ static int __test_skcipher(struct crypto_skcipher *tfm, int enc,
     	else
     		e = "decryption";
     
    -	init_completion(&result.completion);
    +	crypto_init_wait(&wait);
     
     	req = skcipher_request_alloc(tfm, GFP_KERNEL);
     	if (!req) {
    @@ -1117,7 +1067,7 @@ static int __test_skcipher(struct crypto_skcipher *tfm, int enc,
     	}
     
     	skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
    -				      tcrypt_complete, &result);
    +				      crypto_req_done, &wait);
     
     	j = 0;
     	for (i = 0; i < tcount; i++) {
    @@ -1164,21 +1114,10 @@ static int __test_skcipher(struct crypto_skcipher *tfm, int enc,
     
     		skcipher_request_set_crypt(req, sg, (diff_dst) ? sgout : sg,
     					   template[i].ilen, iv);
    -		ret = enc ? crypto_skcipher_encrypt(req) :
    -			    crypto_skcipher_decrypt(req);
    +		ret = crypto_wait_req(enc ? crypto_skcipher_encrypt(req) :
    +				      crypto_skcipher_decrypt(req), &wait);
     
    -		switch (ret) {
    -		case 0:
    -			break;
    -		case -EINPROGRESS:
    -		case -EBUSY:
    -			wait_for_completion(&result.completion);
    -			reinit_completion(&result.completion);
    -			ret = result.err;
    -			if (!ret)
    -				break;
    -			/* fall through */
    -		default:
    +		if (ret) {
     			pr_err("alg: skcipher%s: %s failed on test %d for %s: ret=%d\n",
     			       d, e, j, algo, -ret);
     			goto out;
    @@ -1272,21 +1211,10 @@ static int __test_skcipher(struct crypto_skcipher *tfm, int enc,
     		skcipher_request_set_crypt(req, sg, (diff_dst) ? sgout : sg,
     					   template[i].ilen, iv);
     
    -		ret = enc ? crypto_skcipher_encrypt(req) :
    -			    crypto_skcipher_decrypt(req);
    +		ret = crypto_wait_req(enc ? crypto_skcipher_encrypt(req) :
    +				      crypto_skcipher_decrypt(req), &wait);
     
    -		switch (ret) {
    -		case 0:
    -			break;
    -		case -EINPROGRESS:
    -		case -EBUSY:
    -			wait_for_completion(&result.completion);
    -			reinit_completion(&result.completion);
    -			ret = result.err;
    -			if (!ret)
    -				break;
    -			/* fall through */
    -		default:
    +		if (ret) {
     			pr_err("alg: skcipher%s: %s failed on chunk test %d for %s: ret=%d\n",
     			       d, e, j, algo, -ret);
     			goto out;
    @@ -1462,7 +1390,7 @@ static int test_acomp(struct crypto_acomp *tfm,
     	int ret;
     	struct scatterlist src, dst;
     	struct acomp_req *req;
    -	struct tcrypt_result result;
    +	struct crypto_wait wait;
     
     	output = kmalloc(COMP_BUF_SIZE, GFP_KERNEL);
     	if (!output)
    @@ -1486,7 +1414,7 @@ static int test_acomp(struct crypto_acomp *tfm,
     		}
     
     		memset(output, 0, dlen);
    -		init_completion(&result.completion);
    +		crypto_init_wait(&wait);
     		sg_init_one(&src, input_vec, ilen);
     		sg_init_one(&dst, output, dlen);
     
    @@ -1501,9 +1429,9 @@ static int test_acomp(struct crypto_acomp *tfm,
     
     		acomp_request_set_params(req, &src, &dst, ilen, dlen);
     		acomp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
    -					   tcrypt_complete, &result);
    +					   crypto_req_done, &wait);
     
    -		ret = wait_async_op(&result, crypto_acomp_compress(req));
    +		ret = crypto_wait_req(crypto_acomp_compress(req), &wait);
     		if (ret) {
     			pr_err("alg: acomp: compression failed on test %d for %s: ret=%d\n",
     			       i + 1, algo, -ret);
    @@ -1516,10 +1444,10 @@ static int test_acomp(struct crypto_acomp *tfm,
     		dlen = COMP_BUF_SIZE;
     		sg_init_one(&src, output, ilen);
     		sg_init_one(&dst, decomp_out, dlen);
    -		init_completion(&result.completion);
    +		crypto_init_wait(&wait);
     		acomp_request_set_params(req, &src, &dst, ilen, dlen);
     
    -		ret = wait_async_op(&result, crypto_acomp_decompress(req));
    +		ret = crypto_wait_req(crypto_acomp_decompress(req), &wait);
     		if (ret) {
     			pr_err("alg: acomp: compression failed on test %d for %s: ret=%d\n",
     			       i + 1, algo, -ret);
    @@ -1563,7 +1491,7 @@ static int test_acomp(struct crypto_acomp *tfm,
     		}
     
     		memset(output, 0, dlen);
    -		init_completion(&result.completion);
    +		crypto_init_wait(&wait);
     		sg_init_one(&src, input_vec, ilen);
     		sg_init_one(&dst, output, dlen);
     
    @@ -1578,9 +1506,9 @@ static int test_acomp(struct crypto_acomp *tfm,
     
     		acomp_request_set_params(req, &src, &dst, ilen, dlen);
     		acomp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
    -					   tcrypt_complete, &result);
    +					   crypto_req_done, &wait);
     
    -		ret = wait_async_op(&result, crypto_acomp_decompress(req));
    +		ret = crypto_wait_req(crypto_acomp_decompress(req), &wait);
     		if (ret) {
     			pr_err("alg: acomp: decompression failed on test %d for %s: ret=%d\n",
     			       i + 1, algo, -ret);
    @@ -2000,7 +1928,7 @@ static int do_test_kpp(struct crypto_kpp *tfm, const struct kpp_testvec *vec,
     	void *a_public = NULL;
     	void *a_ss = NULL;
     	void *shared_secret = NULL;
    -	struct tcrypt_result result;
    +	struct crypto_wait wait;
     	unsigned int out_len_max;
     	int err = -ENOMEM;
     	struct scatterlist src, dst;
    @@ -2009,7 +1937,7 @@ static int do_test_kpp(struct crypto_kpp *tfm, const struct kpp_testvec *vec,
     	if (!req)
     		return err;
     
    -	init_completion(&result.completion);
    +	crypto_init_wait(&wait);
     
     	err = crypto_kpp_set_secret(tfm, vec->secret, vec->secret_size);
     	if (err < 0)
    @@ -2027,10 +1955,10 @@ static int do_test_kpp(struct crypto_kpp *tfm, const struct kpp_testvec *vec,
     	sg_init_one(&dst, output_buf, out_len_max);
     	kpp_request_set_output(req, &dst, out_len_max);
     	kpp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
    -				 tcrypt_complete, &result);
    +				 crypto_req_done, &wait);
     
     	/* Compute party A's public key */
    -	err = wait_async_op(&result, crypto_kpp_generate_public_key(req));
    +	err = crypto_wait_req(crypto_kpp_generate_public_key(req), &wait);
     	if (err) {
     		pr_err("alg: %s: Party A: generate public key test failed. err %d\n",
     		       alg, err);
    @@ -2069,8 +1997,8 @@ static int do_test_kpp(struct crypto_kpp *tfm, const struct kpp_testvec *vec,
     	kpp_request_set_input(req, &src, vec->b_public_size);
     	kpp_request_set_output(req, &dst, out_len_max);
     	kpp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
    -				 tcrypt_complete, &result);
    -	err = wait_async_op(&result, crypto_kpp_compute_shared_secret(req));
    +				 crypto_req_done, &wait);
    +	err = crypto_wait_req(crypto_kpp_compute_shared_secret(req), &wait);
     	if (err) {
     		pr_err("alg: %s: Party A: compute shared secret test failed. err %d\n",
     		       alg, err);
    @@ -2100,9 +2028,9 @@ static int do_test_kpp(struct crypto_kpp *tfm, const struct kpp_testvec *vec,
     		kpp_request_set_input(req, &src, vec->expected_a_public_size);
     		kpp_request_set_output(req, &dst, out_len_max);
     		kpp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
    -					 tcrypt_complete, &result);
    -		err = wait_async_op(&result,
    -				    crypto_kpp_compute_shared_secret(req));
    +					 crypto_req_done, &wait);
    +		err = crypto_wait_req(crypto_kpp_compute_shared_secret(req),
    +				      &wait);
     		if (err) {
     			pr_err("alg: %s: Party B: compute shared secret failed. err %d\n",
     			       alg, err);
    @@ -2179,7 +2107,7 @@ static int test_akcipher_one(struct crypto_akcipher *tfm,
     	struct akcipher_request *req;
     	void *outbuf_enc = NULL;
     	void *outbuf_dec = NULL;
    -	struct tcrypt_result result;
    +	struct crypto_wait wait;
     	unsigned int out_len_max, out_len = 0;
     	int err = -ENOMEM;
     	struct scatterlist src, dst, src_tab[2];
    @@ -2191,7 +2119,7 @@ static int test_akcipher_one(struct crypto_akcipher *tfm,
     	if (!req)
     		goto free_xbuf;
     
    -	init_completion(&result.completion);
    +	crypto_init_wait(&wait);
     
     	if (vecs->public_key_vec)
     		err = crypto_akcipher_set_pub_key(tfm, vecs->key,
    @@ -2220,13 +2148,13 @@ static int test_akcipher_one(struct crypto_akcipher *tfm,
     	akcipher_request_set_crypt(req, src_tab, &dst, vecs->m_size,
     				   out_len_max);
     	akcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
    -				      tcrypt_complete, &result);
    +				      crypto_req_done, &wait);
     
    -	err = wait_async_op(&result, vecs->siggen_sigver_test ?
    -				     /* Run asymmetric signature generation */
    -				     crypto_akcipher_sign(req) :
    -				     /* Run asymmetric encrypt */
    -				     crypto_akcipher_encrypt(req));
    +	err = crypto_wait_req(vecs->siggen_sigver_test ?
    +			      /* Run asymmetric signature generation */
    +			      crypto_akcipher_sign(req) :
    +			      /* Run asymmetric encrypt */
    +			      crypto_akcipher_encrypt(req), &wait);
     	if (err) {
     		pr_err("alg: akcipher: encrypt test failed. err %d\n", err);
     		goto free_all;
    @@ -2261,14 +2189,14 @@ static int test_akcipher_one(struct crypto_akcipher *tfm,
     
     	sg_init_one(&src, xbuf[0], vecs->c_size);
     	sg_init_one(&dst, outbuf_dec, out_len_max);
    -	init_completion(&result.completion);
    +	crypto_init_wait(&wait);
     	akcipher_request_set_crypt(req, &src, &dst, vecs->c_size, out_len_max);
     
    -	err = wait_async_op(&result, vecs->siggen_sigver_test ?
    -				     /* Run asymmetric signature verification */
    -				     crypto_akcipher_verify(req) :
    -				     /* Run asymmetric decrypt */
    -				     crypto_akcipher_decrypt(req));
    +	err = crypto_wait_req(vecs->siggen_sigver_test ?
    +			      /* Run asymmetric signature verification */
    +			      crypto_akcipher_verify(req) :
    +			      /* Run asymmetric decrypt */
    +			      crypto_akcipher_decrypt(req), &wait);
     	if (err) {
     		pr_err("alg: akcipher: decrypt test failed. err %d\n", err);
     		goto free_all;
    -- 
    2.1.4
    
    ^ permalink raw reply related	[flat|nested] 58+ messages in thread
  • * [PATCH v5 11/19] fscrypt: move to generic async completion
           [not found] <1502724094-23305-1-git-send-email-gilad@benyossef.com>
                       ` (18 preceding siblings ...)
      2017-08-14 15:21 ` Gilad Ben-Yossef
    @ 2017-08-14 15:21 ` Gilad Ben-Yossef
      2017-08-14 15:21 ` Gilad Ben-Yossef
                       ` (20 subsequent siblings)
      40 siblings, 0 replies; 58+ messages in thread
    From: Gilad Ben-Yossef @ 2017-08-14 15:21 UTC (permalink / raw)
      To: Herbert Xu, David S. Miller, Jonathan Corbet, David Howells,
    	Tom Lendacky, Gary Hook, Boris Brezillon, Arnaud Ebalard,
    	Matthias Brugger, Alasdair Kergon, Mike Snitzer, dm-devel,
    	Shaohua Li, Steve French, Theodore Y. Ts'o, Jaegeuk Kim,
    	Mimi Zohar, Dmitry Kasatkin, James Morris, Serge E. Hallyn,
    	linux-crypto, linux-doc, linux-kernel, keyrings, linux-arm-kernel
      Cc: Ofir Drang
    
    fscrypt starts several async. crypto ops and waiting for them to
    complete. Move it over to generic code doing the same.
    
    Signed-off-by: Gilad Ben-Yossef <gilad@benyossef.com>
    ---
     fs/crypto/crypto.c          | 28 ++++------------------------
     fs/crypto/fname.c           | 36 ++++++------------------------------
     fs/crypto/fscrypt_private.h | 10 ----------
     fs/crypto/keyinfo.c         | 21 +++------------------
     4 files changed, 13 insertions(+), 82 deletions(-)
    
    diff --git a/fs/crypto/crypto.c b/fs/crypto/crypto.c
    index c7835df..80a3cad 100644
    --- a/fs/crypto/crypto.c
    +++ b/fs/crypto/crypto.c
    @@ -126,21 +126,6 @@ struct fscrypt_ctx *fscrypt_get_ctx(const struct inode *inode, gfp_t gfp_flags)
     }
     EXPORT_SYMBOL(fscrypt_get_ctx);
     
    -/**
    - * page_crypt_complete() - completion callback for page crypto
    - * @req: The asynchronous cipher request context
    - * @res: The result of the cipher operation
    - */
    -static void page_crypt_complete(struct crypto_async_request *req, int res)
    -{
    -	struct fscrypt_completion_result *ecr = req->data;
    -
    -	if (res == -EINPROGRESS)
    -		return;
    -	ecr->res = res;
    -	complete(&ecr->completion);
    -}
    -
     int fscrypt_do_page_crypto(const struct inode *inode, fscrypt_direction_t rw,
     			   u64 lblk_num, struct page *src_page,
     			   struct page *dest_page, unsigned int len,
    @@ -151,7 +136,7 @@ int fscrypt_do_page_crypto(const struct inode *inode, fscrypt_direction_t rw,
     		u8 padding[FS_IV_SIZE - sizeof(__le64)];
     	} iv;
     	struct skcipher_request *req = NULL;
    -	DECLARE_FS_COMPLETION_RESULT(ecr);
    +	DECLARE_CRYPTO_WAIT(wait);
     	struct scatterlist dst, src;
     	struct fscrypt_info *ci = inode->i_crypt_info;
     	struct crypto_skcipher *tfm = ci->ci_ctfm;
    @@ -179,7 +164,7 @@ int fscrypt_do_page_crypto(const struct inode *inode, fscrypt_direction_t rw,
     
     	skcipher_request_set_callback(
     		req, CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP,
    -		page_crypt_complete, &ecr);
    +		crypto_req_done, &wait);
     
     	sg_init_table(&dst, 1);
     	sg_set_page(&dst, dest_page, len, offs);
    @@ -187,14 +172,9 @@ int fscrypt_do_page_crypto(const struct inode *inode, fscrypt_direction_t rw,
     	sg_set_page(&src, src_page, len, offs);
     	skcipher_request_set_crypt(req, &src, &dst, len, &iv);
     	if (rw == FS_DECRYPT)
    -		res = crypto_skcipher_decrypt(req);
    +		res = crypto_wait_req(crypto_skcipher_decrypt(req), &wait);
     	else
    -		res = crypto_skcipher_encrypt(req);
    -	if (res == -EINPROGRESS || res == -EBUSY) {
    -		BUG_ON(req->base.data != &ecr);
    -		wait_for_completion(&ecr.completion);
    -		res = ecr.res;
    -	}
    +		res = crypto_wait_req(crypto_skcipher_encrypt(req), &wait);
     	skcipher_request_free(req);
     	if (res) {
     		printk_ratelimited(KERN_ERR
    diff --git a/fs/crypto/fname.c b/fs/crypto/fname.c
    index ad9f814..a80a0d3 100644
    --- a/fs/crypto/fname.c
    +++ b/fs/crypto/fname.c
    @@ -15,21 +15,6 @@
     #include "fscrypt_private.h"
     
     /**
    - * fname_crypt_complete() - completion callback for filename crypto
    - * @req: The asynchronous cipher request context
    - * @res: The result of the cipher operation
    - */
    -static void fname_crypt_complete(struct crypto_async_request *req, int res)
    -{
    -	struct fscrypt_completion_result *ecr = req->data;
    -
    -	if (res == -EINPROGRESS)
    -		return;
    -	ecr->res = res;
    -	complete(&ecr->completion);
    -}
    -
    -/**
      * fname_encrypt() - encrypt a filename
      *
      * The caller must have allocated sufficient memory for the @oname string.
    @@ -40,7 +25,7 @@ static int fname_encrypt(struct inode *inode,
     			const struct qstr *iname, struct fscrypt_str *oname)
     {
     	struct skcipher_request *req = NULL;
    -	DECLARE_FS_COMPLETION_RESULT(ecr);
    +	DECLARE_CRYPTO_WAIT(wait);
     	struct fscrypt_info *ci = inode->i_crypt_info;
     	struct crypto_skcipher *tfm = ci->ci_ctfm;
     	int res = 0;
    @@ -76,17 +61,12 @@ static int fname_encrypt(struct inode *inode,
     	}
     	skcipher_request_set_callback(req,
     			CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP,
    -			fname_crypt_complete, &ecr);
    +			crypto_req_done, &wait);
     	sg_init_one(&sg, oname->name, cryptlen);
     	skcipher_request_set_crypt(req, &sg, &sg, cryptlen, iv);
     
     	/* Do the encryption */
    -	res = crypto_skcipher_encrypt(req);
    -	if (res == -EINPROGRESS || res == -EBUSY) {
    -		/* Request is being completed asynchronously; wait for it */
    -		wait_for_completion(&ecr.completion);
    -		res = ecr.res;
    -	}
    +	res = crypto_wait_req(crypto_skcipher_encrypt(req), &wait);
     	skcipher_request_free(req);
     	if (res < 0) {
     		printk_ratelimited(KERN_ERR
    @@ -110,7 +90,7 @@ static int fname_decrypt(struct inode *inode,
     				struct fscrypt_str *oname)
     {
     	struct skcipher_request *req = NULL;
    -	DECLARE_FS_COMPLETION_RESULT(ecr);
    +	DECLARE_CRYPTO_WAIT(wait);
     	struct scatterlist src_sg, dst_sg;
     	struct fscrypt_info *ci = inode->i_crypt_info;
     	struct crypto_skcipher *tfm = ci->ci_ctfm;
    @@ -131,7 +111,7 @@ static int fname_decrypt(struct inode *inode,
     	}
     	skcipher_request_set_callback(req,
     		CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP,
    -		fname_crypt_complete, &ecr);
    +		crypto_req_done, &wait);
     
     	/* Initialize IV */
     	memset(iv, 0, FS_CRYPTO_BLOCK_SIZE);
    @@ -140,11 +120,7 @@ static int fname_decrypt(struct inode *inode,
     	sg_init_one(&src_sg, iname->name, iname->len);
     	sg_init_one(&dst_sg, oname->name, oname->len);
     	skcipher_request_set_crypt(req, &src_sg, &dst_sg, iname->len, iv);
    -	res = crypto_skcipher_decrypt(req);
    -	if (res == -EINPROGRESS || res == -EBUSY) {
    -		wait_for_completion(&ecr.completion);
    -		res = ecr.res;
    -	}
    +	res = crypto_wait_req(crypto_skcipher_decrypt(req), &wait);
     	skcipher_request_free(req);
     	if (res < 0) {
     		printk_ratelimited(KERN_ERR
    diff --git a/fs/crypto/fscrypt_private.h b/fs/crypto/fscrypt_private.h
    index a1d5021..c0f1881 100644
    --- a/fs/crypto/fscrypt_private.h
    +++ b/fs/crypto/fscrypt_private.h
    @@ -69,16 +69,6 @@ typedef enum {
     #define FS_CTX_REQUIRES_FREE_ENCRYPT_FL		0x00000001
     #define FS_CTX_HAS_BOUNCE_BUFFER_FL		0x00000002
     
    -struct fscrypt_completion_result {
    -	struct completion completion;
    -	int res;
    -};
    -
    -#define DECLARE_FS_COMPLETION_RESULT(ecr) \
    -	struct fscrypt_completion_result ecr = { \
    -		COMPLETION_INITIALIZER_ONSTACK((ecr).completion), 0 }
    -
    -
     /* crypto.c */
     extern int fscrypt_initialize(unsigned int cop_flags);
     extern struct workqueue_struct *fscrypt_read_workqueue;
    diff --git a/fs/crypto/keyinfo.c b/fs/crypto/keyinfo.c
    index 018c588..3c84cac 100644
    --- a/fs/crypto/keyinfo.c
    +++ b/fs/crypto/keyinfo.c
    @@ -17,17 +17,6 @@
     
     static struct crypto_shash *essiv_hash_tfm;
     
    -static void derive_crypt_complete(struct crypto_async_request *req, int rc)
    -{
    -	struct fscrypt_completion_result *ecr = req->data;
    -
    -	if (rc == -EINPROGRESS)
    -		return;
    -
    -	ecr->res = rc;
    -	complete(&ecr->completion);
    -}
    -
     /**
      * derive_key_aes() - Derive a key using AES-128-ECB
      * @deriving_key: Encryption key used for derivation.
    @@ -42,7 +31,7 @@ static int derive_key_aes(u8 deriving_key[FS_AES_128_ECB_KEY_SIZE],
     {
     	int res = 0;
     	struct skcipher_request *req = NULL;
    -	DECLARE_FS_COMPLETION_RESULT(ecr);
    +	DECLARE_CRYPTO_WAIT(wait);
     	struct scatterlist src_sg, dst_sg;
     	struct crypto_skcipher *tfm = crypto_alloc_skcipher("ecb(aes)", 0, 0);
     
    @@ -59,7 +48,7 @@ static int derive_key_aes(u8 deriving_key[FS_AES_128_ECB_KEY_SIZE],
     	}
     	skcipher_request_set_callback(req,
     			CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP,
    -			derive_crypt_complete, &ecr);
    +			crypto_req_done, &wait);
     	res = crypto_skcipher_setkey(tfm, deriving_key,
     					FS_AES_128_ECB_KEY_SIZE);
     	if (res < 0)
    @@ -69,11 +58,7 @@ static int derive_key_aes(u8 deriving_key[FS_AES_128_ECB_KEY_SIZE],
     	sg_init_one(&dst_sg, derived_raw_key, source_key->size);
     	skcipher_request_set_crypt(req, &src_sg, &dst_sg, source_key->size,
     				   NULL);
    -	res = crypto_skcipher_encrypt(req);
    -	if (res == -EINPROGRESS || res == -EBUSY) {
    -		wait_for_completion(&ecr.completion);
    -		res = ecr.res;
    -	}
    +	res = crypto_wait_req(crypto_skcipher_encrypt(req), &wait);
     out:
     	skcipher_request_free(req);
     	crypto_free_skcipher(tfm);
    -- 
    2.1.4
    
    ^ permalink raw reply related	[flat|nested] 58+ messages in thread
  • * [PATCH v5 11/19] fscrypt: move to generic async completion
           [not found] <1502724094-23305-1-git-send-email-gilad@benyossef.com>
                       ` (19 preceding siblings ...)
      2017-08-14 15:21 ` [PATCH v5 11/19] fscrypt: move " Gilad Ben-Yossef
    @ 2017-08-14 15:21 ` Gilad Ben-Yossef
      2017-08-14 15:21 ` [PATCH v5 12/19] dm: move dm-verity " Gilad Ben-Yossef
                       ` (19 subsequent siblings)
      40 siblings, 0 replies; 58+ messages in thread
    From: Gilad Ben-Yossef @ 2017-08-14 15:21 UTC (permalink / raw)
      To: Herbert Xu, David S. Miller, Jonathan Corbet, David Howells,
    	Tom Lendacky, Gary Hook, Boris Brezillon, Arnaud Ebalard,
    	Matthias Brugger, Alasdair Kergon, Mike Snitzer, dm-devel,
    	Shaohua Li, Steve French, Theodore Y. Ts'o, Jaegeuk Kim,
    	Mimi Zohar, Dmitry Kasatkin, James Morris, Serge E. Hallyn,
    	linux-crypto
      Cc: Ofir Drang
    
    fscrypt starts several async. crypto ops and waiting for them to
    complete. Move it over to generic code doing the same.
    
    Signed-off-by: Gilad Ben-Yossef <gilad@benyossef.com>
    ---
     fs/crypto/crypto.c          | 28 ++++------------------------
     fs/crypto/fname.c           | 36 ++++++------------------------------
     fs/crypto/fscrypt_private.h | 10 ----------
     fs/crypto/keyinfo.c         | 21 +++------------------
     4 files changed, 13 insertions(+), 82 deletions(-)
    
    diff --git a/fs/crypto/crypto.c b/fs/crypto/crypto.c
    index c7835df..80a3cad 100644
    --- a/fs/crypto/crypto.c
    +++ b/fs/crypto/crypto.c
    @@ -126,21 +126,6 @@ struct fscrypt_ctx *fscrypt_get_ctx(const struct inode *inode, gfp_t gfp_flags)
     }
     EXPORT_SYMBOL(fscrypt_get_ctx);
     
    -/**
    - * page_crypt_complete() - completion callback for page crypto
    - * @req: The asynchronous cipher request context
    - * @res: The result of the cipher operation
    - */
    -static void page_crypt_complete(struct crypto_async_request *req, int res)
    -{
    -	struct fscrypt_completion_result *ecr = req->data;
    -
    -	if (res == -EINPROGRESS)
    -		return;
    -	ecr->res = res;
    -	complete(&ecr->completion);
    -}
    -
     int fscrypt_do_page_crypto(const struct inode *inode, fscrypt_direction_t rw,
     			   u64 lblk_num, struct page *src_page,
     			   struct page *dest_page, unsigned int len,
    @@ -151,7 +136,7 @@ int fscrypt_do_page_crypto(const struct inode *inode, fscrypt_direction_t rw,
     		u8 padding[FS_IV_SIZE - sizeof(__le64)];
     	} iv;
     	struct skcipher_request *req = NULL;
    -	DECLARE_FS_COMPLETION_RESULT(ecr);
    +	DECLARE_CRYPTO_WAIT(wait);
     	struct scatterlist dst, src;
     	struct fscrypt_info *ci = inode->i_crypt_info;
     	struct crypto_skcipher *tfm = ci->ci_ctfm;
    @@ -179,7 +164,7 @@ int fscrypt_do_page_crypto(const struct inode *inode, fscrypt_direction_t rw,
     
     	skcipher_request_set_callback(
     		req, CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP,
    -		page_crypt_complete, &ecr);
    +		crypto_req_done, &wait);
     
     	sg_init_table(&dst, 1);
     	sg_set_page(&dst, dest_page, len, offs);
    @@ -187,14 +172,9 @@ int fscrypt_do_page_crypto(const struct inode *inode, fscrypt_direction_t rw,
     	sg_set_page(&src, src_page, len, offs);
     	skcipher_request_set_crypt(req, &src, &dst, len, &iv);
     	if (rw == FS_DECRYPT)
    -		res = crypto_skcipher_decrypt(req);
    +		res = crypto_wait_req(crypto_skcipher_decrypt(req), &wait);
     	else
    -		res = crypto_skcipher_encrypt(req);
    -	if (res == -EINPROGRESS || res == -EBUSY) {
    -		BUG_ON(req->base.data != &ecr);
    -		wait_for_completion(&ecr.completion);
    -		res = ecr.res;
    -	}
    +		res = crypto_wait_req(crypto_skcipher_encrypt(req), &wait);
     	skcipher_request_free(req);
     	if (res) {
     		printk_ratelimited(KERN_ERR
    diff --git a/fs/crypto/fname.c b/fs/crypto/fname.c
    index ad9f814..a80a0d3 100644
    --- a/fs/crypto/fname.c
    +++ b/fs/crypto/fname.c
    @@ -15,21 +15,6 @@
     #include "fscrypt_private.h"
     
     /**
    - * fname_crypt_complete() - completion callback for filename crypto
    - * @req: The asynchronous cipher request context
    - * @res: The result of the cipher operation
    - */
    -static void fname_crypt_complete(struct crypto_async_request *req, int res)
    -{
    -	struct fscrypt_completion_result *ecr = req->data;
    -
    -	if (res == -EINPROGRESS)
    -		return;
    -	ecr->res = res;
    -	complete(&ecr->completion);
    -}
    -
    -/**
      * fname_encrypt() - encrypt a filename
      *
      * The caller must have allocated sufficient memory for the @oname string.
    @@ -40,7 +25,7 @@ static int fname_encrypt(struct inode *inode,
     			const struct qstr *iname, struct fscrypt_str *oname)
     {
     	struct skcipher_request *req = NULL;
    -	DECLARE_FS_COMPLETION_RESULT(ecr);
    +	DECLARE_CRYPTO_WAIT(wait);
     	struct fscrypt_info *ci = inode->i_crypt_info;
     	struct crypto_skcipher *tfm = ci->ci_ctfm;
     	int res = 0;
    @@ -76,17 +61,12 @@ static int fname_encrypt(struct inode *inode,
     	}
     	skcipher_request_set_callback(req,
     			CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP,
    -			fname_crypt_complete, &ecr);
    +			crypto_req_done, &wait);
     	sg_init_one(&sg, oname->name, cryptlen);
     	skcipher_request_set_crypt(req, &sg, &sg, cryptlen, iv);
     
     	/* Do the encryption */
    -	res = crypto_skcipher_encrypt(req);
    -	if (res == -EINPROGRESS || res == -EBUSY) {
    -		/* Request is being completed asynchronously; wait for it */
    -		wait_for_completion(&ecr.completion);
    -		res = ecr.res;
    -	}
    +	res = crypto_wait_req(crypto_skcipher_encrypt(req), &wait);
     	skcipher_request_free(req);
     	if (res < 0) {
     		printk_ratelimited(KERN_ERR
    @@ -110,7 +90,7 @@ static int fname_decrypt(struct inode *inode,
     				struct fscrypt_str *oname)
     {
     	struct skcipher_request *req = NULL;
    -	DECLARE_FS_COMPLETION_RESULT(ecr);
    +	DECLARE_CRYPTO_WAIT(wait);
     	struct scatterlist src_sg, dst_sg;
     	struct fscrypt_info *ci = inode->i_crypt_info;
     	struct crypto_skcipher *tfm = ci->ci_ctfm;
    @@ -131,7 +111,7 @@ static int fname_decrypt(struct inode *inode,
     	}
     	skcipher_request_set_callback(req,
     		CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP,
    -		fname_crypt_complete, &ecr);
    +		crypto_req_done, &wait);
     
     	/* Initialize IV */
     	memset(iv, 0, FS_CRYPTO_BLOCK_SIZE);
    @@ -140,11 +120,7 @@ static int fname_decrypt(struct inode *inode,
     	sg_init_one(&src_sg, iname->name, iname->len);
     	sg_init_one(&dst_sg, oname->name, oname->len);
     	skcipher_request_set_crypt(req, &src_sg, &dst_sg, iname->len, iv);
    -	res = crypto_skcipher_decrypt(req);
    -	if (res == -EINPROGRESS || res == -EBUSY) {
    -		wait_for_completion(&ecr.completion);
    -		res = ecr.res;
    -	}
    +	res = crypto_wait_req(crypto_skcipher_decrypt(req), &wait);
     	skcipher_request_free(req);
     	if (res < 0) {
     		printk_ratelimited(KERN_ERR
    diff --git a/fs/crypto/fscrypt_private.h b/fs/crypto/fscrypt_private.h
    index a1d5021..c0f1881 100644
    --- a/fs/crypto/fscrypt_private.h
    +++ b/fs/crypto/fscrypt_private.h
    @@ -69,16 +69,6 @@ typedef enum {
     #define FS_CTX_REQUIRES_FREE_ENCRYPT_FL		0x00000001
     #define FS_CTX_HAS_BOUNCE_BUFFER_FL		0x00000002
     
    -struct fscrypt_completion_result {
    -	struct completion completion;
    -	int res;
    -};
    -
    -#define DECLARE_FS_COMPLETION_RESULT(ecr) \
    -	struct fscrypt_completion_result ecr = { \
    -		COMPLETION_INITIALIZER_ONSTACK((ecr).completion), 0 }
    -
    -
     /* crypto.c */
     extern int fscrypt_initialize(unsigned int cop_flags);
     extern struct workqueue_struct *fscrypt_read_workqueue;
    diff --git a/fs/crypto/keyinfo.c b/fs/crypto/keyinfo.c
    index 018c588..3c84cac 100644
    --- a/fs/crypto/keyinfo.c
    +++ b/fs/crypto/keyinfo.c
    @@ -17,17 +17,6 @@
     
     static struct crypto_shash *essiv_hash_tfm;
     
    -static void derive_crypt_complete(struct crypto_async_request *req, int rc)
    -{
    -	struct fscrypt_completion_result *ecr = req->data;
    -
    -	if (rc == -EINPROGRESS)
    -		return;
    -
    -	ecr->res = rc;
    -	complete(&ecr->completion);
    -}
    -
     /**
      * derive_key_aes() - Derive a key using AES-128-ECB
      * @deriving_key: Encryption key used for derivation.
    @@ -42,7 +31,7 @@ static int derive_key_aes(u8 deriving_key[FS_AES_128_ECB_KEY_SIZE],
     {
     	int res = 0;
     	struct skcipher_request *req = NULL;
    -	DECLARE_FS_COMPLETION_RESULT(ecr);
    +	DECLARE_CRYPTO_WAIT(wait);
     	struct scatterlist src_sg, dst_sg;
     	struct crypto_skcipher *tfm = crypto_alloc_skcipher("ecb(aes)", 0, 0);
     
    @@ -59,7 +48,7 @@ static int derive_key_aes(u8 deriving_key[FS_AES_128_ECB_KEY_SIZE],
     	}
     	skcipher_request_set_callback(req,
     			CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP,
    -			derive_crypt_complete, &ecr);
    +			crypto_req_done, &wait);
     	res = crypto_skcipher_setkey(tfm, deriving_key,
     					FS_AES_128_ECB_KEY_SIZE);
     	if (res < 0)
    @@ -69,11 +58,7 @@ static int derive_key_aes(u8 deriving_key[FS_AES_128_ECB_KEY_SIZE],
     	sg_init_one(&dst_sg, derived_raw_key, source_key->size);
     	skcipher_request_set_crypt(req, &src_sg, &dst_sg, source_key->size,
     				   NULL);
    -	res = crypto_skcipher_encrypt(req);
    -	if (res == -EINPROGRESS || res == -EBUSY) {
    -		wait_for_completion(&ecr.completion);
    -		res = ecr.res;
    -	}
    +	res = crypto_wait_req(crypto_skcipher_encrypt(req), &wait);
     out:
     	skcipher_request_free(req);
     	crypto_free_skcipher(tfm);
    -- 
    2.1.4
    
    
    ^ permalink raw reply related	[flat|nested] 58+ messages in thread
  • * [PATCH v5 12/19] dm: move dm-verity to generic async completion
           [not found] <1502724094-23305-1-git-send-email-gilad@benyossef.com>
                       ` (20 preceding siblings ...)
      2017-08-14 15:21 ` Gilad Ben-Yossef
    @ 2017-08-14 15:21 ` Gilad Ben-Yossef
      2017-08-14 15:21 ` Gilad Ben-Yossef
                       ` (18 subsequent siblings)
      40 siblings, 0 replies; 58+ messages in thread
    From: Gilad Ben-Yossef @ 2017-08-14 15:21 UTC (permalink / raw)
      To: Herbert Xu, David S. Miller, Jonathan Corbet, David Howells,
    	Tom Lendacky, Gary Hook, Boris Brezillon, Arnaud Ebalard,
    	Matthias Brugger, Alasdair Kergon, Mike Snitzer, dm-devel,
    	Shaohua Li, Steve French, Theodore Y. Ts'o, Jaegeuk Kim,
    	Mimi Zohar, Dmitry Kasatkin, James Morris, Serge E. Hallyn,
    	linux-crypto
      Cc: Ofir Drang
    
    dm-verity is starting async. crypto ops and waiting for them to complete.
    Move it over to generic code doing the same.
    
    This also fixes a possible data coruption bug created by the
    use of wait_for_completion_interruptible() without dealing
    correctly with an interrupt aborting the wait prior to the
    async op finishing.
    
    Signed-off-by: Gilad Ben-Yossef <gilad@benyossef.com>
    ---
     drivers/md/dm-verity-target.c | 81 +++++++++++--------------------------------
     drivers/md/dm-verity.h        |  5 ---
     2 files changed, 20 insertions(+), 66 deletions(-)
    
    diff --git a/drivers/md/dm-verity-target.c b/drivers/md/dm-verity-target.c
    index 79f18d4..8df08a8 100644
    --- a/drivers/md/dm-verity-target.c
    +++ b/drivers/md/dm-verity-target.c
    @@ -92,74 +92,33 @@ static sector_t verity_position_at_level(struct dm_verity *v, sector_t block,
     	return block >> (level * v->hash_per_block_bits);
     }
     
    -/*
    - * Callback function for asynchrnous crypto API completion notification
    - */
    -static void verity_op_done(struct crypto_async_request *base, int err)
    -{
    -	struct verity_result *res = (struct verity_result *)base->data;
    -
    -	if (err == -EINPROGRESS)
    -		return;
    -
    -	res->err = err;
    -	complete(&res->completion);
    -}
    -
    -/*
    - * Wait for async crypto API callback
    - */
    -static inline int verity_complete_op(struct verity_result *res, int ret)
    -{
    -	switch (ret) {
    -	case 0:
    -		break;
    -
    -	case -EINPROGRESS:
    -	case -EBUSY:
    -		ret = wait_for_completion_interruptible(&res->completion);
    -		if (!ret)
    -			ret = res->err;
    -		reinit_completion(&res->completion);
    -		break;
    -
    -	default:
    -		DMERR("verity_wait_hash: crypto op submission failed: %d", ret);
    -	}
    -
    -	if (unlikely(ret < 0))
    -		DMERR("verity_wait_hash: crypto op failed: %d", ret);
    -
    -	return ret;
    -}
    -
     static int verity_hash_update(struct dm_verity *v, struct ahash_request *req,
     				const u8 *data, size_t len,
    -				struct verity_result *res)
    +				struct crypto_wait *wait)
     {
     	struct scatterlist sg;
     
     	sg_init_one(&sg, data, len);
     	ahash_request_set_crypt(req, &sg, NULL, len);
     
    -	return verity_complete_op(res, crypto_ahash_update(req));
    +	return crypto_wait_req(crypto_ahash_update(req), wait);
     }
     
     /*
      * Wrapper for crypto_ahash_init, which handles verity salting.
      */
     static int verity_hash_init(struct dm_verity *v, struct ahash_request *req,
    -				struct verity_result *res)
    +				struct crypto_wait *wait)
     {
     	int r;
     
     	ahash_request_set_tfm(req, v->tfm);
     	ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_SLEEP |
     					CRYPTO_TFM_REQ_MAY_BACKLOG,
    -					verity_op_done, (void *)res);
    -	init_completion(&res->completion);
    +					crypto_req_done, (void *)wait);
    +	crypto_init_wait(wait);
     
    -	r = verity_complete_op(res, crypto_ahash_init(req));
    +	r = crypto_wait_req(crypto_ahash_init(req), wait);
     
     	if (unlikely(r < 0)) {
     		DMERR("crypto_ahash_init failed: %d", r);
    @@ -167,18 +126,18 @@ static int verity_hash_init(struct dm_verity *v, struct ahash_request *req,
     	}
     
     	if (likely(v->salt_size && (v->version >= 1)))
    -		r = verity_hash_update(v, req, v->salt, v->salt_size, res);
    +		r = verity_hash_update(v, req, v->salt, v->salt_size, wait);
     
     	return r;
     }
     
     static int verity_hash_final(struct dm_verity *v, struct ahash_request *req,
    -			     u8 *digest, struct verity_result *res)
    +			     u8 *digest, struct crypto_wait *wait)
     {
     	int r;
     
     	if (unlikely(v->salt_size && (!v->version))) {
    -		r = verity_hash_update(v, req, v->salt, v->salt_size, res);
    +		r = verity_hash_update(v, req, v->salt, v->salt_size, wait);
     
     		if (r < 0) {
     			DMERR("verity_hash_final failed updating salt: %d", r);
    @@ -187,7 +146,7 @@ static int verity_hash_final(struct dm_verity *v, struct ahash_request *req,
     	}
     
     	ahash_request_set_crypt(req, NULL, digest, 0);
    -	r = verity_complete_op(res, crypto_ahash_final(req));
    +	r = crypto_wait_req(crypto_ahash_final(req), wait);
     out:
     	return r;
     }
    @@ -196,17 +155,17 @@ int verity_hash(struct dm_verity *v, struct ahash_request *req,
     		const u8 *data, size_t len, u8 *digest)
     {
     	int r;
    -	struct verity_result res;
    +	struct crypto_wait wait;
     
    -	r = verity_hash_init(v, req, &res);
    +	r = verity_hash_init(v, req, &wait);
     	if (unlikely(r < 0))
     		goto out;
     
    -	r = verity_hash_update(v, req, data, len, &res);
    +	r = verity_hash_update(v, req, data, len, &wait);
     	if (unlikely(r < 0))
     		goto out;
     
    -	r = verity_hash_final(v, req, digest, &res);
    +	r = verity_hash_final(v, req, digest, &wait);
     
     out:
     	return r;
    @@ -389,7 +348,7 @@ int verity_hash_for_block(struct dm_verity *v, struct dm_verity_io *io,
      * Calculates the digest for the given bio
      */
     int verity_for_io_block(struct dm_verity *v, struct dm_verity_io *io,
    -			struct bvec_iter *iter, struct verity_result *res)
    +			struct bvec_iter *iter, struct crypto_wait *wait)
     {
     	unsigned int todo = 1 << v->data_dev_block_bits;
     	struct bio *bio = dm_bio_from_per_bio_data(io, v->ti->per_io_data_size);
    @@ -414,7 +373,7 @@ int verity_for_io_block(struct dm_verity *v, struct dm_verity_io *io,
     		 */
     		sg_set_page(&sg, bv.bv_page, len, bv.bv_offset);
     		ahash_request_set_crypt(req, &sg, NULL, len);
    -		r = verity_complete_op(res, crypto_ahash_update(req));
    +		r = crypto_wait_req(crypto_ahash_update(req), wait);
     
     		if (unlikely(r < 0)) {
     			DMERR("verity_for_io_block crypto op failed: %d", r);
    @@ -482,7 +441,7 @@ static int verity_verify_io(struct dm_verity_io *io)
     	struct dm_verity *v = io->v;
     	struct bvec_iter start;
     	unsigned b;
    -	struct verity_result res;
    +	struct crypto_wait wait;
     
     	for (b = 0; b < io->n_blocks; b++) {
     		int r;
    @@ -507,17 +466,17 @@ static int verity_verify_io(struct dm_verity_io *io)
     			continue;
     		}
     
    -		r = verity_hash_init(v, req, &res);
    +		r = verity_hash_init(v, req, &wait);
     		if (unlikely(r < 0))
     			return r;
     
     		start = io->iter;
    -		r = verity_for_io_block(v, io, &io->iter, &res);
    +		r = verity_for_io_block(v, io, &io->iter, &wait);
     		if (unlikely(r < 0))
     			return r;
     
     		r = verity_hash_final(v, req, verity_io_real_digest(v, io),
    -					&res);
    +					&wait);
     		if (unlikely(r < 0))
     			return r;
     
    diff --git a/drivers/md/dm-verity.h b/drivers/md/dm-verity.h
    index a59e0ad..b675bc0 100644
    --- a/drivers/md/dm-verity.h
    +++ b/drivers/md/dm-verity.h
    @@ -90,11 +90,6 @@ struct dm_verity_io {
     	 */
     };
     
    -struct verity_result {
    -	struct completion completion;
    -	int err;
    -};
    -
     static inline struct ahash_request *verity_io_hash_req(struct dm_verity *v,
     						     struct dm_verity_io *io)
     {
    -- 
    2.1.4
    
    
    ^ permalink raw reply related	[flat|nested] 58+ messages in thread
  • * [PATCH v5 12/19] dm: move dm-verity to generic async completion
           [not found] <1502724094-23305-1-git-send-email-gilad@benyossef.com>
                       ` (21 preceding siblings ...)
      2017-08-14 15:21 ` [PATCH v5 12/19] dm: move dm-verity " Gilad Ben-Yossef
    @ 2017-08-14 15:21 ` Gilad Ben-Yossef
      2017-08-14 15:21 ` [PATCH v5 13/19] cifs: move " Gilad Ben-Yossef
                       ` (17 subsequent siblings)
      40 siblings, 0 replies; 58+ messages in thread
    From: Gilad Ben-Yossef @ 2017-08-14 15:21 UTC (permalink / raw)
      To: Herbert Xu, David S. Miller, Jonathan Corbet, David Howells,
    	Tom Lendacky, Gary Hook, Boris Brezillon, Arnaud Ebalard,
    	Matthias Brugger, Alasdair Kergon, Mike Snitzer, dm-devel,
    	Shaohua Li, Steve French, Theodore Y. Ts'o, Jaegeuk Kim,
    	Mimi Zohar, Dmitry Kasatkin, James Morris, Serge E. Hallyn,
    	linux-crypto, linux-doc, linux-kernel, keyrings, linux-arm-kernel
      Cc: Ofir Drang
    
    dm-verity is starting async. crypto ops and waiting for them to complete.
    Move it over to generic code doing the same.
    
    This also fixes a possible data coruption bug created by the
    use of wait_for_completion_interruptible() without dealing
    correctly with an interrupt aborting the wait prior to the
    async op finishing.
    
    Signed-off-by: Gilad Ben-Yossef <gilad@benyossef.com>
    ---
     drivers/md/dm-verity-target.c | 81 +++++++++++--------------------------------
     drivers/md/dm-verity.h        |  5 ---
     2 files changed, 20 insertions(+), 66 deletions(-)
    
    diff --git a/drivers/md/dm-verity-target.c b/drivers/md/dm-verity-target.c
    index 79f18d4..8df08a8 100644
    --- a/drivers/md/dm-verity-target.c
    +++ b/drivers/md/dm-verity-target.c
    @@ -92,74 +92,33 @@ static sector_t verity_position_at_level(struct dm_verity *v, sector_t block,
     	return block >> (level * v->hash_per_block_bits);
     }
     
    -/*
    - * Callback function for asynchrnous crypto API completion notification
    - */
    -static void verity_op_done(struct crypto_async_request *base, int err)
    -{
    -	struct verity_result *res = (struct verity_result *)base->data;
    -
    -	if (err == -EINPROGRESS)
    -		return;
    -
    -	res->err = err;
    -	complete(&res->completion);
    -}
    -
    -/*
    - * Wait for async crypto API callback
    - */
    -static inline int verity_complete_op(struct verity_result *res, int ret)
    -{
    -	switch (ret) {
    -	case 0:
    -		break;
    -
    -	case -EINPROGRESS:
    -	case -EBUSY:
    -		ret = wait_for_completion_interruptible(&res->completion);
    -		if (!ret)
    -			ret = res->err;
    -		reinit_completion(&res->completion);
    -		break;
    -
    -	default:
    -		DMERR("verity_wait_hash: crypto op submission failed: %d", ret);
    -	}
    -
    -	if (unlikely(ret < 0))
    -		DMERR("verity_wait_hash: crypto op failed: %d", ret);
    -
    -	return ret;
    -}
    -
     static int verity_hash_update(struct dm_verity *v, struct ahash_request *req,
     				const u8 *data, size_t len,
    -				struct verity_result *res)
    +				struct crypto_wait *wait)
     {
     	struct scatterlist sg;
     
     	sg_init_one(&sg, data, len);
     	ahash_request_set_crypt(req, &sg, NULL, len);
     
    -	return verity_complete_op(res, crypto_ahash_update(req));
    +	return crypto_wait_req(crypto_ahash_update(req), wait);
     }
     
     /*
      * Wrapper for crypto_ahash_init, which handles verity salting.
      */
     static int verity_hash_init(struct dm_verity *v, struct ahash_request *req,
    -				struct verity_result *res)
    +				struct crypto_wait *wait)
     {
     	int r;
     
     	ahash_request_set_tfm(req, v->tfm);
     	ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_SLEEP |
     					CRYPTO_TFM_REQ_MAY_BACKLOG,
    -					verity_op_done, (void *)res);
    -	init_completion(&res->completion);
    +					crypto_req_done, (void *)wait);
    +	crypto_init_wait(wait);
     
    -	r = verity_complete_op(res, crypto_ahash_init(req));
    +	r = crypto_wait_req(crypto_ahash_init(req), wait);
     
     	if (unlikely(r < 0)) {
     		DMERR("crypto_ahash_init failed: %d", r);
    @@ -167,18 +126,18 @@ static int verity_hash_init(struct dm_verity *v, struct ahash_request *req,
     	}
     
     	if (likely(v->salt_size && (v->version >= 1)))
    -		r = verity_hash_update(v, req, v->salt, v->salt_size, res);
    +		r = verity_hash_update(v, req, v->salt, v->salt_size, wait);
     
     	return r;
     }
     
     static int verity_hash_final(struct dm_verity *v, struct ahash_request *req,
    -			     u8 *digest, struct verity_result *res)
    +			     u8 *digest, struct crypto_wait *wait)
     {
     	int r;
     
     	if (unlikely(v->salt_size && (!v->version))) {
    -		r = verity_hash_update(v, req, v->salt, v->salt_size, res);
    +		r = verity_hash_update(v, req, v->salt, v->salt_size, wait);
     
     		if (r < 0) {
     			DMERR("verity_hash_final failed updating salt: %d", r);
    @@ -187,7 +146,7 @@ static int verity_hash_final(struct dm_verity *v, struct ahash_request *req,
     	}
     
     	ahash_request_set_crypt(req, NULL, digest, 0);
    -	r = verity_complete_op(res, crypto_ahash_final(req));
    +	r = crypto_wait_req(crypto_ahash_final(req), wait);
     out:
     	return r;
     }
    @@ -196,17 +155,17 @@ int verity_hash(struct dm_verity *v, struct ahash_request *req,
     		const u8 *data, size_t len, u8 *digest)
     {
     	int r;
    -	struct verity_result res;
    +	struct crypto_wait wait;
     
    -	r = verity_hash_init(v, req, &res);
    +	r = verity_hash_init(v, req, &wait);
     	if (unlikely(r < 0))
     		goto out;
     
    -	r = verity_hash_update(v, req, data, len, &res);
    +	r = verity_hash_update(v, req, data, len, &wait);
     	if (unlikely(r < 0))
     		goto out;
     
    -	r = verity_hash_final(v, req, digest, &res);
    +	r = verity_hash_final(v, req, digest, &wait);
     
     out:
     	return r;
    @@ -389,7 +348,7 @@ int verity_hash_for_block(struct dm_verity *v, struct dm_verity_io *io,
      * Calculates the digest for the given bio
      */
     int verity_for_io_block(struct dm_verity *v, struct dm_verity_io *io,
    -			struct bvec_iter *iter, struct verity_result *res)
    +			struct bvec_iter *iter, struct crypto_wait *wait)
     {
     	unsigned int todo = 1 << v->data_dev_block_bits;
     	struct bio *bio = dm_bio_from_per_bio_data(io, v->ti->per_io_data_size);
    @@ -414,7 +373,7 @@ int verity_for_io_block(struct dm_verity *v, struct dm_verity_io *io,
     		 */
     		sg_set_page(&sg, bv.bv_page, len, bv.bv_offset);
     		ahash_request_set_crypt(req, &sg, NULL, len);
    -		r = verity_complete_op(res, crypto_ahash_update(req));
    +		r = crypto_wait_req(crypto_ahash_update(req), wait);
     
     		if (unlikely(r < 0)) {
     			DMERR("verity_for_io_block crypto op failed: %d", r);
    @@ -482,7 +441,7 @@ static int verity_verify_io(struct dm_verity_io *io)
     	struct dm_verity *v = io->v;
     	struct bvec_iter start;
     	unsigned b;
    -	struct verity_result res;
    +	struct crypto_wait wait;
     
     	for (b = 0; b < io->n_blocks; b++) {
     		int r;
    @@ -507,17 +466,17 @@ static int verity_verify_io(struct dm_verity_io *io)
     			continue;
     		}
     
    -		r = verity_hash_init(v, req, &res);
    +		r = verity_hash_init(v, req, &wait);
     		if (unlikely(r < 0))
     			return r;
     
     		start = io->iter;
    -		r = verity_for_io_block(v, io, &io->iter, &res);
    +		r = verity_for_io_block(v, io, &io->iter, &wait);
     		if (unlikely(r < 0))
     			return r;
     
     		r = verity_hash_final(v, req, verity_io_real_digest(v, io),
    -					&res);
    +					&wait);
     		if (unlikely(r < 0))
     			return r;
     
    diff --git a/drivers/md/dm-verity.h b/drivers/md/dm-verity.h
    index a59e0ad..b675bc0 100644
    --- a/drivers/md/dm-verity.h
    +++ b/drivers/md/dm-verity.h
    @@ -90,11 +90,6 @@ struct dm_verity_io {
     	 */
     };
     
    -struct verity_result {
    -	struct completion completion;
    -	int err;
    -};
    -
     static inline struct ahash_request *verity_io_hash_req(struct dm_verity *v,
     						     struct dm_verity_io *io)
     {
    -- 
    2.1.4
    
    ^ permalink raw reply related	[flat|nested] 58+ messages in thread
  • * [PATCH v5 13/19] cifs: move to generic async completion
           [not found] <1502724094-23305-1-git-send-email-gilad@benyossef.com>
                       ` (22 preceding siblings ...)
      2017-08-14 15:21 ` Gilad Ben-Yossef
    @ 2017-08-14 15:21 ` Gilad Ben-Yossef
      2017-08-14 15:21 ` Gilad Ben-Yossef
                       ` (16 subsequent siblings)
      40 siblings, 0 replies; 58+ messages in thread
    From: Gilad Ben-Yossef @ 2017-08-14 15:21 UTC (permalink / raw)
      To: Herbert Xu, David S. Miller, Jonathan Corbet, David Howells,
    	Tom Lendacky, Gary Hook, Boris Brezillon, Arnaud Ebalard,
    	Matthias Brugger, Alasdair Kergon, Mike Snitzer, dm-devel,
    	Shaohua Li, Steve French, Theodore Y. Ts'o, Jaegeuk Kim,
    	Mimi Zohar, Dmitry Kasatkin, James Morris, Serge E. Hallyn,
    	linux-crypto
      Cc: Ofir Drang
    
    cifs starts an async. crypto op and waits for their completion.
    Move it over to generic code doing the same.
    
    Signed-off-by: Gilad Ben-Yossef <gilad@benyossef.com>
    Acked-by: Pavel Shilovsky <pshilov@microsoft.com>
    ---
     fs/cifs/smb2ops.c | 30 ++++--------------------------
     1 file changed, 4 insertions(+), 26 deletions(-)
    
    diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c
    index cfacf2c..16fb041 100644
    --- a/fs/cifs/smb2ops.c
    +++ b/fs/cifs/smb2ops.c
    @@ -1878,22 +1878,6 @@ init_sg(struct smb_rqst *rqst, u8 *sign)
     	return sg;
     }
     
    -struct cifs_crypt_result {
    -	int err;
    -	struct completion completion;
    -};
    -
    -static void cifs_crypt_complete(struct crypto_async_request *req, int err)
    -{
    -	struct cifs_crypt_result *res = req->data;
    -
    -	if (err == -EINPROGRESS)
    -		return;
    -
    -	res->err = err;
    -	complete(&res->completion);
    -}
    -
     static int
     smb2_get_enc_key(struct TCP_Server_Info *server, __u64 ses_id, int enc, u8 *key)
     {
    @@ -1934,12 +1918,10 @@ crypt_message(struct TCP_Server_Info *server, struct smb_rqst *rqst, int enc)
     	struct aead_request *req;
     	char *iv;
     	unsigned int iv_len;
    -	struct cifs_crypt_result result = {0, };
    +	DECLARE_CRYPTO_WAIT(wait);
     	struct crypto_aead *tfm;
     	unsigned int crypt_len = le32_to_cpu(tr_hdr->OriginalMessageSize);
     
    -	init_completion(&result.completion);
    -
     	rc = smb2_get_enc_key(server, tr_hdr->SessionId, enc, key);
     	if (rc) {
     		cifs_dbg(VFS, "%s: Could not get %scryption key\n", __func__,
    @@ -1999,14 +1981,10 @@ crypt_message(struct TCP_Server_Info *server, struct smb_rqst *rqst, int enc)
     	aead_request_set_ad(req, assoc_data_len);
     
     	aead_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
    -				  cifs_crypt_complete, &result);
    +				  crypto_req_done, &wait);
     
    -	rc = enc ? crypto_aead_encrypt(req) : crypto_aead_decrypt(req);
    -
    -	if (rc == -EINPROGRESS || rc == -EBUSY) {
    -		wait_for_completion(&result.completion);
    -		rc = result.err;
    -	}
    +	rc = crypto_wait_req(enc ? crypto_aead_encrypt(req)
    +				: crypto_aead_decrypt(req), &wait);
     
     	if (!rc && enc)
     		memcpy(&tr_hdr->Signature, sign, SMB2_SIGNATURE_SIZE);
    -- 
    2.1.4
    
    
    ^ permalink raw reply related	[flat|nested] 58+ messages in thread
  • * [PATCH v5 13/19] cifs: move to generic async completion
           [not found] <1502724094-23305-1-git-send-email-gilad@benyossef.com>
                       ` (23 preceding siblings ...)
      2017-08-14 15:21 ` [PATCH v5 13/19] cifs: move " Gilad Ben-Yossef
    @ 2017-08-14 15:21 ` Gilad Ben-Yossef
      2017-08-14 15:21 ` [PATCH v5 14/19] ima: " Gilad Ben-Yossef
                       ` (15 subsequent siblings)
      40 siblings, 0 replies; 58+ messages in thread
    From: Gilad Ben-Yossef @ 2017-08-14 15:21 UTC (permalink / raw)
      To: Herbert Xu, David S. Miller, Jonathan Corbet, David Howells,
    	Tom Lendacky, Gary Hook, Boris Brezillon, Arnaud Ebalard,
    	Matthias Brugger, Alasdair Kergon, Mike Snitzer, dm-devel,
    	Shaohua Li, Steve French, Theodore Y. Ts'o, Jaegeuk Kim,
    	Mimi Zohar, Dmitry Kasatkin, James Morris, Serge E. Hallyn,
    	linux-crypto, linux-doc, linux-kernel, keyrings, linux-arm-kernel
      Cc: Ofir Drang
    
    cifs starts an async. crypto op and waits for their completion.
    Move it over to generic code doing the same.
    
    Signed-off-by: Gilad Ben-Yossef <gilad@benyossef.com>
    Acked-by: Pavel Shilovsky <pshilov@microsoft.com>
    ---
     fs/cifs/smb2ops.c | 30 ++++--------------------------
     1 file changed, 4 insertions(+), 26 deletions(-)
    
    diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c
    index cfacf2c..16fb041 100644
    --- a/fs/cifs/smb2ops.c
    +++ b/fs/cifs/smb2ops.c
    @@ -1878,22 +1878,6 @@ init_sg(struct smb_rqst *rqst, u8 *sign)
     	return sg;
     }
     
    -struct cifs_crypt_result {
    -	int err;
    -	struct completion completion;
    -};
    -
    -static void cifs_crypt_complete(struct crypto_async_request *req, int err)
    -{
    -	struct cifs_crypt_result *res = req->data;
    -
    -	if (err == -EINPROGRESS)
    -		return;
    -
    -	res->err = err;
    -	complete(&res->completion);
    -}
    -
     static int
     smb2_get_enc_key(struct TCP_Server_Info *server, __u64 ses_id, int enc, u8 *key)
     {
    @@ -1934,12 +1918,10 @@ crypt_message(struct TCP_Server_Info *server, struct smb_rqst *rqst, int enc)
     	struct aead_request *req;
     	char *iv;
     	unsigned int iv_len;
    -	struct cifs_crypt_result result = {0, };
    +	DECLARE_CRYPTO_WAIT(wait);
     	struct crypto_aead *tfm;
     	unsigned int crypt_len = le32_to_cpu(tr_hdr->OriginalMessageSize);
     
    -	init_completion(&result.completion);
    -
     	rc = smb2_get_enc_key(server, tr_hdr->SessionId, enc, key);
     	if (rc) {
     		cifs_dbg(VFS, "%s: Could not get %scryption key\n", __func__,
    @@ -1999,14 +1981,10 @@ crypt_message(struct TCP_Server_Info *server, struct smb_rqst *rqst, int enc)
     	aead_request_set_ad(req, assoc_data_len);
     
     	aead_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
    -				  cifs_crypt_complete, &result);
    +				  crypto_req_done, &wait);
     
    -	rc = enc ? crypto_aead_encrypt(req) : crypto_aead_decrypt(req);
    -
    -	if (rc == -EINPROGRESS || rc == -EBUSY) {
    -		wait_for_completion(&result.completion);
    -		rc = result.err;
    -	}
    +	rc = crypto_wait_req(enc ? crypto_aead_encrypt(req)
    +				: crypto_aead_decrypt(req), &wait);
     
     	if (!rc && enc)
     		memcpy(&tr_hdr->Signature, sign, SMB2_SIGNATURE_SIZE);
    -- 
    2.1.4
    
    ^ permalink raw reply related	[flat|nested] 58+ messages in thread
  • * [PATCH v5 14/19] ima: move to generic async completion
           [not found] <1502724094-23305-1-git-send-email-gilad@benyossef.com>
                       ` (24 preceding siblings ...)
      2017-08-14 15:21 ` Gilad Ben-Yossef
    @ 2017-08-14 15:21 ` Gilad Ben-Yossef
      2017-08-14 15:21 ` Gilad Ben-Yossef
                       ` (14 subsequent siblings)
      40 siblings, 0 replies; 58+ messages in thread
    From: Gilad Ben-Yossef @ 2017-08-14 15:21 UTC (permalink / raw)
      To: Herbert Xu, David S. Miller, Jonathan Corbet, David Howells,
    	Tom Lendacky, Gary Hook, Boris Brezillon, Arnaud Ebalard,
    	Matthias Brugger, Alasdair Kergon, Mike Snitzer, dm-devel,
    	Shaohua Li, Steve French, Theodore Y. Ts'o, Jaegeuk Kim,
    	Mimi Zohar, Dmitry Kasatkin, James Morris, Serge E. Hallyn,
    	linux-crypto
      Cc: Ofir Drang
    
    ima starts several async crypto ops and  waits for their completions.
    Move it over to generic code doing the same.
    
    Signed-off-by: Gilad Ben-Yossef <gilad@benyossef.com>
    Acked-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
    ---
     security/integrity/ima/ima_crypto.c | 56 +++++++++++--------------------------
     1 file changed, 17 insertions(+), 39 deletions(-)
    
    diff --git a/security/integrity/ima/ima_crypto.c b/security/integrity/ima/ima_crypto.c
    index 802d5d2..0e4db1fe 100644
    --- a/security/integrity/ima/ima_crypto.c
    +++ b/security/integrity/ima/ima_crypto.c
    @@ -27,11 +27,6 @@
     
     #include "ima.h"
     
    -struct ahash_completion {
    -	struct completion completion;
    -	int err;
    -};
    -
     /* minimum file size for ahash use */
     static unsigned long ima_ahash_minsize;
     module_param_named(ahash_minsize, ima_ahash_minsize, ulong, 0644);
    @@ -196,30 +191,13 @@ static void ima_free_atfm(struct crypto_ahash *tfm)
     		crypto_free_ahash(tfm);
     }
     
    -static void ahash_complete(struct crypto_async_request *req, int err)
    +static inline int ahash_wait(int err, struct crypto_wait *wait)
     {
    -	struct ahash_completion *res = req->data;
     
    -	if (err == -EINPROGRESS)
    -		return;
    -	res->err = err;
    -	complete(&res->completion);
    -}
    +	err = crypto_wait_req(err, wait);
     
    -static int ahash_wait(int err, struct ahash_completion *res)
    -{
    -	switch (err) {
    -	case 0:
    -		break;
    -	case -EINPROGRESS:
    -	case -EBUSY:
    -		wait_for_completion(&res->completion);
    -		reinit_completion(&res->completion);
    -		err = res->err;
    -		/* fall through */
    -	default:
    +	if (err)
     		pr_crit_ratelimited("ahash calculation failed: err: %d\n", err);
    -	}
     
     	return err;
     }
    @@ -233,7 +211,7 @@ static int ima_calc_file_hash_atfm(struct file *file,
     	int rc, read = 0, rbuf_len, active = 0, ahash_rc = 0;
     	struct ahash_request *req;
     	struct scatterlist sg[1];
    -	struct ahash_completion res;
    +	struct crypto_wait wait;
     	size_t rbuf_size[2];
     
     	hash->length = crypto_ahash_digestsize(tfm);
    @@ -242,12 +220,12 @@ static int ima_calc_file_hash_atfm(struct file *file,
     	if (!req)
     		return -ENOMEM;
     
    -	init_completion(&res.completion);
    +	crypto_init_wait(&wait);
     	ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG |
     				   CRYPTO_TFM_REQ_MAY_SLEEP,
    -				   ahash_complete, &res);
    +				   crypto_req_done, &wait);
     
    -	rc = ahash_wait(crypto_ahash_init(req), &res);
    +	rc = ahash_wait(crypto_ahash_init(req), &wait);
     	if (rc)
     		goto out1;
     
    @@ -288,7 +266,7 @@ static int ima_calc_file_hash_atfm(struct file *file,
     			 * read/request, wait for the completion of the
     			 * previous ahash_update() request.
     			 */
    -			rc = ahash_wait(ahash_rc, &res);
    +			rc = ahash_wait(ahash_rc, &wait);
     			if (rc)
     				goto out3;
     		}
    @@ -304,7 +282,7 @@ static int ima_calc_file_hash_atfm(struct file *file,
     			 * read/request, wait for the completion of the
     			 * previous ahash_update() request.
     			 */
    -			rc = ahash_wait(ahash_rc, &res);
    +			rc = ahash_wait(ahash_rc, &wait);
     			if (rc)
     				goto out3;
     		}
    @@ -318,7 +296,7 @@ static int ima_calc_file_hash_atfm(struct file *file,
     			active = !active; /* swap buffers, if we use two */
     	}
     	/* wait for the last update request to complete */
    -	rc = ahash_wait(ahash_rc, &res);
    +	rc = ahash_wait(ahash_rc, &wait);
     out3:
     	if (read)
     		file->f_mode &= ~FMODE_READ;
    @@ -327,7 +305,7 @@ static int ima_calc_file_hash_atfm(struct file *file,
     out2:
     	if (!rc) {
     		ahash_request_set_crypt(req, NULL, hash->digest, 0);
    -		rc = ahash_wait(crypto_ahash_final(req), &res);
    +		rc = ahash_wait(crypto_ahash_final(req), &wait);
     	}
     out1:
     	ahash_request_free(req);
    @@ -527,7 +505,7 @@ static int calc_buffer_ahash_atfm(const void *buf, loff_t len,
     {
     	struct ahash_request *req;
     	struct scatterlist sg;
    -	struct ahash_completion res;
    +	struct crypto_wait wait;
     	int rc, ahash_rc = 0;
     
     	hash->length = crypto_ahash_digestsize(tfm);
    @@ -536,12 +514,12 @@ static int calc_buffer_ahash_atfm(const void *buf, loff_t len,
     	if (!req)
     		return -ENOMEM;
     
    -	init_completion(&res.completion);
    +	crypto_init_wait(&wait);
     	ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG |
     				   CRYPTO_TFM_REQ_MAY_SLEEP,
    -				   ahash_complete, &res);
    +				   crypto_req_done, &wait);
     
    -	rc = ahash_wait(crypto_ahash_init(req), &res);
    +	rc = ahash_wait(crypto_ahash_init(req), &wait);
     	if (rc)
     		goto out;
     
    @@ -551,10 +529,10 @@ static int calc_buffer_ahash_atfm(const void *buf, loff_t len,
     	ahash_rc = crypto_ahash_update(req);
     
     	/* wait for the update request to complete */
    -	rc = ahash_wait(ahash_rc, &res);
    +	rc = ahash_wait(ahash_rc, &wait);
     	if (!rc) {
     		ahash_request_set_crypt(req, NULL, hash->digest, 0);
    -		rc = ahash_wait(crypto_ahash_final(req), &res);
    +		rc = ahash_wait(crypto_ahash_final(req), &wait);
     	}
     out:
     	ahash_request_free(req);
    -- 
    2.1.4
    
    
    ^ permalink raw reply related	[flat|nested] 58+ messages in thread
  • * [PATCH v5 14/19] ima: move to generic async completion
           [not found] <1502724094-23305-1-git-send-email-gilad@benyossef.com>
                       ` (25 preceding siblings ...)
      2017-08-14 15:21 ` [PATCH v5 14/19] ima: " Gilad Ben-Yossef
    @ 2017-08-14 15:21 ` Gilad Ben-Yossef
      2017-08-14 15:21 ` [PATCH v5 15/19] crypto: tcrypt: " Gilad Ben-Yossef
                       ` (13 subsequent siblings)
      40 siblings, 0 replies; 58+ messages in thread
    From: Gilad Ben-Yossef @ 2017-08-14 15:21 UTC (permalink / raw)
      To: Herbert Xu, David S. Miller, Jonathan Corbet, David Howells,
    	Tom Lendacky, Gary Hook, Boris Brezillon, Arnaud Ebalard,
    	Matthias Brugger, Alasdair Kergon, Mike Snitzer, dm-devel,
    	Shaohua Li, Steve French, Theodore Y. Ts'o, Jaegeuk Kim,
    	Mimi Zohar, Dmitry Kasatkin, James Morris, Serge E. Hallyn,
    	linux-crypto, linux-doc, linux-kernel, keyrings, linux-arm-kernel
      Cc: Ofir Drang
    
    ima starts several async crypto ops and  waits for their completions.
    Move it over to generic code doing the same.
    
    Signed-off-by: Gilad Ben-Yossef <gilad@benyossef.com>
    Acked-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
    ---
     security/integrity/ima/ima_crypto.c | 56 +++++++++++--------------------------
     1 file changed, 17 insertions(+), 39 deletions(-)
    
    diff --git a/security/integrity/ima/ima_crypto.c b/security/integrity/ima/ima_crypto.c
    index 802d5d2..0e4db1fe 100644
    --- a/security/integrity/ima/ima_crypto.c
    +++ b/security/integrity/ima/ima_crypto.c
    @@ -27,11 +27,6 @@
     
     #include "ima.h"
     
    -struct ahash_completion {
    -	struct completion completion;
    -	int err;
    -};
    -
     /* minimum file size for ahash use */
     static unsigned long ima_ahash_minsize;
     module_param_named(ahash_minsize, ima_ahash_minsize, ulong, 0644);
    @@ -196,30 +191,13 @@ static void ima_free_atfm(struct crypto_ahash *tfm)
     		crypto_free_ahash(tfm);
     }
     
    -static void ahash_complete(struct crypto_async_request *req, int err)
    +static inline int ahash_wait(int err, struct crypto_wait *wait)
     {
    -	struct ahash_completion *res = req->data;
     
    -	if (err == -EINPROGRESS)
    -		return;
    -	res->err = err;
    -	complete(&res->completion);
    -}
    +	err = crypto_wait_req(err, wait);
     
    -static int ahash_wait(int err, struct ahash_completion *res)
    -{
    -	switch (err) {
    -	case 0:
    -		break;
    -	case -EINPROGRESS:
    -	case -EBUSY:
    -		wait_for_completion(&res->completion);
    -		reinit_completion(&res->completion);
    -		err = res->err;
    -		/* fall through */
    -	default:
    +	if (err)
     		pr_crit_ratelimited("ahash calculation failed: err: %d\n", err);
    -	}
     
     	return err;
     }
    @@ -233,7 +211,7 @@ static int ima_calc_file_hash_atfm(struct file *file,
     	int rc, read = 0, rbuf_len, active = 0, ahash_rc = 0;
     	struct ahash_request *req;
     	struct scatterlist sg[1];
    -	struct ahash_completion res;
    +	struct crypto_wait wait;
     	size_t rbuf_size[2];
     
     	hash->length = crypto_ahash_digestsize(tfm);
    @@ -242,12 +220,12 @@ static int ima_calc_file_hash_atfm(struct file *file,
     	if (!req)
     		return -ENOMEM;
     
    -	init_completion(&res.completion);
    +	crypto_init_wait(&wait);
     	ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG |
     				   CRYPTO_TFM_REQ_MAY_SLEEP,
    -				   ahash_complete, &res);
    +				   crypto_req_done, &wait);
     
    -	rc = ahash_wait(crypto_ahash_init(req), &res);
    +	rc = ahash_wait(crypto_ahash_init(req), &wait);
     	if (rc)
     		goto out1;
     
    @@ -288,7 +266,7 @@ static int ima_calc_file_hash_atfm(struct file *file,
     			 * read/request, wait for the completion of the
     			 * previous ahash_update() request.
     			 */
    -			rc = ahash_wait(ahash_rc, &res);
    +			rc = ahash_wait(ahash_rc, &wait);
     			if (rc)
     				goto out3;
     		}
    @@ -304,7 +282,7 @@ static int ima_calc_file_hash_atfm(struct file *file,
     			 * read/request, wait for the completion of the
     			 * previous ahash_update() request.
     			 */
    -			rc = ahash_wait(ahash_rc, &res);
    +			rc = ahash_wait(ahash_rc, &wait);
     			if (rc)
     				goto out3;
     		}
    @@ -318,7 +296,7 @@ static int ima_calc_file_hash_atfm(struct file *file,
     			active = !active; /* swap buffers, if we use two */
     	}
     	/* wait for the last update request to complete */
    -	rc = ahash_wait(ahash_rc, &res);
    +	rc = ahash_wait(ahash_rc, &wait);
     out3:
     	if (read)
     		file->f_mode &= ~FMODE_READ;
    @@ -327,7 +305,7 @@ static int ima_calc_file_hash_atfm(struct file *file,
     out2:
     	if (!rc) {
     		ahash_request_set_crypt(req, NULL, hash->digest, 0);
    -		rc = ahash_wait(crypto_ahash_final(req), &res);
    +		rc = ahash_wait(crypto_ahash_final(req), &wait);
     	}
     out1:
     	ahash_request_free(req);
    @@ -527,7 +505,7 @@ static int calc_buffer_ahash_atfm(const void *buf, loff_t len,
     {
     	struct ahash_request *req;
     	struct scatterlist sg;
    -	struct ahash_completion res;
    +	struct crypto_wait wait;
     	int rc, ahash_rc = 0;
     
     	hash->length = crypto_ahash_digestsize(tfm);
    @@ -536,12 +514,12 @@ static int calc_buffer_ahash_atfm(const void *buf, loff_t len,
     	if (!req)
     		return -ENOMEM;
     
    -	init_completion(&res.completion);
    +	crypto_init_wait(&wait);
     	ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG |
     				   CRYPTO_TFM_REQ_MAY_SLEEP,
    -				   ahash_complete, &res);
    +				   crypto_req_done, &wait);
     
    -	rc = ahash_wait(crypto_ahash_init(req), &res);
    +	rc = ahash_wait(crypto_ahash_init(req), &wait);
     	if (rc)
     		goto out;
     
    @@ -551,10 +529,10 @@ static int calc_buffer_ahash_atfm(const void *buf, loff_t len,
     	ahash_rc = crypto_ahash_update(req);
     
     	/* wait for the update request to complete */
    -	rc = ahash_wait(ahash_rc, &res);
    +	rc = ahash_wait(ahash_rc, &wait);
     	if (!rc) {
     		ahash_request_set_crypt(req, NULL, hash->digest, 0);
    -		rc = ahash_wait(crypto_ahash_final(req), &res);
    +		rc = ahash_wait(crypto_ahash_final(req), &wait);
     	}
     out:
     	ahash_request_free(req);
    -- 
    2.1.4
    
    ^ permalink raw reply related	[flat|nested] 58+ messages in thread
  • * [PATCH v5 15/19] crypto: tcrypt: move to generic async completion
           [not found] <1502724094-23305-1-git-send-email-gilad@benyossef.com>
                       ` (26 preceding siblings ...)
      2017-08-14 15:21 ` Gilad Ben-Yossef
    @ 2017-08-14 15:21 ` Gilad Ben-Yossef
      2017-08-14 15:21 ` [PATCH v5 16/19] crypto: talitos: " Gilad Ben-Yossef
                       ` (12 subsequent siblings)
      40 siblings, 0 replies; 58+ messages in thread
    From: Gilad Ben-Yossef @ 2017-08-14 15:21 UTC (permalink / raw)
      To: Herbert Xu, David S. Miller, Jonathan Corbet, David Howells,
    	Tom Lendacky, Gary Hook, Boris Brezillon, Arnaud Ebalard,
    	Matthias Brugger, Alasdair Kergon, Mike Snitzer, dm-devel,
    	Shaohua Li, Steve French, Theodore Y. Ts'o, Jaegeuk Kim,
    	Mimi Zohar, Dmitry Kasatkin, James Morris, Serge E. Hallyn,
    	linux-crypto
      Cc: Ofir Drang
    
    tcrypt starts several async crypto ops and  waits for their completions.
    Move it over to generic code doing the same.
    
    Signed-off-by: Gilad Ben-Yossef <gilad@benyossef.com>
    ---
     crypto/tcrypt.c | 84 +++++++++++++++++----------------------------------------
     1 file changed, 25 insertions(+), 59 deletions(-)
    
    diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c
    index 0022a18..802aa81 100644
    --- a/crypto/tcrypt.c
    +++ b/crypto/tcrypt.c
    @@ -79,34 +79,11 @@ static char *check[] = {
     	NULL
     };
     
    -struct tcrypt_result {
    -	struct completion completion;
    -	int err;
    -};
    -
    -static void tcrypt_complete(struct crypto_async_request *req, int err)
    -{
    -	struct tcrypt_result *res = req->data;
    -
    -	if (err == -EINPROGRESS)
    -		return;
    -
    -	res->err = err;
    -	complete(&res->completion);
    -}
    -
     static inline int do_one_aead_op(struct aead_request *req, int ret)
     {
    -	if (ret == -EINPROGRESS || ret == -EBUSY) {
    -		struct tcrypt_result *tr = req->base.data;
    +	struct crypto_wait *wait = req->base.data;
     
    -		ret = wait_for_completion_interruptible(&tr->completion);
    -		if (!ret)
    -			ret = tr->err;
    -		reinit_completion(&tr->completion);
    -	}
    -
    -	return ret;
    +	return crypto_wait_req(ret, wait);
     }
     
     static int test_aead_jiffies(struct aead_request *req, int enc,
    @@ -248,7 +225,7 @@ static void test_aead_speed(const char *algo, int enc, unsigned int secs,
     	char *axbuf[XBUFSIZE];
     	unsigned int *b_size;
     	unsigned int iv_len;
    -	struct tcrypt_result result;
    +	struct crypto_wait wait;
     
     	iv = kzalloc(MAX_IVLEN, GFP_KERNEL);
     	if (!iv)
    @@ -284,7 +261,7 @@ static void test_aead_speed(const char *algo, int enc, unsigned int secs,
     		goto out_notfm;
     	}
     
    -	init_completion(&result.completion);
    +	crypto_init_wait(&wait);
     	printk(KERN_INFO "\ntesting speed of %s (%s) %s\n", algo,
     			get_driver_name(crypto_aead, tfm), e);
     
    @@ -296,7 +273,7 @@ static void test_aead_speed(const char *algo, int enc, unsigned int secs,
     	}
     
     	aead_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
    -				  tcrypt_complete, &result);
    +				  crypto_req_done, &wait);
     
     	i = 0;
     	do {
    @@ -397,21 +374,16 @@ static void test_hash_sg_init(struct scatterlist *sg)
     
     static inline int do_one_ahash_op(struct ahash_request *req, int ret)
     {
    -	if (ret == -EINPROGRESS || ret == -EBUSY) {
    -		struct tcrypt_result *tr = req->base.data;
    +	struct crypto_wait *wait = req->base.data;
     
    -		wait_for_completion(&tr->completion);
    -		reinit_completion(&tr->completion);
    -		ret = tr->err;
    -	}
    -	return ret;
    +	return crypto_wait_req(ret, wait);
     }
     
     struct test_mb_ahash_data {
     	struct scatterlist sg[TVMEMSIZE];
     	char result[64];
     	struct ahash_request *req;
    -	struct tcrypt_result tresult;
    +	struct crypto_wait wait;
     	char *xbuf[XBUFSIZE];
     };
     
    @@ -440,7 +412,7 @@ static void test_mb_ahash_speed(const char *algo, unsigned int sec,
     		if (testmgr_alloc_buf(data[i].xbuf))
     			goto out;
     
    -		init_completion(&data[i].tresult.completion);
    +		crypto_init_wait(&data[i].wait);
     
     		data[i].req = ahash_request_alloc(tfm, GFP_KERNEL);
     		if (!data[i].req) {
    @@ -449,8 +421,8 @@ static void test_mb_ahash_speed(const char *algo, unsigned int sec,
     			goto out;
     		}
     
    -		ahash_request_set_callback(data[i].req, 0,
    -					   tcrypt_complete, &data[i].tresult);
    +		ahash_request_set_callback(data[i].req, 0, crypto_req_done,
    +					   &data[i].wait);
     		test_hash_sg_init(data[i].sg);
     	}
     
    @@ -492,16 +464,16 @@ static void test_mb_ahash_speed(const char *algo, unsigned int sec,
     			if (ret)
     				break;
     
    -			complete(&data[k].tresult.completion);
    -			data[k].tresult.err = 0;
    +			crypto_req_done(&data[k].req->base, 0);
     		}
     
     		for (j = 0; j < k; j++) {
    -			struct tcrypt_result *tr = &data[j].tresult;
    +			struct crypto_wait *wait = &data[j].wait;
    +			int wait_ret;
     
    -			wait_for_completion(&tr->completion);
    -			if (tr->err)
    -				ret = tr->err;
    +			wait_ret = crypto_wait_req(-EINPROGRESS, wait);
    +			if (wait_ret)
    +				ret = wait_ret;
     		}
     
     		end = get_cycles();
    @@ -679,7 +651,7 @@ static void test_ahash_speed_common(const char *algo, unsigned int secs,
     				    struct hash_speed *speed, unsigned mask)
     {
     	struct scatterlist sg[TVMEMSIZE];
    -	struct tcrypt_result tresult;
    +	struct crypto_wait wait;
     	struct ahash_request *req;
     	struct crypto_ahash *tfm;
     	char *output;
    @@ -708,9 +680,9 @@ static void test_ahash_speed_common(const char *algo, unsigned int secs,
     		goto out;
     	}
     
    -	init_completion(&tresult.completion);
    +	crypto_init_wait(&wait);
     	ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
    -				   tcrypt_complete, &tresult);
    +				   crypto_req_done, &wait);
     
     	output = kmalloc(MAX_DIGEST_SIZE, GFP_KERNEL);
     	if (!output)
    @@ -765,15 +737,9 @@ static void test_hash_speed(const char *algo, unsigned int secs,
     
     static inline int do_one_acipher_op(struct skcipher_request *req, int ret)
     {
    -	if (ret == -EINPROGRESS || ret == -EBUSY) {
    -		struct tcrypt_result *tr = req->base.data;
    -
    -		wait_for_completion(&tr->completion);
    -		reinit_completion(&tr->completion);
    -		ret = tr->err;
    -	}
    +	struct crypto_wait *wait = req->base.data;
     
    -	return ret;
    +	return crypto_wait_req(ret, wait);
     }
     
     static int test_acipher_jiffies(struct skcipher_request *req, int enc,
    @@ -853,7 +819,7 @@ static void test_skcipher_speed(const char *algo, int enc, unsigned int secs,
     				unsigned int tcount, u8 *keysize, bool async)
     {
     	unsigned int ret, i, j, k, iv_len;
    -	struct tcrypt_result tresult;
    +	struct crypto_wait wait;
     	const char *key;
     	char iv[128];
     	struct skcipher_request *req;
    @@ -866,7 +832,7 @@ static void test_skcipher_speed(const char *algo, int enc, unsigned int secs,
     	else
     		e = "decryption";
     
    -	init_completion(&tresult.completion);
    +	crypto_init_wait(&wait);
     
     	tfm = crypto_alloc_skcipher(algo, 0, async ? 0 : CRYPTO_ALG_ASYNC);
     
    @@ -887,7 +853,7 @@ static void test_skcipher_speed(const char *algo, int enc, unsigned int secs,
     	}
     
     	skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
    -				      tcrypt_complete, &tresult);
    +				      crypto_req_done, &wait);
     
     	i = 0;
     	do {
    -- 
    2.1.4
    
    
    ^ permalink raw reply related	[flat|nested] 58+ messages in thread
  • * [PATCH v5 16/19] crypto: talitos: move to generic async completion
           [not found] <1502724094-23305-1-git-send-email-gilad@benyossef.com>
                       ` (27 preceding siblings ...)
      2017-08-14 15:21 ` [PATCH v5 15/19] crypto: tcrypt: " Gilad Ben-Yossef
    @ 2017-08-14 15:21 ` Gilad Ben-Yossef
      2017-08-14 15:21 ` Gilad Ben-Yossef
                       ` (11 subsequent siblings)
      40 siblings, 0 replies; 58+ messages in thread
    From: Gilad Ben-Yossef @ 2017-08-14 15:21 UTC (permalink / raw)
      To: Herbert Xu, David S. Miller, Jonathan Corbet, David Howells,
    	Tom Lendacky, Gary Hook, Boris Brezillon, Arnaud Ebalard,
    	Matthias Brugger, Alasdair Kergon, Mike Snitzer, dm-devel,
    	Shaohua Li, Steve French, Theodore Y. Ts'o, Jaegeuk Kim,
    	Mimi Zohar, Dmitry Kasatkin, James Morris, Serge E. Hallyn,
    	linux-crypto, linux-doc, linux-kernel, keyrings, linux-arm-kernel
      Cc: Ofir Drang
    
    The talitos driver starts several async crypto ops and  waits for their
    completions. Move it over to generic code doing the same.
    
    Signed-off-by: Gilad Ben-Yossef <gilad@benyossef.com>
    ---
     drivers/crypto/talitos.c | 38 +++++---------------------------------
     1 file changed, 5 insertions(+), 33 deletions(-)
    
    diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
    index 79791c6..194a307 100644
    --- a/drivers/crypto/talitos.c
    +++ b/drivers/crypto/talitos.c
    @@ -2037,22 +2037,6 @@ static int ahash_import(struct ahash_request *areq, const void *in)
     	return 0;
     }
     
    -struct keyhash_result {
    -	struct completion completion;
    -	int err;
    -};
    -
    -static void keyhash_complete(struct crypto_async_request *req, int err)
    -{
    -	struct keyhash_result *res = req->data;
    -
    -	if (err == -EINPROGRESS)
    -		return;
    -
    -	res->err = err;
    -	complete(&res->completion);
    -}
    -
     static int keyhash(struct crypto_ahash *tfm, const u8 *key, unsigned int keylen,
     		   u8 *hash)
     {
    @@ -2060,10 +2044,10 @@ static int keyhash(struct crypto_ahash *tfm, const u8 *key, unsigned int keylen,
     
     	struct scatterlist sg[1];
     	struct ahash_request *req;
    -	struct keyhash_result hresult;
    +	struct crypto_wait wait;
     	int ret;
     
    -	init_completion(&hresult.completion);
    +	crypto_init_wait(&wait);
     
     	req = ahash_request_alloc(tfm, GFP_KERNEL);
     	if (!req)
    @@ -2072,25 +2056,13 @@ static int keyhash(struct crypto_ahash *tfm, const u8 *key, unsigned int keylen,
     	/* Keep tfm keylen == 0 during hash of the long key */
     	ctx->keylen = 0;
     	ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
    -				   keyhash_complete, &hresult);
    +				   crypto_req_done, &wait);
     
     	sg_init_one(&sg[0], key, keylen);
     
     	ahash_request_set_crypt(req, sg, hash, keylen);
    -	ret = crypto_ahash_digest(req);
    -	switch (ret) {
    -	case 0:
    -		break;
    -	case -EINPROGRESS:
    -	case -EBUSY:
    -		ret = wait_for_completion_interruptible(
    -			&hresult.completion);
    -		if (!ret)
    -			ret = hresult.err;
    -		break;
    -	default:
    -		break;
    -	}
    +	ret = crypto_wait_req(crypto_ahash_digest(req), &wait);
    +
     	ahash_request_free(req);
     
     	return ret;
    -- 
    2.1.4
    
    ^ permalink raw reply related	[flat|nested] 58+ messages in thread
  • * [PATCH v5 16/19] crypto: talitos: move to generic async completion
           [not found] <1502724094-23305-1-git-send-email-gilad@benyossef.com>
                       ` (28 preceding siblings ...)
      2017-08-14 15:21 ` [PATCH v5 16/19] crypto: talitos: " Gilad Ben-Yossef
    @ 2017-08-14 15:21 ` Gilad Ben-Yossef
      2017-08-14 15:21 ` [PATCH v5 17/19] crypto: qce: " Gilad Ben-Yossef
                       ` (10 subsequent siblings)
      40 siblings, 0 replies; 58+ messages in thread
    From: Gilad Ben-Yossef @ 2017-08-14 15:21 UTC (permalink / raw)
      To: Herbert Xu, David S. Miller, Jonathan Corbet, David Howells,
    	Tom Lendacky, Gary Hook, Boris Brezillon, Arnaud Ebalard,
    	Matthias Brugger, Alasdair Kergon, Mike Snitzer, dm-devel,
    	Shaohua Li, Steve French, Theodore Y. Ts'o, Jaegeuk Kim,
    	Mimi Zohar, Dmitry Kasatkin, James Morris, Serge E. Hallyn,
    	linux-crypto
      Cc: Ofir Drang
    
    The talitos driver starts several async crypto ops and  waits for their
    completions. Move it over to generic code doing the same.
    
    Signed-off-by: Gilad Ben-Yossef <gilad@benyossef.com>
    ---
     drivers/crypto/talitos.c | 38 +++++---------------------------------
     1 file changed, 5 insertions(+), 33 deletions(-)
    
    diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
    index 79791c6..194a307 100644
    --- a/drivers/crypto/talitos.c
    +++ b/drivers/crypto/talitos.c
    @@ -2037,22 +2037,6 @@ static int ahash_import(struct ahash_request *areq, const void *in)
     	return 0;
     }
     
    -struct keyhash_result {
    -	struct completion completion;
    -	int err;
    -};
    -
    -static void keyhash_complete(struct crypto_async_request *req, int err)
    -{
    -	struct keyhash_result *res = req->data;
    -
    -	if (err == -EINPROGRESS)
    -		return;
    -
    -	res->err = err;
    -	complete(&res->completion);
    -}
    -
     static int keyhash(struct crypto_ahash *tfm, const u8 *key, unsigned int keylen,
     		   u8 *hash)
     {
    @@ -2060,10 +2044,10 @@ static int keyhash(struct crypto_ahash *tfm, const u8 *key, unsigned int keylen,
     
     	struct scatterlist sg[1];
     	struct ahash_request *req;
    -	struct keyhash_result hresult;
    +	struct crypto_wait wait;
     	int ret;
     
    -	init_completion(&hresult.completion);
    +	crypto_init_wait(&wait);
     
     	req = ahash_request_alloc(tfm, GFP_KERNEL);
     	if (!req)
    @@ -2072,25 +2056,13 @@ static int keyhash(struct crypto_ahash *tfm, const u8 *key, unsigned int keylen,
     	/* Keep tfm keylen == 0 during hash of the long key */
     	ctx->keylen = 0;
     	ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
    -				   keyhash_complete, &hresult);
    +				   crypto_req_done, &wait);
     
     	sg_init_one(&sg[0], key, keylen);
     
     	ahash_request_set_crypt(req, sg, hash, keylen);
    -	ret = crypto_ahash_digest(req);
    -	switch (ret) {
    -	case 0:
    -		break;
    -	case -EINPROGRESS:
    -	case -EBUSY:
    -		ret = wait_for_completion_interruptible(
    -			&hresult.completion);
    -		if (!ret)
    -			ret = hresult.err;
    -		break;
    -	default:
    -		break;
    -	}
    +	ret = crypto_wait_req(crypto_ahash_digest(req), &wait);
    +
     	ahash_request_free(req);
     
     	return ret;
    -- 
    2.1.4
    
    
    ^ permalink raw reply related	[flat|nested] 58+ messages in thread
  • * [PATCH v5 17/19] crypto: qce: move to generic async completion
           [not found] <1502724094-23305-1-git-send-email-gilad@benyossef.com>
                       ` (29 preceding siblings ...)
      2017-08-14 15:21 ` Gilad Ben-Yossef
    @ 2017-08-14 15:21 ` Gilad Ben-Yossef
      2017-08-14 15:21 ` Gilad Ben-Yossef
                       ` (9 subsequent siblings)
      40 siblings, 0 replies; 58+ messages in thread
    From: Gilad Ben-Yossef @ 2017-08-14 15:21 UTC (permalink / raw)
      To: Herbert Xu, David S. Miller, Jonathan Corbet, David Howells,
    	Tom Lendacky, Gary Hook, Boris Brezillon, Arnaud Ebalard,
    	Matthias Brugger, Alasdair Kergon, Mike Snitzer, dm-devel,
    	Shaohua Li, Steve French, Theodore Y. Ts'o, Jaegeuk Kim,
    	Mimi Zohar, Dmitry Kasatkin, James Morris, Serge E. Hallyn,
    	linux-crypto
      Cc: Ofir Drang
    
    The qce driver starts several async crypto ops and  waits for their
    completions. Move it over to generic code doing the same.
    
    Signed-off-by: Gilad Ben-Yossef <gilad@benyossef.com>
    ---
     drivers/crypto/qce/sha.c | 30 ++++--------------------------
     1 file changed, 4 insertions(+), 26 deletions(-)
    
    diff --git a/drivers/crypto/qce/sha.c b/drivers/crypto/qce/sha.c
    index 47e114a..53227d7 100644
    --- a/drivers/crypto/qce/sha.c
    +++ b/drivers/crypto/qce/sha.c
    @@ -349,28 +349,12 @@ static int qce_ahash_digest(struct ahash_request *req)
     	return qce->async_req_enqueue(tmpl->qce, &req->base);
     }
     
    -struct qce_ahash_result {
    -	struct completion completion;
    -	int error;
    -};
    -
    -static void qce_digest_complete(struct crypto_async_request *req, int error)
    -{
    -	struct qce_ahash_result *result = req->data;
    -
    -	if (error == -EINPROGRESS)
    -		return;
    -
    -	result->error = error;
    -	complete(&result->completion);
    -}
    -
     static int qce_ahash_hmac_setkey(struct crypto_ahash *tfm, const u8 *key,
     				 unsigned int keylen)
     {
     	unsigned int digestsize = crypto_ahash_digestsize(tfm);
     	struct qce_sha_ctx *ctx = crypto_tfm_ctx(&tfm->base);
    -	struct qce_ahash_result result;
    +	struct crypto_wait wait;
     	struct ahash_request *req;
     	struct scatterlist sg;
     	unsigned int blocksize;
    @@ -405,9 +389,9 @@ static int qce_ahash_hmac_setkey(struct crypto_ahash *tfm, const u8 *key,
     		goto err_free_ahash;
     	}
     
    -	init_completion(&result.completion);
    +	crypto_init_wait(&wait);
     	ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
    -				   qce_digest_complete, &result);
    +				   crypto_req_done, &wait);
     	crypto_ahash_clear_flags(ahash_tfm, ~0);
     
     	buf = kzalloc(keylen + QCE_MAX_ALIGN_SIZE, GFP_KERNEL);
    @@ -420,13 +404,7 @@ static int qce_ahash_hmac_setkey(struct crypto_ahash *tfm, const u8 *key,
     	sg_init_one(&sg, buf, keylen);
     	ahash_request_set_crypt(req, &sg, ctx->authkey, keylen);
     
    -	ret = crypto_ahash_digest(req);
    -	if (ret == -EINPROGRESS || ret == -EBUSY) {
    -		ret = wait_for_completion_interruptible(&result.completion);
    -		if (!ret)
    -			ret = result.error;
    -	}
    -
    +	ret = crypto_wait_req(crypto_ahash_digest(req), &wait);
     	if (ret)
     		crypto_ahash_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
     
    -- 
    2.1.4
    
    
    ^ permalink raw reply related	[flat|nested] 58+ messages in thread
  • * [PATCH v5 17/19] crypto: qce: move to generic async completion
           [not found] <1502724094-23305-1-git-send-email-gilad@benyossef.com>
                       ` (30 preceding siblings ...)
      2017-08-14 15:21 ` [PATCH v5 17/19] crypto: qce: " Gilad Ben-Yossef
    @ 2017-08-14 15:21 ` Gilad Ben-Yossef
      2017-08-14 15:21 ` [PATCH v5 18/19] crypto: mediatek: " Gilad Ben-Yossef
                       ` (8 subsequent siblings)
      40 siblings, 0 replies; 58+ messages in thread
    From: Gilad Ben-Yossef @ 2017-08-14 15:21 UTC (permalink / raw)
      To: Herbert Xu, David S. Miller, Jonathan Corbet, David Howells,
    	Tom Lendacky, Gary Hook, Boris Brezillon, Arnaud Ebalard,
    	Matthias Brugger, Alasdair Kergon, Mike Snitzer, dm-devel,
    	Shaohua Li, Steve French, Theodore Y. Ts'o, Jaegeuk Kim,
    	Mimi Zohar, Dmitry Kasatkin, James Morris, Serge E. Hallyn,
    	linux-crypto, linux-doc, linux-kernel, keyrings, linux-arm-kernel
      Cc: Ofir Drang
    
    The qce driver starts several async crypto ops and  waits for their
    completions. Move it over to generic code doing the same.
    
    Signed-off-by: Gilad Ben-Yossef <gilad@benyossef.com>
    ---
     drivers/crypto/qce/sha.c | 30 ++++--------------------------
     1 file changed, 4 insertions(+), 26 deletions(-)
    
    diff --git a/drivers/crypto/qce/sha.c b/drivers/crypto/qce/sha.c
    index 47e114a..53227d7 100644
    --- a/drivers/crypto/qce/sha.c
    +++ b/drivers/crypto/qce/sha.c
    @@ -349,28 +349,12 @@ static int qce_ahash_digest(struct ahash_request *req)
     	return qce->async_req_enqueue(tmpl->qce, &req->base);
     }
     
    -struct qce_ahash_result {
    -	struct completion completion;
    -	int error;
    -};
    -
    -static void qce_digest_complete(struct crypto_async_request *req, int error)
    -{
    -	struct qce_ahash_result *result = req->data;
    -
    -	if (error == -EINPROGRESS)
    -		return;
    -
    -	result->error = error;
    -	complete(&result->completion);
    -}
    -
     static int qce_ahash_hmac_setkey(struct crypto_ahash *tfm, const u8 *key,
     				 unsigned int keylen)
     {
     	unsigned int digestsize = crypto_ahash_digestsize(tfm);
     	struct qce_sha_ctx *ctx = crypto_tfm_ctx(&tfm->base);
    -	struct qce_ahash_result result;
    +	struct crypto_wait wait;
     	struct ahash_request *req;
     	struct scatterlist sg;
     	unsigned int blocksize;
    @@ -405,9 +389,9 @@ static int qce_ahash_hmac_setkey(struct crypto_ahash *tfm, const u8 *key,
     		goto err_free_ahash;
     	}
     
    -	init_completion(&result.completion);
    +	crypto_init_wait(&wait);
     	ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
    -				   qce_digest_complete, &result);
    +				   crypto_req_done, &wait);
     	crypto_ahash_clear_flags(ahash_tfm, ~0);
     
     	buf = kzalloc(keylen + QCE_MAX_ALIGN_SIZE, GFP_KERNEL);
    @@ -420,13 +404,7 @@ static int qce_ahash_hmac_setkey(struct crypto_ahash *tfm, const u8 *key,
     	sg_init_one(&sg, buf, keylen);
     	ahash_request_set_crypt(req, &sg, ctx->authkey, keylen);
     
    -	ret = crypto_ahash_digest(req);
    -	if (ret == -EINPROGRESS || ret == -EBUSY) {
    -		ret = wait_for_completion_interruptible(&result.completion);
    -		if (!ret)
    -			ret = result.error;
    -	}
    -
    +	ret = crypto_wait_req(crypto_ahash_digest(req), &wait);
     	if (ret)
     		crypto_ahash_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
     
    -- 
    2.1.4
    
    ^ permalink raw reply related	[flat|nested] 58+ messages in thread
  • * [PATCH v5 18/19] crypto: mediatek: move to generic async completion
           [not found] <1502724094-23305-1-git-send-email-gilad@benyossef.com>
                       ` (31 preceding siblings ...)
      2017-08-14 15:21 ` Gilad Ben-Yossef
    @ 2017-08-14 15:21 ` Gilad Ben-Yossef
      2017-08-14 15:21 ` Gilad Ben-Yossef
                       ` (7 subsequent siblings)
      40 siblings, 0 replies; 58+ messages in thread
    From: Gilad Ben-Yossef @ 2017-08-14 15:21 UTC (permalink / raw)
      To: Herbert Xu, David S. Miller, Jonathan Corbet, David Howells,
    	Tom Lendacky, Gary Hook, Boris Brezillon, Arnaud Ebalard,
    	Matthias Brugger, Alasdair Kergon, Mike Snitzer, dm-devel,
    	Shaohua Li, Steve French, Theodore Y. Ts'o, Jaegeuk Kim,
    	Mimi Zohar, Dmitry Kasatkin, James Morris, Serge E. Hallyn,
    	linux-crypto, linux-doc, linux-kernel, keyrings, linux-arm-kernel
      Cc: Ofir Drang
    
    The mediatek driver starts several async crypto ops and waits for their
    completions. Move it over to generic code doing the same.
    
    Signed-off-by: Gilad Ben-Yossef <gilad@benyossef.com>
    ---
     drivers/crypto/mediatek/mtk-aes.c | 31 +++++--------------------------
     1 file changed, 5 insertions(+), 26 deletions(-)
    
    diff --git a/drivers/crypto/mediatek/mtk-aes.c b/drivers/crypto/mediatek/mtk-aes.c
    index 9e845e8..e2c7c95 100644
    --- a/drivers/crypto/mediatek/mtk-aes.c
    +++ b/drivers/crypto/mediatek/mtk-aes.c
    @@ -137,11 +137,6 @@ struct mtk_aes_gcm_ctx {
     	struct crypto_skcipher *ctr;
     };
     
    -struct mtk_aes_gcm_setkey_result {
    -	int err;
    -	struct completion completion;
    -};
    -
     struct mtk_aes_drv {
     	struct list_head dev_list;
     	/* Device list lock */
    @@ -936,17 +931,6 @@ static int mtk_aes_gcm_crypt(struct aead_request *req, u64 mode)
     				    &req->base);
     }
     
    -static void mtk_gcm_setkey_done(struct crypto_async_request *req, int err)
    -{
    -	struct mtk_aes_gcm_setkey_result *result = req->data;
    -
    -	if (err == -EINPROGRESS)
    -		return;
    -
    -	result->err = err;
    -	complete(&result->completion);
    -}
    -
     /*
      * Because of the hardware limitation, we need to pre-calculate key(H)
      * for the GHASH operation. The result of the encryption operation
    @@ -962,7 +946,7 @@ static int mtk_aes_gcm_setkey(struct crypto_aead *aead, const u8 *key,
     		u32 hash[4];
     		u8 iv[8];
     
    -		struct mtk_aes_gcm_setkey_result result;
    +		struct crypto_wait wait;
     
     		struct scatterlist sg[1];
     		struct skcipher_request req;
    @@ -1002,22 +986,17 @@ static int mtk_aes_gcm_setkey(struct crypto_aead *aead, const u8 *key,
     	if (!data)
     		return -ENOMEM;
     
    -	init_completion(&data->result.completion);
    +	crypto_init_wait(&data->wait);
     	sg_init_one(data->sg, &data->hash, AES_BLOCK_SIZE);
     	skcipher_request_set_tfm(&data->req, ctr);
     	skcipher_request_set_callback(&data->req, CRYPTO_TFM_REQ_MAY_SLEEP |
     				      CRYPTO_TFM_REQ_MAY_BACKLOG,
    -				      mtk_gcm_setkey_done, &data->result);
    +				      crypto_req_done, &data->wait);
     	skcipher_request_set_crypt(&data->req, data->sg, data->sg,
     				   AES_BLOCK_SIZE, data->iv);
     
    -	err = crypto_skcipher_encrypt(&data->req);
    -	if (err == -EINPROGRESS || err == -EBUSY) {
    -		err = wait_for_completion_interruptible(
    -			&data->result.completion);
    -		if (!err)
    -			err = data->result.err;
    -	}
    +	err = crypto_wait_req(crypto_skcipher_encrypt(&data->req),
    +			      &data->wait);
     	if (err)
     		goto out;
     
    -- 
    2.1.4
    
    ^ permalink raw reply related	[flat|nested] 58+ messages in thread
  • * [PATCH v5 18/19] crypto: mediatek: move to generic async completion
           [not found] <1502724094-23305-1-git-send-email-gilad@benyossef.com>
                       ` (32 preceding siblings ...)
      2017-08-14 15:21 ` [PATCH v5 18/19] crypto: mediatek: " Gilad Ben-Yossef
    @ 2017-08-14 15:21 ` Gilad Ben-Yossef
      2017-08-14 15:21 ` [PATCH v5 19/19] crypto: adapt api sample to use async. op wait Gilad Ben-Yossef
                       ` (6 subsequent siblings)
      40 siblings, 0 replies; 58+ messages in thread
    From: Gilad Ben-Yossef @ 2017-08-14 15:21 UTC (permalink / raw)
      To: Herbert Xu, David S. Miller, Jonathan Corbet, David Howells,
    	Tom Lendacky, Gary Hook, Boris Brezillon, Arnaud Ebalard,
    	Matthias Brugger, Alasdair Kergon, Mike Snitzer, dm-devel,
    	Shaohua Li, Steve French, Theodore Y. Ts'o, Jaegeuk Kim,
    	Mimi Zohar, Dmitry Kasatkin, James Morris, Serge E. Hallyn,
    	linux-crypto
      Cc: Ofir Drang
    
    The mediatek driver starts several async crypto ops and waits for their
    completions. Move it over to generic code doing the same.
    
    Signed-off-by: Gilad Ben-Yossef <gilad@benyossef.com>
    ---
     drivers/crypto/mediatek/mtk-aes.c | 31 +++++--------------------------
     1 file changed, 5 insertions(+), 26 deletions(-)
    
    diff --git a/drivers/crypto/mediatek/mtk-aes.c b/drivers/crypto/mediatek/mtk-aes.c
    index 9e845e8..e2c7c95 100644
    --- a/drivers/crypto/mediatek/mtk-aes.c
    +++ b/drivers/crypto/mediatek/mtk-aes.c
    @@ -137,11 +137,6 @@ struct mtk_aes_gcm_ctx {
     	struct crypto_skcipher *ctr;
     };
     
    -struct mtk_aes_gcm_setkey_result {
    -	int err;
    -	struct completion completion;
    -};
    -
     struct mtk_aes_drv {
     	struct list_head dev_list;
     	/* Device list lock */
    @@ -936,17 +931,6 @@ static int mtk_aes_gcm_crypt(struct aead_request *req, u64 mode)
     				    &req->base);
     }
     
    -static void mtk_gcm_setkey_done(struct crypto_async_request *req, int err)
    -{
    -	struct mtk_aes_gcm_setkey_result *result = req->data;
    -
    -	if (err == -EINPROGRESS)
    -		return;
    -
    -	result->err = err;
    -	complete(&result->completion);
    -}
    -
     /*
      * Because of the hardware limitation, we need to pre-calculate key(H)
      * for the GHASH operation. The result of the encryption operation
    @@ -962,7 +946,7 @@ static int mtk_aes_gcm_setkey(struct crypto_aead *aead, const u8 *key,
     		u32 hash[4];
     		u8 iv[8];
     
    -		struct mtk_aes_gcm_setkey_result result;
    +		struct crypto_wait wait;
     
     		struct scatterlist sg[1];
     		struct skcipher_request req;
    @@ -1002,22 +986,17 @@ static int mtk_aes_gcm_setkey(struct crypto_aead *aead, const u8 *key,
     	if (!data)
     		return -ENOMEM;
     
    -	init_completion(&data->result.completion);
    +	crypto_init_wait(&data->wait);
     	sg_init_one(data->sg, &data->hash, AES_BLOCK_SIZE);
     	skcipher_request_set_tfm(&data->req, ctr);
     	skcipher_request_set_callback(&data->req, CRYPTO_TFM_REQ_MAY_SLEEP |
     				      CRYPTO_TFM_REQ_MAY_BACKLOG,
    -				      mtk_gcm_setkey_done, &data->result);
    +				      crypto_req_done, &data->wait);
     	skcipher_request_set_crypt(&data->req, data->sg, data->sg,
     				   AES_BLOCK_SIZE, data->iv);
     
    -	err = crypto_skcipher_encrypt(&data->req);
    -	if (err == -EINPROGRESS || err == -EBUSY) {
    -		err = wait_for_completion_interruptible(
    -			&data->result.completion);
    -		if (!err)
    -			err = data->result.err;
    -	}
    +	err = crypto_wait_req(crypto_skcipher_encrypt(&data->req),
    +			      &data->wait);
     	if (err)
     		goto out;
     
    -- 
    2.1.4
    
    
    ^ permalink raw reply related	[flat|nested] 58+ messages in thread
  • * [PATCH v5 19/19] crypto: adapt api sample to use async. op wait
           [not found] <1502724094-23305-1-git-send-email-gilad@benyossef.com>
                       ` (33 preceding siblings ...)
      2017-08-14 15:21 ` Gilad Ben-Yossef
    @ 2017-08-14 15:21 ` Gilad Ben-Yossef
      2017-08-14 15:21 ` Gilad Ben-Yossef
                       ` (5 subsequent siblings)
      40 siblings, 0 replies; 58+ messages in thread
    From: Gilad Ben-Yossef @ 2017-08-14 15:21 UTC (permalink / raw)
      To: Herbert Xu, David S. Miller, Jonathan Corbet, David Howells,
    	Tom Lendacky, Gary Hook, Boris Brezillon, Arnaud Ebalard,
    	Matthias Brugger, Alasdair Kergon, Mike Snitzer, dm-devel,
    	Shaohua Li, Steve French, Theodore Y. Ts'o, Jaegeuk Kim,
    	Mimi Zohar, Dmitry Kasatkin, James Morris, Serge E. Hallyn,
    	linux-crypto, linux-doc, linux-kernel, keyrings, linux-arm-kernel
      Cc: Ofir Drang
    
    The code sample is waiting for an async. crypto op completion.
    Adapt sample to use the new generic infrastructure to do the same.
    
    This also fixes a possible data coruption bug created by the
    use of wait_for_completion_interruptible() without dealing
    correctly with an interrupt aborting the wait prior to the
    async op finishing.
    
    Signed-off-by: Gilad Ben-Yossef <gilad@benyossef.com>
    ---
     Documentation/crypto/api-samples.rst | 52 +++++++-----------------------------
     1 file changed, 10 insertions(+), 42 deletions(-)
    
    diff --git a/Documentation/crypto/api-samples.rst b/Documentation/crypto/api-samples.rst
    index 2531948..006827e 100644
    --- a/Documentation/crypto/api-samples.rst
    +++ b/Documentation/crypto/api-samples.rst
    @@ -7,59 +7,27 @@ Code Example For Symmetric Key Cipher Operation
     ::
     
     
    -    struct tcrypt_result {
    -        struct completion completion;
    -        int err;
    -    };
    -
         /* tie all data structures together */
         struct skcipher_def {
             struct scatterlist sg;
             struct crypto_skcipher *tfm;
             struct skcipher_request *req;
    -        struct tcrypt_result result;
    +        struct crypto_wait wait;
         };
     
    -    /* Callback function */
    -    static void test_skcipher_cb(struct crypto_async_request *req, int error)
    -    {
    -        struct tcrypt_result *result = req->data;
    -
    -        if (error == -EINPROGRESS)
    -            return;
    -        result->err = error;
    -        complete(&result->completion);
    -        pr_info("Encryption finished successfully\n");
    -    }
    -
         /* Perform cipher operation */
         static unsigned int test_skcipher_encdec(struct skcipher_def *sk,
                              int enc)
         {
    -        int rc = 0;
    +        int rc;
     
             if (enc)
    -            rc = crypto_skcipher_encrypt(sk->req);
    +            rc = crypto_wait_req(crypto_skcipher_encrypt(sk->req), &sk->wait);
             else
    -            rc = crypto_skcipher_decrypt(sk->req);
    -
    -        switch (rc) {
    -        case 0:
    -            break;
    -        case -EINPROGRESS:
    -        case -EBUSY:
    -            rc = wait_for_completion_interruptible(
    -                &sk->result.completion);
    -            if (!rc && !sk->result.err) {
    -                reinit_completion(&sk->result.completion);
    -                break;
    -            }
    -        default:
    -            pr_info("skcipher encrypt returned with %d result %d\n",
    -                rc, sk->result.err);
    -            break;
    -        }
    -        init_completion(&sk->result.completion);
    +            rc = crypto_wait_req(crypto_skcipher_decrypt(sk->req), &sk->wait);
    +
    +	if (rc)
    +		pr_info("skcipher encrypt returned with result %d\n", rc);
     
             return rc;
         }
    @@ -89,8 +57,8 @@ Code Example For Symmetric Key Cipher Operation
             }
     
             skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
    -                          test_skcipher_cb,
    -                          &sk.result);
    +                          crypto_req_done,
    +                          &sk.wait);
     
             /* AES 256 with random key */
             get_random_bytes(&key, 32);
    @@ -122,7 +90,7 @@ Code Example For Symmetric Key Cipher Operation
             /* We encrypt one block */
             sg_init_one(&sk.sg, scratchpad, 16);
             skcipher_request_set_crypt(req, &sk.sg, &sk.sg, 16, ivdata);
    -        init_completion(&sk.result.completion);
    +        crypto_init_wait(&sk.wait);
     
             /* encrypt data */
             ret = test_skcipher_encdec(&sk, 1);
    -- 
    2.1.4
    
    ^ permalink raw reply related	[flat|nested] 58+ messages in thread
  • * [PATCH v5 19/19] crypto: adapt api sample to use async. op wait
           [not found] <1502724094-23305-1-git-send-email-gilad@benyossef.com>
                       ` (34 preceding siblings ...)
      2017-08-14 15:21 ` [PATCH v5 19/19] crypto: adapt api sample to use async. op wait Gilad Ben-Yossef
    @ 2017-08-14 15:21 ` Gilad Ben-Yossef
           [not found] ` <1502724094-23305-3-git-send-email-gilad@benyossef.com>
                       ` (4 subsequent siblings)
      40 siblings, 0 replies; 58+ messages in thread
    From: Gilad Ben-Yossef @ 2017-08-14 15:21 UTC (permalink / raw)
      To: Herbert Xu, David S. Miller, Jonathan Corbet, David Howells,
    	Tom Lendacky, Gary Hook, Boris Brezillon, Arnaud Ebalard,
    	Matthias Brugger, Alasdair Kergon, Mike Snitzer, dm-devel,
    	Shaohua Li, Steve French, Theodore Y. Ts'o, Jaegeuk Kim,
    	Mimi Zohar, Dmitry Kasatkin, James Morris, Serge E. Hallyn,
    	linux-crypto
      Cc: Ofir Drang
    
    The code sample is waiting for an async. crypto op completion.
    Adapt sample to use the new generic infrastructure to do the same.
    
    This also fixes a possible data coruption bug created by the
    use of wait_for_completion_interruptible() without dealing
    correctly with an interrupt aborting the wait prior to the
    async op finishing.
    
    Signed-off-by: Gilad Ben-Yossef <gilad@benyossef.com>
    ---
     Documentation/crypto/api-samples.rst | 52 +++++++-----------------------------
     1 file changed, 10 insertions(+), 42 deletions(-)
    
    diff --git a/Documentation/crypto/api-samples.rst b/Documentation/crypto/api-samples.rst
    index 2531948..006827e 100644
    --- a/Documentation/crypto/api-samples.rst
    +++ b/Documentation/crypto/api-samples.rst
    @@ -7,59 +7,27 @@ Code Example For Symmetric Key Cipher Operation
     ::
     
     
    -    struct tcrypt_result {
    -        struct completion completion;
    -        int err;
    -    };
    -
         /* tie all data structures together */
         struct skcipher_def {
             struct scatterlist sg;
             struct crypto_skcipher *tfm;
             struct skcipher_request *req;
    -        struct tcrypt_result result;
    +        struct crypto_wait wait;
         };
     
    -    /* Callback function */
    -    static void test_skcipher_cb(struct crypto_async_request *req, int error)
    -    {
    -        struct tcrypt_result *result = req->data;
    -
    -        if (error == -EINPROGRESS)
    -            return;
    -        result->err = error;
    -        complete(&result->completion);
    -        pr_info("Encryption finished successfully\n");
    -    }
    -
         /* Perform cipher operation */
         static unsigned int test_skcipher_encdec(struct skcipher_def *sk,
                              int enc)
         {
    -        int rc = 0;
    +        int rc;
     
             if (enc)
    -            rc = crypto_skcipher_encrypt(sk->req);
    +            rc = crypto_wait_req(crypto_skcipher_encrypt(sk->req), &sk->wait);
             else
    -            rc = crypto_skcipher_decrypt(sk->req);
    -
    -        switch (rc) {
    -        case 0:
    -            break;
    -        case -EINPROGRESS:
    -        case -EBUSY:
    -            rc = wait_for_completion_interruptible(
    -                &sk->result.completion);
    -            if (!rc && !sk->result.err) {
    -                reinit_completion(&sk->result.completion);
    -                break;
    -            }
    -        default:
    -            pr_info("skcipher encrypt returned with %d result %d\n",
    -                rc, sk->result.err);
    -            break;
    -        }
    -        init_completion(&sk->result.completion);
    +            rc = crypto_wait_req(crypto_skcipher_decrypt(sk->req), &sk->wait);
    +
    +	if (rc)
    +		pr_info("skcipher encrypt returned with result %d\n", rc);
     
             return rc;
         }
    @@ -89,8 +57,8 @@ Code Example For Symmetric Key Cipher Operation
             }
     
             skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
    -                          test_skcipher_cb,
    -                          &sk.result);
    +                          crypto_req_done,
    +                          &sk.wait);
     
             /* AES 256 with random key */
             get_random_bytes(&key, 32);
    @@ -122,7 +90,7 @@ Code Example For Symmetric Key Cipher Operation
             /* We encrypt one block */
             sg_init_one(&sk.sg, scratchpad, 16);
             skcipher_request_set_crypt(req, &sk.sg, &sk.sg, 16, ivdata);
    -        init_completion(&sk.result.completion);
    +        crypto_init_wait(&sk.wait);
     
             /* encrypt data */
             ret = test_skcipher_encdec(&sk, 1);
    -- 
    2.1.4
    
    
    ^ permalink raw reply related	[flat|nested] 58+ messages in thread
  • [parent not found: <1502724094-23305-3-git-send-email-gilad@benyossef.com>]
  • [parent not found: <1502724094-23305-6-git-send-email-gilad@benyossef.com>]
  • [parent not found: <1502724094-23305-19-git-send-email-gilad@benyossef.com>]
  • [parent not found: <1502724094-23305-5-git-send-email-gilad@benyossef.com>]
  • [parent not found: <1502724094-23305-13-git-send-email-gilad@benyossef.com>]

  • end of thread, other threads:[~2017-08-21 12:49 UTC | newest]
    
    Thread overview: 58+ messages (download: mbox.gz follow: Atom feed
    -- links below jump to the message on this page --
         [not found] <1502724094-23305-1-git-send-email-gilad@benyossef.com>
         [not found] ` <1502724094-23305-1-git-send-email-gilad-6S/DczAoZh3WXxRugSxzZg@public.gmane.org>
    2017-08-14 15:21   ` [PATCH v5 01/19] crypto: change transient busy return code to -EAGAIN Gilad Ben-Yossef
    2017-08-14 15:21   ` [PATCH v5 02/19] crypto: ccp: use -EAGAIN for transient busy indication Gilad Ben-Yossef
    2017-08-14 15:21   ` [PATCH v5 03/19] crypto: remove redundant backlog checks on EBUSY Gilad Ben-Yossef
    2017-08-14 15:21   ` [PATCH v5 04/19] crypto: marvell/cesa: " Gilad Ben-Yossef
    2017-08-14 15:21   ` [PATCH v5 05/19] crypto: introduce crypto wait for async op Gilad Ben-Yossef
    2017-08-14 15:21   ` [PATCH v5 08/19] crypto: move drbg to generic async completion Gilad Ben-Yossef
    2017-08-14 15:21   ` [PATCH v5 09/19] crypto: move gcm " Gilad Ben-Yossef
    2017-08-14 15:21   ` [PATCH v5 10/19] crypto: move testmgr " Gilad Ben-Yossef
    2017-08-14 15:21   ` [PATCH v5 11/19] fscrypt: move " Gilad Ben-Yossef
    2017-08-14 15:21   ` [PATCH v5 12/19] dm: move dm-verity " Gilad Ben-Yossef
    2017-08-14 15:21   ` [PATCH v5 13/19] cifs: move " Gilad Ben-Yossef
    2017-08-14 15:21   ` [PATCH v5 14/19] ima: " Gilad Ben-Yossef
    2017-08-14 15:21   ` [PATCH v5 16/19] crypto: talitos: " Gilad Ben-Yossef
    2017-08-14 15:21   ` [PATCH v5 17/19] crypto: qce: " Gilad Ben-Yossef
    2017-08-14 15:21   ` [PATCH v5 18/19] crypto: mediatek: " Gilad Ben-Yossef
    2017-08-14 15:21   ` [PATCH v5 19/19] crypto: adapt api sample to use async. op wait Gilad Ben-Yossef
    2017-08-14 15:21 ` [PATCH v5 01/19] crypto: change transient busy return code to -EAGAIN Gilad Ben-Yossef
    2017-08-14 15:21 ` Gilad Ben-Yossef
    2017-08-14 15:21 ` [PATCH v5 02/19] crypto: ccp: use -EAGAIN for transient busy indication Gilad Ben-Yossef
    2017-08-14 15:21 ` Gilad Ben-Yossef
    2017-08-14 15:21 ` [PATCH v5 03/19] crypto: remove redundant backlog checks on EBUSY Gilad Ben-Yossef
    2017-08-14 15:21 ` Gilad Ben-Yossef
    2017-08-14 15:21 ` [PATCH v5 04/19] crypto: marvell/cesa: " Gilad Ben-Yossef
    2017-08-14 15:21 ` Gilad Ben-Yossef
    2017-08-14 15:21 ` [PATCH v5 05/19] crypto: introduce crypto wait for async op Gilad Ben-Yossef
    2017-08-14 15:21 ` Gilad Ben-Yossef
    2017-08-14 15:21 ` [PATCH v5 06/19] crypto: move algif to generic async completion Gilad Ben-Yossef
    2017-08-14 15:21 ` [PATCH v5 07/19] crypto: move pub key " Gilad Ben-Yossef
    2017-08-14 15:21 ` [PATCH v5 08/19] crypto: move drbg " Gilad Ben-Yossef
    2017-08-14 15:21 ` Gilad Ben-Yossef
    2017-08-14 15:21 ` [PATCH v5 09/19] crypto: move gcm " Gilad Ben-Yossef
    2017-08-14 15:21 ` Gilad Ben-Yossef
    2017-08-14 15:21 ` [PATCH v5 10/19] crypto: move testmgr " Gilad Ben-Yossef
    2017-08-14 15:21 ` Gilad Ben-Yossef
    2017-08-14 15:21 ` [PATCH v5 11/19] fscrypt: move " Gilad Ben-Yossef
    2017-08-14 15:21 ` Gilad Ben-Yossef
    2017-08-14 15:21 ` [PATCH v5 12/19] dm: move dm-verity " Gilad Ben-Yossef
    2017-08-14 15:21 ` Gilad Ben-Yossef
    2017-08-14 15:21 ` [PATCH v5 13/19] cifs: move " Gilad Ben-Yossef
    2017-08-14 15:21 ` Gilad Ben-Yossef
    2017-08-14 15:21 ` [PATCH v5 14/19] ima: " Gilad Ben-Yossef
    2017-08-14 15:21 ` Gilad Ben-Yossef
    2017-08-14 15:21 ` [PATCH v5 15/19] crypto: tcrypt: " Gilad Ben-Yossef
    2017-08-14 15:21 ` [PATCH v5 16/19] crypto: talitos: " Gilad Ben-Yossef
    2017-08-14 15:21 ` Gilad Ben-Yossef
    2017-08-14 15:21 ` [PATCH v5 17/19] crypto: qce: " Gilad Ben-Yossef
    2017-08-14 15:21 ` Gilad Ben-Yossef
    2017-08-14 15:21 ` [PATCH v5 18/19] crypto: mediatek: " Gilad Ben-Yossef
    2017-08-14 15:21 ` Gilad Ben-Yossef
    2017-08-14 15:21 ` [PATCH v5 19/19] crypto: adapt api sample to use async. op wait Gilad Ben-Yossef
    2017-08-14 15:21 ` Gilad Ben-Yossef
         [not found] ` <1502724094-23305-3-git-send-email-gilad@benyossef.com>
    2017-08-14 16:55   ` [PATCH v5 02/19] crypto: ccp: use -EAGAIN for transient busy indication Gary R Hook
         [not found] ` <1502724094-23305-6-git-send-email-gilad@benyossef.com>
    2017-08-15  2:23   ` [PATCH v5 05/19] crypto: introduce crypto wait for async op Jonathan Cameron
    2017-08-21 12:49     ` Gilad Ben-Yossef
         [not found] ` <1502724094-23305-19-git-send-email-gilad@benyossef.com>
         [not found]   ` <1502724094-23305-19-git-send-email-gilad-6S/DczAoZh3WXxRugSxzZg@public.gmane.org>
    2017-08-15  5:13     ` [PATCH v5 18/19] crypto: mediatek: move to generic async completion Ryder Lee
         [not found] ` <1502724094-23305-5-git-send-email-gilad@benyossef.com>
    2017-08-15  8:16   ` [PATCH v5 04/19] crypto: marvell/cesa: remove redundant backlog checks on EBUSY Boris Brezillon
         [not found] ` <1502724094-23305-13-git-send-email-gilad@benyossef.com>
    2017-08-19 20:08   ` [dm-devel] [PATCH v5 12/19] dm: move dm-verity to generic async completion Mikulas Patocka
         [not found]     ` <alpine.LRH.2.02.1708191605370.2380-Hpncn10jQN4oNljnaZt3ZvA+iT7yCHsGwRM8/txMwJMAicBL8TP8PQ@public.gmane.org>
    2017-08-21 12:48       ` Gilad Ben-Yossef
    

    This is a public inbox, see mirroring instructions
    for how to clone and mirror all data and code used for this inbox