diff options
| author | Tom Lendacky <thomas.lendacky@amd.com> | 2014-02-24 09:42:14 -0500 |
|---|---|---|
| committer | Herbert Xu <herbert@gondor.apana.org.au> | 2014-02-26 16:57:01 -0500 |
| commit | c65a52f8360dc29116395708bde18399e4699f87 (patch) | |
| tree | 82e139cf4cde4bcb172aa94243a015590ab645aa | |
| parent | 950b10bae656d7edf5e2047bf0c9205980f49f2c (diff) | |
crypto: ccp - Account for CCP backlog processing
When the crypto layer is able to queue up a command for processing
by the CCP on the initial call to ccp_crypto_enqueue_request and
the CCP returns -EBUSY, then if the backlog flag is not set the
command needs to be freed and not added to the active command list.
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
| -rw-r--r-- | drivers/crypto/ccp/ccp-crypto-main.c | 18 |
1 files changed, 11 insertions, 7 deletions
diff --git a/drivers/crypto/ccp/ccp-crypto-main.c b/drivers/crypto/ccp/ccp-crypto-main.c index 7d98635c2c5e..20dc848481e7 100644 --- a/drivers/crypto/ccp/ccp-crypto-main.c +++ b/drivers/crypto/ccp/ccp-crypto-main.c | |||
| @@ -205,6 +205,7 @@ static int ccp_crypto_enqueue_cmd(struct ccp_crypto_cmd *crypto_cmd) | |||
| 205 | { | 205 | { |
| 206 | struct ccp_crypto_cmd *active = NULL, *tmp; | 206 | struct ccp_crypto_cmd *active = NULL, *tmp; |
| 207 | unsigned long flags; | 207 | unsigned long flags; |
| 208 | bool free_cmd = true; | ||
| 208 | int ret; | 209 | int ret; |
| 209 | 210 | ||
| 210 | spin_lock_irqsave(&req_queue_lock, flags); | 211 | spin_lock_irqsave(&req_queue_lock, flags); |
| @@ -231,7 +232,10 @@ static int ccp_crypto_enqueue_cmd(struct ccp_crypto_cmd *crypto_cmd) | |||
| 231 | if (!active) { | 232 | if (!active) { |
| 232 | ret = ccp_enqueue_cmd(crypto_cmd->cmd); | 233 | ret = ccp_enqueue_cmd(crypto_cmd->cmd); |
| 233 | if (!ccp_crypto_success(ret)) | 234 | if (!ccp_crypto_success(ret)) |
| 234 | goto e_lock; | 235 | goto e_lock; /* Error, don't queue it */ |
| 236 | if ((ret == -EBUSY) && | ||
| 237 | !(crypto_cmd->cmd->flags & CCP_CMD_MAY_BACKLOG)) | ||
| 238 | goto e_lock; /* Not backlogging, don't queue it */ | ||
| 235 | } | 239 | } |
| 236 | 240 | ||
| 237 | if (req_queue.cmd_count >= CCP_CRYPTO_MAX_QLEN) { | 241 | if (req_queue.cmd_count >= CCP_CRYPTO_MAX_QLEN) { |
| @@ -244,9 +248,14 @@ static int ccp_crypto_enqueue_cmd(struct ccp_crypto_cmd *crypto_cmd) | |||
| 244 | req_queue.cmd_count++; | 248 | req_queue.cmd_count++; |
| 245 | list_add_tail(&crypto_cmd->entry, &req_queue.cmds); | 249 | list_add_tail(&crypto_cmd->entry, &req_queue.cmds); |
| 246 | 250 | ||
| 251 | free_cmd = false; | ||
| 252 | |||
| 247 | e_lock: | 253 | e_lock: |
| 248 | spin_unlock_irqrestore(&req_queue_lock, flags); | 254 | spin_unlock_irqrestore(&req_queue_lock, flags); |
| 249 | 255 | ||
| 256 | if (free_cmd) | ||
| 257 | kfree(crypto_cmd); | ||
| 258 | |||
| 250 | return ret; | 259 | return ret; |
| 251 | } | 260 | } |
| 252 | 261 | ||
| @@ -262,7 +271,6 @@ int ccp_crypto_enqueue_request(struct crypto_async_request *req, | |||
| 262 | { | 271 | { |
| 263 | struct ccp_crypto_cmd *crypto_cmd; | 272 | struct ccp_crypto_cmd *crypto_cmd; |
| 264 | gfp_t gfp; | 273 | gfp_t gfp; |
| 265 | int ret; | ||
| 266 | 274 | ||
| 267 | gfp = req->flags & CRYPTO_TFM_REQ_MAY_SLEEP ? GFP_KERNEL : GFP_ATOMIC; | 275 | gfp = req->flags & CRYPTO_TFM_REQ_MAY_SLEEP ? GFP_KERNEL : GFP_ATOMIC; |
| 268 | 276 | ||
| @@ -287,11 +295,7 @@ int ccp_crypto_enqueue_request(struct crypto_async_request *req, | |||
| 287 | else | 295 | else |
| 288 | cmd->flags &= ~CCP_CMD_MAY_BACKLOG; | 296 | cmd->flags &= ~CCP_CMD_MAY_BACKLOG; |
| 289 | 297 | ||
| 290 | ret = ccp_crypto_enqueue_cmd(crypto_cmd); | 298 | return ccp_crypto_enqueue_cmd(crypto_cmd); |
| 291 | if (!ccp_crypto_success(ret)) | ||
| 292 | kfree(crypto_cmd); | ||
| 293 | |||
| 294 | return ret; | ||
| 295 | } | 299 | } |
| 296 | 300 | ||
| 297 | struct scatterlist *ccp_crypto_sg_table_add(struct sg_table *table, | 301 | struct scatterlist *ccp_crypto_sg_table_add(struct sg_table *table, |
