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 branch 'drm-fixes' of git://people.freedesktop.org/~airlied/linux

Pull drm fixes from Dave Airlie:
"Radeon and Nouveau fixes:

So nouveau had a few regression introduced, Ben and Maarten finally
tracked down the one that was causing problems on my MacBookPro, also
nvidia gave some info on the an engine we were using incorrectly, so
disable our use of it, and one regresion with pci hotplug affecting
optimus users.

Radeon has an oops fixs, sync fix, and one workaround to avoid broken
functionality on 32-bit x86, this needs better root causing and a
better fix, but the bandaid is a lot safer at this point"

* 'drm-fixes' of git://people.freedesktop.org/~airlied/linux:
drm/radeon: kernel panic in drm_calc_vbltimestamp_from_scanoutpos with 3.18.0-rc6
drm/radeon: Ignore RADEON_GEM_GTT_WC on 32-bit x86
drm/radeon: sync all BOs involved in a CS v2
nouveau: move the hotplug ignore to correct place.
drm/nouveau/gf116: remove copy1 engine
drm/nouveau: prevent stale fence->channel pointers, and protect with rcu
drm/nouveau/fifo/g84-: ack non-stall interrupt before handling it

+88 -45
-1
drivers/gpu/drm/nouveau/core/engine/device/nvc0.c
··· 218 218 device->oclass[NVDEV_ENGINE_BSP ] = &nvc0_bsp_oclass; 219 219 device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass; 220 220 device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass; 221 - device->oclass[NVDEV_ENGINE_COPY1 ] = &nvc0_copy1_oclass; 222 221 device->oclass[NVDEV_ENGINE_DISP ] = nva3_disp_oclass; 223 222 device->oclass[NVDEV_ENGINE_PERFMON] = &nvc0_perfmon_oclass; 224 223 break;
+1 -1
drivers/gpu/drm/nouveau/core/engine/fifo/nv04.c
··· 551 551 } 552 552 553 553 if (status & 0x40000000) { 554 - nouveau_fifo_uevent(&priv->base); 555 554 nv_wr32(priv, 0x002100, 0x40000000); 555 + nouveau_fifo_uevent(&priv->base); 556 556 status &= ~0x40000000; 557 557 } 558 558 }
+2 -2
drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c
··· 740 740 u32 inte = nv_rd32(priv, 0x002628); 741 741 u32 unkn; 742 742 743 + nv_wr32(priv, 0x0025a8 + (engn * 0x04), intr); 744 + 743 745 for (unkn = 0; unkn < 8; unkn++) { 744 746 u32 ints = (intr >> (unkn * 0x04)) & inte; 745 747 if (ints & 0x1) { ··· 753 751 nv_mask(priv, 0x002628, ints, 0); 754 752 } 755 753 } 756 - 757 - nv_wr32(priv, 0x0025a8 + (engn * 0x04), intr); 758 754 } 759 755 760 756 static void
+1 -1
drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c
··· 952 952 } 953 953 954 954 if (stat & 0x80000000) { 955 - nve0_fifo_intr_engine(priv); 956 955 nv_wr32(priv, 0x002100, 0x80000000); 956 + nve0_fifo_intr_engine(priv); 957 957 stat &= ~0x80000000; 958 958 } 959 959
+1 -1
drivers/gpu/drm/nouveau/nouveau_drm.c
··· 629 629 630 630 pci_save_state(pdev); 631 631 pci_disable_device(pdev); 632 - pci_ignore_hotplug(pdev); 633 632 pci_set_power_state(pdev, PCI_D3hot); 634 633 return 0; 635 634 } ··· 932 933 ret = nouveau_do_suspend(drm_dev, true); 933 934 pci_save_state(pdev); 934 935 pci_disable_device(pdev); 936 + pci_ignore_hotplug(pdev); 935 937 pci_set_power_state(pdev, PCI_D3cold); 936 938 drm_dev->switch_power_state = DRM_SWITCH_POWER_DYNAMIC_OFF; 937 939 return ret;
+65 -27
drivers/gpu/drm/nouveau/nouveau_fence.c
··· 52 52 return container_of(fence->base.lock, struct nouveau_fence_chan, lock); 53 53 } 54 54 55 - static void 55 + static int 56 56 nouveau_fence_signal(struct nouveau_fence *fence) 57 57 { 58 + int drop = 0; 59 + 58 60 fence_signal_locked(&fence->base); 59 61 list_del(&fence->head); 62 + rcu_assign_pointer(fence->channel, NULL); 60 63 61 64 if (test_bit(FENCE_FLAG_USER_BITS, &fence->base.flags)) { 62 65 struct nouveau_fence_chan *fctx = nouveau_fctx(fence); 63 66 64 67 if (!--fctx->notify_ref) 65 - nvif_notify_put(&fctx->notify); 68 + drop = 1; 66 69 } 67 70 68 71 fence_put(&fence->base); 72 + return drop; 69 73 } 70 74 71 75 static struct nouveau_fence * ··· 92 88 { 93 89 struct nouveau_fence *fence; 94 90 95 - nvif_notify_fini(&fctx->notify); 96 - 97 91 spin_lock_irq(&fctx->lock); 98 92 while (!list_empty(&fctx->pending)) { 99 93 fence = list_entry(fctx->pending.next, typeof(*fence), head); 100 94 101 - nouveau_fence_signal(fence); 102 - fence->channel = NULL; 95 + if (nouveau_fence_signal(fence)) 96 + nvif_notify_put(&fctx->notify); 103 97 } 104 98 spin_unlock_irq(&fctx->lock); 99 + 100 + nvif_notify_fini(&fctx->notify); 101 + fctx->dead = 1; 102 + 103 + /* 104 + * Ensure that all accesses to fence->channel complete before freeing 105 + * the channel. 106 + */ 107 + synchronize_rcu(); 105 108 } 106 109 107 110 static void ··· 123 112 kref_put(&fctx->fence_ref, nouveau_fence_context_put); 124 113 } 125 114 126 - static void 115 + static int 127 116 nouveau_fence_update(struct nouveau_channel *chan, struct nouveau_fence_chan *fctx) 128 117 { 129 118 struct nouveau_fence *fence; 130 - 119 + int drop = 0; 131 120 u32 seq = fctx->read(chan); 132 121 133 122 while (!list_empty(&fctx->pending)) { 134 123 fence = list_entry(fctx->pending.next, typeof(*fence), head); 135 124 136 125 if ((int)(seq - fence->base.seqno) < 0) 137 - return; 126 + break; 138 127 139 - nouveau_fence_signal(fence); 128 + drop |= nouveau_fence_signal(fence); 140 129 } 130 + 131 + return drop; 141 132 } 142 133 143 134 static int ··· 148 135 struct nouveau_fence_chan *fctx = 149 136 container_of(notify, typeof(*fctx), notify); 150 137 unsigned long flags; 138 + int ret = NVIF_NOTIFY_KEEP; 151 139 152 140 spin_lock_irqsave(&fctx->lock, flags); 153 141 if (!list_empty(&fctx->pending)) { 154 142 struct nouveau_fence *fence; 143 + struct nouveau_channel *chan; 155 144 156 145 fence = list_entry(fctx->pending.next, typeof(*fence), head); 157 - nouveau_fence_update(fence->channel, fctx); 146 + chan = rcu_dereference_protected(fence->channel, lockdep_is_held(&fctx->lock)); 147 + if (nouveau_fence_update(fence->channel, fctx)) 148 + ret = NVIF_NOTIFY_DROP; 158 149 } 159 150 spin_unlock_irqrestore(&fctx->lock, flags); 160 151 161 - /* Always return keep here. NVIF refcount is handled with nouveau_fence_update */ 162 - return NVIF_NOTIFY_KEEP; 152 + return ret; 163 153 } 164 154 165 155 void ··· 278 262 if (!ret) { 279 263 fence_get(&fence->base); 280 264 spin_lock_irq(&fctx->lock); 281 - nouveau_fence_update(chan, fctx); 265 + 266 + if (nouveau_fence_update(chan, fctx)) 267 + nvif_notify_put(&fctx->notify); 268 + 282 269 list_add_tail(&fence->head, &fctx->pending); 283 270 spin_unlock_irq(&fctx->lock); 284 271 } ··· 295 276 if (fence->base.ops == &nouveau_fence_ops_legacy || 296 277 fence->base.ops == &nouveau_fence_ops_uevent) { 297 278 struct nouveau_fence_chan *fctx = nouveau_fctx(fence); 279 + struct nouveau_channel *chan; 298 280 unsigned long flags; 299 281 300 282 if (test_bit(FENCE_FLAG_SIGNALED_BIT, &fence->base.flags)) 301 283 return true; 302 284 303 285 spin_lock_irqsave(&fctx->lock, flags); 304 - nouveau_fence_update(fence->channel, fctx); 286 + chan = rcu_dereference_protected(fence->channel, lockdep_is_held(&fctx->lock)); 287 + if (chan && nouveau_fence_update(chan, fctx)) 288 + nvif_notify_put(&fctx->notify); 305 289 spin_unlock_irqrestore(&fctx->lock, flags); 306 290 } 307 291 return fence_is_signaled(&fence->base); ··· 409 387 410 388 if (fence && (!exclusive || !fobj || !fobj->shared_count)) { 411 389 struct nouveau_channel *prev = NULL; 390 + bool must_wait = true; 412 391 413 392 f = nouveau_local_fence(fence, chan->drm); 414 - if (f) 415 - prev = f->channel; 393 + if (f) { 394 + rcu_read_lock(); 395 + prev = rcu_dereference(f->channel); 396 + if (prev && (prev == chan || fctx->sync(f, prev, chan) == 0)) 397 + must_wait = false; 398 + rcu_read_unlock(); 399 + } 416 400 417 - if (!prev || (prev != chan && (ret = fctx->sync(f, prev, chan)))) 401 + if (must_wait) 418 402 ret = fence_wait(fence, intr); 419 403 420 404 return ret; ··· 431 403 432 404 for (i = 0; i < fobj->shared_count && !ret; ++i) { 433 405 struct nouveau_channel *prev = NULL; 406 + bool must_wait = true; 434 407 435 408 fence = rcu_dereference_protected(fobj->shared[i], 436 409 reservation_object_held(resv)); 437 410 438 411 f = nouveau_local_fence(fence, chan->drm); 439 - if (f) 440 - prev = f->channel; 412 + if (f) { 413 + rcu_read_lock(); 414 + prev = rcu_dereference(f->channel); 415 + if (prev && (prev == chan || fctx->sync(f, prev, chan) == 0)) 416 + must_wait = false; 417 + rcu_read_unlock(); 418 + } 441 419 442 - if (!prev || (prev != chan && (ret = fctx->sync(f, prev, chan)))) 420 + if (must_wait) 443 421 ret = fence_wait(fence, intr); 444 - 445 - if (ret) 446 - break; 447 422 } 448 423 449 424 return ret; ··· 494 463 struct nouveau_fence *fence = from_fence(f); 495 464 struct nouveau_fence_chan *fctx = nouveau_fctx(fence); 496 465 497 - return fence->channel ? fctx->name : "dead channel"; 466 + return !fctx->dead ? fctx->name : "dead channel"; 498 467 } 499 468 500 469 /* ··· 507 476 { 508 477 struct nouveau_fence *fence = from_fence(f); 509 478 struct nouveau_fence_chan *fctx = nouveau_fctx(fence); 510 - struct nouveau_channel *chan = fence->channel; 479 + struct nouveau_channel *chan; 480 + bool ret = false; 511 481 512 - return (int)(fctx->read(chan) - fence->base.seqno) >= 0; 482 + rcu_read_lock(); 483 + chan = rcu_dereference(fence->channel); 484 + if (chan) 485 + ret = (int)(fctx->read(chan) - fence->base.seqno) >= 0; 486 + rcu_read_unlock(); 487 + 488 + return ret; 513 489 } 514 490 515 491 static bool nouveau_fence_no_signaling(struct fence *f)
+2 -2
drivers/gpu/drm/nouveau/nouveau_fence.h
··· 14 14 15 15 bool sysmem; 16 16 17 - struct nouveau_channel *channel; 17 + struct nouveau_channel __rcu *channel; 18 18 unsigned long timeout; 19 19 }; 20 20 ··· 47 47 char name[32]; 48 48 49 49 struct nvif_notify notify; 50 - int notify_ref; 50 + int notify_ref, dead; 51 51 }; 52 52 53 53 struct nouveau_fence_priv {
+7 -10
drivers/gpu/drm/radeon/radeon_cs.c
··· 251 251 252 252 static int radeon_cs_sync_rings(struct radeon_cs_parser *p) 253 253 { 254 - int i, r = 0; 254 + struct radeon_cs_reloc *reloc; 255 + int r; 255 256 256 - for (i = 0; i < p->nrelocs; i++) { 257 + list_for_each_entry(reloc, &p->validated, tv.head) { 257 258 struct reservation_object *resv; 258 259 259 - if (!p->relocs[i].robj) 260 - continue; 261 - 262 - resv = p->relocs[i].robj->tbo.resv; 260 + resv = reloc->robj->tbo.resv; 263 261 r = radeon_semaphore_sync_resv(p->rdev, p->ib.semaphore, resv, 264 - p->relocs[i].tv.shared); 265 - 262 + reloc->tv.shared); 266 263 if (r) 267 - break; 264 + return r; 268 265 } 269 - return r; 266 + return 0; 270 267 } 271 268 272 269 /* XXX: note that this is called from the legacy UMS CS ioctl as well */
+2
drivers/gpu/drm/radeon/radeon_kms.c
··· 795 795 796 796 /* Get associated drm_crtc: */ 797 797 drmcrtc = &rdev->mode_info.crtcs[crtc]->base; 798 + if (!drmcrtc) 799 + return -EINVAL; 798 800 799 801 /* Helper routine in DRM core does all the work: */ 800 802 return drm_calc_vbltimestamp_from_scanoutpos(dev, crtc, max_error,
+7
drivers/gpu/drm/radeon/radeon_object.c
··· 213 213 if (!(rdev->flags & RADEON_IS_PCIE)) 214 214 bo->flags &= ~(RADEON_GEM_GTT_WC | RADEON_GEM_GTT_UC); 215 215 216 + #ifdef CONFIG_X86_32 217 + /* XXX: Write-combined CPU mappings of GTT seem broken on 32-bit 218 + * See https://bugs.freedesktop.org/show_bug.cgi?id=84627 219 + */ 220 + bo->flags &= ~RADEON_GEM_GTT_WC; 221 + #endif 222 + 216 223 radeon_ttm_placement_from_domain(bo, domain); 217 224 /* Kernel allocation are uninterruptible */ 218 225 down_read(&rdev->pm.mclk_lock);