If user calls map twice for kms_sw_displaytarget, the first mapped buffer could get leaked. Instead of calling mmap every time, just reuse previous mapping. Since user could map same displaytarget with different flags, we have to keep two different pointers, one for rw mapping and one for ro mapping.
Change-Id: I65308f0ff2640bd57b2577c6a3469540c9722859 Signed-off-by: Lepton Wu <lep...@chromium.org> --- .../winsys/sw/kms-dri/kms_dri_sw_winsys.c | 26 ++++++++++++++----- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/src/gallium/winsys/sw/kms-dri/kms_dri_sw_winsys.c b/src/gallium/winsys/sw/kms-dri/kms_dri_sw_winsys.c index 22e1c936ac5..30343222470 100644 --- a/src/gallium/winsys/sw/kms-dri/kms_dri_sw_winsys.c +++ b/src/gallium/winsys/sw/kms-dri/kms_dri_sw_winsys.c @@ -70,6 +70,7 @@ struct kms_sw_displaytarget uint32_t handle; void *mapped; + void *ro_mapped; int ref_count; struct list_head link; @@ -170,6 +171,11 @@ kms_sw_displaytarget_destroy(struct sw_winsys *ws, if (kms_sw_dt->ref_count > 0) return; + if (kms_sw_dt->ro_mapped) + munmap(kms_sw_dt->ro_mapped, kms_sw_dt->size); + if (kms_sw_dt->mapped) + munmap(kms_sw_dt->mapped, kms_sw_dt->size); + memset(&destroy_req, 0, sizeof destroy_req); destroy_req.handle = kms_sw_dt->handle; drmIoctl(kms_sw->fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destroy_req); @@ -198,16 +204,19 @@ kms_sw_displaytarget_map(struct sw_winsys *ws, return NULL; prot = (flags == PIPE_TRANSFER_READ) ? PROT_READ : (PROT_READ | PROT_WRITE); - kms_sw_dt->mapped = mmap(0, kms_sw_dt->size, prot, MAP_SHARED, - kms_sw->fd, map_req.offset); - - if (kms_sw_dt->mapped == MAP_FAILED) - return NULL; + void **ptr = (flags == PIPE_TRANSFER_READ) ? &kms_sw_dt->ro_mapped : &kms_sw_dt->mapped; + if (!*ptr) { + void *tmp = mmap(0, kms_sw_dt->size, prot, MAP_SHARED, + kms_sw->fd, map_req.offset); + if (tmp == MAP_FAILED) + return NULL; + *ptr = tmp; + } DEBUG_PRINT("KMS-DEBUG: mapped buffer %u (size %u) at %p\n", - kms_sw_dt->handle, kms_sw_dt->size, kms_sw_dt->mapped); + kms_sw_dt->handle, kms_sw_dt->size, *ptr); - return kms_sw_dt->mapped; + return *ptr; } static struct kms_sw_displaytarget * @@ -278,9 +287,12 @@ kms_sw_displaytarget_unmap(struct sw_winsys *ws, struct kms_sw_displaytarget *kms_sw_dt = kms_sw_displaytarget(dt); DEBUG_PRINT("KMS-DEBUG: unmapped buffer %u (was %p)\n", kms_sw_dt->handle, kms_sw_dt->mapped); + DEBUG_PRINT("KMS-DEBUG: unmapped buffer %u (was %p)\n", kms_sw_dt->handle, kms_sw_dt->ro_mapped); munmap(kms_sw_dt->mapped, kms_sw_dt->size); kms_sw_dt->mapped = NULL; + munmap(kms_sw_dt->ro_mapped, kms_sw_dt->size); + kms_sw_dt->ro_mapped = NULL; } static struct sw_displaytarget * -- 2.16.2.395.g2e18187dfd-goog _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev