Skip to content

Commit d9fb840

Browse files
dmuszynsherbertx
authored andcommitted
crypto: qat - add rate limiting feature to qat_4xxx
The Rate Limiting (RL) feature allows to control the rate of requests that can be submitted on a ring pair (RP). This allows sharing a QAT device among multiple users while ensuring a guaranteed throughput. The driver provides a mechanism that allows users to set policies, that are programmed to the device. The device is then enforcing those policies. Configuration of RL is accomplished through entities called SLAs (Service Level Agreement). Each SLA object gets a unique identifier and defines the limitations for a single service across up to four ring pairs (RPs count allocated to a single VF). The rate is determined using two fields: * CIR (Committed Information Rate), i.e., the guaranteed rate. * PIR (Peak Information Rate), i.e., the maximum rate achievable when the device has available resources. The rate values are expressed in permille scale i.e. 0-1000. Ring pair selection is achieved by providing a 64-bit mask, where each bit corresponds to one of the ring pairs. This adds an interface and logic that allow to add, update, retrieve and remove an SLA. Signed-off-by: Damian Muszynski <damian.muszynski@intel.com> Reviewed-by: Giovanni Cabiddu <giovanni.cabiddu@intel.com> Reviewed-by: Tero Kristo <tero.kristo@linux.intel.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
1 parent c7fd537 commit d9fb840

File tree

13 files changed

+1590
-1
lines changed

13 files changed

+1590
-1
lines changed

drivers/crypto/intel/qat/qat_4xxx/adf_4xxx_hw_data.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,24 @@ static u32 get_heartbeat_clock(struct adf_hw_device_data *self)
343343
return ADF_4XXX_KPT_COUNTER_FREQ;
344344
}
345345

346+
static void adf_init_rl_data(struct adf_rl_hw_data *rl_data)
347+
{
348+
rl_data->pciout_tb_offset = ADF_GEN4_RL_TOKEN_PCIEOUT_BUCKET_OFFSET;
349+
rl_data->pciin_tb_offset = ADF_GEN4_RL_TOKEN_PCIEIN_BUCKET_OFFSET;
350+
rl_data->r2l_offset = ADF_GEN4_RL_R2L_OFFSET;
351+
rl_data->l2c_offset = ADF_GEN4_RL_L2C_OFFSET;
352+
rl_data->c2s_offset = ADF_GEN4_RL_C2S_OFFSET;
353+
354+
rl_data->pcie_scale_div = ADF_4XXX_RL_PCIE_SCALE_FACTOR_DIV;
355+
rl_data->pcie_scale_mul = ADF_4XXX_RL_PCIE_SCALE_FACTOR_MUL;
356+
rl_data->dcpr_correction = ADF_4XXX_RL_DCPR_CORRECTION;
357+
rl_data->max_tp[ADF_SVC_ASYM] = ADF_4XXX_RL_MAX_TP_ASYM;
358+
rl_data->max_tp[ADF_SVC_SYM] = ADF_4XXX_RL_MAX_TP_SYM;
359+
rl_data->max_tp[ADF_SVC_DC] = ADF_4XXX_RL_MAX_TP_DC;
360+
rl_data->scan_interval = ADF_4XXX_RL_SCANS_PER_SEC;
361+
rl_data->scale_ref = ADF_4XXX_RL_SLICE_REF;
362+
}
363+
346364
static void adf_enable_error_correction(struct adf_accel_dev *accel_dev)
347365
{
348366
struct adf_bar *misc_bar = &GET_BARS(accel_dev)[ADF_4XXX_PMISC_BAR];
@@ -594,12 +612,14 @@ void adf_init_hw_data_4xxx(struct adf_hw_device_data *hw_data, u32 dev_id)
594612
hw_data->stop_timer = adf_gen4_timer_stop;
595613
hw_data->get_hb_clock = get_heartbeat_clock;
596614
hw_data->num_hb_ctrs = ADF_NUM_HB_CNT_PER_AE;
615+
hw_data->clock_frequency = ADF_4XXX_AE_FREQ;
597616

598617
adf_gen4_set_err_mask(&hw_data->dev_err_mask);
599618
adf_gen4_init_hw_csr_ops(&hw_data->csr_ops);
600619
adf_gen4_init_pf_pfvf_ops(&hw_data->pfvf_ops);
601620
adf_gen4_init_dc_ops(&hw_data->dc_ops);
602621
adf_gen4_init_ras_ops(&hw_data->ras_ops);
622+
adf_init_rl_data(&hw_data->rl_data);
603623
}
604624

605625
void adf_clean_hw_data_4xxx(struct adf_hw_device_data *hw_data)

drivers/crypto/intel/qat/qat_4xxx/adf_4xxx_hw_data.h

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,19 @@
8282
#define ADF_402XX_ASYM_OBJ "qat_402xx_asym.bin"
8383
#define ADF_402XX_ADMIN_OBJ "qat_402xx_admin.bin"
8484

85+
/* RL constants */
86+
#define ADF_4XXX_RL_PCIE_SCALE_FACTOR_DIV 100
87+
#define ADF_4XXX_RL_PCIE_SCALE_FACTOR_MUL 102
88+
#define ADF_4XXX_RL_DCPR_CORRECTION 1
89+
#define ADF_4XXX_RL_SCANS_PER_SEC 954
90+
#define ADF_4XXX_RL_MAX_TP_ASYM 173750UL
91+
#define ADF_4XXX_RL_MAX_TP_SYM 95000UL
92+
#define ADF_4XXX_RL_MAX_TP_DC 45000UL
93+
#define ADF_4XXX_RL_SLICE_REF 1000UL
94+
8595
/* Clocks frequency */
86-
#define ADF_4XXX_KPT_COUNTER_FREQ (100 * HZ_PER_MHZ)
96+
#define ADF_4XXX_KPT_COUNTER_FREQ (100 * HZ_PER_MHZ)
97+
#define ADF_4XXX_AE_FREQ (1000 * HZ_PER_MHZ)
8798

8899
/* qat_4xxx fuse bits are different from old GENs, redefine them */
89100
enum icp_qat_4xxx_slice_mask {

drivers/crypto/intel/qat/qat_common/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ intel_qat-objs := adf_cfg.o \
2828
qat_algs.o \
2929
qat_asym_algs.o \
3030
qat_algs_send.o \
31+
adf_rl.o \
32+
adf_rl_admin.o \
3133
qat_uclo.o \
3234
qat_hal.o \
3335
qat_bl.o

drivers/crypto/intel/qat/qat_common/adf_accel_devices.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <linux/ratelimit.h>
1010
#include <linux/types.h>
1111
#include "adf_cfg_common.h"
12+
#include "adf_rl.h"
1213
#include "adf_pfvf_msg.h"
1314

1415
#define ADF_DH895XCC_DEVICE_NAME "dh895xcc"
@@ -247,6 +248,7 @@ struct adf_hw_device_data {
247248
struct adf_dc_ops dc_ops;
248249
struct adf_ras_ops ras_ops;
249250
struct adf_dev_err_mask dev_err_mask;
251+
struct adf_rl_hw_data rl_data;
250252
const char *fw_name;
251253
const char *fw_mmp_name;
252254
u32 fuses;
@@ -358,6 +360,7 @@ struct adf_accel_dev {
358360
struct adf_accel_pci accel_pci_dev;
359361
struct adf_timer *timer;
360362
struct adf_heartbeat *heartbeat;
363+
struct adf_rl *rate_limiting;
361364
union {
362365
struct {
363366
/* protects VF2PF interrupts access */

drivers/crypto/intel/qat/qat_common/adf_admin.c

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,53 @@ static int adf_get_fw_capabilities(struct adf_accel_dev *accel_dev, u16 *caps)
330330
return 0;
331331
}
332332

333+
int adf_send_admin_rl_init(struct adf_accel_dev *accel_dev,
334+
struct icp_qat_fw_init_admin_slice_cnt *slices)
335+
{
336+
u32 ae_mask = accel_dev->hw_device->admin_ae_mask;
337+
struct icp_qat_fw_init_admin_resp resp = { };
338+
struct icp_qat_fw_init_admin_req req = { };
339+
int ret;
340+
341+
req.cmd_id = ICP_QAT_FW_RL_INIT;
342+
343+
ret = adf_send_admin(accel_dev, &req, &resp, ae_mask);
344+
if (ret)
345+
return ret;
346+
347+
memcpy(slices, &resp.slices, sizeof(*slices));
348+
349+
return 0;
350+
}
351+
352+
int adf_send_admin_rl_add_update(struct adf_accel_dev *accel_dev,
353+
struct icp_qat_fw_init_admin_req *req)
354+
{
355+
u32 ae_mask = accel_dev->hw_device->admin_ae_mask;
356+
struct icp_qat_fw_init_admin_resp resp = { };
357+
358+
/*
359+
* req struct filled in rl implementation. Used commands
360+
* ICP_QAT_FW_RL_ADD for a new SLA
361+
* ICP_QAT_FW_RL_UPDATE for update SLA
362+
*/
363+
return adf_send_admin(accel_dev, req, &resp, ae_mask);
364+
}
365+
366+
int adf_send_admin_rl_delete(struct adf_accel_dev *accel_dev, u16 node_id,
367+
u8 node_type)
368+
{
369+
u32 ae_mask = accel_dev->hw_device->admin_ae_mask;
370+
struct icp_qat_fw_init_admin_resp resp = { };
371+
struct icp_qat_fw_init_admin_req req = { };
372+
373+
req.cmd_id = ICP_QAT_FW_RL_REMOVE;
374+
req.node_id = node_id;
375+
req.node_type = node_type;
376+
377+
return adf_send_admin(accel_dev, &req, &resp, ae_mask);
378+
}
379+
333380
/**
334381
* adf_send_admin_init() - Function sends init message to FW
335382
* @accel_dev: Pointer to acceleration device.

drivers/crypto/intel/qat/qat_common/adf_admin.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
#ifndef ADF_ADMIN
44
#define ADF_ADMIN
55

6+
#include "icp_qat_fw_init_admin.h"
7+
68
struct adf_accel_dev;
79

810
int adf_init_admin_comms(struct adf_accel_dev *accel_dev);
@@ -12,6 +14,12 @@ int adf_get_ae_fw_counters(struct adf_accel_dev *accel_dev, u16 ae, u64 *reqs, u
1214
int adf_init_admin_pm(struct adf_accel_dev *accel_dev, u32 idle_delay);
1315
int adf_send_admin_tim_sync(struct adf_accel_dev *accel_dev, u32 cnt);
1416
int adf_send_admin_hb_timer(struct adf_accel_dev *accel_dev, uint32_t ticks);
17+
int adf_send_admin_rl_init(struct adf_accel_dev *accel_dev,
18+
struct icp_qat_fw_init_admin_slice_cnt *slices);
19+
int adf_send_admin_rl_add_update(struct adf_accel_dev *accel_dev,
20+
struct icp_qat_fw_init_admin_req *req);
21+
int adf_send_admin_rl_delete(struct adf_accel_dev *accel_dev, u16 node_id,
22+
u8 node_type);
1523
int adf_get_fw_timestamp(struct adf_accel_dev *accel_dev, u64 *timestamp);
1624
int adf_get_pm_info(struct adf_accel_dev *accel_dev, dma_addr_t p_state_addr, size_t buff_size);
1725
int adf_get_cnv_stats(struct adf_accel_dev *accel_dev, u16 ae, u16 *err_cnt, u16 *latest_err);

drivers/crypto/intel/qat/qat_common/adf_gen4_hw_data.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,13 @@ do { \
139139
/* Number of heartbeat counter pairs */
140140
#define ADF_NUM_HB_CNT_PER_AE ADF_NUM_THREADS_PER_AE
141141

142+
/* Rate Limiting */
143+
#define ADF_GEN4_RL_R2L_OFFSET 0x508000
144+
#define ADF_GEN4_RL_L2C_OFFSET 0x509000
145+
#define ADF_GEN4_RL_C2S_OFFSET 0x508818
146+
#define ADF_GEN4_RL_TOKEN_PCIEIN_BUCKET_OFFSET 0x508800
147+
#define ADF_GEN4_RL_TOKEN_PCIEOUT_BUCKET_OFFSET 0x508804
148+
142149
void adf_gen4_set_ssm_wdtimer(struct adf_accel_dev *accel_dev);
143150
void adf_gen4_init_hw_csr_ops(struct adf_hw_csr_ops *csr_ops);
144151
int adf_gen4_ring_pair_reset(struct adf_accel_dev *accel_dev, u32 bank_number);

drivers/crypto/intel/qat/qat_common/adf_init.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "adf_common_drv.h"
1010
#include "adf_dbgfs.h"
1111
#include "adf_heartbeat.h"
12+
#include "adf_rl.h"
1213
#include "adf_sysfs_ras_counters.h"
1314

1415
static LIST_HEAD(service_table);
@@ -137,6 +138,9 @@ static int adf_dev_init(struct adf_accel_dev *accel_dev)
137138
}
138139

139140
adf_heartbeat_init(accel_dev);
141+
ret = adf_rl_init(accel_dev);
142+
if (ret && ret != -EOPNOTSUPP)
143+
return ret;
140144

141145
/*
142146
* Subservice initialisation is divided into two stages: init and start.
@@ -212,6 +216,9 @@ static int adf_dev_start(struct adf_accel_dev *accel_dev)
212216
}
213217

214218
adf_heartbeat_start(accel_dev);
219+
ret = adf_rl_start(accel_dev);
220+
if (ret && ret != -EOPNOTSUPP)
221+
return ret;
215222

216223
list_for_each_entry(service, &service_table, list) {
217224
if (service->event_hld(accel_dev, ADF_EVENT_START)) {
@@ -272,6 +279,7 @@ static void adf_dev_stop(struct adf_accel_dev *accel_dev)
272279
!test_bit(ADF_STATUS_STARTING, &accel_dev->status))
273280
return;
274281

282+
adf_rl_stop(accel_dev);
275283
adf_dbgfs_rm(accel_dev);
276284
adf_sysfs_stop_ras(accel_dev);
277285

@@ -359,6 +367,8 @@ static void adf_dev_shutdown(struct adf_accel_dev *accel_dev)
359367
clear_bit(accel_dev->accel_id, service->init_status);
360368
}
361369

370+
adf_rl_exit(accel_dev);
371+
362372
if (hw_data->ras_ops.disable_ras_errors)
363373
hw_data->ras_ops.disable_ras_errors(accel_dev);
364374

0 commit comments

Comments
 (0)