Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'drm-fixes-for-v4.15-rc10-2' of git://people.freedesktop.org/~airlied/linux

Pull drm fixes from Dave Airlie:
"A fairly urgent nouveau regression fix for broken irqs across
suspend/resume came in. This was broken before but a patch in 4.15 has
made it much more obviously broken and now s/r fails a lot more often.

The fix removes freeing the irq across s/r which never should have
been done anyways.

Also two vc4 fixes for a NULL deference and some misrendering /
flickering on screen"

* tag 'drm-fixes-for-v4.15-rc10-2' of git://people.freedesktop.org/~airlied/linux:
drm/nouveau: Move irq setup/teardown to pci ctor/dtor
drm/vc4: Fix NULL pointer dereference in vc4_save_hang_state()
drm/vc4: Flush the caches before the bin jobs, as well.

+58 -21
+31 -15
drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c
··· 71 71 struct nvkm_pci *pci = arg; 72 72 struct nvkm_device *device = pci->subdev.device; 73 73 bool handled = false; 74 + 75 + if (pci->irq < 0) 76 + return IRQ_HANDLED; 77 + 74 78 nvkm_mc_intr_unarm(device); 75 79 if (pci->msi) 76 80 pci->func->msi_rearm(pci); ··· 87 83 nvkm_pci_fini(struct nvkm_subdev *subdev, bool suspend) 88 84 { 89 85 struct nvkm_pci *pci = nvkm_pci(subdev); 90 - 91 - if (pci->irq >= 0) { 92 - free_irq(pci->irq, pci); 93 - pci->irq = -1; 94 - } 95 86 96 87 if (pci->agp.bridge) 97 88 nvkm_agp_fini(pci); ··· 107 108 nvkm_pci_oneinit(struct nvkm_subdev *subdev) 108 109 { 109 110 struct nvkm_pci *pci = nvkm_pci(subdev); 110 - if (pci_is_pcie(pci->pdev)) 111 - return nvkm_pcie_oneinit(pci); 111 + struct pci_dev *pdev = pci->pdev; 112 + int ret; 113 + 114 + if (pci_is_pcie(pci->pdev)) { 115 + ret = nvkm_pcie_oneinit(pci); 116 + if (ret) 117 + return ret; 118 + } 119 + 120 + ret = request_irq(pdev->irq, nvkm_pci_intr, IRQF_SHARED, "nvkm", pci); 121 + if (ret) 122 + return ret; 123 + 124 + pci->irq = pdev->irq; 112 125 return 0; 113 126 } 114 127 ··· 128 117 nvkm_pci_init(struct nvkm_subdev *subdev) 129 118 { 130 119 struct nvkm_pci *pci = nvkm_pci(subdev); 131 - struct pci_dev *pdev = pci->pdev; 132 120 int ret; 133 121 134 122 if (pci->agp.bridge) { ··· 141 131 if (pci->func->init) 142 132 pci->func->init(pci); 143 133 144 - ret = request_irq(pdev->irq, nvkm_pci_intr, IRQF_SHARED, "nvkm", pci); 145 - if (ret) 146 - return ret; 147 - 148 - pci->irq = pdev->irq; 149 - 150 134 /* Ensure MSI interrupts are armed, for the case where there are 151 135 * already interrupts pending (for whatever reason) at load time. 152 136 */ 153 137 if (pci->msi) 154 138 pci->func->msi_rearm(pci); 155 139 156 - return ret; 140 + return 0; 157 141 } 158 142 159 143 static void * 160 144 nvkm_pci_dtor(struct nvkm_subdev *subdev) 161 145 { 162 146 struct nvkm_pci *pci = nvkm_pci(subdev); 147 + 163 148 nvkm_agp_dtor(pci); 149 + 150 + if (pci->irq >= 0) { 151 + /* freq_irq() will call the handler, we use pci->irq == -1 152 + * to signal that it's been torn down and should be a noop. 153 + */ 154 + int irq = pci->irq; 155 + pci->irq = -1; 156 + free_irq(irq, pci); 157 + } 158 + 164 159 if (pci->msi) 165 160 pci_disable_msi(pci->pdev); 161 + 166 162 return nvkm_pci(subdev); 167 163 } 168 164
+27 -6
drivers/gpu/drm/vc4/vc4_gem.c
··· 146 146 struct vc4_exec_info *exec[2]; 147 147 struct vc4_bo *bo; 148 148 unsigned long irqflags; 149 - unsigned int i, j, unref_list_count, prev_idx; 149 + unsigned int i, j, k, unref_list_count; 150 150 151 151 kernel_state = kcalloc(1, sizeof(*kernel_state), GFP_KERNEL); 152 152 if (!kernel_state) ··· 182 182 return; 183 183 } 184 184 185 - prev_idx = 0; 185 + k = 0; 186 186 for (i = 0; i < 2; i++) { 187 187 if (!exec[i]) 188 188 continue; ··· 197 197 WARN_ON(!refcount_read(&bo->usecnt)); 198 198 refcount_inc(&bo->usecnt); 199 199 drm_gem_object_get(&exec[i]->bo[j]->base); 200 - kernel_state->bo[j + prev_idx] = &exec[i]->bo[j]->base; 200 + kernel_state->bo[k++] = &exec[i]->bo[j]->base; 201 201 } 202 202 203 203 list_for_each_entry(bo, &exec[i]->unref_list, unref_head) { ··· 205 205 * because they are naturally unpurgeable. 206 206 */ 207 207 drm_gem_object_get(&bo->base.base); 208 - kernel_state->bo[j + prev_idx] = &bo->base.base; 209 - j++; 208 + kernel_state->bo[k++] = &bo->base.base; 210 209 } 211 - prev_idx = j + 1; 212 210 } 211 + 212 + WARN_ON_ONCE(k != state->bo_count); 213 213 214 214 if (exec[0]) 215 215 state->start_bin = exec[0]->ct0ca; ··· 436 436 VC4_SET_FIELD(0xf, V3D_SLCACTL_ICC)); 437 437 } 438 438 439 + static void 440 + vc4_flush_texture_caches(struct drm_device *dev) 441 + { 442 + struct vc4_dev *vc4 = to_vc4_dev(dev); 443 + 444 + V3D_WRITE(V3D_L2CACTL, 445 + V3D_L2CACTL_L2CCLR); 446 + 447 + V3D_WRITE(V3D_SLCACTL, 448 + VC4_SET_FIELD(0xf, V3D_SLCACTL_T1CC) | 449 + VC4_SET_FIELD(0xf, V3D_SLCACTL_T0CC)); 450 + } 451 + 439 452 /* Sets the registers for the next job to be actually be executed in 440 453 * the hardware. 441 454 * ··· 486 473 487 474 if (!exec) 488 475 return; 476 + 477 + /* A previous RCL may have written to one of our textures, and 478 + * our full cache flush at bin time may have occurred before 479 + * that RCL completed. Flush the texture cache now, but not 480 + * the instructions or uniforms (since we don't write those 481 + * from an RCL). 482 + */ 483 + vc4_flush_texture_caches(dev); 489 484 490 485 submit_cl(dev, 1, exec->ct1ca, exec->ct1ea); 491 486 }