QAT related bug fixes

1. Fix issue:  Kernel BUG with QAT during decompression  #9276.
   Now it is uninterruptible for a specific given QAT request,
   but Ctrl-C interrupt still works in user-space process.

2. Copy the digest result to the buffer only when doing encryption,
   and vise-versa for decryption.

Reviewed-by: Tom Caputi <tcaputi@datto.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Chengfei Zhu <chengfeix.zhu@intel.com>
Closes #9276
Closes #9303
This commit is contained in:
Chengfei ZHu 2019-09-13 04:33:44 +08:00 committed by Tony Hutter
parent e17445d1f7
commit 9fa8b5b55b
4 changed files with 18 additions and 32 deletions

View File

@ -21,7 +21,7 @@
#if defined(_KERNEL) && defined(HAVE_QAT) #if defined(_KERNEL) && defined(HAVE_QAT)
#include <sys/zfs_context.h> #include <sys/zfs_context.h>
#include "qat.h" #include <sys/qat.h>
qat_stats_t qat_stats = { qat_stats_t qat_stats = {
{ "comp_requests", KSTAT_DATA_UINT64 }, { "comp_requests", KSTAT_DATA_UINT64 },

View File

@ -40,11 +40,6 @@ typedef enum qat_encrypt_dir {
#include "dc/cpa_dc.h" #include "dc/cpa_dc.h"
#include "lac/cpa_cy_sym.h" #include "lac/cpa_cy_sym.h"
/*
* Timeout - no response from hardware after 0.5 seconds
*/
#define QAT_TIMEOUT_MS 500
/* /*
* The minimal and maximal buffer size which are not restricted * The minimal and maximal buffer size which are not restricted
* in the QAT hardware, but with the input buffer size between 4KB * in the QAT hardware, but with the input buffer size between 4KB

View File

@ -28,7 +28,7 @@
#include <sys/zfs_context.h> #include <sys/zfs_context.h>
#include <sys/byteorder.h> #include <sys/byteorder.h>
#include <sys/zio.h> #include <sys/zio.h>
#include "qat.h" #include <sys/qat.h>
/* /*
* Max instances in a QAT device, each instance is a channel to submit * Max instances in a QAT device, each instance is a channel to submit
@ -404,11 +404,7 @@ qat_compress_impl(qat_compress_dir_t dir, char *src, int src_len,
} }
/* we now wait until the completion of the operation. */ /* we now wait until the completion of the operation. */
if (!wait_for_completion_interruptible_timeout(&complete, wait_for_completion(&complete);
QAT_TIMEOUT_MS)) {
status = CPA_STATUS_FAIL;
goto fail;
}
if (dc_results.status != CPA_STATUS_SUCCESS) { if (dc_results.status != CPA_STATUS_SUCCESS) {
status = CPA_STATUS_FAIL; status = CPA_STATUS_FAIL;
@ -463,11 +459,7 @@ qat_compress_impl(qat_compress_dir_t dir, char *src, int src_len,
} }
/* we now wait until the completion of the operation. */ /* we now wait until the completion of the operation. */
if (!wait_for_completion_interruptible_timeout(&complete, wait_for_completion(&complete);
QAT_TIMEOUT_MS)) {
status = CPA_STATUS_FAIL;
goto fail;
}
if (dc_results.status != CPA_STATUS_SUCCESS) { if (dc_results.status != CPA_STATUS_SUCCESS) {
status = CPA_STATUS_FAIL; status = CPA_STATUS_FAIL;

View File

@ -36,7 +36,7 @@
#include <sys/zio_crypt.h> #include <sys/zio_crypt.h>
#include "lac/cpa_cy_im.h" #include "lac/cpa_cy_im.h"
#include "lac/cpa_cy_common.h" #include "lac/cpa_cy_common.h"
#include "qat.h" #include <sys/qat.h>
/* /*
* Max instances in a QAT device, each instance is a channel to submit * Max instances in a QAT device, each instance is a channel to submit
@ -415,6 +415,9 @@ qat_crypt(qat_encrypt_dir_t dir, uint8_t *src_buf, uint8_t *dst_buf,
op_data.messageLenToCipherInBytes = enc_len; op_data.messageLenToCipherInBytes = enc_len;
op_data.ivLenInBytes = ZIO_DATA_IV_LEN; op_data.ivLenInBytes = ZIO_DATA_IV_LEN;
bcopy(iv_buf, op_data.pIv, ZIO_DATA_IV_LEN); bcopy(iv_buf, op_data.pIv, ZIO_DATA_IV_LEN);
/* if dir is QAT_DECRYPT, copy digest_buf to pDigestResult */
if (dir == QAT_DECRYPT)
bcopy(digest_buf, op_data.pDigestResult, ZIO_DATA_MAC_LEN);
cb.verify_result = CPA_FALSE; cb.verify_result = CPA_FALSE;
init_completion(&cb.complete); init_completion(&cb.complete);
@ -423,23 +426,21 @@ qat_crypt(qat_encrypt_dir_t dir, uint8_t *src_buf, uint8_t *dst_buf,
if (status != CPA_STATUS_SUCCESS) if (status != CPA_STATUS_SUCCESS)
goto fail; goto fail;
if (!wait_for_completion_interruptible_timeout(&cb.complete, /* we now wait until the completion of the operation. */
QAT_TIMEOUT_MS)) { wait_for_completion(&cb.complete);
status = CPA_STATUS_FAIL;
goto fail;
}
if (cb.verify_result == CPA_FALSE) { if (cb.verify_result == CPA_FALSE) {
status = CPA_STATUS_FAIL; status = CPA_STATUS_FAIL;
goto fail; goto fail;
} }
/* save digest result to digest_buf */ if (dir == QAT_ENCRYPT) {
/* if dir is QAT_ENCRYPT, save pDigestResult to digest_buf */
bcopy(op_data.pDigestResult, digest_buf, ZIO_DATA_MAC_LEN); bcopy(op_data.pDigestResult, digest_buf, ZIO_DATA_MAC_LEN);
if (dir == QAT_ENCRYPT)
QAT_STAT_INCR(encrypt_total_out_bytes, enc_len); QAT_STAT_INCR(encrypt_total_out_bytes, enc_len);
else } else {
QAT_STAT_INCR(decrypt_total_out_bytes, enc_len); QAT_STAT_INCR(decrypt_total_out_bytes, enc_len);
}
fail: fail:
if (status != CPA_STATUS_SUCCESS) if (status != CPA_STATUS_SUCCESS)
@ -549,11 +550,9 @@ qat_checksum(uint64_t cksum, uint8_t *buf, uint64_t size, zio_cksum_t *zcp)
if (status != CPA_STATUS_SUCCESS) if (status != CPA_STATUS_SUCCESS)
goto fail; goto fail;
if (!wait_for_completion_interruptible_timeout(&cb.complete, /* we now wait until the completion of the operation. */
QAT_TIMEOUT_MS)) { wait_for_completion(&cb.complete);
status = CPA_STATUS_FAIL;
goto fail;
}
if (cb.verify_result == CPA_FALSE) { if (cb.verify_result == CPA_FALSE) {
status = CPA_STATUS_FAIL; status = CPA_STATUS_FAIL;
goto fail; goto fail;