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.
Unified · Split
| @@ -270,6 +270,12 @@ Description: Shows the operation capability bits displayed in bitmap format · 269 unmodified lines | |||
| 270 | correlates to the operations allowed. It's visible only | 270 | correlates to the operations allowed. It's visible only |
| 271 | on platforms that support the capability. | 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 | What: /sys/bus/dsa/devices/engine<m>.<n>/group_id | 279 | What: /sys/bus/dsa/devices/engine<m>.<n>/group_id |
| 274 | Date: Oct 25, 2019 | 280 | Date: Oct 25, 2019 |
| 275 | KernelVersion: 5.6.0 | 281 | KernelVersion: 5.6.0 |
| @@ -509,6 +509,7 @@ void idxd_wq_del_cdev(struct idxd_wq *wq) · 508 unmodified lines | |||
| 509 | 509 | ||
| 510 | static int idxd_user_drv_probe(struct idxd_dev *idxd_dev) | 510 | static int idxd_user_drv_probe(struct idxd_dev *idxd_dev) |
| 511 | { | 511 | { |
| 512 | struct device *dev = &idxd_dev->conf_dev; | ||
| 512 | struct idxd_wq *wq = idxd_dev_to_wq(idxd_dev); | 513 | struct idxd_wq *wq = idxd_dev_to_wq(idxd_dev); |
| 513 | struct idxd_device *idxd = wq->idxd; | 514 | struct idxd_device *idxd = wq->idxd; |
| 514 | int rc; | 515 | int rc; |
| @@ -536,6 +537,12 @@ static int idxd_user_drv_probe(struct idxd_dev *idxd_dev) · 21 unmodified lines | |||
| 536 | 537 | ||
| 537 | mutex_lock(&wq->wq_lock); | 538 | mutex_lock(&wq->wq_lock); |
| 538 | 539 | ||
| 540 | if (!idxd_wq_driver_name_match(wq, dev)) { | ||
| 541 | idxd->cmd_status = IDXD_SCMD_WQ_NO_DRV_NAME; | ||
| 542 | rc = -ENODEV; | ||
| 543 | goto wq_err; | ||
| 544 | } | ||
| 545 | |||
| 539 | wq->wq = create_workqueue(dev_name(wq_confdev(wq))); | 546 | wq->wq = create_workqueue(dev_name(wq_confdev(wq))); |
| 540 | if (!wq->wq) { | 547 | if (!wq->wq) { |
| 541 | rc = -ENOMEM; | 548 | rc = -ENOMEM; |
| @@ -306,6 +306,12 @@ static int idxd_dmaengine_drv_probe(struct idxd_dev *idxd_dev) · 305 unmodified lines | |||
| 306 | return -ENXIO; | 306 | return -ENXIO; |
| 307 | 307 | ||
| 308 | mutex_lock(&wq->wq_lock); | 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 | wq->type = IDXD_WQT_KERNEL; | 315 | wq->type = IDXD_WQT_KERNEL; |
| 310 | 316 | ||
| 311 | rc = drv_enable_wq(wq); | 317 | rc = drv_enable_wq(wq); |
| @@ -159,6 +159,8 @@ struct idxd_cdev { · 158 unmodified lines | |||
| 159 | int minor; | 159 | int minor; |
| 160 | }; | 160 | }; |
| 161 | 161 | ||
| 162 | #define DRIVER_NAME_SIZE 128 | ||
| 163 | |||
| 162 | #define IDXD_ALLOCATED_BATCH_SIZE 128U | 164 | #define IDXD_ALLOCATED_BATCH_SIZE 128U |
| 163 | #define WQ_NAME_SIZE 1024 | 165 | #define WQ_NAME_SIZE 1024 |
| 164 | #define WQ_TYPE_SIZE 10 | 166 | #define WQ_TYPE_SIZE 10 |
| @@ -227,6 +229,8 @@ struct idxd_wq { · 62 unmodified lines | |||
| 227 | /* Lock to protect upasid_xa access. */ | 229 | /* Lock to protect upasid_xa access. */ |
| 228 | struct mutex uc_lock; | 230 | struct mutex uc_lock; |
| 229 | struct xarray upasid_xa; | 231 | struct xarray upasid_xa; |
| 232 | |||
| 233 | char driver_name[DRIVER_NAME_SIZE + 1]; | ||
| 230 | }; | 234 | }; |
| 231 | 235 | ||
| 232 | struct idxd_engine { | 236 | struct idxd_engine { |
| @@ -646,6 +650,11 @@ static inline void idxd_wqcfg_set_max_batch_shift(int idxd_type, union wqcfg *wq · 413 unmodified lines | |||
| 646 | wqcfg->max_batch_shift = max_batch_shift; | 650 | wqcfg->max_batch_shift = max_batch_shift; |
| 647 | } | 651 | } |
| 648 | 652 | ||
| 653 | static inline int idxd_wq_driver_name_match(struct idxd_wq *wq, struct device *dev) | ||
| 654 | { | ||
| 655 | return (strncmp(wq->driver_name, dev->driver->name, strlen(dev->driver->name)) == 0); | ||
| 656 | } | ||
| 657 | |||
| 649 | int __must_check __idxd_driver_register(struct idxd_device_driver *idxd_drv, | 658 | int __must_check __idxd_driver_register(struct idxd_device_driver *idxd_drv, |
| 650 | struct module *module, const char *mod_name); | 659 | struct module *module, const char *mod_name); |
| 651 | #define idxd_driver_register(driver) \ | 660 | #define idxd_driver_register(driver) \ |
| @@ -1259,6 +1259,39 @@ err: · 1258 unmodified lines | |||
| 1259 | static struct device_attribute dev_attr_wq_op_config = | 1259 | static struct device_attribute dev_attr_wq_op_config = |
| 1260 | __ATTR(op_config, 0644, wq_op_config_show, wq_op_config_store); | 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 | static struct attribute *idxd_wq_attributes[] = { | 1295 | static struct attribute *idxd_wq_attributes[] = { |
| 1263 | &dev_attr_wq_clients.attr, | 1296 | &dev_attr_wq_clients.attr, |
| 1264 | &dev_attr_wq_state.attr, | 1297 | &dev_attr_wq_state.attr, |
| @@ -1278,6 +1311,7 @@ static struct attribute *idxd_wq_attributes[] = { · 13 unmodified lines | |||
| 1278 | &dev_attr_wq_occupancy.attr, | 1311 | &dev_attr_wq_occupancy.attr, |
| 1279 | &dev_attr_wq_enqcmds_retries.attr, | 1312 | &dev_attr_wq_enqcmds_retries.attr, |
| 1280 | &dev_attr_wq_op_config.attr, | 1313 | &dev_attr_wq_op_config.attr, |
| 1314 | &dev_attr_wq_driver_name.attr, | ||
| 1281 | NULL, | 1315 | NULL, |
| 1282 | }; | 1316 | }; |
| 1283 | 1317 | ||
| @@ -31,6 +31,7 @@ enum idxd_scmd_stat { · 30 unmodified lines | |||
| 31 | IDXD_SCMD_WQ_IRQ_ERR = 0x80100000, | 31 | IDXD_SCMD_WQ_IRQ_ERR = 0x80100000, |
| 32 | IDXD_SCMD_WQ_USER_NO_IOMMU = 0x80110000, | 32 | IDXD_SCMD_WQ_USER_NO_IOMMU = 0x80110000, |
| 33 | IDXD_SCMD_DEV_EVL_ERR = 0x80120000, | 33 | IDXD_SCMD_DEV_EVL_ERR = 0x80120000, |
| 34 | IDXD_SCMD_WQ_NO_DRV_NAME = 0x80200000, | ||
| 34 | }; | 35 | }; |
| 35 | 36 | ||
| 36 | #define IDXD_SCMD_SOFTERR_MASK 0x80000000 | 37 | #define IDXD_SCMD_SOFTERR_MASK 0x80000000 |