mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-06 13:48:06 +02:00
panfrost: Fix GEM handle refcount leak in panfrost_bo_import
panfrost_bo_import() calls drmPrimeFDToHandle() then pan_kmod_bo_import(), which also calls drmPrimeFDToHandle() internally. This double import causes GEM handle refcount leaks because each drmPrimeFDToHandle() increments the kernel's GEM handle refcount, but only one drmCloseBufferHandle() is called during cleanup by panfrost_kmod_bo_free(or panthor_kmod_bo_free). Fix by removing the redundant drmPrimeFDToHandle() and using pan_kmod_bo_import() directly. On re-import of existing buffers, properly release the extra pan_kmod_bo reference with pan_kmod_bo_put(). This ensures GEM handle refcount, pan_kmod_bo refcount, and panfrost_bo refcount are all properly balanced. Fixes:5089a758df("panfrost: Back panfrost_bo with pan_kmod_bo object") Signed-off-by: Xianzhong Li <xianzhong.li@nxp.com> Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com> Reviewed-by: Eric R. Smith <eric.smith@collabora.com> (cherry picked from commit248b0b47b7) Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/40979>
This commit is contained in:
parent
e8955066a7
commit
871a933cac
2 changed files with 17 additions and 5 deletions
|
|
@ -3744,7 +3744,7 @@
|
|||
"description": "panfrost: Fix GEM handle refcount leak in panfrost_bo_import",
|
||||
"nominated": true,
|
||||
"nomination_type": 2,
|
||||
"resolution": 0,
|
||||
"resolution": 1,
|
||||
"main_sha": null,
|
||||
"because_sha": "5089a758dfb1760a0dc397b0f491c4a6dc2160af",
|
||||
"notes": null
|
||||
|
|
|
|||
|
|
@ -471,18 +471,24 @@ struct panfrost_bo *
|
|||
panfrost_bo_import(struct panfrost_device *dev, int fd)
|
||||
{
|
||||
struct panfrost_bo *bo;
|
||||
ASSERTED int ret;
|
||||
struct pan_kmod_bo *kmod_bo;
|
||||
unsigned gem_handle;
|
||||
|
||||
pthread_mutex_lock(&dev->bo_map_lock);
|
||||
ret = drmPrimeFDToHandle(dev->kmod.dev->fd, fd, &gem_handle);
|
||||
assert(!ret);
|
||||
/* Import via pan_kmod_bo_import - it handles drmPrimeFDToHandle internally */
|
||||
kmod_bo = pan_kmod_bo_import(dev->kmod.dev, fd, 0);
|
||||
if (!kmod_bo) {
|
||||
pthread_mutex_unlock(&dev->bo_map_lock);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Look up panfrost_bo by the GEM handle from kmod_bo */
|
||||
gem_handle = pan_kmod_bo_handle(kmod_bo);
|
||||
bo = pan_lookup_bo(dev, gem_handle);
|
||||
|
||||
if (!bo->dev) {
|
||||
bo->dev = dev;
|
||||
bo->kmod_bo = pan_kmod_bo_import(dev->kmod.dev, fd, 0);
|
||||
bo->kmod_bo = kmod_bo; /* Take ownership of kmod_bo reference */
|
||||
|
||||
struct pan_kmod_vm_op vm_op = {
|
||||
.type = PAN_KMOD_VM_OP_TYPE_MAP,
|
||||
|
|
@ -510,6 +516,12 @@ panfrost_bo_import(struct panfrost_device *dev, int fd)
|
|||
if ((dev->debug & PAN_DBG_DUMP) && panfrost_bo_mmap(bo))
|
||||
mesa_loge("failed to mmap");
|
||||
} else {
|
||||
/* pan_kmod_bo_import already incremented kmod_bo->refcnt,
|
||||
* but we already have a reference in bo->kmod_bo,
|
||||
* so release this extra kmod_bo reference.
|
||||
*/
|
||||
pan_kmod_bo_put(kmod_bo);
|
||||
|
||||
/* bo->refcnt == 0 can happen if the BO
|
||||
* was being released but panfrost_bo_import() acquired the
|
||||
* lock before panfrost_bo_unreference(). In that case, refcnt
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue