Skip to content

Commit 217b812

Browse files
Pranjal Ramajor Asha Kanojiyaquic-jhugo
authored andcommitted
accel/qaic: Add QAIC_DETACH_SLICE_BO IOCTL
Once a BO is attached with slicing configuration that BO can only be used for that particular setting. With this new feature user can detach slicing configuration off an already sliced BO and attach new slicing configuration using QAIC_ATTACH_SLICE_BO. This will support BO recycling. detach_slice_bo() detaches slicing configuration from a BO. This new helper function can also be used in release_dbc() as we are doing the exact same thing. Signed-off-by: Pranjal Ramajor Asha Kanojiya <[email protected]> Reviewed-by: Jeffrey Hugo <[email protected]> [jhugo: add documentation for new ioctl] Signed-off-by: Jeffrey Hugo <[email protected]> Reviewed-by: Stanislaw Gruszka <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
1 parent b2576f6 commit 217b812

File tree

5 files changed

+135
-11
lines changed

5 files changed

+135
-11
lines changed

Documentation/accel/qaic/qaic.rst

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,16 @@ DRM_IOCTL_QAIC_PART_DEV
123123
AIC100 device and can be used for limiting a process to some subset of
124124
resources.
125125

126+
DRM_IOCTL_QAIC_DETACH_SLICE_BO
127+
This IOCTL allows userspace to remove the slicing information from a BO that
128+
was originally provided by a call to DRM_IOCTL_QAIC_ATTACH_SLICE_BO. This
129+
is the inverse of DRM_IOCTL_QAIC_ATTACH_SLICE_BO. The BO must be idle for
130+
DRM_IOCTL_QAIC_DETACH_SLICE_BO to be called. After a successful detach slice
131+
operation the BO may have new slicing information attached with a new call
132+
to DRM_IOCTL_QAIC_ATTACH_SLICE_BO. After detach slice, the BO cannot be
133+
executed until after a new attach slice operation. Combining attach slice
134+
and detach slice calls allows userspace to use a BO with multiple workloads.
135+
126136
Userspace Client Isolation
127137
==========================
128138

drivers/accel/qaic/qaic.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,8 @@ struct qaic_bo {
222222
*/
223223
u32 queue_level_before;
224224
} perf_stats;
225-
225+
/* Synchronizes BO operations */
226+
struct mutex lock;
226227
};
227228

228229
struct bo_slice {
@@ -278,6 +279,7 @@ int qaic_execute_bo_ioctl(struct drm_device *dev, void *data, struct drm_file *f
278279
int qaic_partial_execute_bo_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);
279280
int qaic_wait_bo_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);
280281
int qaic_perf_stats_bo_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);
282+
int qaic_detach_slice_bo_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);
281283
void irq_polling_work(struct work_struct *work);
282284

283285
#endif /* _QAIC_H_ */

drivers/accel/qaic/qaic_data.c

Lines changed: 109 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -624,6 +624,7 @@ static void qaic_free_object(struct drm_gem_object *obj)
624624
qaic_free_sgt(bo->sgt);
625625
}
626626

627+
mutex_destroy(&bo->lock);
627628
drm_gem_object_release(obj);
628629
kfree(bo);
629630
}
@@ -641,6 +642,7 @@ static void qaic_init_bo(struct qaic_bo *bo, bool reinit)
641642
bo->sliced = false;
642643
reinit_completion(&bo->xfer_done);
643644
} else {
645+
mutex_init(&bo->lock);
644646
init_completion(&bo->xfer_done);
645647
}
646648
complete_all(&bo->xfer_done);
@@ -1002,10 +1004,13 @@ int qaic_attach_slice_bo_ioctl(struct drm_device *dev, void *data, struct drm_fi
10021004
}
10031005

10041006
bo = to_qaic_bo(obj);
1007+
ret = mutex_lock_interruptible(&bo->lock);
1008+
if (ret)
1009+
goto put_bo;
10051010

10061011
if (bo->sliced) {
10071012
ret = -EINVAL;
1008-
goto put_bo;
1013+
goto unlock_bo;
10091014
}
10101015

10111016
dbc = &qdev->dbc[args->hdr.dbc_id];
@@ -1029,7 +1034,7 @@ int qaic_attach_slice_bo_ioctl(struct drm_device *dev, void *data, struct drm_fi
10291034
bo->sliced = true;
10301035
list_add_tail(&bo->bo_list, &bo->dbc->bo_lists);
10311036
srcu_read_unlock(&dbc->ch_lock, rcu_id);
1032-
drm_gem_object_put(obj);
1037+
mutex_unlock(&bo->lock);
10331038
srcu_read_unlock(&qdev->dev_lock, qdev_rcu_id);
10341039
srcu_read_unlock(&usr->qddev_lock, usr_rcu_id);
10351040

@@ -1039,6 +1044,8 @@ int qaic_attach_slice_bo_ioctl(struct drm_device *dev, void *data, struct drm_fi
10391044
qaic_unprepare_bo(qdev, bo);
10401045
unlock_ch_srcu:
10411046
srcu_read_unlock(&dbc->ch_lock, rcu_id);
1047+
unlock_bo:
1048+
mutex_unlock(&bo->lock);
10421049
put_bo:
10431050
drm_gem_object_put(obj);
10441051
free_slice_ent:
@@ -1193,15 +1200,18 @@ static int send_bo_list_to_device(struct qaic_device *qdev, struct drm_file *fil
11931200
}
11941201

11951202
bo = to_qaic_bo(obj);
1203+
ret = mutex_lock_interruptible(&bo->lock);
1204+
if (ret)
1205+
goto failed_to_send_bo;
11961206

11971207
if (!bo->sliced) {
11981208
ret = -EINVAL;
1199-
goto failed_to_send_bo;
1209+
goto unlock_bo;
12001210
}
12011211

12021212
if (is_partial && pexec[i].resize > bo->base.size) {
12031213
ret = -EINVAL;
1204-
goto failed_to_send_bo;
1214+
goto unlock_bo;
12051215
}
12061216

12071217
spin_lock_irqsave(&dbc->xfer_lock, flags);
@@ -1210,7 +1220,7 @@ static int send_bo_list_to_device(struct qaic_device *qdev, struct drm_file *fil
12101220
if (queued) {
12111221
spin_unlock_irqrestore(&dbc->xfer_lock, flags);
12121222
ret = -EINVAL;
1213-
goto failed_to_send_bo;
1223+
goto unlock_bo;
12141224
}
12151225

12161226
bo->req_id = dbc->next_req_id++;
@@ -1241,17 +1251,20 @@ static int send_bo_list_to_device(struct qaic_device *qdev, struct drm_file *fil
12411251
if (ret) {
12421252
bo->queued = false;
12431253
spin_unlock_irqrestore(&dbc->xfer_lock, flags);
1244-
goto failed_to_send_bo;
1254+
goto unlock_bo;
12451255
}
12461256
}
12471257
reinit_completion(&bo->xfer_done);
12481258
list_add_tail(&bo->xfer_list, &dbc->xfer_list);
12491259
spin_unlock_irqrestore(&dbc->xfer_lock, flags);
12501260
dma_sync_sgtable_for_device(&qdev->pdev->dev, bo->sgt, bo->dir);
1261+
mutex_unlock(&bo->lock);
12511262
}
12521263

12531264
return 0;
12541265

1266+
unlock_bo:
1267+
mutex_unlock(&bo->lock);
12551268
failed_to_send_bo:
12561269
if (likely(obj))
12571270
drm_gem_object_put(obj);
@@ -1807,6 +1820,91 @@ int qaic_perf_stats_bo_ioctl(struct drm_device *dev, void *data, struct drm_file
18071820
return ret;
18081821
}
18091822

1823+
static void detach_slice_bo(struct qaic_device *qdev, struct qaic_bo *bo)
1824+
{
1825+
qaic_free_slices_bo(bo);
1826+
qaic_unprepare_bo(qdev, bo);
1827+
qaic_init_bo(bo, true);
1828+
list_del(&bo->bo_list);
1829+
drm_gem_object_put(&bo->base);
1830+
}
1831+
1832+
int qaic_detach_slice_bo_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv)
1833+
{
1834+
struct qaic_detach_slice *args = data;
1835+
int rcu_id, usr_rcu_id, qdev_rcu_id;
1836+
struct dma_bridge_chan *dbc;
1837+
struct drm_gem_object *obj;
1838+
struct qaic_device *qdev;
1839+
struct qaic_user *usr;
1840+
unsigned long flags;
1841+
struct qaic_bo *bo;
1842+
int ret;
1843+
1844+
if (args->pad != 0)
1845+
return -EINVAL;
1846+
1847+
usr = file_priv->driver_priv;
1848+
usr_rcu_id = srcu_read_lock(&usr->qddev_lock);
1849+
if (!usr->qddev) {
1850+
ret = -ENODEV;
1851+
goto unlock_usr_srcu;
1852+
}
1853+
1854+
qdev = usr->qddev->qdev;
1855+
qdev_rcu_id = srcu_read_lock(&qdev->dev_lock);
1856+
if (qdev->in_reset) {
1857+
ret = -ENODEV;
1858+
goto unlock_dev_srcu;
1859+
}
1860+
1861+
obj = drm_gem_object_lookup(file_priv, args->handle);
1862+
if (!obj) {
1863+
ret = -ENOENT;
1864+
goto unlock_dev_srcu;
1865+
}
1866+
1867+
bo = to_qaic_bo(obj);
1868+
ret = mutex_lock_interruptible(&bo->lock);
1869+
if (ret)
1870+
goto put_bo;
1871+
1872+
if (!bo->sliced) {
1873+
ret = -EINVAL;
1874+
goto unlock_bo;
1875+
}
1876+
1877+
dbc = bo->dbc;
1878+
rcu_id = srcu_read_lock(&dbc->ch_lock);
1879+
if (dbc->usr != usr) {
1880+
ret = -EINVAL;
1881+
goto unlock_ch_srcu;
1882+
}
1883+
1884+
/* Check if BO is committed to H/W for DMA */
1885+
spin_lock_irqsave(&dbc->xfer_lock, flags);
1886+
if (bo->queued) {
1887+
spin_unlock_irqrestore(&dbc->xfer_lock, flags);
1888+
ret = -EBUSY;
1889+
goto unlock_ch_srcu;
1890+
}
1891+
spin_unlock_irqrestore(&dbc->xfer_lock, flags);
1892+
1893+
detach_slice_bo(qdev, bo);
1894+
1895+
unlock_ch_srcu:
1896+
srcu_read_unlock(&dbc->ch_lock, rcu_id);
1897+
unlock_bo:
1898+
mutex_unlock(&bo->lock);
1899+
put_bo:
1900+
drm_gem_object_put(obj);
1901+
unlock_dev_srcu:
1902+
srcu_read_unlock(&qdev->dev_lock, qdev_rcu_id);
1903+
unlock_usr_srcu:
1904+
srcu_read_unlock(&usr->qddev_lock, usr_rcu_id);
1905+
return ret;
1906+
}
1907+
18101908
static void empty_xfer_list(struct qaic_device *qdev, struct dma_bridge_chan *dbc)
18111909
{
18121910
unsigned long flags;
@@ -1888,10 +1986,11 @@ void release_dbc(struct qaic_device *qdev, u32 dbc_id)
18881986
dbc->usr = NULL;
18891987

18901988
list_for_each_entry_safe(bo, bo_temp, &dbc->bo_lists, bo_list) {
1891-
qaic_free_slices_bo(bo);
1892-
qaic_unprepare_bo(qdev, bo);
1893-
qaic_init_bo(bo, true);
1894-
list_del(&bo->bo_list);
1989+
drm_gem_object_get(&bo->base);
1990+
mutex_lock(&bo->lock);
1991+
detach_slice_bo(qdev, bo);
1992+
mutex_unlock(&bo->lock);
1993+
drm_gem_object_put(&bo->base);
18951994
}
18961995

18971996
dbc->in_use = false;

drivers/accel/qaic/qaic_drv.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ static const struct drm_ioctl_desc qaic_drm_ioctls[] = {
151151
DRM_IOCTL_DEF_DRV(QAIC_PARTIAL_EXECUTE_BO, qaic_partial_execute_bo_ioctl, 0),
152152
DRM_IOCTL_DEF_DRV(QAIC_WAIT_BO, qaic_wait_bo_ioctl, 0),
153153
DRM_IOCTL_DEF_DRV(QAIC_PERF_STATS_BO, qaic_perf_stats_bo_ioctl, 0),
154+
DRM_IOCTL_DEF_DRV(QAIC_DETACH_SLICE_BO, qaic_detach_slice_bo_ioctl, 0),
154155
};
155156

156157
static const struct drm_driver qaic_accel_driver = {

include/uapi/drm/qaic_accel.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,16 @@ struct qaic_perf_stats_entry {
372372
__u32 pad;
373373
};
374374

375+
/**
376+
* struct qaic_detach_slice - Detaches slicing configuration from BO.
377+
* @handle: In. GEM handle of the BO to detach slicing configuration.
378+
* @pad: Structure padding. Must be 0.
379+
*/
380+
struct qaic_detach_slice {
381+
__u32 handle;
382+
__u32 pad;
383+
};
384+
375385
#define DRM_QAIC_MANAGE 0x00
376386
#define DRM_QAIC_CREATE_BO 0x01
377387
#define DRM_QAIC_MMAP_BO 0x02
@@ -380,6 +390,7 @@ struct qaic_perf_stats_entry {
380390
#define DRM_QAIC_PARTIAL_EXECUTE_BO 0x05
381391
#define DRM_QAIC_WAIT_BO 0x06
382392
#define DRM_QAIC_PERF_STATS_BO 0x07
393+
#define DRM_QAIC_DETACH_SLICE_BO 0x08
383394

384395
#define DRM_IOCTL_QAIC_MANAGE DRM_IOWR(DRM_COMMAND_BASE + DRM_QAIC_MANAGE, struct qaic_manage_msg)
385396
#define DRM_IOCTL_QAIC_CREATE_BO DRM_IOWR(DRM_COMMAND_BASE + DRM_QAIC_CREATE_BO, struct qaic_create_bo)
@@ -389,6 +400,7 @@ struct qaic_perf_stats_entry {
389400
#define DRM_IOCTL_QAIC_PARTIAL_EXECUTE_BO DRM_IOW(DRM_COMMAND_BASE + DRM_QAIC_PARTIAL_EXECUTE_BO, struct qaic_execute)
390401
#define DRM_IOCTL_QAIC_WAIT_BO DRM_IOW(DRM_COMMAND_BASE + DRM_QAIC_WAIT_BO, struct qaic_wait)
391402
#define DRM_IOCTL_QAIC_PERF_STATS_BO DRM_IOWR(DRM_COMMAND_BASE + DRM_QAIC_PERF_STATS_BO, struct qaic_perf_stats)
403+
#define DRM_IOCTL_QAIC_DETACH_SLICE_BO DRM_IOW(DRM_COMMAND_BASE + DRM_QAIC_DETACH_SLICE_BO, struct qaic_detach_slice)
392404

393405
#if defined(__cplusplus)
394406
}

0 commit comments

Comments
 (0)