[Mesa-dev] [PATCH v4 1/2] gallium/winsys/kms: Fix possible leak in map/unmap.

Emil Velikov emil.l.velikov at gmail.com
Tue Mar 13 15:41:09 UTC 2018


On 13 March 2018 at 11:46, Tomasz Figa <tfiga at chromium.org> wrote:
> On Thu, Mar 8, 2018 at 7:39 AM, Lepton Wu <lepton at chromium.org> wrote:
>> 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 <lepton at chromium.org>
>> ---
>>  .../winsys/sw/kms-dri/kms_dri_sw_winsys.c     | 21 ++++++++++++-------
>>  1 file changed, 14 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..7fc40488c2e 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;
>> @@ -198,16 +199,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 +282,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;
>>  }
>
> If user calls map twice, wouldn't they also call unmap twice?
> Moreover, wouldn't the pointer be expected to be still valid between
> first and second unmap?
>
> The answer obviously depends on how the API is designed, but i feels
> really weird being asymmetrical like that. Typically the mapping would
> be refcounted and maps would have to be balanced with unmaps to free
> the mapping.
>
Valid points.

If you guys prefer we could land 2/2 (multiplane support), since it
has no dependency of the mapping work.
And polish out ro/rw mappings (even the leaks) at later stage, as time permits?

-Emil


More information about the mesa-dev mailing list