OSDN Git Service

drm/nouveau/fb: protect comptags with private mutex
authorBen Skeggs <bskeggs@redhat.com>
Wed, 2 Dec 2020 06:24:20 +0000 (16:24 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Thu, 11 Feb 2021 00:14:03 +0000 (10:14 +1000)
nvkm_subdev.mutex is going away.

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Reviewed-by: Lyude Paul <lyude@redhat.com>
drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h
drivers/gpu/drm/nouveau/nvkm/core/memory.c
drivers/gpu/drm/nouveau/nvkm/subdev/fb/base.c
drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv20.c
drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv25.c
drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv30.c
drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv35.c
drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv36.c
drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv40.c
drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gf100.c

index 2ecd52a..38c2a5f 100644 (file)
@@ -36,7 +36,11 @@ struct nvkm_fb {
        struct nvkm_blob vpr_scrubber;
 
        struct nvkm_ram *ram;
-       struct nvkm_mm tags;
+
+       struct {
+               struct mutex mutex; /* protects mm and nvkm_memory::tags */
+               struct nvkm_mm mm;
+       } tags;
 
        struct {
                struct nvkm_fb_tile region[16];
index 38130ef..c69daac 100644 (file)
@@ -33,13 +33,13 @@ nvkm_memory_tags_put(struct nvkm_memory *memory, struct nvkm_device *device,
        struct nvkm_fb *fb = device->fb;
        struct nvkm_tags *tags = *ptags;
        if (tags) {
-               mutex_lock(&fb->subdev.mutex);
+               mutex_lock(&fb->tags.mutex);
                if (refcount_dec_and_test(&tags->refcount)) {
-                       nvkm_mm_free(&fb->tags, &tags->mn);
+                       nvkm_mm_free(&fb->tags.mm, &tags->mn);
                        kfree(memory->tags);
                        memory->tags = NULL;
                }
-               mutex_unlock(&fb->subdev.mutex);
+               mutex_unlock(&fb->tags.mutex);
                *ptags = NULL;
        }
 }
@@ -52,29 +52,29 @@ nvkm_memory_tags_get(struct nvkm_memory *memory, struct nvkm_device *device,
        struct nvkm_fb *fb = device->fb;
        struct nvkm_tags *tags;
 
-       mutex_lock(&fb->subdev.mutex);
+       mutex_lock(&fb->tags.mutex);
        if ((tags = memory->tags)) {
                /* If comptags exist for the memory, but a different amount
                 * than requested, the buffer is being mapped with settings
                 * that are incompatible with existing mappings.
                 */
                if (tags->mn && tags->mn->length != nr) {
-                       mutex_unlock(&fb->subdev.mutex);
+                       mutex_unlock(&fb->tags.mutex);
                        return -EINVAL;
                }
 
                refcount_inc(&tags->refcount);
-               mutex_unlock(&fb->subdev.mutex);
+               mutex_unlock(&fb->tags.mutex);
                *ptags = tags;
                return 0;
        }
 
        if (!(tags = kmalloc(sizeof(*tags), GFP_KERNEL))) {
-               mutex_unlock(&fb->subdev.mutex);
+               mutex_unlock(&fb->tags.mutex);
                return -ENOMEM;
        }
 
-       if (!nvkm_mm_head(&fb->tags, 0, 1, nr, nr, 1, &tags->mn)) {
+       if (!nvkm_mm_head(&fb->tags.mm, 0, 1, nr, nr, 1, &tags->mn)) {
                if (clr)
                        clr(device, tags->mn->offset, tags->mn->length);
        } else {
@@ -92,7 +92,7 @@ nvkm_memory_tags_get(struct nvkm_memory *memory, struct nvkm_device *device,
 
        refcount_set(&tags->refcount, 1);
        *ptags = memory->tags = tags;
-       mutex_unlock(&fb->subdev.mutex);
+       mutex_unlock(&fb->tags.mutex);
        return 0;
 }
 
index 5940e0d..7a13165 100644 (file)
@@ -122,7 +122,7 @@ nvkm_fb_oneinit(struct nvkm_subdev *subdev)
                nvkm_debug(subdev, "%d comptags\n", tags);
        }
 
-       return nvkm_mm_init(&fb->tags, 0, 0, tags, 1);
+       return nvkm_mm_init(&fb->tags.mm, 0, 0, tags, 1);
 }
 
 static int
@@ -205,7 +205,9 @@ nvkm_fb_dtor(struct nvkm_subdev *subdev)
        for (i = 0; i < fb->tile.regions; i++)
                fb->func->tile.fini(fb, i, &fb->tile.region[i]);
 
-       nvkm_mm_fini(&fb->tags);
+       nvkm_mm_fini(&fb->tags.mm);
+       mutex_destroy(&fb->tags.mutex);
+
        nvkm_ram_del(&fb->ram);
 
        nvkm_blob_dtor(&fb->vpr_scrubber);
@@ -230,8 +232,8 @@ nvkm_fb_ctor(const struct nvkm_fb_func *func, struct nvkm_device *device,
        nvkm_subdev_ctor(&nvkm_fb, device, index, &fb->subdev);
        fb->func = func;
        fb->tile.regions = fb->func->tile.regions;
-       fb->page = nvkm_longopt(device->cfgopt, "NvFbBigPage",
-                               fb->func->default_bigpage);
+       fb->page = nvkm_longopt(device->cfgopt, "NvFbBigPage", fb->func->default_bigpage);
+       mutex_init(&fb->tags.mutex);
 }
 
 int
index a021d21..e5ddbe6 100644 (file)
@@ -45,7 +45,7 @@ nv20_fb_tile_comp(struct nvkm_fb *fb, int i, u32 size, u32 flags,
 {
        u32 tiles = DIV_ROUND_UP(size, 0x40);
        u32 tags  = round_up(tiles / fb->ram->parts, 0x40);
-       if (!nvkm_mm_head(&fb->tags, 0, 1, tags, tags, 1, &tile->tag)) {
+       if (!nvkm_mm_head(&fb->tags.mm, 0, 1, tags, tags, 1, &tile->tag)) {
                if (!(flags & 2)) tile->zcomp = 0x00000000; /* Z16 */
                else              tile->zcomp = 0x04000000; /* Z24S8 */
                tile->zcomp |= tile->tag->offset;
@@ -63,7 +63,7 @@ nv20_fb_tile_fini(struct nvkm_fb *fb, int i, struct nvkm_fb_tile *tile)
        tile->limit = 0;
        tile->pitch = 0;
        tile->zcomp = 0;
-       nvkm_mm_free(&fb->tags, &tile->tag);
+       nvkm_mm_free(&fb->tags.mm, &tile->tag);
 }
 
 void
index 7709f5f..fb87e69 100644 (file)
@@ -32,7 +32,7 @@ nv25_fb_tile_comp(struct nvkm_fb *fb, int i, u32 size, u32 flags,
 {
        u32 tiles = DIV_ROUND_UP(size, 0x40);
        u32 tags  = round_up(tiles / fb->ram->parts, 0x40);
-       if (!nvkm_mm_head(&fb->tags, 0, 1, tags, tags, 1, &tile->tag)) {
+       if (!nvkm_mm_head(&fb->tags.mm, 0, 1, tags, tags, 1, &tile->tag)) {
                if (!(flags & 2)) tile->zcomp = 0x00100000; /* Z16 */
                else              tile->zcomp = 0x00200000; /* Z24S8 */
                tile->zcomp |= tile->tag->offset;
index 8aa7826..6e03349 100644 (file)
@@ -51,7 +51,7 @@ nv30_fb_tile_comp(struct nvkm_fb *fb, int i, u32 size, u32 flags,
 {
        u32 tiles = DIV_ROUND_UP(size, 0x40);
        u32 tags  = round_up(tiles / fb->ram->parts, 0x40);
-       if (!nvkm_mm_head(&fb->tags, 0, 1, tags, tags, 1, &tile->tag)) {
+       if (!nvkm_mm_head(&fb->tags.mm, 0, 1, tags, tags, 1, &tile->tag)) {
                if (flags & 2) tile->zcomp |= 0x01000000; /* Z16 */
                else           tile->zcomp |= 0x02000000; /* Z24S8 */
                tile->zcomp |= ((tile->tag->offset           ) >> 6);
index 6e83dcf..02a38d8 100644 (file)
@@ -32,7 +32,7 @@ nv35_fb_tile_comp(struct nvkm_fb *fb, int i, u32 size, u32 flags,
 {
        u32 tiles = DIV_ROUND_UP(size, 0x40);
        u32 tags  = round_up(tiles / fb->ram->parts, 0x40);
-       if (!nvkm_mm_head(&fb->tags, 0, 1, tags, tags, 1, &tile->tag)) {
+       if (!nvkm_mm_head(&fb->tags.mm, 0, 1, tags, tags, 1, &tile->tag)) {
                if (flags & 2) tile->zcomp |= 0x04000000; /* Z16 */
                else           tile->zcomp |= 0x08000000; /* Z24S8 */
                tile->zcomp |= ((tile->tag->offset           ) >> 6);
index 2a07617..f45143e 100644 (file)
@@ -32,7 +32,7 @@ nv36_fb_tile_comp(struct nvkm_fb *fb, int i, u32 size, u32 flags,
 {
        u32 tiles = DIV_ROUND_UP(size, 0x40);
        u32 tags  = round_up(tiles / fb->ram->parts, 0x40);
-       if (!nvkm_mm_head(&fb->tags, 0, 1, tags, tags, 1, &tile->tag)) {
+       if (!nvkm_mm_head(&fb->tags.mm, 0, 1, tags, tags, 1, &tile->tag)) {
                if (flags & 2) tile->zcomp |= 0x10000000; /* Z16 */
                else           tile->zcomp |= 0x20000000; /* Z24S8 */
                tile->zcomp |= ((tile->tag->offset           ) >> 6);
index 9551607..f51ba70 100644 (file)
@@ -33,7 +33,7 @@ nv40_fb_tile_comp(struct nvkm_fb *fb, int i, u32 size, u32 flags,
        u32 tiles = DIV_ROUND_UP(size, 0x80);
        u32 tags  = round_up(tiles / fb->ram->parts, 0x100);
        if ( (flags & 2) &&
-           !nvkm_mm_head(&fb->tags, 0, 1, tags, tags, 1, &tile->tag)) {
+           !nvkm_mm_head(&fb->tags.mm, 0, 1, tags, tags, 1, &tile->tag)) {
                tile->zcomp  = 0x28000000; /* Z24S8_SPLIT_GRAD */
                tile->zcomp |= ((tile->tag->offset           ) >> 8);
                tile->zcomp |= ((tile->tag->offset + tags - 1) >> 8) << 13;
index a21ef45..1d45356 100644 (file)
@@ -200,8 +200,8 @@ gf100_ltc_oneinit_tag_ram(struct nvkm_ltc *ltc)
        }
 
 mm_init:
-       nvkm_mm_fini(&fb->tags);
-       return nvkm_mm_init(&fb->tags, 0, 0, ltc->num_tags, 1);
+       nvkm_mm_fini(&fb->tags.mm);
+       return nvkm_mm_init(&fb->tags.mm, 0, 0, ltc->num_tags, 1);
 }
 
 int