Short summary of fixes pull:
amdxdna: - remove mmap and export for ubuf bridge: - chipone-icn6211: managed bridge cleanup - lt66121: acquire reset GPIO - megachips: fix clean up on failed IRQ requests gem: - clean up LRU locking v3d: - fix UAF in error code paths - release GEM-object ref on free'd jobs virtio: - use uninterruptible resv locking in plane updates -----BEGIN PGP SIGNATURE----- iQFPBAABCgA5FiEEchf7rIzpz2NEoWjlaA3BHVMLeiMFAmoOsLobFIAAAAAABAAO bWFudTIsMi41KzEuMTIsMiwyAAoJEGgNwR1TC3ojQ9UH/20+mQA59I+cyK95LLdn 9U7KMXhyN83U5jRSWsIRKaRoNO9y9iFhcraPv7LCJTnEu73EjcB67L1j3ReC0rEp Ws8EUsGF9T9iQR3qdMLJYB7tDhH44Na5LoB72bR4LeFskMwraR9/92iEq9Wfr7gZ y/ot/NnqBCEt5TOb7NVfALupyk4THFvfGVN/XIFEOKpDo24Lg+TDmToiam9hXpcX 0zgAvMAlla3gZr6F+GtwTQJI/GRpRbpUnOBh8XBbGTTq6h5k2R3o/oGTmOTbCoJv jh6o28aLMgE5/OsUdLxCiUwMFoFoR0p1DZJt5k8bnUNQPfuoA1U2CV7RGY9cVi0f 9ew= =QPEc -----END PGP SIGNATURE----- Merge tag 'drm-misc-fixes-2026-05-21' of https://gitlab.freedesktop.org/drm/misc/kernel into drm-fixes Short summary of fixes pull: amdxdna: - remove mmap and export for ubuf bridge: - chipone-icn6211: managed bridge cleanup - lt66121: acquire reset GPIO - megachips: fix clean up on failed IRQ requests gem: - clean up LRU locking v3d: - fix UAF in error code paths - release GEM-object ref on free'd jobs virtio: - use uninterruptible resv locking in plane updates Signed-off-by: Dave Airlie <airlied@redhat.com> From: Thomas Zimmermann <tzimmermann@suse.de> Link: https://patch.msgid.link/20260521071456.GA14644@localhost.localdomainmaster
commit
71d9e1561a
|
|
@ -490,6 +490,9 @@ static struct dma_buf *amdxdna_gem_prime_export(struct drm_gem_object *gobj, int
|
||||||
struct amdxdna_gem_obj *abo = to_xdna_obj(gobj);
|
struct amdxdna_gem_obj *abo = to_xdna_obj(gobj);
|
||||||
DEFINE_DMA_BUF_EXPORT_INFO(exp_info);
|
DEFINE_DMA_BUF_EXPORT_INFO(exp_info);
|
||||||
|
|
||||||
|
if (abo->private_buffer)
|
||||||
|
return ERR_PTR(-EOPNOTSUPP);
|
||||||
|
|
||||||
if (abo->dma_buf) {
|
if (abo->dma_buf) {
|
||||||
get_dma_buf(abo->dma_buf);
|
get_dma_buf(abo->dma_buf);
|
||||||
return abo->dma_buf;
|
return abo->dma_buf;
|
||||||
|
|
@ -685,6 +688,7 @@ amdxdna_gem_create_ubuf_object(struct drm_device *dev, struct amdxdna_drm_create
|
||||||
{
|
{
|
||||||
struct amdxdna_dev *xdna = to_xdna_dev(dev);
|
struct amdxdna_dev *xdna = to_xdna_dev(dev);
|
||||||
struct amdxdna_drm_va_tbl va_tbl;
|
struct amdxdna_drm_va_tbl va_tbl;
|
||||||
|
struct amdxdna_gem_obj *abo;
|
||||||
struct drm_gem_object *gobj;
|
struct drm_gem_object *gobj;
|
||||||
struct dma_buf *dma_buf;
|
struct dma_buf *dma_buf;
|
||||||
|
|
||||||
|
|
@ -711,7 +715,10 @@ amdxdna_gem_create_ubuf_object(struct drm_device *dev, struct amdxdna_drm_create
|
||||||
|
|
||||||
dma_buf_put(dma_buf);
|
dma_buf_put(dma_buf);
|
||||||
|
|
||||||
return to_xdna_obj(gobj);
|
abo = to_xdna_obj(gobj);
|
||||||
|
abo->private_buffer = true;
|
||||||
|
|
||||||
|
return abo;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct drm_gem_object *
|
struct drm_gem_object *
|
||||||
|
|
|
||||||
|
|
@ -54,6 +54,8 @@ struct amdxdna_gem_obj {
|
||||||
|
|
||||||
/* True, if BO is managed by XRT, not application */
|
/* True, if BO is managed by XRT, not application */
|
||||||
bool internal;
|
bool internal;
|
||||||
|
/* True, if BO is not exportable */
|
||||||
|
bool private_buffer;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define to_gobj(obj) (&(obj)->base.base)
|
#define to_gobj(obj) (&(obj)->base.base)
|
||||||
|
|
|
||||||
|
|
@ -69,60 +69,10 @@ static void amdxdna_ubuf_release(struct dma_buf *dbuf)
|
||||||
kfree(ubuf);
|
kfree(ubuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static vm_fault_t amdxdna_ubuf_vm_fault(struct vm_fault *vmf)
|
|
||||||
{
|
|
||||||
struct vm_area_struct *vma = vmf->vma;
|
|
||||||
struct amdxdna_ubuf_priv *ubuf;
|
|
||||||
unsigned long pfn;
|
|
||||||
pgoff_t pgoff;
|
|
||||||
|
|
||||||
ubuf = vma->vm_private_data;
|
|
||||||
pgoff = (vmf->address - vma->vm_start) >> PAGE_SHIFT;
|
|
||||||
|
|
||||||
pfn = page_to_pfn(ubuf->pages[pgoff]);
|
|
||||||
return vmf_insert_pfn(vma, vmf->address, pfn);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct vm_operations_struct amdxdna_ubuf_vm_ops = {
|
|
||||||
.fault = amdxdna_ubuf_vm_fault,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int amdxdna_ubuf_mmap(struct dma_buf *dbuf, struct vm_area_struct *vma)
|
|
||||||
{
|
|
||||||
struct amdxdna_ubuf_priv *ubuf = dbuf->priv;
|
|
||||||
|
|
||||||
vma->vm_ops = &amdxdna_ubuf_vm_ops;
|
|
||||||
vma->vm_private_data = ubuf;
|
|
||||||
vm_flags_set(vma, VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int amdxdna_ubuf_vmap(struct dma_buf *dbuf, struct iosys_map *map)
|
|
||||||
{
|
|
||||||
struct amdxdna_ubuf_priv *ubuf = dbuf->priv;
|
|
||||||
void *kva;
|
|
||||||
|
|
||||||
kva = vmap(ubuf->pages, ubuf->nr_pages, VM_MAP, PAGE_KERNEL);
|
|
||||||
if (!kva)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
iosys_map_set_vaddr(map, kva);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void amdxdna_ubuf_vunmap(struct dma_buf *dbuf, struct iosys_map *map)
|
|
||||||
{
|
|
||||||
vunmap(map->vaddr);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct dma_buf_ops amdxdna_ubuf_dmabuf_ops = {
|
static const struct dma_buf_ops amdxdna_ubuf_dmabuf_ops = {
|
||||||
.map_dma_buf = amdxdna_ubuf_map,
|
.map_dma_buf = amdxdna_ubuf_map,
|
||||||
.unmap_dma_buf = amdxdna_ubuf_unmap,
|
.unmap_dma_buf = amdxdna_ubuf_unmap,
|
||||||
.release = amdxdna_ubuf_release,
|
.release = amdxdna_ubuf_release,
|
||||||
.mmap = amdxdna_ubuf_mmap,
|
|
||||||
.vmap = amdxdna_ubuf_vmap,
|
|
||||||
.vunmap = amdxdna_ubuf_vunmap,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct dma_buf *amdxdna_get_ubuf(struct drm_device *dev,
|
struct dma_buf *amdxdna_get_ubuf(struct drm_device *dev,
|
||||||
|
|
|
||||||
|
|
@ -758,7 +758,9 @@ static int chipone_i2c_probe(struct i2c_client *client)
|
||||||
dev_set_drvdata(dev, icn);
|
dev_set_drvdata(dev, icn);
|
||||||
i2c_set_clientdata(client, icn);
|
i2c_set_clientdata(client, icn);
|
||||||
|
|
||||||
drm_bridge_add(&icn->bridge);
|
ret = devm_drm_bridge_add(dev, &icn->bridge);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
return chipone_dsi_host_attach(icn);
|
return chipone_dsi_host_attach(icn);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1559,6 +1559,11 @@ static int it66121_probe(struct i2c_client *client)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ctx->gpio_reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
|
||||||
|
if (IS_ERR(ctx->gpio_reset))
|
||||||
|
return dev_err_probe(dev, PTR_ERR(ctx->gpio_reset),
|
||||||
|
"Failed to get reset GPIO\n");
|
||||||
|
|
||||||
it66121_hw_reset(ctx);
|
it66121_hw_reset(ctx);
|
||||||
|
|
||||||
ctx->regmap = devm_regmap_init_i2c(client, &it66121_regmap_config);
|
ctx->regmap = devm_regmap_init_i2c(client, &it66121_regmap_config);
|
||||||
|
|
|
||||||
|
|
@ -251,7 +251,6 @@ static void ge_b850v3_lvds_remove(void)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
drm_bridge_remove(&ge_b850v3_lvds_ptr->bridge);
|
drm_bridge_remove(&ge_b850v3_lvds_ptr->bridge);
|
||||||
|
|
||||||
ge_b850v3_lvds_ptr = NULL;
|
ge_b850v3_lvds_ptr = NULL;
|
||||||
out:
|
out:
|
||||||
mutex_unlock(&ge_b850v3_lvds_dev_mutex);
|
mutex_unlock(&ge_b850v3_lvds_dev_mutex);
|
||||||
|
|
@ -261,6 +260,7 @@ static int ge_b850v3_register(void)
|
||||||
{
|
{
|
||||||
struct i2c_client *stdp4028_i2c = ge_b850v3_lvds_ptr->stdp4028_i2c;
|
struct i2c_client *stdp4028_i2c = ge_b850v3_lvds_ptr->stdp4028_i2c;
|
||||||
struct device *dev = &stdp4028_i2c->dev;
|
struct device *dev = &stdp4028_i2c->dev;
|
||||||
|
int ret;
|
||||||
|
|
||||||
/* drm bridge initialization */
|
/* drm bridge initialization */
|
||||||
ge_b850v3_lvds_ptr->bridge.ops = DRM_BRIDGE_OP_DETECT |
|
ge_b850v3_lvds_ptr->bridge.ops = DRM_BRIDGE_OP_DETECT |
|
||||||
|
|
@ -277,11 +277,15 @@ static int ge_b850v3_register(void)
|
||||||
if (!stdp4028_i2c->irq)
|
if (!stdp4028_i2c->irq)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return devm_request_threaded_irq(&stdp4028_i2c->dev,
|
ret = devm_request_threaded_irq(&stdp4028_i2c->dev,
|
||||||
stdp4028_i2c->irq, NULL,
|
stdp4028_i2c->irq, NULL,
|
||||||
ge_b850v3_lvds_irq_handler,
|
ge_b850v3_lvds_irq_handler,
|
||||||
IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
|
IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
|
||||||
"ge-b850v3-lvds-dp", ge_b850v3_lvds_ptr);
|
"ge-b850v3-lvds-dp", ge_b850v3_lvds_ptr);
|
||||||
|
if (ret)
|
||||||
|
drm_bridge_remove(&ge_b850v3_lvds_ptr->bridge);
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int stdp4028_ge_b850v3_fw_probe(struct i2c_client *stdp4028_i2c)
|
static int stdp4028_ge_b850v3_fw_probe(struct i2c_client *stdp4028_i2c)
|
||||||
|
|
|
||||||
|
|
@ -697,6 +697,7 @@ static void drm_dev_init_release(struct drm_device *dev, void *res)
|
||||||
mutex_destroy(&dev->master_mutex);
|
mutex_destroy(&dev->master_mutex);
|
||||||
mutex_destroy(&dev->clientlist_mutex);
|
mutex_destroy(&dev->clientlist_mutex);
|
||||||
mutex_destroy(&dev->filelist_mutex);
|
mutex_destroy(&dev->filelist_mutex);
|
||||||
|
mutex_destroy(&dev->gem_lru_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int drm_dev_init(struct drm_device *dev,
|
static int drm_dev_init(struct drm_device *dev,
|
||||||
|
|
@ -738,6 +739,7 @@ static int drm_dev_init(struct drm_device *dev,
|
||||||
INIT_LIST_HEAD(&dev->vblank_event_list);
|
INIT_LIST_HEAD(&dev->vblank_event_list);
|
||||||
|
|
||||||
spin_lock_init(&dev->event_lock);
|
spin_lock_init(&dev->event_lock);
|
||||||
|
mutex_init(&dev->gem_lru_mutex);
|
||||||
mutex_init(&dev->filelist_mutex);
|
mutex_init(&dev->filelist_mutex);
|
||||||
mutex_init(&dev->clientlist_mutex);
|
mutex_init(&dev->clientlist_mutex);
|
||||||
mutex_init(&dev->master_mutex);
|
mutex_init(&dev->master_mutex);
|
||||||
|
|
|
||||||
|
|
@ -1561,12 +1561,10 @@ EXPORT_SYMBOL(drm_gem_unlock_reservations);
|
||||||
* drm_gem_lru_init - initialize a LRU
|
* drm_gem_lru_init - initialize a LRU
|
||||||
*
|
*
|
||||||
* @lru: The LRU to initialize
|
* @lru: The LRU to initialize
|
||||||
* @lock: The lock protecting the LRU
|
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
drm_gem_lru_init(struct drm_gem_lru *lru, struct mutex *lock)
|
drm_gem_lru_init(struct drm_gem_lru *lru)
|
||||||
{
|
{
|
||||||
lru->lock = lock;
|
|
||||||
lru->count = 0;
|
lru->count = 0;
|
||||||
INIT_LIST_HEAD(&lru->list);
|
INIT_LIST_HEAD(&lru->list);
|
||||||
}
|
}
|
||||||
|
|
@ -1591,14 +1589,10 @@ drm_gem_lru_remove_locked(struct drm_gem_object *obj)
|
||||||
void
|
void
|
||||||
drm_gem_lru_remove(struct drm_gem_object *obj)
|
drm_gem_lru_remove(struct drm_gem_object *obj)
|
||||||
{
|
{
|
||||||
struct drm_gem_lru *lru = obj->lru;
|
mutex_lock(&obj->dev->gem_lru_mutex);
|
||||||
|
if (obj->lru)
|
||||||
if (!lru)
|
|
||||||
return;
|
|
||||||
|
|
||||||
mutex_lock(lru->lock);
|
|
||||||
drm_gem_lru_remove_locked(obj);
|
drm_gem_lru_remove_locked(obj);
|
||||||
mutex_unlock(lru->lock);
|
mutex_unlock(&obj->dev->gem_lru_mutex);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(drm_gem_lru_remove);
|
EXPORT_SYMBOL(drm_gem_lru_remove);
|
||||||
|
|
||||||
|
|
@ -1613,7 +1607,7 @@ EXPORT_SYMBOL(drm_gem_lru_remove);
|
||||||
void
|
void
|
||||||
drm_gem_lru_move_tail_locked(struct drm_gem_lru *lru, struct drm_gem_object *obj)
|
drm_gem_lru_move_tail_locked(struct drm_gem_lru *lru, struct drm_gem_object *obj)
|
||||||
{
|
{
|
||||||
lockdep_assert_held_once(lru->lock);
|
lockdep_assert_held_once(&obj->dev->gem_lru_mutex);
|
||||||
|
|
||||||
if (obj->lru)
|
if (obj->lru)
|
||||||
drm_gem_lru_remove_locked(obj);
|
drm_gem_lru_remove_locked(obj);
|
||||||
|
|
@ -1637,9 +1631,9 @@ EXPORT_SYMBOL(drm_gem_lru_move_tail_locked);
|
||||||
void
|
void
|
||||||
drm_gem_lru_move_tail(struct drm_gem_lru *lru, struct drm_gem_object *obj)
|
drm_gem_lru_move_tail(struct drm_gem_lru *lru, struct drm_gem_object *obj)
|
||||||
{
|
{
|
||||||
mutex_lock(lru->lock);
|
mutex_lock(&obj->dev->gem_lru_mutex);
|
||||||
drm_gem_lru_move_tail_locked(lru, obj);
|
drm_gem_lru_move_tail_locked(lru, obj);
|
||||||
mutex_unlock(lru->lock);
|
mutex_unlock(&obj->dev->gem_lru_mutex);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(drm_gem_lru_move_tail);
|
EXPORT_SYMBOL(drm_gem_lru_move_tail);
|
||||||
|
|
||||||
|
|
@ -1653,6 +1647,7 @@ EXPORT_SYMBOL(drm_gem_lru_move_tail);
|
||||||
* of the shrink callback to check for this (ie. dma_resv_test_signaled())
|
* of the shrink callback to check for this (ie. dma_resv_test_signaled())
|
||||||
* or if necessary block until the buffer becomes idle.
|
* or if necessary block until the buffer becomes idle.
|
||||||
*
|
*
|
||||||
|
* @dev: DRM device the LRU belongs to
|
||||||
* @lru: The LRU to scan
|
* @lru: The LRU to scan
|
||||||
* @nr_to_scan: The number of pages to try to reclaim
|
* @nr_to_scan: The number of pages to try to reclaim
|
||||||
* @remaining: The number of pages left to reclaim, should be initialized by caller
|
* @remaining: The number of pages left to reclaim, should be initialized by caller
|
||||||
|
|
@ -1660,7 +1655,8 @@ EXPORT_SYMBOL(drm_gem_lru_move_tail);
|
||||||
* @ticket: Optional ww_acquire_ctx context to use for locking
|
* @ticket: Optional ww_acquire_ctx context to use for locking
|
||||||
*/
|
*/
|
||||||
unsigned long
|
unsigned long
|
||||||
drm_gem_lru_scan(struct drm_gem_lru *lru,
|
drm_gem_lru_scan(struct drm_device *dev,
|
||||||
|
struct drm_gem_lru *lru,
|
||||||
unsigned int nr_to_scan,
|
unsigned int nr_to_scan,
|
||||||
unsigned long *remaining,
|
unsigned long *remaining,
|
||||||
bool (*shrink)(struct drm_gem_object *obj, struct ww_acquire_ctx *ticket),
|
bool (*shrink)(struct drm_gem_object *obj, struct ww_acquire_ctx *ticket),
|
||||||
|
|
@ -1670,9 +1666,9 @@ drm_gem_lru_scan(struct drm_gem_lru *lru,
|
||||||
struct drm_gem_object *obj;
|
struct drm_gem_object *obj;
|
||||||
unsigned freed = 0;
|
unsigned freed = 0;
|
||||||
|
|
||||||
drm_gem_lru_init(&still_in_lru, lru->lock);
|
drm_gem_lru_init(&still_in_lru);
|
||||||
|
|
||||||
mutex_lock(lru->lock);
|
mutex_lock(&dev->gem_lru_mutex);
|
||||||
|
|
||||||
while (freed < nr_to_scan) {
|
while (freed < nr_to_scan) {
|
||||||
obj = list_first_entry_or_null(&lru->list, typeof(*obj), lru_node);
|
obj = list_first_entry_or_null(&lru->list, typeof(*obj), lru_node);
|
||||||
|
|
@ -1695,7 +1691,7 @@ drm_gem_lru_scan(struct drm_gem_lru *lru,
|
||||||
* rest of the loop body, to reduce contention with other
|
* rest of the loop body, to reduce contention with other
|
||||||
* code paths that need the LRU lock
|
* code paths that need the LRU lock
|
||||||
*/
|
*/
|
||||||
mutex_unlock(lru->lock);
|
mutex_unlock(&dev->gem_lru_mutex);
|
||||||
|
|
||||||
if (ticket)
|
if (ticket)
|
||||||
ww_acquire_init(ticket, &reservation_ww_class);
|
ww_acquire_init(ticket, &reservation_ww_class);
|
||||||
|
|
@ -1729,7 +1725,7 @@ drm_gem_lru_scan(struct drm_gem_lru *lru,
|
||||||
|
|
||||||
tail:
|
tail:
|
||||||
drm_gem_object_put(obj);
|
drm_gem_object_put(obj);
|
||||||
mutex_lock(lru->lock);
|
mutex_lock(&dev->gem_lru_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -1741,7 +1737,7 @@ tail:
|
||||||
list_splice_tail(&still_in_lru.list, &lru->list);
|
list_splice_tail(&still_in_lru.list, &lru->list);
|
||||||
lru->count += still_in_lru.count;
|
lru->count += still_in_lru.count;
|
||||||
|
|
||||||
mutex_unlock(lru->lock);
|
mutex_unlock(&dev->gem_lru_mutex);
|
||||||
|
|
||||||
return freed;
|
return freed;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -128,11 +128,10 @@ static int msm_drm_init(struct device *dev, const struct drm_driver *drv,
|
||||||
/*
|
/*
|
||||||
* Initialize the LRUs:
|
* Initialize the LRUs:
|
||||||
*/
|
*/
|
||||||
mutex_init(&priv->lru.lock);
|
drm_gem_lru_init(&priv->lru.unbacked);
|
||||||
drm_gem_lru_init(&priv->lru.unbacked, &priv->lru.lock);
|
drm_gem_lru_init(&priv->lru.pinned);
|
||||||
drm_gem_lru_init(&priv->lru.pinned, &priv->lru.lock);
|
drm_gem_lru_init(&priv->lru.willneed);
|
||||||
drm_gem_lru_init(&priv->lru.willneed, &priv->lru.lock);
|
drm_gem_lru_init(&priv->lru.dontneed);
|
||||||
drm_gem_lru_init(&priv->lru.dontneed, &priv->lru.lock);
|
|
||||||
|
|
||||||
/* Initialize stall-on-fault */
|
/* Initialize stall-on-fault */
|
||||||
spin_lock_init(&priv->fault_stall_lock);
|
spin_lock_init(&priv->fault_stall_lock);
|
||||||
|
|
@ -140,7 +139,7 @@ static int msm_drm_init(struct device *dev, const struct drm_driver *drv,
|
||||||
|
|
||||||
/* Teach lockdep about lock ordering wrt. shrinker: */
|
/* Teach lockdep about lock ordering wrt. shrinker: */
|
||||||
fs_reclaim_acquire(GFP_KERNEL);
|
fs_reclaim_acquire(GFP_KERNEL);
|
||||||
might_lock(&priv->lru.lock);
|
might_lock(&ddev->gem_lru_mutex);
|
||||||
fs_reclaim_release(GFP_KERNEL);
|
fs_reclaim_release(GFP_KERNEL);
|
||||||
|
|
||||||
if (priv->kms_init) {
|
if (priv->kms_init) {
|
||||||
|
|
|
||||||
|
|
@ -150,13 +150,6 @@ struct msm_drm_private {
|
||||||
* DONTNEED state (ie. can be purged)
|
* DONTNEED state (ie. can be purged)
|
||||||
*/
|
*/
|
||||||
struct drm_gem_lru dontneed;
|
struct drm_gem_lru dontneed;
|
||||||
|
|
||||||
/**
|
|
||||||
* lock:
|
|
||||||
*
|
|
||||||
* Protects manipulation of all of the LRUs.
|
|
||||||
*/
|
|
||||||
struct mutex lock;
|
|
||||||
} lru;
|
} lru;
|
||||||
|
|
||||||
struct notifier_block vmap_notifier;
|
struct notifier_block vmap_notifier;
|
||||||
|
|
|
||||||
|
|
@ -177,11 +177,11 @@ static void update_lru_locked(struct drm_gem_object *obj)
|
||||||
|
|
||||||
static void update_lru(struct drm_gem_object *obj)
|
static void update_lru(struct drm_gem_object *obj)
|
||||||
{
|
{
|
||||||
struct msm_drm_private *priv = obj->dev->dev_private;
|
struct drm_device *dev = obj->dev;
|
||||||
|
|
||||||
mutex_lock(&priv->lru.lock);
|
mutex_lock(&dev->gem_lru_mutex);
|
||||||
update_lru_locked(obj);
|
update_lru_locked(obj);
|
||||||
mutex_unlock(&priv->lru.lock);
|
mutex_unlock(&dev->gem_lru_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct page **get_pages(struct drm_gem_object *obj)
|
static struct page **get_pages(struct drm_gem_object *obj)
|
||||||
|
|
@ -292,11 +292,11 @@ void msm_gem_pin_obj_locked(struct drm_gem_object *obj)
|
||||||
|
|
||||||
static void pin_obj_locked(struct drm_gem_object *obj)
|
static void pin_obj_locked(struct drm_gem_object *obj)
|
||||||
{
|
{
|
||||||
struct msm_drm_private *priv = obj->dev->dev_private;
|
struct drm_device *dev = obj->dev;
|
||||||
|
|
||||||
mutex_lock(&priv->lru.lock);
|
mutex_lock(&dev->gem_lru_mutex);
|
||||||
msm_gem_pin_obj_locked(obj);
|
msm_gem_pin_obj_locked(obj);
|
||||||
mutex_unlock(&priv->lru.lock);
|
mutex_unlock(&dev->gem_lru_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct page **msm_gem_pin_pages_locked(struct drm_gem_object *obj)
|
struct page **msm_gem_pin_pages_locked(struct drm_gem_object *obj)
|
||||||
|
|
@ -487,16 +487,16 @@ int msm_gem_pin_vma_locked(struct drm_gem_object *obj, struct drm_gpuva *vma)
|
||||||
|
|
||||||
void msm_gem_unpin_locked(struct drm_gem_object *obj)
|
void msm_gem_unpin_locked(struct drm_gem_object *obj)
|
||||||
{
|
{
|
||||||
struct msm_drm_private *priv = obj->dev->dev_private;
|
struct drm_device *dev = obj->dev;
|
||||||
struct msm_gem_object *msm_obj = to_msm_bo(obj);
|
struct msm_gem_object *msm_obj = to_msm_bo(obj);
|
||||||
|
|
||||||
msm_gem_assert_locked(obj);
|
msm_gem_assert_locked(obj);
|
||||||
|
|
||||||
mutex_lock(&priv->lru.lock);
|
mutex_lock(&dev->gem_lru_mutex);
|
||||||
msm_obj->pin_count--;
|
msm_obj->pin_count--;
|
||||||
GEM_WARN_ON(msm_obj->pin_count < 0);
|
GEM_WARN_ON(msm_obj->pin_count < 0);
|
||||||
update_lru_locked(obj);
|
update_lru_locked(obj);
|
||||||
mutex_unlock(&priv->lru.lock);
|
mutex_unlock(&dev->gem_lru_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Special unpin path for use in fence-signaling path, avoiding the need
|
/* Special unpin path for use in fence-signaling path, avoiding the need
|
||||||
|
|
@ -507,10 +507,10 @@ void msm_gem_unpin_locked(struct drm_gem_object *obj)
|
||||||
*/
|
*/
|
||||||
void msm_gem_unpin_active(struct drm_gem_object *obj)
|
void msm_gem_unpin_active(struct drm_gem_object *obj)
|
||||||
{
|
{
|
||||||
struct msm_drm_private *priv = obj->dev->dev_private;
|
struct drm_device *dev = obj->dev;
|
||||||
struct msm_gem_object *msm_obj = to_msm_bo(obj);
|
struct msm_gem_object *msm_obj = to_msm_bo(obj);
|
||||||
|
|
||||||
GEM_WARN_ON(!mutex_is_locked(&priv->lru.lock));
|
GEM_WARN_ON(!mutex_is_locked(&dev->gem_lru_mutex));
|
||||||
|
|
||||||
msm_obj->pin_count--;
|
msm_obj->pin_count--;
|
||||||
GEM_WARN_ON(msm_obj->pin_count < 0);
|
GEM_WARN_ON(msm_obj->pin_count < 0);
|
||||||
|
|
@ -797,12 +797,12 @@ void msm_gem_put_vaddr(struct drm_gem_object *obj)
|
||||||
*/
|
*/
|
||||||
int msm_gem_madvise(struct drm_gem_object *obj, unsigned madv)
|
int msm_gem_madvise(struct drm_gem_object *obj, unsigned madv)
|
||||||
{
|
{
|
||||||
struct msm_drm_private *priv = obj->dev->dev_private;
|
struct drm_device *dev = obj->dev;
|
||||||
struct msm_gem_object *msm_obj = to_msm_bo(obj);
|
struct msm_gem_object *msm_obj = to_msm_bo(obj);
|
||||||
|
|
||||||
msm_gem_lock(obj);
|
msm_gem_lock(obj);
|
||||||
|
|
||||||
mutex_lock(&priv->lru.lock);
|
mutex_lock(&dev->gem_lru_mutex);
|
||||||
|
|
||||||
if (msm_obj->madv != __MSM_MADV_PURGED)
|
if (msm_obj->madv != __MSM_MADV_PURGED)
|
||||||
msm_obj->madv = madv;
|
msm_obj->madv = madv;
|
||||||
|
|
@ -814,7 +814,7 @@ int msm_gem_madvise(struct drm_gem_object *obj, unsigned madv)
|
||||||
*/
|
*/
|
||||||
update_lru_locked(obj);
|
update_lru_locked(obj);
|
||||||
|
|
||||||
mutex_unlock(&priv->lru.lock);
|
mutex_unlock(&dev->gem_lru_mutex);
|
||||||
|
|
||||||
msm_gem_unlock(obj);
|
msm_gem_unlock(obj);
|
||||||
|
|
||||||
|
|
@ -824,7 +824,6 @@ int msm_gem_madvise(struct drm_gem_object *obj, unsigned madv)
|
||||||
void msm_gem_purge(struct drm_gem_object *obj)
|
void msm_gem_purge(struct drm_gem_object *obj)
|
||||||
{
|
{
|
||||||
struct drm_device *dev = obj->dev;
|
struct drm_device *dev = obj->dev;
|
||||||
struct msm_drm_private *priv = obj->dev->dev_private;
|
|
||||||
struct msm_gem_object *msm_obj = to_msm_bo(obj);
|
struct msm_gem_object *msm_obj = to_msm_bo(obj);
|
||||||
|
|
||||||
msm_gem_assert_locked(obj);
|
msm_gem_assert_locked(obj);
|
||||||
|
|
@ -839,10 +838,10 @@ void msm_gem_purge(struct drm_gem_object *obj)
|
||||||
|
|
||||||
put_pages(obj);
|
put_pages(obj);
|
||||||
|
|
||||||
mutex_lock(&priv->lru.lock);
|
mutex_lock(&dev->gem_lru_mutex);
|
||||||
/* A one-way transition: */
|
/* A one-way transition: */
|
||||||
msm_obj->madv = __MSM_MADV_PURGED;
|
msm_obj->madv = __MSM_MADV_PURGED;
|
||||||
mutex_unlock(&priv->lru.lock);
|
mutex_unlock(&dev->gem_lru_mutex);
|
||||||
|
|
||||||
drm_gem_free_mmap_offset(obj);
|
drm_gem_free_mmap_offset(obj);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -178,7 +178,7 @@ msm_gem_shrinker_scan(struct shrinker *shrinker, struct shrink_control *sc)
|
||||||
* 'ticket' not needed on trylock paths
|
* 'ticket' not needed on trylock paths
|
||||||
*/
|
*/
|
||||||
stages[i].freed =
|
stages[i].freed =
|
||||||
drm_gem_lru_scan(stages[i].lru, nr,
|
drm_gem_lru_scan(priv->dev, stages[i].lru, nr,
|
||||||
&stages[i].remaining,
|
&stages[i].remaining,
|
||||||
stages[i].shrink,
|
stages[i].shrink,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
@ -247,7 +247,7 @@ msm_gem_shrinker_vmap(struct notifier_block *nb, unsigned long event, void *ptr)
|
||||||
unsigned long remaining = 0;
|
unsigned long remaining = 0;
|
||||||
|
|
||||||
for (idx = 0; lrus[idx] && unmapped < vmap_shrink_limit; idx++) {
|
for (idx = 0; lrus[idx] && unmapped < vmap_shrink_limit; idx++) {
|
||||||
unmapped += drm_gem_lru_scan(lrus[idx],
|
unmapped += drm_gem_lru_scan(priv->dev, lrus[idx],
|
||||||
vmap_shrink_limit - unmapped,
|
vmap_shrink_limit - unmapped,
|
||||||
&remaining,
|
&remaining,
|
||||||
vmap_shrink,
|
vmap_shrink,
|
||||||
|
|
|
||||||
|
|
@ -352,7 +352,7 @@ static int submit_fence_sync(struct msm_gem_submit *submit)
|
||||||
|
|
||||||
static int submit_pin_objects(struct msm_gem_submit *submit)
|
static int submit_pin_objects(struct msm_gem_submit *submit)
|
||||||
{
|
{
|
||||||
struct msm_drm_private *priv = submit->dev->dev_private;
|
struct drm_device *dev = submit->dev;
|
||||||
int i, ret = 0;
|
int i, ret = 0;
|
||||||
|
|
||||||
for (i = 0; i < submit->nr_bos; i++) {
|
for (i = 0; i < submit->nr_bos; i++) {
|
||||||
|
|
@ -381,11 +381,11 @@ static int submit_pin_objects(struct msm_gem_submit *submit)
|
||||||
* get_pages() which could trigger reclaim.. and if we held the LRU lock
|
* get_pages() which could trigger reclaim.. and if we held the LRU lock
|
||||||
* could trigger deadlock with the shrinker).
|
* could trigger deadlock with the shrinker).
|
||||||
*/
|
*/
|
||||||
mutex_lock(&priv->lru.lock);
|
mutex_lock(&dev->gem_lru_mutex);
|
||||||
for (i = 0; i < submit->nr_bos; i++) {
|
for (i = 0; i < submit->nr_bos; i++) {
|
||||||
msm_gem_pin_obj_locked(submit->bos[i].obj);
|
msm_gem_pin_obj_locked(submit->bos[i].obj);
|
||||||
}
|
}
|
||||||
mutex_unlock(&priv->lru.lock);
|
mutex_unlock(&dev->gem_lru_mutex);
|
||||||
|
|
||||||
submit->bos_pinned = true;
|
submit->bos_pinned = true;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -702,7 +702,7 @@ static struct dma_fence *
|
||||||
msm_vma_job_run(struct drm_sched_job *_job)
|
msm_vma_job_run(struct drm_sched_job *_job)
|
||||||
{
|
{
|
||||||
struct msm_vm_bind_job *job = to_msm_vm_bind_job(_job);
|
struct msm_vm_bind_job *job = to_msm_vm_bind_job(_job);
|
||||||
struct msm_drm_private *priv = job->vm->drm->dev_private;
|
struct drm_device *dev = job->vm->drm;
|
||||||
struct msm_gem_vm *vm = to_msm_vm(job->vm);
|
struct msm_gem_vm *vm = to_msm_vm(job->vm);
|
||||||
struct drm_gem_object *obj;
|
struct drm_gem_object *obj;
|
||||||
int ret = vm->unusable ? -EINVAL : 0;
|
int ret = vm->unusable ? -EINVAL : 0;
|
||||||
|
|
@ -745,13 +745,13 @@ msm_vma_job_run(struct drm_sched_job *_job)
|
||||||
if (ret)
|
if (ret)
|
||||||
msm_gem_vm_unusable(job->vm);
|
msm_gem_vm_unusable(job->vm);
|
||||||
|
|
||||||
mutex_lock(&priv->lru.lock);
|
mutex_lock(&dev->gem_lru_mutex);
|
||||||
|
|
||||||
job_foreach_bo (obj, job) {
|
job_foreach_bo (obj, job) {
|
||||||
msm_gem_unpin_active(obj);
|
msm_gem_unpin_active(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_unlock(&priv->lru.lock);
|
mutex_unlock(&dev->gem_lru_mutex);
|
||||||
|
|
||||||
/* VM_BIND ops are synchronous, so no fence to wait on: */
|
/* VM_BIND ops are synchronous, so no fence to wait on: */
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
@ -1305,7 +1305,7 @@ vm_bind_job_pin_objects(struct msm_vm_bind_job *job)
|
||||||
return PTR_ERR(pages);
|
return PTR_ERR(pages);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct msm_drm_private *priv = job->vm->drm->dev_private;
|
struct drm_device *dev = job->vm->drm;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A second loop while holding the LRU lock (a) avoids acquiring/dropping
|
* A second loop while holding the LRU lock (a) avoids acquiring/dropping
|
||||||
|
|
@ -1314,10 +1314,10 @@ vm_bind_job_pin_objects(struct msm_vm_bind_job *job)
|
||||||
* get_pages() which could trigger reclaim.. and if we held the LRU lock
|
* get_pages() which could trigger reclaim.. and if we held the LRU lock
|
||||||
* could trigger deadlock with the shrinker).
|
* could trigger deadlock with the shrinker).
|
||||||
*/
|
*/
|
||||||
mutex_lock(&priv->lru.lock);
|
mutex_lock(&dev->gem_lru_mutex);
|
||||||
job_foreach_bo (obj, job)
|
job_foreach_bo (obj, job)
|
||||||
msm_gem_pin_obj_locked(obj);
|
msm_gem_pin_obj_locked(obj);
|
||||||
mutex_unlock(&priv->lru.lock);
|
mutex_unlock(&dev->gem_lru_mutex);
|
||||||
|
|
||||||
job->bos_pinned = true;
|
job->bos_pinned = true;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,13 +16,13 @@ static struct dma_fence *msm_job_run(struct drm_sched_job *job)
|
||||||
struct msm_gem_submit *submit = to_msm_submit(job);
|
struct msm_gem_submit *submit = to_msm_submit(job);
|
||||||
struct msm_fence_context *fctx = submit->ring->fctx;
|
struct msm_fence_context *fctx = submit->ring->fctx;
|
||||||
struct msm_gpu *gpu = submit->gpu;
|
struct msm_gpu *gpu = submit->gpu;
|
||||||
struct msm_drm_private *priv = gpu->dev->dev_private;
|
struct drm_device *dev = gpu->dev;
|
||||||
unsigned nr_cmds = submit->nr_cmds;
|
unsigned nr_cmds = submit->nr_cmds;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
msm_fence_init(submit->hw_fence, fctx);
|
msm_fence_init(submit->hw_fence, fctx);
|
||||||
|
|
||||||
mutex_lock(&priv->lru.lock);
|
mutex_lock(&dev->gem_lru_mutex);
|
||||||
|
|
||||||
for (i = 0; i < submit->nr_bos; i++) {
|
for (i = 0; i < submit->nr_bos; i++) {
|
||||||
struct drm_gem_object *obj = submit->bos[i].obj;
|
struct drm_gem_object *obj = submit->bos[i].obj;
|
||||||
|
|
@ -32,7 +32,7 @@ static struct dma_fence *msm_job_run(struct drm_sched_job *job)
|
||||||
|
|
||||||
submit->bos_pinned = false;
|
submit->bos_pinned = false;
|
||||||
|
|
||||||
mutex_unlock(&priv->lru.lock);
|
mutex_unlock(&dev->gem_lru_mutex);
|
||||||
|
|
||||||
/* TODO move submit path over to using a per-ring lock.. */
|
/* TODO move submit path over to using a per-ring lock.. */
|
||||||
mutex_lock(&gpu->lock);
|
mutex_lock(&gpu->lock);
|
||||||
|
|
|
||||||
|
|
@ -125,20 +125,6 @@ v3d_performance_query_info_free(struct v3d_performance_query_info *query_info,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
v3d_cpu_job_free(struct drm_sched_job *sched_job)
|
|
||||||
{
|
|
||||||
struct v3d_cpu_job *job = to_cpu_job(sched_job);
|
|
||||||
|
|
||||||
v3d_timestamp_query_info_free(&job->timestamp_query,
|
|
||||||
job->timestamp_query.count);
|
|
||||||
|
|
||||||
v3d_performance_query_info_free(&job->performance_query,
|
|
||||||
job->performance_query.count);
|
|
||||||
|
|
||||||
v3d_job_cleanup(&job->base);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
v3d_switch_perfmon(struct v3d_dev *v3d, struct v3d_job *job)
|
v3d_switch_perfmon(struct v3d_dev *v3d, struct v3d_job *job)
|
||||||
{
|
{
|
||||||
|
|
@ -830,7 +816,7 @@ static const struct drm_sched_backend_ops v3d_cache_clean_sched_ops = {
|
||||||
|
|
||||||
static const struct drm_sched_backend_ops v3d_cpu_sched_ops = {
|
static const struct drm_sched_backend_ops v3d_cpu_sched_ops = {
|
||||||
.run_job = v3d_cpu_job_run,
|
.run_job = v3d_cpu_job_run,
|
||||||
.free_job = v3d_cpu_job_free
|
.free_job = v3d_sched_job_free
|
||||||
};
|
};
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
|
|
||||||
|
|
@ -123,6 +123,24 @@ v3d_render_job_free(struct kref *ref)
|
||||||
v3d_job_free(ref);
|
v3d_job_free(ref);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
v3d_cpu_job_free(struct kref *ref)
|
||||||
|
{
|
||||||
|
struct v3d_cpu_job *job = container_of(ref, struct v3d_cpu_job,
|
||||||
|
base.refcount);
|
||||||
|
|
||||||
|
v3d_timestamp_query_info_free(&job->timestamp_query,
|
||||||
|
job->timestamp_query.count);
|
||||||
|
|
||||||
|
v3d_performance_query_info_free(&job->performance_query,
|
||||||
|
job->performance_query.count);
|
||||||
|
|
||||||
|
if (job->indirect_csd.indirect)
|
||||||
|
drm_gem_object_put(job->indirect_csd.indirect);
|
||||||
|
|
||||||
|
v3d_job_free(ref);
|
||||||
|
}
|
||||||
|
|
||||||
void v3d_job_cleanup(struct v3d_job *job)
|
void v3d_job_cleanup(struct v3d_job *job)
|
||||||
{
|
{
|
||||||
if (!job)
|
if (!job)
|
||||||
|
|
@ -1302,7 +1320,7 @@ v3d_submit_cpu_ioctl(struct drm_device *dev, void *data,
|
||||||
trace_v3d_submit_cpu_ioctl(&v3d->drm, cpu_job->job_type);
|
trace_v3d_submit_cpu_ioctl(&v3d->drm, cpu_job->job_type);
|
||||||
|
|
||||||
ret = v3d_job_init(v3d, file_priv, &cpu_job->base,
|
ret = v3d_job_init(v3d, file_priv, &cpu_job->base,
|
||||||
v3d_job_free, 0, &se, V3D_CPU);
|
v3d_cpu_job_free, 0, &se, V3D_CPU);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
v3d_job_deallocate((void *)&cpu_job);
|
v3d_job_deallocate((void *)&cpu_job);
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
@ -1385,8 +1403,6 @@ fail:
|
||||||
v3d_job_cleanup((void *)csd_job);
|
v3d_job_cleanup((void *)csd_job);
|
||||||
v3d_job_cleanup(clean_job);
|
v3d_job_cleanup(clean_job);
|
||||||
v3d_put_multisync_post_deps(&se);
|
v3d_put_multisync_post_deps(&se);
|
||||||
kvfree(cpu_job->timestamp_query.queries);
|
|
||||||
kvfree(cpu_job->performance_query.queries);
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -317,6 +317,7 @@ virtio_gpu_array_from_handles(struct drm_file *drm_file, u32 *handles, u32 nents
|
||||||
void virtio_gpu_array_add_obj(struct virtio_gpu_object_array *objs,
|
void virtio_gpu_array_add_obj(struct virtio_gpu_object_array *objs,
|
||||||
struct drm_gem_object *obj);
|
struct drm_gem_object *obj);
|
||||||
int virtio_gpu_array_lock_resv(struct virtio_gpu_object_array *objs);
|
int virtio_gpu_array_lock_resv(struct virtio_gpu_object_array *objs);
|
||||||
|
int virtio_gpu_lock_one_resv_uninterruptible(struct virtio_gpu_object_array *objs);
|
||||||
void virtio_gpu_array_unlock_resv(struct virtio_gpu_object_array *objs);
|
void virtio_gpu_array_unlock_resv(struct virtio_gpu_object_array *objs);
|
||||||
void virtio_gpu_array_add_fence(struct virtio_gpu_object_array *objs,
|
void virtio_gpu_array_add_fence(struct virtio_gpu_object_array *objs,
|
||||||
struct dma_fence *fence);
|
struct dma_fence *fence);
|
||||||
|
|
|
||||||
|
|
@ -238,6 +238,23 @@ int virtio_gpu_array_lock_resv(struct virtio_gpu_object_array *objs)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int virtio_gpu_lock_one_resv_uninterruptible(struct virtio_gpu_object_array *objs)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (objs->nents != 1)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
dma_resv_lock(objs->objs[0]->resv, NULL);
|
||||||
|
|
||||||
|
ret = dma_resv_reserve_fences(objs->objs[0]->resv, 1);
|
||||||
|
if (ret) {
|
||||||
|
virtio_gpu_array_unlock_resv(objs);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void virtio_gpu_array_unlock_resv(struct virtio_gpu_object_array *objs)
|
void virtio_gpu_array_unlock_resv(struct virtio_gpu_object_array *objs)
|
||||||
{
|
{
|
||||||
if (objs->nents == 1) {
|
if (objs->nents == 1) {
|
||||||
|
|
|
||||||
|
|
@ -215,7 +215,10 @@ static void virtio_gpu_resource_flush(struct drm_plane *plane,
|
||||||
if (!objs)
|
if (!objs)
|
||||||
return;
|
return;
|
||||||
virtio_gpu_array_add_obj(objs, vgfb->base.obj[0]);
|
virtio_gpu_array_add_obj(objs, vgfb->base.obj[0]);
|
||||||
virtio_gpu_array_lock_resv(objs);
|
if (virtio_gpu_lock_one_resv_uninterruptible(objs)) {
|
||||||
|
virtio_gpu_array_put_free(objs);
|
||||||
|
return;
|
||||||
|
}
|
||||||
virtio_gpu_cmd_resource_flush(vgdev, bo->hw_res_handle, x, y,
|
virtio_gpu_cmd_resource_flush(vgdev, bo->hw_res_handle, x, y,
|
||||||
width, height, objs,
|
width, height, objs,
|
||||||
vgplane_st->fence);
|
vgplane_st->fence);
|
||||||
|
|
@ -459,7 +462,10 @@ static void virtio_gpu_cursor_plane_update(struct drm_plane *plane,
|
||||||
if (!objs)
|
if (!objs)
|
||||||
return;
|
return;
|
||||||
virtio_gpu_array_add_obj(objs, vgfb->base.obj[0]);
|
virtio_gpu_array_add_obj(objs, vgfb->base.obj[0]);
|
||||||
virtio_gpu_array_lock_resv(objs);
|
if (virtio_gpu_lock_one_resv_uninterruptible(objs)) {
|
||||||
|
virtio_gpu_array_put_free(objs);
|
||||||
|
return;
|
||||||
|
}
|
||||||
virtio_gpu_cmd_transfer_to_host_2d
|
virtio_gpu_cmd_transfer_to_host_2d
|
||||||
(vgdev, 0,
|
(vgdev, 0,
|
||||||
plane->state->crtc_w,
|
plane->state->crtc_w,
|
||||||
|
|
|
||||||
|
|
@ -375,6 +375,13 @@ struct drm_device {
|
||||||
* Root directory for debugfs files.
|
* Root directory for debugfs files.
|
||||||
*/
|
*/
|
||||||
struct dentry *debugfs_root;
|
struct dentry *debugfs_root;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @gem_lru_mutex:
|
||||||
|
*
|
||||||
|
* Lock protecting movement of GEM objects between LRUs.
|
||||||
|
*/
|
||||||
|
struct mutex gem_lru_mutex;
|
||||||
};
|
};
|
||||||
|
|
||||||
void drm_dev_set_dma_dev(struct drm_device *dev, struct device *dma_dev);
|
void drm_dev_set_dma_dev(struct drm_device *dev, struct device *dma_dev);
|
||||||
|
|
|
||||||
|
|
@ -245,17 +245,11 @@ struct drm_gem_object_funcs {
|
||||||
* for lockless &shrinker.count_objects, and provides
|
* for lockless &shrinker.count_objects, and provides
|
||||||
* &drm_gem_lru_scan for driver's &shrinker.scan_objects
|
* &drm_gem_lru_scan for driver's &shrinker.scan_objects
|
||||||
* implementation.
|
* implementation.
|
||||||
|
*
|
||||||
|
* Any access to this kind of object must be done with
|
||||||
|
* drm_device::gem_lru_mutex held.
|
||||||
*/
|
*/
|
||||||
struct drm_gem_lru {
|
struct drm_gem_lru {
|
||||||
/**
|
|
||||||
* @lock:
|
|
||||||
*
|
|
||||||
* Lock protecting movement of GEM objects between LRUs. All
|
|
||||||
* LRUs that the object can move between should be protected
|
|
||||||
* by the same lock.
|
|
||||||
*/
|
|
||||||
struct mutex *lock;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @count:
|
* @count:
|
||||||
*
|
*
|
||||||
|
|
@ -453,6 +447,9 @@ struct drm_gem_object {
|
||||||
* @lru:
|
* @lru:
|
||||||
*
|
*
|
||||||
* The current LRU list that the GEM object is on.
|
* The current LRU list that the GEM object is on.
|
||||||
|
*
|
||||||
|
* Access to this field must be done with drm_device::gem_lru_mutex
|
||||||
|
* held.
|
||||||
*/
|
*/
|
||||||
struct drm_gem_lru *lru;
|
struct drm_gem_lru *lru;
|
||||||
};
|
};
|
||||||
|
|
@ -610,12 +607,13 @@ void drm_gem_unlock_reservations(struct drm_gem_object **objs, int count,
|
||||||
int drm_gem_dumb_map_offset(struct drm_file *file, struct drm_device *dev,
|
int drm_gem_dumb_map_offset(struct drm_file *file, struct drm_device *dev,
|
||||||
u32 handle, u64 *offset);
|
u32 handle, u64 *offset);
|
||||||
|
|
||||||
void drm_gem_lru_init(struct drm_gem_lru *lru, struct mutex *lock);
|
void drm_gem_lru_init(struct drm_gem_lru *lru);
|
||||||
void drm_gem_lru_remove(struct drm_gem_object *obj);
|
void drm_gem_lru_remove(struct drm_gem_object *obj);
|
||||||
void drm_gem_lru_move_tail_locked(struct drm_gem_lru *lru, struct drm_gem_object *obj);
|
void drm_gem_lru_move_tail_locked(struct drm_gem_lru *lru, struct drm_gem_object *obj);
|
||||||
void drm_gem_lru_move_tail(struct drm_gem_lru *lru, struct drm_gem_object *obj);
|
void drm_gem_lru_move_tail(struct drm_gem_lru *lru, struct drm_gem_object *obj);
|
||||||
unsigned long
|
unsigned long
|
||||||
drm_gem_lru_scan(struct drm_gem_lru *lru,
|
drm_gem_lru_scan(struct drm_device *dev,
|
||||||
|
struct drm_gem_lru *lru,
|
||||||
unsigned int nr_to_scan,
|
unsigned int nr_to_scan,
|
||||||
unsigned long *remaining,
|
unsigned long *remaining,
|
||||||
bool (*shrink)(struct drm_gem_object *obj, struct ww_acquire_ctx *ticket),
|
bool (*shrink)(struct drm_gem_object *obj, struct ww_acquire_ctx *ticket),
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue