mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-11-01 17:08:10 +00:00
3868238397
The implementations of the crypto algorithms (aead, skcipher, etc) in
the QAT driver do not properly support requests with the
CRYPTO_TFM_REQ_MAY_BACKLOG flag set. If the HW queue is full, the driver
returns -EBUSY but does not enqueue the request. This can result in
applications like dm-crypt waiting indefinitely for the completion of a
request that was never submitted to the hardware.
Fix this by adding a software backlog queue: if the ring buffer is more
than eighty percent full, then the request is enqueued to a backlog
list and the error code -EBUSY is returned back to the caller.
Requests in the backlog queue are resubmitted at a later time, in the
context of the callback of a previously submitted request.
The request for which -EBUSY is returned is then marked as -EINPROGRESS
once submitted to the HW queues.
The submission loop inside the function qat_alg_send_message() has been
modified to decide which submission policy to use based on the request
flags. If the request does not have the CRYPTO_TFM_REQ_MAY_BACKLOG set,
the previous behaviour has been preserved.
Based on a patch by
Vishnu Das Ramachandran <vishnu.dasx.ramachandran@intel.com>
Cc: stable@vger.kernel.org
Fixes: d370cec321
("crypto: qat - Intel(R) QAT crypto interface")
Reported-by: Mikulas Patocka <mpatocka@redhat.com>
Reported-by: Kyle Sanderson <kyle.leet@gmail.com>
Signed-off-by: Giovanni Cabiddu <giovanni.cabiddu@intel.com>
Reviewed-by: Marco Chiappero <marco.chiappero@intel.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
20 lines
689 B
C
20 lines
689 B
C
/* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0-only) */
|
|
/* Copyright(c) 2014 - 2020 Intel Corporation */
|
|
#ifndef ADF_TRANSPORT_H
|
|
#define ADF_TRANSPORT_H
|
|
|
|
#include "adf_accel_devices.h"
|
|
|
|
struct adf_etr_ring_data;
|
|
|
|
typedef void (*adf_callback_fn)(void *resp_msg);
|
|
|
|
int adf_create_ring(struct adf_accel_dev *accel_dev, const char *section,
|
|
u32 bank_num, u32 num_mgs, u32 msg_size,
|
|
const char *ring_name, adf_callback_fn callback,
|
|
int poll_mode, struct adf_etr_ring_data **ring_ptr);
|
|
|
|
bool adf_ring_nearly_full(struct adf_etr_ring_data *ring);
|
|
int adf_send_message(struct adf_etr_ring_data *ring, u32 *msg);
|
|
void adf_remove_ring(struct adf_etr_ring_data *ring);
|
|
#endif
|