mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-22 22:51:37 +00:00
* dma-buf: name_lock fixes
* prime: Keep object ref during mmap * nouveau: Fix a refcount issue; Fix device removal; Protect client list with dedicated mutex; Fix address CE0 address calculation * ttm: Fix race condition during BO eviction -----BEGIN PGP SIGNATURE----- iQEzBAABCAAdFiEEchf7rIzpz2NEoWjlaA3BHVMLeiMFAmGM2AgACgkQaA3BHVML eiNIwggAnLwEu8mkkMznHDL/+Y0yDI2+NE6yJLu9qfmJg/qV3kBe5Fc6AMGtKwgR fOaBBzdSAXF/wRabfmnzgl/zsojLU1b0gFVhDa2Oq/wzcjuNJybTPMxCu2nzSRaT DT/iED3bdpmNgBTJhrY8WO474miNLnCutmO3x2FIxib1I84ycddFlrNJ8IFZ+nXp bUjjwy6QYHsAICB2rATp/YulxxtItX7ute+3eRrrkg2Y8zyuXt1SidXDr77JjeX2 FDVmuvuR6Gbvjx9CbsP5G94M3AF08dnsmJfQG1XHemHtht2mbp3CJPzfqVq+NgVr LA6FMLHsyDSK9C8K8622UD7DgG7fbQ== =bfFO -----END PGP SIGNATURE----- Merge tag 'drm-misc-fixes-2021-11-11' of git://anongit.freedesktop.org/drm/drm-misc into drm-next * dma-buf: name_lock fixes * prime: Keep object ref during mmap * nouveau: Fix a refcount issue; Fix device removal; Protect client list with dedicated mutex; Fix address CE0 address calculation * ttm: Fix race condition during BO eviction Signed-off-by: Dave Airlie <airlied@redhat.com> From: Thomas Zimmermann <tzimmermann@suse.de> Link: https://patchwork.freedesktop.org/patch/msgid/YYzY6jeox9EeI15i@linux-uq9g.fritz.box
This commit is contained in:
commit
b6c2472524
8 changed files with 59 additions and 13 deletions
|
@ -1359,6 +1359,8 @@ static int dma_buf_debug_show(struct seq_file *s, void *unused)
|
||||||
if (ret)
|
if (ret)
|
||||||
goto error_unlock;
|
goto error_unlock;
|
||||||
|
|
||||||
|
|
||||||
|
spin_lock(&buf_obj->name_lock);
|
||||||
seq_printf(s, "%08zu\t%08x\t%08x\t%08ld\t%s\t%08lu\t%s\n",
|
seq_printf(s, "%08zu\t%08x\t%08x\t%08ld\t%s\t%08lu\t%s\n",
|
||||||
buf_obj->size,
|
buf_obj->size,
|
||||||
buf_obj->file->f_flags, buf_obj->file->f_mode,
|
buf_obj->file->f_flags, buf_obj->file->f_mode,
|
||||||
|
@ -1366,6 +1368,7 @@ static int dma_buf_debug_show(struct seq_file *s, void *unused)
|
||||||
buf_obj->exp_name,
|
buf_obj->exp_name,
|
||||||
file_inode(buf_obj->file)->i_ino,
|
file_inode(buf_obj->file)->i_ino,
|
||||||
buf_obj->name ?: "");
|
buf_obj->name ?: "");
|
||||||
|
spin_unlock(&buf_obj->name_lock);
|
||||||
|
|
||||||
dma_resv_for_each_fence(&cursor, buf_obj->resv, true, fence) {
|
dma_resv_for_each_fence(&cursor, buf_obj->resv, true, fence) {
|
||||||
seq_printf(s, "\t%s fence: %s %s %ssignalled\n",
|
seq_printf(s, "\t%s fence: %s %s %ssignalled\n",
|
||||||
|
|
|
@ -719,11 +719,13 @@ int drm_gem_prime_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma)
|
||||||
if (obj->funcs && obj->funcs->mmap) {
|
if (obj->funcs && obj->funcs->mmap) {
|
||||||
vma->vm_ops = obj->funcs->vm_ops;
|
vma->vm_ops = obj->funcs->vm_ops;
|
||||||
|
|
||||||
ret = obj->funcs->mmap(obj, vma);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
vma->vm_private_data = obj;
|
|
||||||
drm_gem_object_get(obj);
|
drm_gem_object_get(obj);
|
||||||
|
ret = obj->funcs->mmap(obj, vma);
|
||||||
|
if (ret) {
|
||||||
|
drm_gem_object_put(obj);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
vma->vm_private_data = obj;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -562,6 +562,7 @@ nouveau_drm_device_init(struct drm_device *dev)
|
||||||
nvkm_dbgopt(nouveau_debug, "DRM");
|
nvkm_dbgopt(nouveau_debug, "DRM");
|
||||||
|
|
||||||
INIT_LIST_HEAD(&drm->clients);
|
INIT_LIST_HEAD(&drm->clients);
|
||||||
|
mutex_init(&drm->clients_lock);
|
||||||
spin_lock_init(&drm->tile.lock);
|
spin_lock_init(&drm->tile.lock);
|
||||||
|
|
||||||
/* workaround an odd issue on nvc1 by disabling the device's
|
/* workaround an odd issue on nvc1 by disabling the device's
|
||||||
|
@ -632,6 +633,7 @@ fail_alloc:
|
||||||
static void
|
static void
|
||||||
nouveau_drm_device_fini(struct drm_device *dev)
|
nouveau_drm_device_fini(struct drm_device *dev)
|
||||||
{
|
{
|
||||||
|
struct nouveau_cli *cli, *temp_cli;
|
||||||
struct nouveau_drm *drm = nouveau_drm(dev);
|
struct nouveau_drm *drm = nouveau_drm(dev);
|
||||||
|
|
||||||
if (nouveau_pmops_runtime()) {
|
if (nouveau_pmops_runtime()) {
|
||||||
|
@ -656,9 +658,28 @@ nouveau_drm_device_fini(struct drm_device *dev)
|
||||||
nouveau_ttm_fini(drm);
|
nouveau_ttm_fini(drm);
|
||||||
nouveau_vga_fini(drm);
|
nouveau_vga_fini(drm);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* There may be existing clients from as-yet unclosed files. For now,
|
||||||
|
* clean them up here rather than deferring until the file is closed,
|
||||||
|
* but this likely not correct if we want to support hot-unplugging
|
||||||
|
* properly.
|
||||||
|
*/
|
||||||
|
mutex_lock(&drm->clients_lock);
|
||||||
|
list_for_each_entry_safe(cli, temp_cli, &drm->clients, head) {
|
||||||
|
list_del(&cli->head);
|
||||||
|
mutex_lock(&cli->mutex);
|
||||||
|
if (cli->abi16)
|
||||||
|
nouveau_abi16_fini(cli->abi16);
|
||||||
|
mutex_unlock(&cli->mutex);
|
||||||
|
nouveau_cli_fini(cli);
|
||||||
|
kfree(cli);
|
||||||
|
}
|
||||||
|
mutex_unlock(&drm->clients_lock);
|
||||||
|
|
||||||
nouveau_cli_fini(&drm->client);
|
nouveau_cli_fini(&drm->client);
|
||||||
nouveau_cli_fini(&drm->master);
|
nouveau_cli_fini(&drm->master);
|
||||||
nvif_parent_dtor(&drm->parent);
|
nvif_parent_dtor(&drm->parent);
|
||||||
|
mutex_destroy(&drm->clients_lock);
|
||||||
kfree(drm);
|
kfree(drm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -796,7 +817,7 @@ nouveau_drm_device_remove(struct drm_device *dev)
|
||||||
struct nvkm_client *client;
|
struct nvkm_client *client;
|
||||||
struct nvkm_device *device;
|
struct nvkm_device *device;
|
||||||
|
|
||||||
drm_dev_unregister(dev);
|
drm_dev_unplug(dev);
|
||||||
|
|
||||||
client = nvxx_client(&drm->client.base);
|
client = nvxx_client(&drm->client.base);
|
||||||
device = nvkm_device_find(client->device);
|
device = nvkm_device_find(client->device);
|
||||||
|
@ -1090,9 +1111,9 @@ nouveau_drm_open(struct drm_device *dev, struct drm_file *fpriv)
|
||||||
|
|
||||||
fpriv->driver_priv = cli;
|
fpriv->driver_priv = cli;
|
||||||
|
|
||||||
mutex_lock(&drm->client.mutex);
|
mutex_lock(&drm->clients_lock);
|
||||||
list_add(&cli->head, &drm->clients);
|
list_add(&cli->head, &drm->clients);
|
||||||
mutex_unlock(&drm->client.mutex);
|
mutex_unlock(&drm->clients_lock);
|
||||||
|
|
||||||
done:
|
done:
|
||||||
if (ret && cli) {
|
if (ret && cli) {
|
||||||
|
@ -1110,6 +1131,16 @@ nouveau_drm_postclose(struct drm_device *dev, struct drm_file *fpriv)
|
||||||
{
|
{
|
||||||
struct nouveau_cli *cli = nouveau_cli(fpriv);
|
struct nouveau_cli *cli = nouveau_cli(fpriv);
|
||||||
struct nouveau_drm *drm = nouveau_drm(dev);
|
struct nouveau_drm *drm = nouveau_drm(dev);
|
||||||
|
int dev_index;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The device is gone, and as it currently stands all clients are
|
||||||
|
* cleaned up in the removal codepath. In the future this may change
|
||||||
|
* so that we can support hot-unplugging, but for now we immediately
|
||||||
|
* return to avoid a double-free situation.
|
||||||
|
*/
|
||||||
|
if (!drm_dev_enter(dev, &dev_index))
|
||||||
|
return;
|
||||||
|
|
||||||
pm_runtime_get_sync(dev->dev);
|
pm_runtime_get_sync(dev->dev);
|
||||||
|
|
||||||
|
@ -1118,14 +1149,15 @@ nouveau_drm_postclose(struct drm_device *dev, struct drm_file *fpriv)
|
||||||
nouveau_abi16_fini(cli->abi16);
|
nouveau_abi16_fini(cli->abi16);
|
||||||
mutex_unlock(&cli->mutex);
|
mutex_unlock(&cli->mutex);
|
||||||
|
|
||||||
mutex_lock(&drm->client.mutex);
|
mutex_lock(&drm->clients_lock);
|
||||||
list_del(&cli->head);
|
list_del(&cli->head);
|
||||||
mutex_unlock(&drm->client.mutex);
|
mutex_unlock(&drm->clients_lock);
|
||||||
|
|
||||||
nouveau_cli_fini(cli);
|
nouveau_cli_fini(cli);
|
||||||
kfree(cli);
|
kfree(cli);
|
||||||
pm_runtime_mark_last_busy(dev->dev);
|
pm_runtime_mark_last_busy(dev->dev);
|
||||||
pm_runtime_put_autosuspend(dev->dev);
|
pm_runtime_put_autosuspend(dev->dev);
|
||||||
|
drm_dev_exit(dev_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct drm_ioctl_desc
|
static const struct drm_ioctl_desc
|
||||||
|
|
|
@ -139,6 +139,11 @@ struct nouveau_drm {
|
||||||
|
|
||||||
struct list_head clients;
|
struct list_head clients;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @clients_lock: Protects access to the @clients list of &struct nouveau_cli.
|
||||||
|
*/
|
||||||
|
struct mutex clients_lock;
|
||||||
|
|
||||||
u8 old_pm_cap;
|
u8 old_pm_cap;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
|
|
|
@ -162,10 +162,14 @@ nouveau_svmm_bind(struct drm_device *dev, void *data,
|
||||||
*/
|
*/
|
||||||
|
|
||||||
mm = get_task_mm(current);
|
mm = get_task_mm(current);
|
||||||
|
if (!mm) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
mmap_read_lock(mm);
|
mmap_read_lock(mm);
|
||||||
|
|
||||||
if (!cli->svm.svmm) {
|
if (!cli->svm.svmm) {
|
||||||
mmap_read_unlock(mm);
|
mmap_read_unlock(mm);
|
||||||
|
mmput(mm);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -78,6 +78,6 @@ int
|
||||||
gt215_ce_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst,
|
gt215_ce_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst,
|
||||||
struct nvkm_engine **pengine)
|
struct nvkm_engine **pengine)
|
||||||
{
|
{
|
||||||
return nvkm_falcon_new_(>215_ce, device, type, inst,
|
return nvkm_falcon_new_(>215_ce, device, type, -1,
|
||||||
(device->chipset != 0xaf), 0x104000, pengine);
|
(device->chipset != 0xaf), 0x104000, pengine);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3147,8 +3147,7 @@ nvkm_device_ctor(const struct nvkm_device_func *func,
|
||||||
WARN_ON(device->chip->ptr.inst & ~((1 << ARRAY_SIZE(device->ptr)) - 1)); \
|
WARN_ON(device->chip->ptr.inst & ~((1 << ARRAY_SIZE(device->ptr)) - 1)); \
|
||||||
for (j = 0; device->chip->ptr.inst && j < ARRAY_SIZE(device->ptr); j++) { \
|
for (j = 0; device->chip->ptr.inst && j < ARRAY_SIZE(device->ptr); j++) { \
|
||||||
if ((device->chip->ptr.inst & BIT(j)) && (subdev_mask & BIT_ULL(type))) { \
|
if ((device->chip->ptr.inst & BIT(j)) && (subdev_mask & BIT_ULL(type))) { \
|
||||||
int inst = (device->chip->ptr.inst == 1) ? -1 : (j); \
|
ret = device->chip->ptr.ctor(device, (type), (j), &device->ptr[j]); \
|
||||||
ret = device->chip->ptr.ctor(device, (type), inst, &device->ptr[j]); \
|
|
||||||
subdev = nvkm_device_subdev(device, (type), (j)); \
|
subdev = nvkm_device_subdev(device, (type), (j)); \
|
||||||
if (ret) { \
|
if (ret) { \
|
||||||
nvkm_subdev_del(&subdev); \
|
nvkm_subdev_del(&subdev); \
|
||||||
|
|
|
@ -619,7 +619,8 @@ static bool ttm_bo_evict_swapout_allowable(struct ttm_buffer_object *bo,
|
||||||
*busy = !ret;
|
*busy = !ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret && place && !bo->bdev->funcs->eviction_valuable(bo, place)) {
|
if (ret && place && (bo->resource->mem_type != place->mem_type ||
|
||||||
|
!bo->bdev->funcs->eviction_valuable(bo, place))) {
|
||||||
ret = false;
|
ret = false;
|
||||||
if (*locked) {
|
if (*locked) {
|
||||||
dma_resv_unlock(bo->base.resv);
|
dma_resv_unlock(bo->base.resv);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue