Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

dmaengine: idxd: Add support for device/wq defaults

Add a load_device_defaults() function pointer to struct
idxd_driver_data, which if defined, will be called when an idxd device
is probed and will allow the idxd device to be configured with default
values.

The load_device_defaults() function is passed an idxd device to work
with to set specific device attributes.

Also add a load_device_defaults() implementation IAA devices; future
patches would add default functions for other device types such as
DSA.

The way idxd device probing works, if the device configuration is
valid at that point e.g. at least one workqueue and engine is properly
configured then the device will be enabled and ready to go.

The IAA implementation, idxd_load_iaa_device_defaults(), configures a
single workqueue (wq0) for each device with the following default
values:

mode "dedicated"
threshold 0
size Total WQ Size from WQCAP
priority 10
type IDXD_WQT_KERNEL
group 0
name "iaa_crypto"
driver_name "crypto"

Note that this now adds another configuration step for any users that
want to configure their own devices/workqueus with something different
in that they'll first need to disable (in the case of IAA) wq0 and the
device itself before they can set their own attributes and re-enable,
since they've been already been auto-enabled. Note also that in order
for the new configuration to be applied to the deflate-iaa crypto
algorithm the iaa_crypto module needs to unregister the old version,
which is accomplished by removing the iaa_crypto module, and
re-registering it with the new configuration by reinserting the
iaa_crypto module.

Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Reviewed-by: Dave Jiang <dave.jiang@intel.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

authored by

Tom Zanussi and committed by
Herbert Xu
979f6ded 93382a91

+65 -1
+1 -1
drivers/dma/idxd/Makefile
··· 4 4 idxd_bus-y := bus.o 5 5 6 6 obj-$(CONFIG_INTEL_IDXD) += idxd.o 7 - idxd-y := init.o irq.o device.o sysfs.o submit.o dma.o cdev.o debugfs.o 7 + idxd-y := init.o irq.o device.o sysfs.o submit.o dma.o cdev.o debugfs.o defaults.o 8 8 9 9 idxd-$(CONFIG_INTEL_IDXD_PERFMON) += perfmon.o 10 10
+53
drivers/dma/idxd/defaults.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* Copyright(c) 2023 Intel Corporation. All rights rsvd. */ 3 + #include <linux/kernel.h> 4 + #include "idxd.h" 5 + 6 + int idxd_load_iaa_device_defaults(struct idxd_device *idxd) 7 + { 8 + struct idxd_engine *engine; 9 + struct idxd_group *group; 10 + struct idxd_wq *wq; 11 + 12 + if (!test_bit(IDXD_FLAG_CONFIGURABLE, &idxd->flags)) 13 + return 0; 14 + 15 + wq = idxd->wqs[0]; 16 + 17 + if (wq->state != IDXD_WQ_DISABLED) 18 + return -EPERM; 19 + 20 + /* set mode to "dedicated" */ 21 + set_bit(WQ_FLAG_DEDICATED, &wq->flags); 22 + wq->threshold = 0; 23 + 24 + /* only setting up 1 wq, so give it all the wq space */ 25 + wq->size = idxd->max_wq_size; 26 + 27 + /* set priority to 10 */ 28 + wq->priority = 10; 29 + 30 + /* set type to "kernel" */ 31 + wq->type = IDXD_WQT_KERNEL; 32 + 33 + /* set wq group to 0 */ 34 + group = idxd->groups[0]; 35 + wq->group = group; 36 + group->num_wqs++; 37 + 38 + /* set name to "iaa_crypto" */ 39 + memset(wq->name, 0, WQ_NAME_SIZE + 1); 40 + strscpy(wq->name, "iaa_crypto", WQ_NAME_SIZE + 1); 41 + 42 + /* set driver_name to "crypto" */ 43 + memset(wq->driver_name, 0, DRIVER_NAME_SIZE + 1); 44 + strscpy(wq->driver_name, "crypto", DRIVER_NAME_SIZE + 1); 45 + 46 + engine = idxd->engines[0]; 47 + 48 + /* set engine group to 0 */ 49 + engine->group = idxd->groups[0]; 50 + engine->group->num_engines++; 51 + 52 + return 0; 53 + }
+4
drivers/dma/idxd/idxd.h
··· 277 277 struct dma_device dma; 278 278 }; 279 279 280 + typedef int (*load_device_defaults_fn_t) (struct idxd_device *idxd); 281 + 280 282 struct idxd_driver_data { 281 283 const char *name_prefix; 282 284 enum idxd_type type; ··· 288 286 int evl_cr_off; 289 287 int cr_status_off; 290 288 int cr_result_off; 289 + load_device_defaults_fn_t load_device_defaults; 291 290 }; 292 291 293 292 struct idxd_evl { ··· 733 730 void idxd_wqs_quiesce(struct idxd_device *idxd); 734 731 bool idxd_queue_int_handle_resubmit(struct idxd_desc *desc); 735 732 void multi_u64_to_bmap(unsigned long *bmap, u64 *val, int count); 733 + int idxd_load_iaa_device_defaults(struct idxd_device *idxd); 736 734 737 735 /* device interrupt control */ 738 736 irqreturn_t idxd_misc_thread(int vec, void *data);
+7
drivers/dma/idxd/init.c
··· 59 59 .evl_cr_off = offsetof(struct iax_evl_entry, cr), 60 60 .cr_status_off = offsetof(struct iax_completion_record, status), 61 61 .cr_result_off = offsetof(struct iax_completion_record, error_code), 62 + .load_device_defaults = idxd_load_iaa_device_defaults, 62 63 }, 63 64 }; 64 65 ··· 744 743 if (rc) { 745 744 dev_err(dev, "Intel(R) IDXD DMA Engine init failed\n"); 746 745 goto err; 746 + } 747 + 748 + if (data->load_device_defaults) { 749 + rc = data->load_device_defaults(idxd); 750 + if (rc) 751 + dev_warn(dev, "IDXD loading device defaults failed\n"); 747 752 } 748 753 749 754 rc = idxd_register_devices(idxd);