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

dmaengine: idxd: add wq driver name support for accel-config user tool

With the possibility of multiple wq drivers that can be bound to the wq,
the user config tool accel-config needs a way to know which wq driver to
bind to the wq. Introduce per wq driver_name sysfs attribute where the user
can indicate the driver to be bound to the wq. This allows accel-config to
just bind to the driver using wq->driver_name.

Signed-off-by: Dave Jiang <dave.jiang@intel.com>
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Reviewed-by: Fenghua Yu <fenghua.yu@intel.com>
Acked-by: Vinod Koul <vkoul@kernel.org>
Link: https://lore.kernel.org/r/20230908201045.4115614-1-fenghua.yu@intel.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>

authored by

Dave Jiang and committed by
Vinod Koul
7af1e0ac c223bafd

+63
+6
Documentation/ABI/stable/sysfs-driver-dma-idxd
··· 270 270 correlates to the operations allowed. It's visible only 271 271 on platforms that support the capability. 272 272 273 + What: /sys/bus/dsa/devices/wq<m>.<n>/driver_name 274 + Date: Sept 8, 2023 275 + KernelVersion: 6.7.0 276 + Contact: dmaengine@vger.kernel.org 277 + Description: Name of driver to be bounded to the wq. 278 + 273 279 What: /sys/bus/dsa/devices/engine<m>.<n>/group_id 274 280 Date: Oct 25, 2019 275 281 KernelVersion: 5.6.0
+7
drivers/dma/idxd/cdev.c
··· 509 509 510 510 static int idxd_user_drv_probe(struct idxd_dev *idxd_dev) 511 511 { 512 + struct device *dev = &idxd_dev->conf_dev; 512 513 struct idxd_wq *wq = idxd_dev_to_wq(idxd_dev); 513 514 struct idxd_device *idxd = wq->idxd; 514 515 int rc; ··· 536 535 } 537 536 538 537 mutex_lock(&wq->wq_lock); 538 + 539 + if (!idxd_wq_driver_name_match(wq, dev)) { 540 + idxd->cmd_status = IDXD_SCMD_WQ_NO_DRV_NAME; 541 + rc = -ENODEV; 542 + goto wq_err; 543 + } 539 544 540 545 wq->wq = create_workqueue(dev_name(wq_confdev(wq))); 541 546 if (!wq->wq) {
+6
drivers/dma/idxd/dma.c
··· 306 306 return -ENXIO; 307 307 308 308 mutex_lock(&wq->wq_lock); 309 + if (!idxd_wq_driver_name_match(wq, dev)) { 310 + idxd->cmd_status = IDXD_SCMD_WQ_NO_DRV_NAME; 311 + rc = -ENODEV; 312 + goto err; 313 + } 314 + 309 315 wq->type = IDXD_WQT_KERNEL; 310 316 311 317 rc = drv_enable_wq(wq);
+9
drivers/dma/idxd/idxd.h
··· 159 159 int minor; 160 160 }; 161 161 162 + #define DRIVER_NAME_SIZE 128 163 + 162 164 #define IDXD_ALLOCATED_BATCH_SIZE 128U 163 165 #define WQ_NAME_SIZE 1024 164 166 #define WQ_TYPE_SIZE 10 ··· 229 227 /* Lock to protect upasid_xa access. */ 230 228 struct mutex uc_lock; 231 229 struct xarray upasid_xa; 230 + 231 + char driver_name[DRIVER_NAME_SIZE + 1]; 232 232 }; 233 233 234 234 struct idxd_engine { ··· 648 644 wqcfg->max_batch_shift = 0; 649 645 else 650 646 wqcfg->max_batch_shift = max_batch_shift; 647 + } 648 + 649 + static inline int idxd_wq_driver_name_match(struct idxd_wq *wq, struct device *dev) 650 + { 651 + return (strncmp(wq->driver_name, dev->driver->name, strlen(dev->driver->name)) == 0); 651 652 } 652 653 653 654 int __must_check __idxd_driver_register(struct idxd_device_driver *idxd_drv,
+34
drivers/dma/idxd/sysfs.c
··· 1259 1259 static struct device_attribute dev_attr_wq_op_config = 1260 1260 __ATTR(op_config, 0644, wq_op_config_show, wq_op_config_store); 1261 1261 1262 + static ssize_t wq_driver_name_show(struct device *dev, struct device_attribute *attr, char *buf) 1263 + { 1264 + struct idxd_wq *wq = confdev_to_wq(dev); 1265 + 1266 + return sysfs_emit(buf, "%s\n", wq->driver_name); 1267 + } 1268 + 1269 + static ssize_t wq_driver_name_store(struct device *dev, struct device_attribute *attr, 1270 + const char *buf, size_t count) 1271 + { 1272 + struct idxd_wq *wq = confdev_to_wq(dev); 1273 + char *input, *pos; 1274 + 1275 + if (wq->state != IDXD_WQ_DISABLED) 1276 + return -EPERM; 1277 + 1278 + if (strlen(buf) > DRIVER_NAME_SIZE || strlen(buf) == 0) 1279 + return -EINVAL; 1280 + 1281 + input = kstrndup(buf, count, GFP_KERNEL); 1282 + if (!input) 1283 + return -ENOMEM; 1284 + 1285 + pos = strim(input); 1286 + memset(wq->driver_name, 0, DRIVER_NAME_SIZE + 1); 1287 + sprintf(wq->driver_name, "%s", pos); 1288 + kfree(input); 1289 + return count; 1290 + } 1291 + 1292 + static struct device_attribute dev_attr_wq_driver_name = 1293 + __ATTR(driver_name, 0644, wq_driver_name_show, wq_driver_name_store); 1294 + 1262 1295 static struct attribute *idxd_wq_attributes[] = { 1263 1296 &dev_attr_wq_clients.attr, 1264 1297 &dev_attr_wq_state.attr, ··· 1311 1278 &dev_attr_wq_occupancy.attr, 1312 1279 &dev_attr_wq_enqcmds_retries.attr, 1313 1280 &dev_attr_wq_op_config.attr, 1281 + &dev_attr_wq_driver_name.attr, 1314 1282 NULL, 1315 1283 }; 1316 1284
+1
include/uapi/linux/idxd.h
··· 31 31 IDXD_SCMD_WQ_IRQ_ERR = 0x80100000, 32 32 IDXD_SCMD_WQ_USER_NO_IOMMU = 0x80110000, 33 33 IDXD_SCMD_DEV_EVL_ERR = 0x80120000, 34 + IDXD_SCMD_WQ_NO_DRV_NAME = 0x80200000, 34 35 }; 35 36 36 37 #define IDXD_SCMD_SOFTERR_MASK 0x80000000