[bug report] drm/omap: gem: Replace struct_mutex usage with omap_obj private lock
Tomi Valkeinen
tomi.valkeinen at ideasonboard.com
Mon Aug 5 18:49:30 UTC 2024
On 31/07/2024 15:26, Laurent Pinchart wrote:
> Hi Dan,
>
> (CC'ing Tomi)
>
> Thank for the report. It indeed seems that something is wrong.
>
> Tomi, could you handle this and send a fix ?
>
> On Tue, Jul 30, 2024 at 05:01:35PM -0500, Dan Carpenter wrote:
>> Hello Laurent Pinchart,
>>
>> Commit 3cbd0c587b12 ("drm/omap: gem: Replace struct_mutex usage with
>> omap_obj private lock") from May 26, 2018 (linux-next), leads to the
>> following Smatch static checker warning:
>>
>> drivers/gpu/drm/omapdrm/omap_gem.c:1435 omap_gem_new_dmabuf()
>> warn: 'omap_obj' was already freed. (line 1434)
>>
>> drivers/gpu/drm/omapdrm/omap_gem.c
>> 1386 struct drm_gem_object *omap_gem_new_dmabuf(struct drm_device *dev, size_t size,
>> 1387 struct sg_table *sgt)
>> 1388 {
>> 1389 struct omap_drm_private *priv = dev->dev_private;
>> 1390 struct omap_gem_object *omap_obj;
>> 1391 struct drm_gem_object *obj;
>> 1392 union omap_gem_size gsize;
>> 1393
>> 1394 /* Without a DMM only physically contiguous buffers can be supported. */
>> 1395 if (!omap_gem_sgt_is_contiguous(sgt, size) && !priv->has_dmm)
>> 1396 return ERR_PTR(-EINVAL);
>> 1397
>> 1398 gsize.bytes = PAGE_ALIGN(size);
>> 1399 obj = omap_gem_new(dev, gsize, OMAP_BO_MEM_DMABUF | OMAP_BO_WC);
>> 1400 if (!obj)
>> 1401 return ERR_PTR(-ENOMEM);
>> 1402
>> 1403 omap_obj = to_omap_bo(obj);
>> ^^^^^^^^^^^^^^^^^^^^^^^^^^
>> This is omap_obj
>>
>> 1404
>> 1405 mutex_lock(&omap_obj->lock);
I wonder why we even lock it. We just allocated it above, no one else
can be using it.
Not only that, but omap_gem_free_object(), which is called in the error
paths, _also_ takes the same lock.
I think we can just drop the locking from this function. But first I
need to figure out how to run this piece of code to test it...
Tomi
>> 1406
>> 1407 omap_obj->sgt = sgt;
>> 1408
>> 1409 if (omap_gem_sgt_is_contiguous(sgt, size)) {
>> 1410 omap_obj->dma_addr = sg_dma_address(sgt->sgl);
>> 1411 } else {
>> 1412 /* Create pages list from sgt */
>> 1413 struct page **pages;
>> 1414 unsigned int npages;
>> 1415 unsigned int ret;
>> 1416
>> 1417 npages = DIV_ROUND_UP(size, PAGE_SIZE);
>> 1418 pages = kcalloc(npages, sizeof(*pages), GFP_KERNEL);
>> 1419 if (!pages) {
>> 1420 omap_gem_free_object(obj);
>> ^^^
>> It gets free inside this function
>>
>> 1421 obj = ERR_PTR(-ENOMEM);
>> 1422 goto done;
>> 1423 }
>> 1424
>> 1425 omap_obj->pages = pages;
>> 1426 ret = drm_prime_sg_to_page_array(sgt, pages, npages);
>> 1427 if (ret) {
>> 1428 omap_gem_free_object(obj);
>> ^^^
>> Same
>>
>> 1429 obj = ERR_PTR(-ENOMEM);
>> 1430 goto done;
>>
>> So I think we can just return directly instead of unlocking.
>>
>> 1431 }
>> 1432 }
>> 1433
>> 1434 done:
>> --> 1435 mutex_unlock(&omap_obj->lock);
>> 1436 return obj;
>> 1437 }
>
More information about the dri-devel
mailing list