mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git/
synced 2026-04-18 06:33:43 -04:00
crypto: hisilicon/sec2 - implement full backlog mode for sec
This patch introduces a hierarchical backlog mechanism to cache user data in high-throughput encryption/decryption scenarios, the implementation addresses packet loss issues when hardware queues overflow during peak loads. First, we use sec_alloc_req_id to obtain an exclusive resource from the pre-allocated resource pool of each queue, if no resource is allocated, perform the DMA map operation on the request memory. When the task is ready, we will attempt to send it to the hardware, if the hardware queue is already full, we cache the request into the backlog list, then return an EBUSY status to the upper layer and instruct the packet-sending thread to pause transmission. Simultaneously, when the hardware completes a task, it triggers the sec callback function, within this function, reattempt to send the requests from the backlog list and wake up the sending thread until the hardware queue becomes fully occupied again. In addition, it handles such exceptions like the hardware is reset when packets are sent, it will switch to the software computing and release occupied resources. Signed-off-by: Wenkai Lin <linwenkai6@hisilicon.com> Signed-off-by: Chenghai Huang <huangchenghai2@huawei.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
This commit is contained in:
@@ -7,6 +7,12 @@
|
||||
#include <linux/hisi_acc_qm.h>
|
||||
#include "sec_crypto.h"
|
||||
|
||||
#define SEC_PBUF_SZ 512
|
||||
#define SEC_MAX_MAC_LEN 64
|
||||
#define SEC_IV_SIZE 24
|
||||
#define SEC_SGE_NR_NUM 4
|
||||
#define SEC_SGL_ALIGN_SIZE 64
|
||||
|
||||
/* Algorithm resource per hardware SEC queue */
|
||||
struct sec_alg_res {
|
||||
u8 *pbuf;
|
||||
@@ -20,6 +26,40 @@ struct sec_alg_res {
|
||||
u16 depth;
|
||||
};
|
||||
|
||||
struct sec_hw_sge {
|
||||
dma_addr_t buf;
|
||||
void *page_ctrl;
|
||||
__le32 len;
|
||||
__le32 pad;
|
||||
__le32 pad0;
|
||||
__le32 pad1;
|
||||
};
|
||||
|
||||
struct sec_hw_sgl {
|
||||
dma_addr_t next_dma;
|
||||
__le16 entry_sum_in_chain;
|
||||
__le16 entry_sum_in_sgl;
|
||||
__le16 entry_length_in_sgl;
|
||||
__le16 pad0;
|
||||
__le64 pad1[5];
|
||||
struct sec_hw_sgl *next;
|
||||
struct sec_hw_sge sge_entries[SEC_SGE_NR_NUM];
|
||||
} __aligned(SEC_SGL_ALIGN_SIZE);
|
||||
|
||||
struct sec_src_dst_buf {
|
||||
struct sec_hw_sgl in;
|
||||
struct sec_hw_sgl out;
|
||||
};
|
||||
|
||||
struct sec_request_buf {
|
||||
union {
|
||||
struct sec_src_dst_buf data_buf;
|
||||
__u8 pbuf[SEC_PBUF_SZ];
|
||||
};
|
||||
dma_addr_t in_dma;
|
||||
dma_addr_t out_dma;
|
||||
};
|
||||
|
||||
/* Cipher request of SEC private */
|
||||
struct sec_cipher_req {
|
||||
struct hisi_acc_hw_sgl *c_out;
|
||||
@@ -29,6 +69,7 @@ struct sec_cipher_req {
|
||||
struct skcipher_request *sk_req;
|
||||
u32 c_len;
|
||||
bool encrypt;
|
||||
__u8 c_ivin_buf[SEC_IV_SIZE];
|
||||
};
|
||||
|
||||
struct sec_aead_req {
|
||||
@@ -37,6 +78,13 @@ struct sec_aead_req {
|
||||
u8 *a_ivin;
|
||||
dma_addr_t a_ivin_dma;
|
||||
struct aead_request *aead_req;
|
||||
__u8 a_ivin_buf[SEC_IV_SIZE];
|
||||
__u8 out_mac_buf[SEC_MAX_MAC_LEN];
|
||||
};
|
||||
|
||||
struct sec_instance_backlog {
|
||||
struct list_head list;
|
||||
spinlock_t lock;
|
||||
};
|
||||
|
||||
/* SEC request of Crypto */
|
||||
@@ -55,15 +103,17 @@ struct sec_req {
|
||||
dma_addr_t in_dma;
|
||||
struct sec_cipher_req c_req;
|
||||
struct sec_aead_req aead_req;
|
||||
struct list_head backlog_head;
|
||||
struct crypto_async_request *base;
|
||||
|
||||
int err_type;
|
||||
int req_id;
|
||||
u32 flag;
|
||||
|
||||
/* Status of the SEC request */
|
||||
bool fake_busy;
|
||||
bool use_pbuf;
|
||||
|
||||
struct list_head list;
|
||||
struct sec_instance_backlog *backlog;
|
||||
struct sec_request_buf buf;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -119,9 +169,11 @@ struct sec_qp_ctx {
|
||||
struct sec_alg_res *res;
|
||||
struct sec_ctx *ctx;
|
||||
spinlock_t req_lock;
|
||||
struct list_head backlog;
|
||||
spinlock_t id_lock;
|
||||
struct hisi_acc_sgl_pool *c_in_pool;
|
||||
struct hisi_acc_sgl_pool *c_out_pool;
|
||||
struct sec_instance_backlog backlog;
|
||||
u16 send_head;
|
||||
};
|
||||
|
||||
enum sec_alg_type {
|
||||
@@ -139,9 +191,6 @@ struct sec_ctx {
|
||||
/* Half queues for encipher, and half for decipher */
|
||||
u32 hlf_q_num;
|
||||
|
||||
/* Threshold for fake busy, trigger to return -EBUSY to user */
|
||||
u32 fake_req_limit;
|
||||
|
||||
/* Current cyclic index to select a queue for encipher */
|
||||
atomic_t enc_qcyclic;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user