v3d_perfmon_find() takes a reference to the perfmon which the ioctl transfers to the global pointer on success. The error paths are missing this transfer: clearing the global perfmon while none is set, and setting a global perfmon when one is already configured both return without dropping the reference. Release it on both paths. Fixes: c6eabbab359c ("drm/v3d: Add DRM_IOCTL_V3D_PERFMON_SET_GLOBAL") Cc: stable@vger.kernel.org Signed-off-by: Wentao Liang --- drivers/gpu/drm/v3d/v3d_perfmon.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/v3d/v3d_perfmon.c b/drivers/gpu/drm/v3d/v3d_perfmon.c index 8e0249580bba..12bb1b087fa9 100644 --- a/drivers/gpu/drm/v3d/v3d_perfmon.c +++ b/drivers/gpu/drm/v3d/v3d_perfmon.c @@ -461,16 +461,20 @@ int v3d_perfmon_set_global_ioctl(struct drm_device *dev, void *data, /* If the request is to clear the global performance monitor */ if (req->flags & DRM_V3D_PERFMON_CLEAR_GLOBAL) { - if (!v3d->global_perfmon) + if (!v3d->global_perfmon) { + v3d_perfmon_put(perfmon); return -EINVAL; + } xchg(&v3d->global_perfmon, NULL); return 0; } - if (cmpxchg(&v3d->global_perfmon, NULL, perfmon)) + if (cmpxchg(&v3d->global_perfmon, NULL, perfmon)) { + v3d_perfmon_put(perfmon); return -EBUSY; + } return 0; } -- 2.34.1