Commit 7af1e0ac authored by Dave Jiang's avatar Dave Jiang Committed by Vinod Koul
Browse files

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: default avatarDave Jiang <dave.jiang@intel.com>
Signed-off-by: default avatarTom Zanussi <tom.zanussi@linux.intel.com>
Reviewed-by: default avatarFenghua Yu <fenghua.yu@intel.com>
Acked-by: default avatarVinod Koul <vkoul@kernel.org>
Link: https://lore.kernel.org/r/20230908201045.4115614-1-fenghua.yu@intel.com


Signed-off-by: default avatarVinod Koul <vkoul@kernel.org>
parent c223bafd
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -270,6 +270,12 @@ Description: Shows the operation capability bits displayed in bitmap format
		correlates to the operations allowed. It's visible only
		on platforms that support the capability.

What:		/sys/bus/dsa/devices/wq<m>.<n>/driver_name
Date:		Sept 8, 2023
KernelVersion:	6.7.0
Contact:	dmaengine@vger.kernel.org
Description:	Name of driver to be bounded to the wq.

What:           /sys/bus/dsa/devices/engine<m>.<n>/group_id
Date:           Oct 25, 2019
KernelVersion:  5.6.0
+7 −0
Original line number Diff line number Diff line
@@ -509,6 +509,7 @@ void idxd_wq_del_cdev(struct idxd_wq *wq)

static int idxd_user_drv_probe(struct idxd_dev *idxd_dev)
{
	struct device *dev = &idxd_dev->conf_dev;
	struct idxd_wq *wq = idxd_dev_to_wq(idxd_dev);
	struct idxd_device *idxd = wq->idxd;
	int rc;
@@ -536,6 +537,12 @@ static int idxd_user_drv_probe(struct idxd_dev *idxd_dev)

	mutex_lock(&wq->wq_lock);

	if (!idxd_wq_driver_name_match(wq, dev)) {
		idxd->cmd_status = IDXD_SCMD_WQ_NO_DRV_NAME;
		rc = -ENODEV;
		goto wq_err;
	}

	wq->wq = create_workqueue(dev_name(wq_confdev(wq)));
	if (!wq->wq) {
		rc = -ENOMEM;
+6 −0
Original line number Diff line number Diff line
@@ -306,6 +306,12 @@ static int idxd_dmaengine_drv_probe(struct idxd_dev *idxd_dev)
		return -ENXIO;

	mutex_lock(&wq->wq_lock);
	if (!idxd_wq_driver_name_match(wq, dev)) {
		idxd->cmd_status = IDXD_SCMD_WQ_NO_DRV_NAME;
		rc = -ENODEV;
		goto err;
	}

	wq->type = IDXD_WQT_KERNEL;

	rc = drv_enable_wq(wq);
+9 −0
Original line number Diff line number Diff line
@@ -159,6 +159,8 @@ struct idxd_cdev {
	int minor;
};

#define DRIVER_NAME_SIZE		128

#define IDXD_ALLOCATED_BATCH_SIZE	128U
#define WQ_NAME_SIZE   1024
#define WQ_TYPE_SIZE   10
@@ -227,6 +229,8 @@ struct idxd_wq {
	/* Lock to protect upasid_xa access. */
	struct mutex uc_lock;
	struct xarray upasid_xa;

	char driver_name[DRIVER_NAME_SIZE + 1];
};

struct idxd_engine {
@@ -646,6 +650,11 @@ static inline void idxd_wqcfg_set_max_batch_shift(int idxd_type, union wqcfg *wq
		wqcfg->max_batch_shift = max_batch_shift;
}

static inline int idxd_wq_driver_name_match(struct idxd_wq *wq, struct device *dev)
{
	return (strncmp(wq->driver_name, dev->driver->name, strlen(dev->driver->name)) == 0);
}

int __must_check __idxd_driver_register(struct idxd_device_driver *idxd_drv,
					struct module *module, const char *mod_name);
#define idxd_driver_register(driver) \
+34 −0
Original line number Diff line number Diff line
@@ -1259,6 +1259,39 @@ static ssize_t wq_op_config_store(struct device *dev, struct device_attribute *a
static struct device_attribute dev_attr_wq_op_config =
		__ATTR(op_config, 0644, wq_op_config_show, wq_op_config_store);

static ssize_t wq_driver_name_show(struct device *dev, struct device_attribute *attr, char *buf)
{
	struct idxd_wq *wq = confdev_to_wq(dev);

	return sysfs_emit(buf, "%s\n", wq->driver_name);
}

static ssize_t wq_driver_name_store(struct device *dev, struct device_attribute *attr,
				    const char *buf, size_t count)
{
	struct idxd_wq *wq = confdev_to_wq(dev);
	char *input, *pos;

	if (wq->state != IDXD_WQ_DISABLED)
		return -EPERM;

	if (strlen(buf) > DRIVER_NAME_SIZE || strlen(buf) == 0)
		return -EINVAL;

	input = kstrndup(buf, count, GFP_KERNEL);
	if (!input)
		return -ENOMEM;

	pos = strim(input);
	memset(wq->driver_name, 0, DRIVER_NAME_SIZE + 1);
	sprintf(wq->driver_name, "%s", pos);
	kfree(input);
	return count;
}

static struct device_attribute dev_attr_wq_driver_name =
		__ATTR(driver_name, 0644, wq_driver_name_show, wq_driver_name_store);

static struct attribute *idxd_wq_attributes[] = {
	&dev_attr_wq_clients.attr,
	&dev_attr_wq_state.attr,
@@ -1278,6 +1311,7 @@ static struct attribute *idxd_wq_attributes[] = {
	&dev_attr_wq_occupancy.attr,
	&dev_attr_wq_enqcmds_retries.attr,
	&dev_attr_wq_op_config.attr,
	&dev_attr_wq_driver_name.attr,
	NULL,
};

Loading