diff --git a/src/nouveau/vulkan/nvkmd/nouveau/nvkmd_nouveau_dev.c b/src/nouveau/vulkan/nvkmd/nouveau/nvkmd_nouveau_dev.c index 37b931aee2a..1b350814095 100644 --- a/src/nouveau/vulkan/nvkmd/nouveau/nvkmd_nouveau_dev.c +++ b/src/nouveau/vulkan/nvkmd/nouveau/nvkmd_nouveau_dev.c @@ -26,6 +26,9 @@ nvkmd_nouveau_create_dev(struct nvkmd_pdev *_pdev, dev->base.va_start = 0; dev->base.va_end = NOUVEAU_WS_DEVICE_KERNEL_RESERVATION_START; + list_inithead(&dev->base.mems); + simple_mtx_init(&dev->base.mems_mutex, mtx_plain); + drmDevicePtr drm_device = NULL; int ret = drmGetDeviceFromDevId(pdev->base.drm.render_dev, 0, &drm_device); if (ret != 0) { diff --git a/src/nouveau/vulkan/nvkmd/nvkmd.c b/src/nouveau/vulkan/nvkmd/nvkmd.c index e1fe45bb938..5e0572b9f91 100644 --- a/src/nouveau/vulkan/nvkmd/nvkmd.c +++ b/src/nouveau/vulkan/nvkmd/nvkmd.c @@ -8,6 +8,60 @@ #include +void +nvkmd_dev_track_mem(struct nvkmd_dev *dev, + struct nvkmd_mem *mem) +{ + if (mem->link.next == NULL) { + simple_mtx_lock(&dev->mems_mutex); + list_addtail(&mem->link, &dev->mems); + simple_mtx_unlock(&dev->mems_mutex); + } +} + +static void +nvkmd_dev_untrack_mem(struct nvkmd_dev *dev, + struct nvkmd_mem *mem) +{ + if (mem->link.next != NULL) { + simple_mtx_lock(&dev->mems_mutex); + list_del(&mem->link); + simple_mtx_unlock(&dev->mems_mutex); + } +} + +static struct nvkmd_mem * +nvkmd_dev_lookup_mem_by_va_locked(struct nvkmd_dev *dev, + uint64_t addr, + uint64_t *offset_out) +{ + list_for_each_entry(struct nvkmd_mem, mem, &dev->mems, link) { + if (mem->va == NULL || addr < mem->va->addr) + continue; + + const uint64_t offset = addr - mem->va->addr; + if (offset < mem->va->size_B) { + if (offset_out != NULL) + *offset_out = offset; + return nvkmd_mem_ref(mem); + } + } + + return NULL; +} + +struct nvkmd_mem * +nvkmd_dev_lookup_mem_by_va(struct nvkmd_dev *dev, + uint64_t addr, + uint64_t *offset_out) +{ + simple_mtx_lock(&dev->mems_mutex); + struct nvkmd_mem *mem = + nvkmd_dev_lookup_mem_by_va_locked(dev, addr, offset_out); + simple_mtx_unlock(&dev->mems_mutex); + return mem; +} + void nvkmd_mem_init(struct nvkmd_dev *dev, struct nvkmd_mem *mem, @@ -215,6 +269,8 @@ nvkmd_mem_unref(struct nvkmd_mem *mem) if (mem->map != NULL) mem->ops->unmap(mem, 0, mem->map); + nvkmd_dev_untrack_mem(mem->dev, mem); + mem->ops->free(mem); } diff --git a/src/nouveau/vulkan/nvkmd/nvkmd.h b/src/nouveau/vulkan/nvkmd/nvkmd.h index 604bba1b882..6296c316057 100644 --- a/src/nouveau/vulkan/nvkmd/nvkmd.h +++ b/src/nouveau/vulkan/nvkmd/nvkmd.h @@ -6,6 +6,7 @@ #define NVKMD_H 1 #include "nv_device_info.h" +#include "util/list.h" #include "util/simple_mtx.h" #include "util/u_atomic.h" @@ -194,6 +195,9 @@ struct nvkmd_dev { * allocated within this range. */ uint64_t va_start, va_end; + + struct list_head mems; + simple_mtx_t mems_mutex; }; struct nvkmd_mem_ops { @@ -226,6 +230,9 @@ struct nvkmd_mem { const struct nvkmd_mem_ops *ops; struct nvkmd_dev *dev; + /* Optional link in nvkmd_dev::mems */ + struct list_head link; + uint32_t refcnt; enum nvkmd_mem_flags flags; @@ -440,6 +447,15 @@ nvkmd_dev_alloc_mapped_mem(struct nvkmd_dev *dev, enum nvkmd_mem_map_flags map_flags, struct nvkmd_mem **mem_out); +void +nvkmd_dev_track_mem(struct nvkmd_dev *dev, + struct nvkmd_mem *mem); + +struct nvkmd_mem * +nvkmd_dev_lookup_mem_by_va(struct nvkmd_dev *dev, + uint64_t addr, + uint64_t *offset_out); + static inline VkResult MUST_CHECK nvkmd_dev_import_dma_buf(struct nvkmd_dev *dev, struct vk_object_base *log_obj,