Skip to content

Commit

Permalink
dmaengine: idxd: create user driver for wq 'device'
Browse files Browse the repository at this point in the history
The original architecture of /sys/bus/dsa invented a scheme whereby a
single entry in the list of bus drivers, /sys/bus/drivers/dsa, handled
all device types and internally routed them to different drivers.
Those internal drivers were invisible to userspace. Now, as
/sys/bus/dsa wants to grow support for alternate drivers for a given
device, for example vfio-mdev instead of kernel-internal-dmaengine, a
proper bus device-driver model is needed. The first step in that process
is separating the existing omnibus/implicit "dsa" driver into proper
individual drivers registered on /sys/bus/dsa. Establish the
idxd_user_drv driver that controls the enabling and disabling of the
wq and also register and unregister a char device to allow user space
to mmap the descriptor submission portal.

The cdev related bits are moved to the cdev driver probe/remove and out of
the drv_enabe/disable_wq() calls. These bits are exclusive to the cdev
operation and not part of the generic enable/disable of the wq device.

Reviewed-by: Dan Williams <dan.j.williams@intel.com>
Signed-off-by: Dave Jiang <dave.jiang@intel.com>
Link: https://lore.kernel.org/r/162637467578.744545.10203997610072341376.stgit@djiang5-desk3.ch.intel.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
  • Loading branch information
Dave Jiang authored and Vinod Koul committed Jul 21, 2021
1 parent 0cda4f6 commit 448c3de
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 14 deletions.
53 changes: 53 additions & 0 deletions drivers/dma/idxd/cdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,59 @@ void idxd_wq_del_cdev(struct idxd_wq *wq)
put_device(cdev_dev(idxd_cdev));
}

static int idxd_user_drv_probe(struct idxd_dev *idxd_dev)
{
struct idxd_wq *wq = idxd_dev_to_wq(idxd_dev);
struct idxd_device *idxd = wq->idxd;
int rc;

if (idxd->state != IDXD_DEV_ENABLED)
return -ENXIO;

mutex_lock(&wq->wq_lock);
wq->type = IDXD_WQT_USER;
rc = __drv_enable_wq(wq);
if (rc < 0)
goto err;

rc = idxd_wq_add_cdev(wq);
if (rc < 0)
goto err_cdev;

mutex_unlock(&wq->wq_lock);
return 0;

err_cdev:
__drv_disable_wq(wq);
err:
wq->type = IDXD_WQT_NONE;
mutex_unlock(&wq->wq_lock);
return rc;
}

static void idxd_user_drv_remove(struct idxd_dev *idxd_dev)
{
struct idxd_wq *wq = idxd_dev_to_wq(idxd_dev);

mutex_lock(&wq->wq_lock);
idxd_wq_del_cdev(wq);
__drv_disable_wq(wq);
wq->type = IDXD_WQT_NONE;
mutex_unlock(&wq->wq_lock);
}

static enum idxd_dev_type dev_types[] = {
IDXD_DEV_WQ,
IDXD_DEV_NONE,
};

struct idxd_device_driver idxd_user_drv = {
.probe = idxd_user_drv_probe,
.remove = idxd_user_drv_remove,
.name = "user",
.type = dev_types,
};

int idxd_cdev_register(void)
{
int rc, i;
Expand Down
14 changes: 0 additions & 14 deletions drivers/dma/idxd/device.c
Original file line number Diff line number Diff line change
Expand Up @@ -1201,19 +1201,8 @@ int __drv_enable_wq(struct idxd_wq *wq)
}

wq->client_count = 0;

if (is_idxd_wq_cdev(wq)) {
rc = idxd_wq_add_cdev(wq);
if (rc < 0) {
dev_dbg(dev, "wq %d cdev creation failed\n", wq->id);
goto err_client;
}
}

return 0;

err_client:
idxd_wq_unmap_portal(wq);
err_map_portal:
rc = idxd_wq_disable(wq, false);
if (rc < 0)
Expand All @@ -1239,9 +1228,6 @@ void __drv_disable_wq(struct idxd_wq *wq)

lockdep_assert_held(&wq->wq_lock);

if (is_idxd_wq_cdev(wq))
idxd_wq_del_cdev(wq);

if (idxd_wq_refcount(wq))
dev_warn(dev, "Clients has claim on wq %d: %d\n",
wq->id, idxd_wq_refcount(wq));
Expand Down
1 change: 1 addition & 0 deletions drivers/dma/idxd/idxd.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ struct idxd_device_driver {
extern struct idxd_device_driver dsa_drv;
extern struct idxd_device_driver idxd_drv;
extern struct idxd_device_driver idxd_dmaengine_drv;
extern struct idxd_device_driver idxd_user_drv;

struct idxd_irq_entry {
struct idxd_device *idxd;
Expand Down
7 changes: 7 additions & 0 deletions drivers/dma/idxd/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -848,6 +848,10 @@ static int __init idxd_init_module(void)
if (err < 0)
goto err_idxd_dmaengine_driver_register;

err = idxd_driver_register(&idxd_user_drv);
if (err < 0)
goto err_idxd_user_driver_register;

err = idxd_driver_register(&dsa_drv);
if (err < 0)
goto err_dsa_driver_register;
Expand All @@ -867,6 +871,8 @@ static int __init idxd_init_module(void)
err_cdev_register:
idxd_driver_unregister(&dsa_drv);
err_dsa_driver_register:
idxd_driver_unregister(&idxd_user_drv);
err_idxd_user_driver_register:
idxd_driver_unregister(&idxd_dmaengine_drv);
err_idxd_dmaengine_driver_register:
idxd_driver_unregister(&idxd_drv);
Expand All @@ -878,6 +884,7 @@ module_init(idxd_init_module);

static void __exit idxd_exit_module(void)
{
idxd_driver_unregister(&idxd_user_drv);
idxd_driver_unregister(&idxd_dmaengine_drv);
idxd_driver_unregister(&idxd_drv);
idxd_driver_unregister(&dsa_drv);
Expand Down

0 comments on commit 448c3de

Please sign in to comment.