Mesa (staging/22.1): kms/dri: add mutex lock around map/unmap

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Wed Jul 27 23:25:25 UTC 2022


Module: Mesa
Branch: staging/22.1
Commit: 9ab162bf59bc5857161d49d7854fb250747bdf31
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=9ab162bf59bc5857161d49d7854fb250747bdf31

Author: Dave Airlie <airlied at redhat.com>
Date:   Thu Jul 14 10:34:04 2022 +1000

kms/dri: add mutex lock around map/unmap

this can get called from multiple threads with the recent llvmpipe
overlapping rendering changes, so make sure to lock around the
map/unmapping so they can't race.

This should fixes some crashes seen with kwin.

Reviewed-by: Mike Blumenkrantz <michael.blumenkrantz at gmail.com>
Tested-by: Adam Williamson (Fedora)
Cc: mesa-stable
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17531>
(cherry picked from commit 50e3303b3d0484ffdc1acbc03bae8655231b19de)

---

 .pick_status.json                                 |  2 +-
 src/gallium/winsys/sw/kms-dri/kms_dri_sw_winsys.c | 20 ++++++++++++++++++--
 2 files changed, 19 insertions(+), 3 deletions(-)

diff --git a/.pick_status.json b/.pick_status.json
index acc1d2e4f59..58f9a811851 100644
--- a/.pick_status.json
+++ b/.pick_status.json
@@ -4648,7 +4648,7 @@
         "description": "kms/dri: add mutex lock around map/unmap",
         "nominated": true,
         "nomination_type": 0,
-        "resolution": 0,
+        "resolution": 1,
         "main_sha": null,
         "because_sha": null
     },
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 c91f7e2ca9a..3444c96ae49 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
@@ -54,6 +54,8 @@
 #include "frontend/drm_driver.h"
 #include "kms_dri_sw_winsys.h"
 
+#include "util/simple_mtx.h"
+
 #ifdef DEBUG
 #define DEBUG_PRINT(msg, ...) fprintf(stderr, msg, __VA_ARGS__)
 #else
@@ -85,6 +87,7 @@ struct kms_sw_displaytarget
    int map_count;
    struct list_head link;
    struct list_head planes;
+   mtx_t map_lock;
 };
 
 struct kms_sw_winsys
@@ -182,6 +185,8 @@ kms_sw_displaytarget_create(struct sw_winsys *ws,
 
    kms_sw_dt->format = format;
 
+   mtx_init(&kms_sw_dt->map_lock, mtx_plain);
+
    memset(&create_req, 0, sizeof(create_req));
    create_req.bpp = util_format_get_blocksizebits(format);
    create_req.width = width;
@@ -236,6 +241,7 @@ kms_sw_displaytarget_destroy(struct sw_winsys *ws,
 
    list_del(&kms_sw_dt->link);
 
+   mtx_destroy(&kms_sw_dt->map_lock);
    DEBUG_PRINT("KMS-DEBUG: destroyed buffer %u\n", kms_sw_dt->handle);
 
    struct kms_sw_plane *tmp;
@@ -257,11 +263,12 @@ kms_sw_displaytarget_map(struct sw_winsys *ws,
    struct drm_mode_map_dumb map_req;
    int prot, ret;
 
+   mtx_lock(&kms_sw_dt->map_lock);
    memset(&map_req, 0, sizeof map_req);
    map_req.handle = kms_sw_dt->handle;
    ret = drmIoctl(kms_sw->fd, DRM_IOCTL_MODE_MAP_DUMB, &map_req);
    if (ret)
-      return NULL;
+      goto fail_locked;
 
    prot = (flags == PIPE_MAP_READ) ? PROT_READ : (PROT_READ | PROT_WRITE);
    void **ptr = (flags == PIPE_MAP_READ) ? &kms_sw_dt->ro_mapped : &kms_sw_dt->mapped;
@@ -269,7 +276,7 @@ kms_sw_displaytarget_map(struct sw_winsys *ws,
       void *tmp = mmap(NULL, kms_sw_dt->size, prot, MAP_SHARED,
                        kms_sw->fd, map_req.offset);
       if (tmp == MAP_FAILED)
-         return NULL;
+         goto fail_locked;
       *ptr = tmp;
    }
 
@@ -278,7 +285,12 @@ kms_sw_displaytarget_map(struct sw_winsys *ws,
 
    kms_sw_dt->map_count++;
 
+   mtx_unlock(&kms_sw_dt->map_lock);
+
    return *ptr + plane->offset;
+fail_locked:
+   mtx_unlock(&kms_sw_dt->map_lock);
+   return NULL;
 }
 
 static struct kms_sw_displaytarget *
@@ -360,13 +372,16 @@ kms_sw_displaytarget_unmap(struct sw_winsys *ws,
    struct kms_sw_plane *plane = kms_sw_plane(dt);
    struct kms_sw_displaytarget *kms_sw_dt = plane->dt;
 
+   mtx_lock(&kms_sw_dt->map_lock);
    if (!kms_sw_dt->map_count)  {
       DEBUG_PRINT("KMS-DEBUG: ignore duplicated unmap %u", kms_sw_dt->handle);
+      mtx_unlock(&kms_sw_dt->map_lock);
       return;
    }
    kms_sw_dt->map_count--;
    if (kms_sw_dt->map_count) {
       DEBUG_PRINT("KMS-DEBUG: ignore unmap for busy buffer %u", kms_sw_dt->handle);
+      mtx_unlock(&kms_sw_dt->map_lock);
       return;
    }
 
@@ -381,6 +396,7 @@ kms_sw_displaytarget_unmap(struct sw_winsys *ws,
       munmap(kms_sw_dt->ro_mapped, kms_sw_dt->size);
       kms_sw_dt->ro_mapped = MAP_FAILED;
    }
+   mtx_unlock(&kms_sw_dt->map_lock);
 }
 
 static struct sw_displaytarget *



More information about the mesa-commit mailing list