drm/nouveau/disp/nv50-: execute supervisor on its own workqueue
authorBen Skeggs <bskeggs@redhat.com>
Fri, 19 May 2017 13:59:35 +0000 (23:59 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Fri, 16 Jun 2017 04:04:52 +0000 (14:04 +1000)
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
drivers/gpu/drm/nouveau/nvkm/engine/disp/gf119.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.h

index 94eb6b2..2ffbb99 100644 (file)
@@ -459,7 +459,7 @@ gf119_disp_intr(struct nv50_disp *disp)
                u32 stat = nvkm_rd32(device, 0x6100ac);
                if (stat & 0x00000007) {
                        disp->super = (stat & 0x00000007);
-                       schedule_work(&disp->supervisor);
+                       queue_work(disp->wq, &disp->supervisor);
                        nvkm_wr32(device, 0x6100ac, disp->super);
                        stat &= ~0x00000007;
                }
index acc6630..21bdf30 100644 (file)
@@ -111,6 +111,8 @@ nv50_disp_dtor_(struct nvkm_disp *base)
 {
        struct nv50_disp *disp = nv50_disp(base);
        nvkm_event_fini(&disp->uevent);
+       if (disp->wq)
+               destroy_workqueue(disp->wq);
        return disp;
 }
 
@@ -136,7 +138,6 @@ nv50_disp_new_(const struct nv50_disp_func *func, struct nvkm_device *device,
 
        if (!(disp = kzalloc(sizeof(*disp), GFP_KERNEL)))
                return -ENOMEM;
-       INIT_WORK(&disp->supervisor, func->super);
        disp->func = func;
        *pdisp = &disp->base;
 
@@ -144,6 +145,11 @@ nv50_disp_new_(const struct nv50_disp_func *func, struct nvkm_device *device,
        if (ret)
                return ret;
 
+       disp->wq = create_singlethread_workqueue("nvkm-disp");
+       if (!disp->wq)
+               return -ENOMEM;
+       INIT_WORK(&disp->supervisor, func->super);
+
        for (i = 0; func->head.new && i < heads; i++) {
                ret = func->head.new(&disp->base, i);
                if (ret)
@@ -803,7 +809,7 @@ nv50_disp_intr(struct nv50_disp *disp)
 
        if (intr1 & 0x00000070) {
                disp->super = (intr1 & 0x00000070);
-               schedule_work(&disp->supervisor);
+               queue_work(disp->wq, &disp->supervisor);
                nvkm_wr32(device, 0x610024, disp->super);
        }
 }
index 06249f6..fe7ef0a 100644 (file)
@@ -12,6 +12,7 @@ struct nv50_disp {
        const struct nv50_disp_func *func;
        struct nvkm_disp base;
 
+       struct workqueue_struct *wq;
        struct work_struct supervisor;
        u32 super;