Skip to content

Commit

Permalink
drm/nouveau: teach nouveau_bo_pin() how to force a contig vram alloca…
Browse files Browse the repository at this point in the history
…tion

We have the ability to move buffers around in the kernel if necessary,
and should probably use it rather than failing if userspace passes us
a non-contig buffer for a plane.

The NOUVEAU_GEM_TILE_NONCONTIG flag from userspace will become a mere
initial placement hint once all the relevant paths have been updated.

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
  • Loading branch information
Ben Skeggs committed Dec 2, 2014
1 parent ef1df1b commit ad76b3f
Show file tree
Hide file tree
Showing 13 changed files with 52 additions and 27 deletions.
4 changes: 2 additions & 2 deletions drivers/gpu/drm/nouveau/dispnv04/crtc.c
Original file line number Diff line number Diff line change
Expand Up @@ -614,7 +614,7 @@ nv_crtc_swap_fbs(struct drm_crtc *crtc, struct drm_framebuffer *old_fb)
struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
int ret;

ret = nouveau_bo_pin(nvfb->nvbo, TTM_PL_FLAG_VRAM);
ret = nouveau_bo_pin(nvfb->nvbo, TTM_PL_FLAG_VRAM, false);
if (ret == 0) {
if (disp->image[nv_crtc->index])
nouveau_bo_unpin(disp->image[nv_crtc->index]);
Expand Down Expand Up @@ -1130,7 +1130,7 @@ nv04_crtc_create(struct drm_device *dev, int crtc_num)
ret = nouveau_bo_new(dev, 64*64*4, 0x100, TTM_PL_FLAG_VRAM,
0, 0x0000, NULL, NULL, &nv_crtc->cursor.nvbo);
if (!ret) {
ret = nouveau_bo_pin(nv_crtc->cursor.nvbo, TTM_PL_FLAG_VRAM);
ret = nouveau_bo_pin(nv_crtc->cursor.nvbo, TTM_PL_FLAG_VRAM, false);
if (!ret) {
ret = nouveau_bo_map(nv_crtc->cursor.nvbo);
if (ret)
Expand Down
4 changes: 2 additions & 2 deletions drivers/gpu/drm/nouveau/dispnv04/overlay.c
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ nv10_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
return -ERANGE;
}

ret = nouveau_bo_pin(nv_fb->nvbo, TTM_PL_FLAG_VRAM);
ret = nouveau_bo_pin(nv_fb->nvbo, TTM_PL_FLAG_VRAM, false);
if (ret)
return ret;

Expand Down Expand Up @@ -373,7 +373,7 @@ nv04_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
if (crtc_w < src_w || crtc_h < src_h)
return -ERANGE;

ret = nouveau_bo_pin(nv_fb->nvbo, TTM_PL_FLAG_VRAM);
ret = nouveau_bo_pin(nv_fb->nvbo, TTM_PL_FLAG_VRAM, false);
if (ret)
return ret;

Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/nouveau/nouveau_abi16.c
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,7 @@ nouveau_abi16_ioctl_channel_alloc(ABI16_IOCTL_ARGS)
ret = nouveau_gem_new(dev, PAGE_SIZE, 0, NOUVEAU_GEM_DOMAIN_GART,
0, 0, &chan->ntfy);
if (ret == 0)
ret = nouveau_bo_pin(chan->ntfy, TTM_PL_FLAG_TT);
ret = nouveau_bo_pin(chan->ntfy, TTM_PL_FLAG_TT, false);
if (ret)
goto done;

Expand Down
39 changes: 32 additions & 7 deletions drivers/gpu/drm/nouveau/nouveau_bo.c
Original file line number Diff line number Diff line change
Expand Up @@ -310,26 +310,49 @@ nouveau_bo_placement_set(struct nouveau_bo *nvbo, uint32_t type, uint32_t busy)
}

int
nouveau_bo_pin(struct nouveau_bo *nvbo, uint32_t memtype)
nouveau_bo_pin(struct nouveau_bo *nvbo, uint32_t memtype, bool contig)
{
struct nouveau_drm *drm = nouveau_bdev(nvbo->bo.bdev);
struct ttm_buffer_object *bo = &nvbo->bo;
bool force = false, evict = false;
int ret;

ret = ttm_bo_reserve(bo, false, false, false, NULL);
if (ret)
return ret;

if (nvbo->pin_refcnt && !(memtype & (1 << bo->mem.mem_type))) {
NV_ERROR(drm, "bo %p pinned elsewhere: 0x%08x vs 0x%08x\n", bo,
1 << bo->mem.mem_type, memtype);
ret = -EINVAL;
goto out;
if (drm->device.info.family >= NV_DEVICE_INFO_V0_TESLA &&
memtype == TTM_PL_FLAG_VRAM && contig) {
if (nvbo->tile_flags & NOUVEAU_GEM_TILE_NONCONTIG) {
if (bo->mem.mem_type == TTM_PL_VRAM) {
struct nouveau_mem *mem = bo->mem.mm_node;
if (!list_is_singular(&mem->regions))
evict = true;
}
nvbo->tile_flags &= ~NOUVEAU_GEM_TILE_NONCONTIG;
force = true;
}
}

if (nvbo->pin_refcnt++)
if (nvbo->pin_refcnt) {
if (!(memtype & (1 << bo->mem.mem_type)) || evict) {
NV_ERROR(drm, "bo %p pinned elsewhere: "
"0x%08x vs 0x%08x\n", bo,
1 << bo->mem.mem_type, memtype);
ret = -EBUSY;
}
nvbo->pin_refcnt++;
goto out;
}

if (evict) {
nouveau_bo_placement_set(nvbo, TTM_PL_FLAG_TT, 0);
ret = nouveau_bo_validate(nvbo, false, false);
if (ret)
goto out;
}

nvbo->pin_refcnt++;
nouveau_bo_placement_set(nvbo, memtype, 0);

/* drop pin_refcnt temporarily, so we don't trip the assertion
Expand All @@ -354,6 +377,8 @@ nouveau_bo_pin(struct nouveau_bo *nvbo, uint32_t memtype)
}

out:
if (force && ret)
nvbo->tile_flags |= NOUVEAU_GEM_TILE_NONCONTIG;
ttm_bo_unreserve(bo);
return ret;
}
Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/nouveau/nouveau_bo.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ int nouveau_bo_new(struct drm_device *, int size, int align, u32 flags,
u32 tile_mode, u32 tile_flags, struct sg_table *sg,
struct reservation_object *robj,
struct nouveau_bo **);
int nouveau_bo_pin(struct nouveau_bo *, u32 flags);
int nouveau_bo_pin(struct nouveau_bo *, u32 flags, bool contig);
int nouveau_bo_unpin(struct nouveau_bo *);
int nouveau_bo_map(struct nouveau_bo *);
void nouveau_bo_unmap(struct nouveau_bo *);
Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/nouveau/nouveau_chan.c
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ nouveau_channel_prep(struct nouveau_drm *drm, struct nvif_device *device,
ret = nouveau_bo_new(drm->dev, size, 0, target, 0, 0, NULL, NULL,
&chan->push.buffer);
if (ret == 0) {
ret = nouveau_bo_pin(chan->push.buffer, target);
ret = nouveau_bo_pin(chan->push.buffer, target, false);
if (ret == 0)
ret = nouveau_bo_map(chan->push.buffer);
}
Expand Down
6 changes: 3 additions & 3 deletions drivers/gpu/drm/nouveau/nouveau_display.c
Original file line number Diff line number Diff line change
Expand Up @@ -592,15 +592,15 @@ nouveau_display_resume(struct drm_device *dev, bool runtime)
if (!nouveau_fb || !nouveau_fb->nvbo)
continue;

ret = nouveau_bo_pin(nouveau_fb->nvbo, TTM_PL_FLAG_VRAM);
ret = nouveau_bo_pin(nouveau_fb->nvbo, TTM_PL_FLAG_VRAM, false);
if (ret)
NV_ERROR(drm, "Could not pin framebuffer\n");
}

list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);

ret = nouveau_bo_pin(nv_crtc->cursor.nvbo, TTM_PL_FLAG_VRAM);
ret = nouveau_bo_pin(nv_crtc->cursor.nvbo, TTM_PL_FLAG_VRAM, false);
if (!ret)
ret = nouveau_bo_map(nv_crtc->cursor.nvbo);
if (ret)
Expand Down Expand Up @@ -713,7 +713,7 @@ nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb,
return -ENOMEM;

if (new_bo != old_bo) {
ret = nouveau_bo_pin(new_bo, TTM_PL_FLAG_VRAM);
ret = nouveau_bo_pin(new_bo, TTM_PL_FLAG_VRAM, false);
if (ret)
goto fail_free;
}
Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/nouveau/nouveau_fbcon.c
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,7 @@ nouveau_fbcon_create(struct drm_fb_helper *helper,
goto out;
}

ret = nouveau_bo_pin(nvbo, TTM_PL_FLAG_VRAM);
ret = nouveau_bo_pin(nvbo, TTM_PL_FLAG_VRAM, false);
if (ret) {
NV_ERROR(drm, "failed to pin fb: %d\n", ret);
goto out_unref;
Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/nouveau/nouveau_prime.c
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ int nouveau_gem_prime_pin(struct drm_gem_object *obj)
int ret;

/* pin buffer into GTT */
ret = nouveau_bo_pin(nvbo, TTM_PL_FLAG_TT);
ret = nouveau_bo_pin(nvbo, TTM_PL_FLAG_TT, false);
if (ret)
return -EINVAL;

Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/nouveau/nv17_fence.c
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ nv17_fence_create(struct nouveau_drm *drm)
ret = nouveau_bo_new(drm->dev, 4096, 0x1000, TTM_PL_FLAG_VRAM,
0, 0x0000, NULL, NULL, &priv->bo);
if (!ret) {
ret = nouveau_bo_pin(priv->bo, TTM_PL_FLAG_VRAM);
ret = nouveau_bo_pin(priv->bo, TTM_PL_FLAG_VRAM, false);
if (!ret) {
ret = nouveau_bo_map(priv->bo);
if (ret)
Expand Down
8 changes: 4 additions & 4 deletions drivers/gpu/drm/nouveau/nv50_display.c
Original file line number Diff line number Diff line change
Expand Up @@ -1073,7 +1073,7 @@ nv50_crtc_swap_fbs(struct drm_crtc *crtc, struct drm_framebuffer *old_fb)
struct nv50_head *head = nv50_head(crtc);
int ret;

ret = nouveau_bo_pin(nvfb->nvbo, TTM_PL_FLAG_VRAM);
ret = nouveau_bo_pin(nvfb->nvbo, TTM_PL_FLAG_VRAM, false);
if (ret == 0) {
if (head->image)
nouveau_bo_unpin(head->image);
Expand Down Expand Up @@ -1402,7 +1402,7 @@ nv50_crtc_create(struct drm_device *dev, int index)
ret = nouveau_bo_new(dev, 8192, 0x100, TTM_PL_FLAG_VRAM,
0, 0x0000, NULL, NULL, &head->base.lut.nvbo);
if (!ret) {
ret = nouveau_bo_pin(head->base.lut.nvbo, TTM_PL_FLAG_VRAM);
ret = nouveau_bo_pin(head->base.lut.nvbo, TTM_PL_FLAG_VRAM, false);
if (!ret) {
ret = nouveau_bo_map(head->base.lut.nvbo);
if (ret)
Expand All @@ -1425,7 +1425,7 @@ nv50_crtc_create(struct drm_device *dev, int index)
ret = nouveau_bo_new(dev, 64 * 64 * 4, 0x100, TTM_PL_FLAG_VRAM,
0, 0x0000, NULL, NULL, &head->base.cursor.nvbo);
if (!ret) {
ret = nouveau_bo_pin(head->base.cursor.nvbo, TTM_PL_FLAG_VRAM);
ret = nouveau_bo_pin(head->base.cursor.nvbo, TTM_PL_FLAG_VRAM, false);
if (!ret) {
ret = nouveau_bo_map(head->base.cursor.nvbo);
if (ret)
Expand Down Expand Up @@ -2487,7 +2487,7 @@ nv50_display_create(struct drm_device *dev)
ret = nouveau_bo_new(dev, 4096, 0x1000, TTM_PL_FLAG_VRAM,
0, 0x0000, NULL, NULL, &disp->sync);
if (!ret) {
ret = nouveau_bo_pin(disp->sync, TTM_PL_FLAG_VRAM);
ret = nouveau_bo_pin(disp->sync, TTM_PL_FLAG_VRAM, false);
if (!ret) {
ret = nouveau_bo_map(disp->sync);
if (ret)
Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/nouveau/nv50_fence.c
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ nv50_fence_create(struct nouveau_drm *drm)
ret = nouveau_bo_new(drm->dev, 4096, 0x1000, TTM_PL_FLAG_VRAM,
0, 0x0000, NULL, NULL, &priv->bo);
if (!ret) {
ret = nouveau_bo_pin(priv->bo, TTM_PL_FLAG_VRAM);
ret = nouveau_bo_pin(priv->bo, TTM_PL_FLAG_VRAM, false);
if (!ret) {
ret = nouveau_bo_map(priv->bo);
if (ret)
Expand Down
4 changes: 2 additions & 2 deletions drivers/gpu/drm/nouveau/nv84_fence.c
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ nv84_fence_create(struct nouveau_drm *drm)
ret = nouveau_bo_new(drm->dev, 16 * priv->base.contexts, 0,
TTM_PL_FLAG_VRAM, 0, 0, NULL, NULL, &priv->bo);
if (ret == 0) {
ret = nouveau_bo_pin(priv->bo, TTM_PL_FLAG_VRAM);
ret = nouveau_bo_pin(priv->bo, TTM_PL_FLAG_VRAM, false);
if (ret == 0) {
ret = nouveau_bo_map(priv->bo);
if (ret)
Expand All @@ -249,7 +249,7 @@ nv84_fence_create(struct nouveau_drm *drm)
TTM_PL_FLAG_TT | TTM_PL_FLAG_UNCACHED, 0,
0, NULL, NULL, &priv->bo_gart);
if (ret == 0) {
ret = nouveau_bo_pin(priv->bo_gart, TTM_PL_FLAG_TT);
ret = nouveau_bo_pin(priv->bo_gart, TTM_PL_FLAG_TT, false);
if (ret == 0) {
ret = nouveau_bo_map(priv->bo_gart);
if (ret)
Expand Down

0 comments on commit ad76b3f

Please sign in to comment.