brintos

brintos / linux-shallow public Read only

0
0
Text · 8.3 KiB · bedb514 Raw
460 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/* Copyright(c) 2023 Intel Corporation */3 4#define dev_fmt(fmt) "RateLimiting: " fmt5 6#include <linux/dev_printk.h>7#include <linux/pci.h>8#include <linux/sysfs.h>9#include <linux/types.h>10 11#include "adf_common_drv.h"12#include "adf_rl.h"13#include "adf_sysfs_rl.h"14 15#define GET_RL_STRUCT(accel_dev) ((accel_dev)->rate_limiting->user_input)16 17enum rl_ops {18	ADD,19	UPDATE,20	RM,21	RM_ALL,22	GET,23};24 25enum rl_params {26	RP_MASK,27	ID,28	CIR,29	PIR,30	SRV,31	CAP_REM_SRV,32};33 34static const char *const rl_services[] = {35	[ADF_SVC_ASYM] = "asym",36	[ADF_SVC_SYM] = "sym",37	[ADF_SVC_DC] = "dc",38};39 40static const char *const rl_operations[] = {41	[ADD] = "add",42	[UPDATE] = "update",43	[RM] = "rm",44	[RM_ALL] = "rm_all",45	[GET] = "get",46};47 48static int set_param_u(struct device *dev, enum rl_params param, u64 set)49{50	struct adf_rl_interface_data *data;51	struct adf_accel_dev *accel_dev;52	int ret = 0;53 54	accel_dev = adf_devmgr_pci_to_accel_dev(to_pci_dev(dev));55	if (!accel_dev)56		return -EINVAL;57 58	data = &GET_RL_STRUCT(accel_dev);59 60	down_write(&data->lock);61	switch (param) {62	case RP_MASK:63		data->input.rp_mask = set;64		break;65	case CIR:66		data->input.cir = set;67		break;68	case PIR:69		data->input.pir = set;70		break;71	case SRV:72		data->input.srv = set;73		break;74	case CAP_REM_SRV:75		data->cap_rem_srv = set;76		break;77	default:78		ret = -EINVAL;79		break;80	}81	up_write(&data->lock);82 83	return ret;84}85 86static int set_param_s(struct device *dev, enum rl_params param, int set)87{88	struct adf_rl_interface_data *data;89	struct adf_accel_dev *accel_dev;90 91	accel_dev = adf_devmgr_pci_to_accel_dev(to_pci_dev(dev));92	if (!accel_dev || param != ID)93		return -EINVAL;94 95	data = &GET_RL_STRUCT(accel_dev);96 97	down_write(&data->lock);98	data->input.sla_id = set;99	up_write(&data->lock);100 101	return 0;102}103 104static int get_param_u(struct device *dev, enum rl_params param, u64 *get)105{106	struct adf_rl_interface_data *data;107	struct adf_accel_dev *accel_dev;108	int ret = 0;109 110	accel_dev = adf_devmgr_pci_to_accel_dev(to_pci_dev(dev));111	if (!accel_dev)112		return -EINVAL;113 114	data = &GET_RL_STRUCT(accel_dev);115 116	down_read(&data->lock);117	switch (param) {118	case RP_MASK:119		*get = data->input.rp_mask;120		break;121	case CIR:122		*get = data->input.cir;123		break;124	case PIR:125		*get = data->input.pir;126		break;127	case SRV:128		*get = data->input.srv;129		break;130	default:131		ret = -EINVAL;132	}133	up_read(&data->lock);134 135	return ret;136}137 138static int get_param_s(struct device *dev, enum rl_params param)139{140	struct adf_rl_interface_data *data;141	struct adf_accel_dev *accel_dev;142	int ret = 0;143 144	accel_dev = adf_devmgr_pci_to_accel_dev(to_pci_dev(dev));145	if (!accel_dev)146		return -EINVAL;147 148	data = &GET_RL_STRUCT(accel_dev);149 150	down_read(&data->lock);151	if (param == ID)152		ret = data->input.sla_id;153	up_read(&data->lock);154 155	return ret;156}157 158static ssize_t rp_show(struct device *dev, struct device_attribute *attr,159		       char *buf)160{161	int ret;162	u64 get;163 164	ret = get_param_u(dev, RP_MASK, &get);165	if (ret)166		return ret;167 168	return sysfs_emit(buf, "%#llx\n", get);169}170 171static ssize_t rp_store(struct device *dev, struct device_attribute *attr,172			const char *buf, size_t count)173{174	int err;175	u64 val;176 177	err = kstrtou64(buf, 16, &val);178	if (err)179		return err;180 181	err = set_param_u(dev, RP_MASK, val);182	if (err)183		return err;184 185	return count;186}187static DEVICE_ATTR_RW(rp);188 189static ssize_t id_show(struct device *dev, struct device_attribute *attr,190		       char *buf)191{192	return sysfs_emit(buf, "%d\n", get_param_s(dev, ID));193}194 195static ssize_t id_store(struct device *dev, struct device_attribute *attr,196			const char *buf, size_t count)197{198	int err;199	int val;200 201	err = kstrtoint(buf, 10, &val);202	if (err)203		return err;204 205	err = set_param_s(dev, ID, val);206	if (err)207		return err;208 209	return count;210}211static DEVICE_ATTR_RW(id);212 213static ssize_t cir_show(struct device *dev, struct device_attribute *attr,214			char *buf)215{216	int ret;217	u64 get;218 219	ret = get_param_u(dev, CIR, &get);220	if (ret)221		return ret;222 223	return sysfs_emit(buf, "%llu\n", get);224}225 226static ssize_t cir_store(struct device *dev, struct device_attribute *attr,227			 const char *buf, size_t count)228{229	unsigned int val;230	int err;231 232	err = kstrtouint(buf, 10, &val);233	if (err)234		return err;235 236	err = set_param_u(dev, CIR, val);237	if (err)238		return err;239 240	return count;241}242static DEVICE_ATTR_RW(cir);243 244static ssize_t pir_show(struct device *dev, struct device_attribute *attr,245			char *buf)246{247	int ret;248	u64 get;249 250	ret = get_param_u(dev, PIR, &get);251	if (ret)252		return ret;253 254	return sysfs_emit(buf, "%llu\n", get);255}256 257static ssize_t pir_store(struct device *dev, struct device_attribute *attr,258			 const char *buf, size_t count)259{260	unsigned int val;261	int err;262 263	err = kstrtouint(buf, 10, &val);264	if (err)265		return err;266 267	err = set_param_u(dev, PIR, val);268	if (err)269		return err;270 271	return count;272}273static DEVICE_ATTR_RW(pir);274 275static ssize_t srv_show(struct device *dev, struct device_attribute *attr,276			char *buf)277{278	int ret;279	u64 get;280 281	ret = get_param_u(dev, SRV, &get);282	if (ret)283		return ret;284 285	if (get == ADF_SVC_NONE)286		return -EINVAL;287 288	return sysfs_emit(buf, "%s\n", rl_services[get]);289}290 291static ssize_t srv_store(struct device *dev, struct device_attribute *attr,292			 const char *buf, size_t count)293{294	unsigned int val;295	int ret;296 297	ret = sysfs_match_string(rl_services, buf);298	if (ret < 0)299		return ret;300 301	val = ret;302	ret = set_param_u(dev, SRV, val);303	if (ret)304		return ret;305 306	return count;307}308static DEVICE_ATTR_RW(srv);309 310static ssize_t cap_rem_show(struct device *dev, struct device_attribute *attr,311			    char *buf)312{313	struct adf_rl_interface_data *data;314	struct adf_accel_dev *accel_dev;315	int ret, rem_cap;316 317	accel_dev = adf_devmgr_pci_to_accel_dev(to_pci_dev(dev));318	if (!accel_dev)319		return -EINVAL;320 321	data = &GET_RL_STRUCT(accel_dev);322 323	down_read(&data->lock);324	rem_cap = adf_rl_get_capability_remaining(accel_dev, data->cap_rem_srv,325						  RL_SLA_EMPTY_ID);326	up_read(&data->lock);327	if (rem_cap < 0)328		return rem_cap;329 330	ret = sysfs_emit(buf, "%u\n", rem_cap);331 332	return ret;333}334 335static ssize_t cap_rem_store(struct device *dev, struct device_attribute *attr,336			     const char *buf, size_t count)337{338	unsigned int val;339	int ret;340 341	ret = sysfs_match_string(rl_services, buf);342	if (ret < 0)343		return ret;344 345	val = ret;346	ret = set_param_u(dev, CAP_REM_SRV, val);347	if (ret)348		return ret;349 350	return count;351}352static DEVICE_ATTR_RW(cap_rem);353 354static ssize_t sla_op_store(struct device *dev, struct device_attribute *attr,355			    const char *buf, size_t count)356{357	struct adf_rl_interface_data *data;358	struct adf_accel_dev *accel_dev;359	int ret;360 361	accel_dev = adf_devmgr_pci_to_accel_dev(to_pci_dev(dev));362	if (!accel_dev)363		return -EINVAL;364 365	data = &GET_RL_STRUCT(accel_dev);366 367	ret = sysfs_match_string(rl_operations, buf);368	if (ret < 0)369		return ret;370 371	down_write(&data->lock);372	switch (ret) {373	case ADD:374		data->input.parent_id = RL_PARENT_DEFAULT_ID;375		data->input.type = RL_LEAF;376		data->input.sla_id = 0;377		ret = adf_rl_add_sla(accel_dev, &data->input);378		if (ret)379			goto err_free_lock;380		break;381	case UPDATE:382		ret = adf_rl_update_sla(accel_dev, &data->input);383		if (ret)384			goto err_free_lock;385		break;386	case RM:387		ret = adf_rl_remove_sla(accel_dev, data->input.sla_id);388		if (ret)389			goto err_free_lock;390		break;391	case RM_ALL:392		adf_rl_remove_sla_all(accel_dev, false);393		break;394	case GET:395		ret = adf_rl_get_sla(accel_dev, &data->input);396		if (ret)397			goto err_free_lock;398		break;399	default:400		ret = -EINVAL;401		goto err_free_lock;402	}403	up_write(&data->lock);404 405	return count;406 407err_free_lock:408	up_write(&data->lock);409 410	return ret;411}412static DEVICE_ATTR_WO(sla_op);413 414static struct attribute *qat_rl_attrs[] = {415	&dev_attr_rp.attr,416	&dev_attr_id.attr,417	&dev_attr_cir.attr,418	&dev_attr_pir.attr,419	&dev_attr_srv.attr,420	&dev_attr_cap_rem.attr,421	&dev_attr_sla_op.attr,422	NULL,423};424 425static struct attribute_group qat_rl_group = {426	.attrs = qat_rl_attrs,427	.name = "qat_rl",428};429 430int adf_sysfs_rl_add(struct adf_accel_dev *accel_dev)431{432	struct adf_rl_interface_data *data;433	int ret;434 435	data = &GET_RL_STRUCT(accel_dev);436 437	ret = device_add_group(&GET_DEV(accel_dev), &qat_rl_group);438	if (ret)439		dev_err(&GET_DEV(accel_dev),440			"Failed to create qat_rl attribute group\n");441 442	data->cap_rem_srv = ADF_SVC_NONE;443	data->input.srv = ADF_SVC_NONE;444	data->sysfs_added = true;445 446	return ret;447}448 449void adf_sysfs_rl_rm(struct adf_accel_dev *accel_dev)450{451	struct adf_rl_interface_data *data;452 453	data = &GET_RL_STRUCT(accel_dev);454	if (!data->sysfs_added)455		return;456 457	device_remove_group(&GET_DEV(accel_dev), &qat_rl_group);458	data->sysfs_added = false;459}460