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

Merge tag 'drm-misc-next-2019-10-31' of git://anongit.freedesktop.org/drm/drm-misc into drm-next

drm-misc-next for 5.5:

UAPI Changes:
-dma-buf: Introduce and revert dma-buf heap (Andrew/John/Sean)

Cross-subsystem Changes:
- None

Core Changes:
-dma-buf: add dynamic mapping to allow exporters to choose dma_resv lock
state on mmap/munmap (Christian)
-vram: add prepare/cleanup fb helpers to vram helpers (Thomas)
-ttm: always keep bo's on the lru + ttm cleanups (Christian)
-sched: allow a free_job routine to sleep (Steven)
-fb_helper: remove unused drm_fb_helper_defio_init() (Thomas)

Driver Changes:
-bochs/hibmc/vboxvideo: Use new vram helpers for prepare/cleanup fb (Thomas)
-amdgpu: Implement dma-buf import/export without drm helpers (Christian)
-panfrost: Simplify devfreq integration in driver (Steven)

Cc: Christian König <christian.koenig@amd.com>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: Steven Price <steven.price@arm.com>
Cc: Andrew F. Davis <afd@ti.com>
Cc: John Stultz <john.stultz@linaro.org>
Cc: Sean Paul <seanpaul@chromium.org>
Signed-off-by: Dave Airlie <airlied@redhat.com>

From: Sean Paul <sean@poorly.run>
Link: https://patchwork.freedesktop.org/patch/msgid/20191031193015.GA243509@art_vandelay

+710 -734
+3 -3
Documentation/driver-api/dma-buf.rst
··· 118 118 Reservation Objects 119 119 ------------------- 120 120 121 - .. kernel-doc:: drivers/dma-buf/reservation.c 121 + .. kernel-doc:: drivers/dma-buf/dma-resv.c 122 122 :doc: Reservation Object Overview 123 123 124 - .. kernel-doc:: drivers/dma-buf/reservation.c 124 + .. kernel-doc:: drivers/dma-buf/dma-resv.c 125 125 :export: 126 126 127 - .. kernel-doc:: include/linux/reservation.h 127 + .. kernel-doc:: include/linux/dma-resv.h 128 128 :internal: 129 129 130 130 DMA Fences
+4 -4
Documentation/gpu/todo.rst
··· 206 206 --------------------------- 207 207 208 208 The defio support code in the fbdev core has some very specific requirements, 209 - which means drivers need to have a special framebuffer for fbdev. Which prevents 210 - us from using the generic fbdev emulation code everywhere. The main issue is 211 - that it uses some fields in struct page itself, which breaks shmem gem objects 212 - (and other things). 209 + which means drivers need to have a special framebuffer for fbdev. The main 210 + issue is that it uses some fields in struct page itself, which breaks shmem 211 + gem objects (and other things). To support defio, affected drivers require 212 + the use of a shadow buffer, which may add CPU and memory overhead. 213 213 214 214 Possible solution would be to write our own defio mmap code in the drm fbdev 215 215 emulation. It would need to fully wrap the existing mmap ops, forwarding
+95 -25
drivers/dma-buf/dma-buf.c
··· 45 45 size_t ret = 0; 46 46 47 47 dmabuf = dentry->d_fsdata; 48 - mutex_lock(&dmabuf->lock); 48 + dma_resv_lock(dmabuf->resv, NULL); 49 49 if (dmabuf->name) 50 50 ret = strlcpy(name, dmabuf->name, DMA_BUF_NAME_LEN); 51 - mutex_unlock(&dmabuf->lock); 51 + dma_resv_unlock(dmabuf->resv); 52 52 53 53 return dynamic_dname(dentry, buffer, buflen, "/%s:%s", 54 54 dentry->d_name.name, ret > 0 ? name : ""); ··· 334 334 if (IS_ERR(name)) 335 335 return PTR_ERR(name); 336 336 337 - mutex_lock(&dmabuf->lock); 337 + dma_resv_lock(dmabuf->resv, NULL); 338 338 if (!list_empty(&dmabuf->attachments)) { 339 339 ret = -EBUSY; 340 340 kfree(name); ··· 344 344 dmabuf->name = name; 345 345 346 346 out_unlock: 347 - mutex_unlock(&dmabuf->lock); 347 + dma_resv_unlock(dmabuf->resv); 348 348 return ret; 349 349 } 350 350 ··· 403 403 /* Don't count the temporary reference taken inside procfs seq_show */ 404 404 seq_printf(m, "count:\t%ld\n", file_count(dmabuf->file) - 1); 405 405 seq_printf(m, "exp_name:\t%s\n", dmabuf->exp_name); 406 - mutex_lock(&dmabuf->lock); 406 + dma_resv_lock(dmabuf->resv, NULL); 407 407 if (dmabuf->name) 408 408 seq_printf(m, "name:\t%s\n", dmabuf->name); 409 - mutex_unlock(&dmabuf->lock); 409 + dma_resv_unlock(dmabuf->resv); 410 410 } 411 411 412 412 static const struct file_operations dma_buf_fops = { ··· 524 524 || !exp_info->ops->release)) { 525 525 return ERR_PTR(-EINVAL); 526 526 } 527 + 528 + if (WARN_ON(exp_info->ops->cache_sgt_mapping && 529 + exp_info->ops->dynamic_mapping)) 530 + return ERR_PTR(-EINVAL); 527 531 528 532 if (!try_module_get(exp_info->owner)) 529 533 return ERR_PTR(-ENOENT); ··· 649 645 EXPORT_SYMBOL_GPL(dma_buf_put); 650 646 651 647 /** 652 - * dma_buf_attach - Add the device to dma_buf's attachments list; optionally, 648 + * dma_buf_dynamic_attach - Add the device to dma_buf's attachments list; optionally, 653 649 * calls attach() of dma_buf_ops to allow device-specific attach functionality 654 - * @dmabuf: [in] buffer to attach device to. 655 - * @dev: [in] device to be attached. 650 + * @dmabuf: [in] buffer to attach device to. 651 + * @dev: [in] device to be attached. 652 + * @dynamic_mapping: [in] calling convention for map/unmap 656 653 * 657 654 * Returns struct dma_buf_attachment pointer for this attachment. Attachments 658 655 * must be cleaned up by calling dma_buf_detach(). ··· 667 662 * accessible to @dev, and cannot be moved to a more suitable place. This is 668 663 * indicated with the error code -EBUSY. 669 664 */ 670 - struct dma_buf_attachment *dma_buf_attach(struct dma_buf *dmabuf, 671 - struct device *dev) 665 + struct dma_buf_attachment * 666 + dma_buf_dynamic_attach(struct dma_buf *dmabuf, struct device *dev, 667 + bool dynamic_mapping) 672 668 { 673 669 struct dma_buf_attachment *attach; 674 670 int ret; ··· 683 677 684 678 attach->dev = dev; 685 679 attach->dmabuf = dmabuf; 686 - 687 - mutex_lock(&dmabuf->lock); 680 + attach->dynamic_mapping = dynamic_mapping; 688 681 689 682 if (dmabuf->ops->attach) { 690 683 ret = dmabuf->ops->attach(dmabuf, attach); 691 684 if (ret) 692 685 goto err_attach; 693 686 } 687 + dma_resv_lock(dmabuf->resv, NULL); 694 688 list_add(&attach->node, &dmabuf->attachments); 689 + dma_resv_unlock(dmabuf->resv); 695 690 696 - mutex_unlock(&dmabuf->lock); 691 + /* When either the importer or the exporter can't handle dynamic 692 + * mappings we cache the mapping here to avoid issues with the 693 + * reservation object lock. 694 + */ 695 + if (dma_buf_attachment_is_dynamic(attach) != 696 + dma_buf_is_dynamic(dmabuf)) { 697 + struct sg_table *sgt; 698 + 699 + if (dma_buf_is_dynamic(attach->dmabuf)) 700 + dma_resv_lock(attach->dmabuf->resv, NULL); 701 + 702 + sgt = dmabuf->ops->map_dma_buf(attach, DMA_BIDIRECTIONAL); 703 + if (!sgt) 704 + sgt = ERR_PTR(-ENOMEM); 705 + if (IS_ERR(sgt)) { 706 + ret = PTR_ERR(sgt); 707 + goto err_unlock; 708 + } 709 + if (dma_buf_is_dynamic(attach->dmabuf)) 710 + dma_resv_unlock(attach->dmabuf->resv); 711 + attach->sgt = sgt; 712 + attach->dir = DMA_BIDIRECTIONAL; 713 + } 697 714 698 715 return attach; 699 716 700 717 err_attach: 701 718 kfree(attach); 702 - mutex_unlock(&dmabuf->lock); 703 719 return ERR_PTR(ret); 720 + 721 + err_unlock: 722 + if (dma_buf_is_dynamic(attach->dmabuf)) 723 + dma_resv_unlock(attach->dmabuf->resv); 724 + 725 + dma_buf_detach(dmabuf, attach); 726 + return ERR_PTR(ret); 727 + } 728 + EXPORT_SYMBOL_GPL(dma_buf_dynamic_attach); 729 + 730 + /** 731 + * dma_buf_attach - Wrapper for dma_buf_dynamic_attach 732 + * @dmabuf: [in] buffer to attach device to. 733 + * @dev: [in] device to be attached. 734 + * 735 + * Wrapper to call dma_buf_dynamic_attach() for drivers which still use a static 736 + * mapping. 737 + */ 738 + struct dma_buf_attachment *dma_buf_attach(struct dma_buf *dmabuf, 739 + struct device *dev) 740 + { 741 + return dma_buf_dynamic_attach(dmabuf, dev, false); 704 742 } 705 743 EXPORT_SYMBOL_GPL(dma_buf_attach); 706 744 ··· 761 711 if (WARN_ON(!dmabuf || !attach)) 762 712 return; 763 713 764 - if (attach->sgt) 714 + if (attach->sgt) { 715 + if (dma_buf_is_dynamic(attach->dmabuf)) 716 + dma_resv_lock(attach->dmabuf->resv, NULL); 717 + 765 718 dmabuf->ops->unmap_dma_buf(attach, attach->sgt, attach->dir); 766 719 767 - mutex_lock(&dmabuf->lock); 720 + if (dma_buf_is_dynamic(attach->dmabuf)) 721 + dma_resv_unlock(attach->dmabuf->resv); 722 + } 723 + 724 + dma_resv_lock(dmabuf->resv, NULL); 768 725 list_del(&attach->node); 726 + dma_resv_unlock(dmabuf->resv); 769 727 if (dmabuf->ops->detach) 770 728 dmabuf->ops->detach(dmabuf, attach); 771 729 772 - mutex_unlock(&dmabuf->lock); 773 730 kfree(attach); 774 731 } 775 732 EXPORT_SYMBOL_GPL(dma_buf_detach); ··· 806 749 if (WARN_ON(!attach || !attach->dmabuf)) 807 750 return ERR_PTR(-EINVAL); 808 751 752 + if (dma_buf_attachment_is_dynamic(attach)) 753 + dma_resv_assert_held(attach->dmabuf->resv); 754 + 809 755 if (attach->sgt) { 810 756 /* 811 757 * Two mappings with different directions for the same ··· 820 760 821 761 return attach->sgt; 822 762 } 763 + 764 + if (dma_buf_is_dynamic(attach->dmabuf)) 765 + dma_resv_assert_held(attach->dmabuf->resv); 823 766 824 767 sg_table = attach->dmabuf->ops->map_dma_buf(attach, direction); 825 768 if (!sg_table) ··· 856 793 if (WARN_ON(!attach || !attach->dmabuf || !sg_table)) 857 794 return; 858 795 796 + if (dma_buf_attachment_is_dynamic(attach)) 797 + dma_resv_assert_held(attach->dmabuf->resv); 798 + 859 799 if (attach->sgt == sg_table) 860 800 return; 801 + 802 + if (dma_buf_is_dynamic(attach->dmabuf)) 803 + dma_resv_assert_held(attach->dmabuf->resv); 861 804 862 805 attach->dmabuf->ops->unmap_dma_buf(attach, sg_table, direction); 863 806 } ··· 1240 1171 "size", "flags", "mode", "count", "ino"); 1241 1172 1242 1173 list_for_each_entry(buf_obj, &db_list.head, list_node) { 1243 - ret = mutex_lock_interruptible(&buf_obj->lock); 1244 1174 1245 - if (ret) { 1246 - seq_puts(s, 1247 - "\tERROR locking buffer object: skipping\n"); 1248 - continue; 1249 - } 1175 + ret = dma_resv_lock_interruptible(buf_obj->resv, NULL); 1176 + if (ret) 1177 + goto error_unlock; 1250 1178 1251 1179 seq_printf(s, "%08zu\t%08x\t%08x\t%08ld\t%s\t%08lu\t%s\n", 1252 1180 buf_obj->size, ··· 1289 1223 seq_printf(s, "\t%s\n", dev_name(attach_obj->dev)); 1290 1224 attach_count++; 1291 1225 } 1226 + dma_resv_unlock(buf_obj->resv); 1292 1227 1293 1228 seq_printf(s, "Total %d devices attached\n\n", 1294 1229 attach_count); 1295 1230 1296 1231 count++; 1297 1232 size += buf_obj->size; 1298 - mutex_unlock(&buf_obj->lock); 1299 1233 } 1300 1234 1301 1235 seq_printf(s, "\nTotal %d objects, %zu bytes\n", count, size); 1302 1236 1303 1237 mutex_unlock(&db_list.lock); 1304 1238 return 0; 1239 + 1240 + error_unlock: 1241 + mutex_unlock(&db_list.lock); 1242 + return ret; 1305 1243 } 1306 1244 1307 1245 DEFINE_SHOW_ATTRIBUTE(dma_buf_debug);
+4 -5
drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
··· 613 613 amdgpu_vm_get_pd_bo(vm, &ctx->list, &ctx->vm_pd[0]); 614 614 615 615 ret = ttm_eu_reserve_buffers(&ctx->ticket, &ctx->list, 616 - false, &ctx->duplicates, true); 616 + false, &ctx->duplicates); 617 617 if (!ret) 618 618 ctx->reserved = true; 619 619 else { ··· 686 686 } 687 687 688 688 ret = ttm_eu_reserve_buffers(&ctx->ticket, &ctx->list, 689 - false, &ctx->duplicates, true); 689 + false, &ctx->duplicates); 690 690 if (!ret) 691 691 ctx->reserved = true; 692 692 else ··· 1805 1805 } 1806 1806 1807 1807 /* Reserve all BOs and page tables for validation */ 1808 - ret = ttm_eu_reserve_buffers(&ticket, &resv_list, false, &duplicates, 1809 - true); 1808 + ret = ttm_eu_reserve_buffers(&ticket, &resv_list, false, &duplicates); 1810 1809 WARN(!list_empty(&duplicates), "Duplicates should be empty"); 1811 1810 if (ret) 1812 1811 goto out_free; ··· 2003 2004 } 2004 2005 2005 2006 ret = ttm_eu_reserve_buffers(&ctx.ticket, &ctx.list, 2006 - false, &duplicate_save, true); 2007 + false, &duplicate_save); 2007 2008 if (ret) { 2008 2009 pr_debug("Memory eviction: TTM Reserve Failed. Try again\n"); 2009 2010 goto ttm_reserve_fail;
+1 -1
drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
··· 581 581 } 582 582 583 583 r = ttm_eu_reserve_buffers(&p->ticket, &p->validated, true, 584 - &duplicates, false); 584 + &duplicates); 585 585 if (unlikely(r != 0)) { 586 586 if (r != -ERESTARTSYS) 587 587 DRM_ERROR("ttm_eu_reserve_buffers failed.\n");
+1 -1
drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c
··· 80 80 list_add(&csa_tv.head, &list); 81 81 amdgpu_vm_get_pd_bo(vm, &list, &pd); 82 82 83 - r = ttm_eu_reserve_buffers(&ticket, &list, true, NULL, false); 83 + r = ttm_eu_reserve_buffers(&ticket, &list, true, NULL); 84 84 if (r) { 85 85 DRM_ERROR("failed to reserve CSA,PD BOs: err=%d\n", r); 86 86 return r;
+122 -95
drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
··· 34 34 #include "amdgpu.h" 35 35 #include "amdgpu_display.h" 36 36 #include "amdgpu_gem.h" 37 + #include "amdgpu_dma_buf.h" 37 38 #include <drm/amdgpu_drm.h> 38 39 #include <linux/dma-buf.h> 39 40 #include <linux/dma-fence-array.h> 40 - 41 - /** 42 - * amdgpu_gem_prime_get_sg_table - &drm_driver.gem_prime_get_sg_table 43 - * implementation 44 - * @obj: GEM buffer object (BO) 45 - * 46 - * Returns: 47 - * A scatter/gather table for the pinned pages of the BO's memory. 48 - */ 49 - struct sg_table *amdgpu_gem_prime_get_sg_table(struct drm_gem_object *obj) 50 - { 51 - struct amdgpu_bo *bo = gem_to_amdgpu_bo(obj); 52 - int npages = bo->tbo.num_pages; 53 - 54 - return drm_prime_pages_to_sg(bo->tbo.ttm->pages, npages); 55 - } 56 41 57 42 /** 58 43 * amdgpu_gem_prime_vmap - &dma_buf_ops.vmap implementation ··· 164 179 } 165 180 166 181 /** 167 - * amdgpu_dma_buf_map_attach - &dma_buf_ops.attach implementation 168 - * @dma_buf: Shared DMA buffer 182 + * amdgpu_dma_buf_attach - &dma_buf_ops.attach implementation 183 + * 184 + * @dmabuf: DMA-buf where we attach to 185 + * @attach: attachment to add 186 + * 187 + * Add the attachment as user to the exported DMA-buf. 188 + */ 189 + static int amdgpu_dma_buf_attach(struct dma_buf *dmabuf, 190 + struct dma_buf_attachment *attach) 191 + { 192 + struct drm_gem_object *obj = dmabuf->priv; 193 + struct amdgpu_bo *bo = gem_to_amdgpu_bo(obj); 194 + struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev); 195 + int r; 196 + 197 + if (attach->dev->driver == adev->dev->driver) 198 + return 0; 199 + 200 + r = amdgpu_bo_reserve(bo, false); 201 + if (unlikely(r != 0)) 202 + return r; 203 + 204 + /* 205 + * We only create shared fences for internal use, but importers 206 + * of the dmabuf rely on exclusive fences for implicitly 207 + * tracking write hazards. As any of the current fences may 208 + * correspond to a write, we need to convert all existing 209 + * fences on the reservation object into a single exclusive 210 + * fence. 211 + */ 212 + r = __dma_resv_make_exclusive(bo->tbo.base.resv); 213 + if (r) 214 + return r; 215 + 216 + bo->prime_shared_count++; 217 + amdgpu_bo_unreserve(bo); 218 + return 0; 219 + } 220 + 221 + /** 222 + * amdgpu_dma_buf_detach - &dma_buf_ops.detach implementation 223 + * 224 + * @dmabuf: DMA-buf where we remove the attachment from 225 + * @attach: the attachment to remove 226 + * 227 + * Called when an attachment is removed from the DMA-buf. 228 + */ 229 + static void amdgpu_dma_buf_detach(struct dma_buf *dmabuf, 230 + struct dma_buf_attachment *attach) 231 + { 232 + struct drm_gem_object *obj = dmabuf->priv; 233 + struct amdgpu_bo *bo = gem_to_amdgpu_bo(obj); 234 + struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev); 235 + 236 + if (attach->dev->driver != adev->dev->driver && bo->prime_shared_count) 237 + bo->prime_shared_count--; 238 + } 239 + 240 + /** 241 + * amdgpu_dma_buf_map - &dma_buf_ops.map_dma_buf implementation 169 242 * @attach: DMA-buf attachment 243 + * @dir: DMA direction 170 244 * 171 245 * Makes sure that the shared DMA buffer can be accessed by the target device. 172 246 * For now, simply pins it to the GTT domain, where it should be accessible by 173 247 * all DMA devices. 174 248 * 175 249 * Returns: 176 - * 0 on success or a negative error code on failure. 250 + * sg_table filled with the DMA addresses to use or ERR_PRT with negative error 251 + * code. 177 252 */ 178 - static int amdgpu_dma_buf_map_attach(struct dma_buf *dma_buf, 179 - struct dma_buf_attachment *attach) 253 + static struct sg_table *amdgpu_dma_buf_map(struct dma_buf_attachment *attach, 254 + enum dma_data_direction dir) 180 255 { 256 + struct dma_buf *dma_buf = attach->dmabuf; 181 257 struct drm_gem_object *obj = dma_buf->priv; 182 258 struct amdgpu_bo *bo = gem_to_amdgpu_bo(obj); 183 - struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev); 259 + struct sg_table *sgt; 184 260 long r; 185 261 186 - r = drm_gem_map_attach(dma_buf, attach); 187 - if (r) 188 - return r; 189 - 190 - r = amdgpu_bo_reserve(bo, false); 191 - if (unlikely(r != 0)) 192 - goto error_detach; 193 - 194 - 195 - if (attach->dev->driver != adev->dev->driver) { 196 - /* 197 - * We only create shared fences for internal use, but importers 198 - * of the dmabuf rely on exclusive fences for implicitly 199 - * tracking write hazards. As any of the current fences may 200 - * correspond to a write, we need to convert all existing 201 - * fences on the reservation object into a single exclusive 202 - * fence. 203 - */ 204 - r = __dma_resv_make_exclusive(bo->tbo.base.resv); 205 - if (r) 206 - goto error_unreserve; 207 - } 208 - 209 - /* pin buffer into GTT */ 210 262 r = amdgpu_bo_pin(bo, AMDGPU_GEM_DOMAIN_GTT); 211 263 if (r) 212 - goto error_unreserve; 264 + return ERR_PTR(r); 213 265 214 - if (attach->dev->driver != adev->dev->driver) 215 - bo->prime_shared_count++; 266 + sgt = drm_prime_pages_to_sg(bo->tbo.ttm->pages, bo->tbo.num_pages); 267 + if (IS_ERR(sgt)) 268 + return sgt; 216 269 217 - error_unreserve: 218 - amdgpu_bo_unreserve(bo); 270 + if (!dma_map_sg_attrs(attach->dev, sgt->sgl, sgt->nents, dir, 271 + DMA_ATTR_SKIP_CPU_SYNC)) 272 + goto error_free; 219 273 220 - error_detach: 221 - if (r) 222 - drm_gem_map_detach(dma_buf, attach); 223 - return r; 274 + return sgt; 275 + 276 + error_free: 277 + sg_free_table(sgt); 278 + kfree(sgt); 279 + return ERR_PTR(-ENOMEM); 224 280 } 225 281 226 282 /** 227 - * amdgpu_dma_buf_map_detach - &dma_buf_ops.detach implementation 228 - * @dma_buf: Shared DMA buffer 283 + * amdgpu_dma_buf_unmap - &dma_buf_ops.unmap_dma_buf implementation 229 284 * @attach: DMA-buf attachment 285 + * @sgt: sg_table to unmap 286 + * @dir: DMA direction 230 287 * 231 288 * This is called when a shared DMA buffer no longer needs to be accessible by 232 289 * another device. For now, simply unpins the buffer from GTT. 233 290 */ 234 - static void amdgpu_dma_buf_map_detach(struct dma_buf *dma_buf, 235 - struct dma_buf_attachment *attach) 291 + static void amdgpu_dma_buf_unmap(struct dma_buf_attachment *attach, 292 + struct sg_table *sgt, 293 + enum dma_data_direction dir) 236 294 { 237 - struct drm_gem_object *obj = dma_buf->priv; 295 + struct drm_gem_object *obj = attach->dmabuf->priv; 238 296 struct amdgpu_bo *bo = gem_to_amdgpu_bo(obj); 239 - struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev); 240 - int ret = 0; 241 297 242 - ret = amdgpu_bo_reserve(bo, true); 243 - if (unlikely(ret != 0)) 244 - goto error; 245 - 298 + dma_unmap_sg(attach->dev, sgt->sgl, sgt->nents, dir); 299 + sg_free_table(sgt); 300 + kfree(sgt); 246 301 amdgpu_bo_unpin(bo); 247 - if (attach->dev->driver != adev->dev->driver && bo->prime_shared_count) 248 - bo->prime_shared_count--; 249 - amdgpu_bo_unreserve(bo); 250 - 251 - error: 252 - drm_gem_map_detach(dma_buf, attach); 253 302 } 254 303 255 304 /** ··· 327 308 } 328 309 329 310 const struct dma_buf_ops amdgpu_dmabuf_ops = { 330 - .attach = amdgpu_dma_buf_map_attach, 331 - .detach = amdgpu_dma_buf_map_detach, 332 - .map_dma_buf = drm_gem_map_dma_buf, 333 - .unmap_dma_buf = drm_gem_unmap_dma_buf, 311 + .dynamic_mapping = true, 312 + .attach = amdgpu_dma_buf_attach, 313 + .detach = amdgpu_dma_buf_detach, 314 + .map_dma_buf = amdgpu_dma_buf_map, 315 + .unmap_dma_buf = amdgpu_dma_buf_unmap, 334 316 .release = drm_gem_dmabuf_release, 335 317 .begin_cpu_access = amdgpu_dma_buf_begin_cpu_access, 336 318 .mmap = drm_gem_dmabuf_mmap, ··· 369 349 } 370 350 371 351 /** 372 - * amdgpu_gem_prime_import_sg_table - &drm_driver.gem_prime_import_sg_table 373 - * implementation 374 - * @dev: DRM device 375 - * @attach: DMA-buf attachment 376 - * @sg: Scatter/gather table 352 + * amdgpu_dma_buf_create_obj - create BO for DMA-buf import 377 353 * 378 - * Imports shared DMA buffer memory exported by another device. 354 + * @dev: DRM device 355 + * @dma_buf: DMA-buf 356 + * 357 + * Creates an empty SG BO for DMA-buf import. 379 358 * 380 359 * Returns: 381 360 * A new GEM BO of the given DRM device, representing the memory 382 361 * described by the given DMA-buf attachment and scatter/gather table. 383 362 */ 384 - struct drm_gem_object * 385 - amdgpu_gem_prime_import_sg_table(struct drm_device *dev, 386 - struct dma_buf_attachment *attach, 387 - struct sg_table *sg) 363 + static struct drm_gem_object * 364 + amdgpu_dma_buf_create_obj(struct drm_device *dev, struct dma_buf *dma_buf) 388 365 { 389 - struct dma_resv *resv = attach->dmabuf->resv; 366 + struct dma_resv *resv = dma_buf->resv; 390 367 struct amdgpu_device *adev = dev->dev_private; 391 368 struct amdgpu_bo *bo; 392 369 struct amdgpu_bo_param bp; 393 370 int ret; 394 371 395 372 memset(&bp, 0, sizeof(bp)); 396 - bp.size = attach->dmabuf->size; 373 + bp.size = dma_buf->size; 397 374 bp.byte_align = PAGE_SIZE; 398 375 bp.domain = AMDGPU_GEM_DOMAIN_CPU; 399 376 bp.flags = 0; ··· 401 384 if (ret) 402 385 goto error; 403 386 404 - bo->tbo.sg = sg; 405 - bo->tbo.ttm->sg = sg; 406 387 bo->allowed_domains = AMDGPU_GEM_DOMAIN_GTT; 407 388 bo->preferred_domains = AMDGPU_GEM_DOMAIN_GTT; 408 - if (attach->dmabuf->ops != &amdgpu_dmabuf_ops) 389 + if (dma_buf->ops != &amdgpu_dmabuf_ops) 409 390 bo->prime_shared_count = 1; 410 391 411 392 dma_resv_unlock(resv); ··· 419 404 * @dev: DRM device 420 405 * @dma_buf: Shared DMA buffer 421 406 * 422 - * The main work is done by the &drm_gem_prime_import helper, which in turn 423 - * uses &amdgpu_gem_prime_import_sg_table. 407 + * Import a dma_buf into a the driver and potentially create a new GEM object. 424 408 * 425 409 * Returns: 426 410 * GEM BO representing the shared DMA buffer for the given device. 427 411 */ 428 412 struct drm_gem_object *amdgpu_gem_prime_import(struct drm_device *dev, 429 - struct dma_buf *dma_buf) 413 + struct dma_buf *dma_buf) 430 414 { 415 + struct dma_buf_attachment *attach; 431 416 struct drm_gem_object *obj; 432 417 433 418 if (dma_buf->ops == &amdgpu_dmabuf_ops) { ··· 442 427 } 443 428 } 444 429 445 - return drm_gem_prime_import(dev, dma_buf); 430 + obj = amdgpu_dma_buf_create_obj(dev, dma_buf); 431 + if (IS_ERR(obj)) 432 + return obj; 433 + 434 + attach = dma_buf_dynamic_attach(dma_buf, dev->dev, true); 435 + if (IS_ERR(attach)) { 436 + drm_gem_object_put(obj); 437 + return ERR_CAST(attach); 438 + } 439 + 440 + get_dma_buf(dma_buf); 441 + obj->import_attach = attach; 442 + return obj; 446 443 }
-5
drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.h
··· 25 25 26 26 #include <drm/drm_gem.h> 27 27 28 - struct sg_table *amdgpu_gem_prime_get_sg_table(struct drm_gem_object *obj); 29 - struct drm_gem_object * 30 - amdgpu_gem_prime_import_sg_table(struct drm_device *dev, 31 - struct dma_buf_attachment *attach, 32 - struct sg_table *sg); 33 28 struct dma_buf *amdgpu_gem_prime_export(struct drm_gem_object *gobj, 34 29 int flags); 35 30 struct drm_gem_object *amdgpu_gem_prime_import(struct drm_device *dev,
-2
drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
··· 1381 1381 .prime_fd_to_handle = drm_gem_prime_fd_to_handle, 1382 1382 .gem_prime_export = amdgpu_gem_prime_export, 1383 1383 .gem_prime_import = amdgpu_gem_prime_import, 1384 - .gem_prime_get_sg_table = amdgpu_gem_prime_get_sg_table, 1385 - .gem_prime_import_sg_table = amdgpu_gem_prime_import_sg_table, 1386 1384 .gem_prime_vmap = amdgpu_gem_prime_vmap, 1387 1385 .gem_prime_vunmap = amdgpu_gem_prime_vunmap, 1388 1386 .gem_prime_mmap = amdgpu_gem_prime_mmap,
+1 -1
drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c
··· 71 71 */ 72 72 static int amdgpu_gart_dummy_page_init(struct amdgpu_device *adev) 73 73 { 74 - struct page *dummy_page = adev->mman.bdev.glob->dummy_read_page; 74 + struct page *dummy_page = ttm_bo_glob.dummy_read_page; 75 75 76 76 if (adev->dummy_page_addr) 77 77 return 0;
+2 -2
drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
··· 175 175 176 176 amdgpu_vm_get_pd_bo(vm, &list, &vm_pd); 177 177 178 - r = ttm_eu_reserve_buffers(&ticket, &list, false, &duplicates, false); 178 + r = ttm_eu_reserve_buffers(&ticket, &list, false, &duplicates); 179 179 if (r) { 180 180 dev_err(adev->dev, "leaking bo va because " 181 181 "we fail to reserve bo (%d)\n", r); ··· 641 641 642 642 amdgpu_vm_get_pd_bo(&fpriv->vm, &list, &vm_pd); 643 643 644 - r = ttm_eu_reserve_buffers(&ticket, &list, true, &duplicates, false); 644 + r = ttm_eu_reserve_buffers(&ticket, &list, true, &duplicates); 645 645 if (r) 646 646 goto error_unref; 647 647
+27 -5
drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
··· 39 39 #include <linux/slab.h> 40 40 #include <linux/swap.h> 41 41 #include <linux/swiotlb.h> 42 + #include <linux/dma-buf.h> 42 43 43 44 #include <drm/ttm/ttm_bo_api.h> 44 45 #include <drm/ttm/ttm_bo_driver.h> ··· 765 764 */ 766 765 struct amdgpu_ttm_tt { 767 766 struct ttm_dma_tt ttm; 767 + struct drm_gem_object *gobj; 768 768 u64 offset; 769 769 uint64_t userptr; 770 770 struct task_struct *usertask; ··· 1230 1228 return NULL; 1231 1229 } 1232 1230 gtt->ttm.ttm.func = &amdgpu_backend_func; 1231 + gtt->gobj = &bo->base; 1233 1232 1234 1233 /* allocate space for the uninitialized page entries */ 1235 1234 if (ttm_sg_tt_init(&gtt->ttm, bo, page_flags)) { ··· 1251 1248 { 1252 1249 struct amdgpu_device *adev = amdgpu_ttm_adev(ttm->bdev); 1253 1250 struct amdgpu_ttm_tt *gtt = (void *)ttm; 1254 - bool slave = !!(ttm->page_flags & TTM_PAGE_FLAG_SG); 1255 1251 1256 1252 /* user pages are bound by amdgpu_ttm_tt_pin_userptr() */ 1257 1253 if (gtt && gtt->userptr) { ··· 1263 1261 return 0; 1264 1262 } 1265 1263 1266 - if (slave && ttm->sg) { 1264 + if (ttm->page_flags & TTM_PAGE_FLAG_SG) { 1265 + if (!ttm->sg) { 1266 + struct dma_buf_attachment *attach; 1267 + struct sg_table *sgt; 1268 + 1269 + attach = gtt->gobj->import_attach; 1270 + sgt = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL); 1271 + if (IS_ERR(sgt)) 1272 + return PTR_ERR(sgt); 1273 + 1274 + ttm->sg = sgt; 1275 + } 1276 + 1267 1277 drm_prime_sg_to_page_addr_arrays(ttm->sg, ttm->pages, 1268 1278 gtt->ttm.dma_address, 1269 1279 ttm->num_pages); ··· 1302 1288 */ 1303 1289 static void amdgpu_ttm_tt_unpopulate(struct ttm_tt *ttm) 1304 1290 { 1305 - struct amdgpu_device *adev; 1306 1291 struct amdgpu_ttm_tt *gtt = (void *)ttm; 1307 - bool slave = !!(ttm->page_flags & TTM_PAGE_FLAG_SG); 1292 + struct amdgpu_device *adev; 1308 1293 1309 1294 if (gtt && gtt->userptr) { 1310 1295 amdgpu_ttm_tt_set_user_pages(ttm, NULL); ··· 1312 1299 return; 1313 1300 } 1314 1301 1315 - if (slave) 1302 + if (ttm->sg && gtt->gobj->import_attach) { 1303 + struct dma_buf_attachment *attach; 1304 + 1305 + attach = gtt->gobj->import_attach; 1306 + dma_buf_unmap_attachment(attach, ttm->sg, DMA_BIDIRECTIONAL); 1307 + ttm->sg = NULL; 1308 + return; 1309 + } 1310 + 1311 + if (ttm->page_flags & TTM_PAGE_FLAG_SG) 1316 1312 return; 1317 1313 1318 1314 adev = amdgpu_ttm_adev(ttm->bdev);
+4 -5
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
··· 610 610 void amdgpu_vm_move_to_lru_tail(struct amdgpu_device *adev, 611 611 struct amdgpu_vm *vm) 612 612 { 613 - struct ttm_bo_global *glob = adev->mman.bdev.glob; 614 613 struct amdgpu_vm_bo_base *bo_base; 615 614 616 615 if (vm->bulk_moveable) { 617 - spin_lock(&glob->lru_lock); 616 + spin_lock(&ttm_bo_glob.lru_lock); 618 617 ttm_bo_bulk_move_lru_tail(&vm->lru_bulk_move); 619 - spin_unlock(&glob->lru_lock); 618 + spin_unlock(&ttm_bo_glob.lru_lock); 620 619 return; 621 620 } 622 621 623 622 memset(&vm->lru_bulk_move, 0, sizeof(vm->lru_bulk_move)); 624 623 625 - spin_lock(&glob->lru_lock); 624 + spin_lock(&ttm_bo_glob.lru_lock); 626 625 list_for_each_entry(bo_base, &vm->idle, vm_status) { 627 626 struct amdgpu_bo *bo = bo_base->bo; 628 627 ··· 633 634 ttm_bo_move_to_lru_tail(&bo->shadow->tbo, 634 635 &vm->lru_bulk_move); 635 636 } 636 - spin_unlock(&glob->lru_lock); 637 + spin_unlock(&ttm_bo_glob.lru_lock); 637 638 638 639 vm->bulk_moveable = true; 639 640 }
+1 -1
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
··· 4596 4596 tv.num_shared = 1; 4597 4597 list_add(&tv.head, &list); 4598 4598 4599 - r = ttm_eu_reserve_buffers(&ticket, &list, false, NULL, true); 4599 + r = ttm_eu_reserve_buffers(&ticket, &list, false, NULL); 4600 4600 if (r) { 4601 4601 dev_err(adev->dev, "fail to reserve bo (%d)\n", r); 4602 4602 return r;
+2 -24
drivers/gpu/drm/bochs/bochs_kms.c
··· 69 69 } 70 70 } 71 71 72 - static int bochs_pipe_prepare_fb(struct drm_simple_display_pipe *pipe, 73 - struct drm_plane_state *new_state) 74 - { 75 - struct drm_gem_vram_object *gbo; 76 - 77 - if (!new_state->fb) 78 - return 0; 79 - gbo = drm_gem_vram_of_gem(new_state->fb->obj[0]); 80 - return drm_gem_vram_pin(gbo, DRM_GEM_VRAM_PL_FLAG_VRAM); 81 - } 82 - 83 - static void bochs_pipe_cleanup_fb(struct drm_simple_display_pipe *pipe, 84 - struct drm_plane_state *old_state) 85 - { 86 - struct drm_gem_vram_object *gbo; 87 - 88 - if (!old_state->fb) 89 - return; 90 - gbo = drm_gem_vram_of_gem(old_state->fb->obj[0]); 91 - drm_gem_vram_unpin(gbo); 92 - } 93 - 94 72 static const struct drm_simple_display_pipe_funcs bochs_pipe_funcs = { 95 73 .enable = bochs_pipe_enable, 96 74 .update = bochs_pipe_update, 97 - .prepare_fb = bochs_pipe_prepare_fb, 98 - .cleanup_fb = bochs_pipe_cleanup_fb, 75 + .prepare_fb = drm_gem_vram_simple_display_pipe_prepare_fb, 76 + .cleanup_fb = drm_gem_vram_simple_display_pipe_cleanup_fb, 99 77 }; 100 78 101 79 static int bochs_connector_get_modes(struct drm_connector *connector)
+1 -1
drivers/gpu/drm/cirrus/cirrus.c
··· 390 390 /* ------------------------------------------------------------------ */ 391 391 /* cirrus (simple) display pipe */ 392 392 393 - static enum drm_mode_status cirrus_pipe_mode_valid(struct drm_crtc *crtc, 393 + static enum drm_mode_status cirrus_pipe_mode_valid(struct drm_simple_display_pipe *pipe, 394 394 const struct drm_display_mode *mode) 395 395 { 396 396 if (cirrus_check_size(mode->hdisplay, mode->vdisplay, NULL) < 0)
+8 -6
drivers/gpu/drm/drm_cache.c
··· 62 62 { 63 63 unsigned long i; 64 64 65 - mb(); 65 + mb(); /*Full memory barrier used before so that CLFLUSH is ordered*/ 66 66 for (i = 0; i < num_pages; i++) 67 67 drm_clflush_page(*pages++); 68 - mb(); 68 + mb(); /*Also used after CLFLUSH so that all cache is flushed*/ 69 69 } 70 70 #endif 71 71 ··· 92 92 93 93 #elif defined(__powerpc__) 94 94 unsigned long i; 95 + 95 96 for (i = 0; i < num_pages; i++) { 96 97 struct page *page = pages[i]; 97 98 void *page_virtual; ··· 126 125 if (static_cpu_has(X86_FEATURE_CLFLUSH)) { 127 126 struct sg_page_iter sg_iter; 128 127 129 - mb(); 128 + mb(); /*CLFLUSH is ordered only by using memory barriers*/ 130 129 for_each_sg_page(st->sgl, &sg_iter, st->nents, 0) 131 130 drm_clflush_page(sg_page_iter_page(&sg_iter)); 132 - mb(); 131 + mb(); /*Make sure that all cache line entry is flushed*/ 133 132 134 133 return; 135 134 } ··· 158 157 if (static_cpu_has(X86_FEATURE_CLFLUSH)) { 159 158 const int size = boot_cpu_data.x86_clflush_size; 160 159 void *end = addr + length; 160 + 161 161 addr = (void *)(((unsigned long)addr) & -size); 162 - mb(); 162 + mb(); /*CLFLUSH is only ordered with a full memory barrier*/ 163 163 for (; addr < end; addr += size) 164 164 clflushopt(addr); 165 165 clflushopt(end - 1); /* force serialisation */ 166 - mb(); 166 + mb(); /*Ensure that evry data cache line entry is flushed*/ 167 167 return; 168 168 } 169 169
+13 -48
drivers/gpu/drm/drm_fb_helper.c
··· 92 92 * 93 93 * Drivers that support a dumb buffer with a virtual address and mmap support, 94 94 * should try out the generic fbdev emulation using drm_fbdev_generic_setup(). 95 + * It will automatically set up deferred I/O if the driver requires a shadow 96 + * buffer. 95 97 * 96 - * Setup fbdev emulation by calling drm_fb_helper_fbdev_setup() and tear it 97 - * down by calling drm_fb_helper_fbdev_teardown(). 98 + * For other drivers, setup fbdev emulation by calling 99 + * drm_fb_helper_fbdev_setup() and tear it down by calling 100 + * drm_fb_helper_fbdev_teardown(). 98 101 * 99 102 * At runtime drivers should restore the fbdev console by using 100 103 * drm_fb_helper_lastclose() as their &drm_driver.lastclose callback. ··· 130 127 * always run in process context since the fb_*() function could be running in 131 128 * atomic context. If drm_fb_helper_deferred_io() is used as the deferred_io 132 129 * callback it will also schedule dirty_work with the damage collected from the 133 - * mmap page writes. Drivers can use drm_fb_helper_defio_init() to setup 134 - * deferred I/O (coupled with drm_fb_helper_fbdev_teardown()). 130 + * mmap page writes. 131 + * 132 + * Deferred I/O is not compatible with SHMEM. Such drivers should request an 133 + * fbdev shadow buffer and call drm_fbdev_generic_setup() instead. 135 134 */ 136 135 137 136 static void drm_fb_helper_restore_lut_atomic(struct drm_crtc *crtc) ··· 683 678 } 684 679 } 685 680 EXPORT_SYMBOL(drm_fb_helper_deferred_io); 686 - 687 - /** 688 - * drm_fb_helper_defio_init - fbdev deferred I/O initialization 689 - * @fb_helper: driver-allocated fbdev helper 690 - * 691 - * This function allocates &fb_deferred_io, sets callback to 692 - * drm_fb_helper_deferred_io(), delay to 50ms and calls fb_deferred_io_init(). 693 - * It should be called from the &drm_fb_helper_funcs->fb_probe callback. 694 - * drm_fb_helper_fbdev_teardown() cleans up deferred I/O. 695 - * 696 - * NOTE: A copy of &fb_ops is made and assigned to &info->fbops. This is done 697 - * because fb_deferred_io_cleanup() clears &fbops->fb_mmap and would thereby 698 - * affect other instances of that &fb_ops. 699 - * 700 - * Returns: 701 - * 0 on success or a negative error code on failure. 702 - */ 703 - int drm_fb_helper_defio_init(struct drm_fb_helper *fb_helper) 704 - { 705 - struct fb_info *info = fb_helper->fbdev; 706 - struct fb_deferred_io *fbdefio; 707 - struct fb_ops *fbops; 708 - 709 - fbdefio = kzalloc(sizeof(*fbdefio), GFP_KERNEL); 710 - fbops = kzalloc(sizeof(*fbops), GFP_KERNEL); 711 - if (!fbdefio || !fbops) { 712 - kfree(fbdefio); 713 - kfree(fbops); 714 - return -ENOMEM; 715 - } 716 - 717 - info->fbdefio = fbdefio; 718 - fbdefio->delay = msecs_to_jiffies(50); 719 - fbdefio->deferred_io = drm_fb_helper_deferred_io; 720 - 721 - *fbops = *info->fbops; 722 - info->fbops = fbops; 723 - 724 - fb_deferred_io_init(info); 725 - 726 - return 0; 727 - } 728 - EXPORT_SYMBOL(drm_fb_helper_defio_init); 729 681 730 682 /** 731 683 * drm_fb_helper_sys_read - wrapper around fb_sys_read ··· 2318 2356 * 2319 2357 * Drivers that set the dirty callback on their framebuffer will get a shadow 2320 2358 * fbdev buffer that is blitted onto the real buffer. This is done in order to 2321 - * make deferred I/O work with all kinds of buffers. 2359 + * make deferred I/O work with all kinds of buffers. A shadow buffer can be 2360 + * requested explicitly by setting struct drm_mode_config.prefer_shadow or 2361 + * struct drm_mode_config.prefer_shadow_fbdev to true beforehand. This is 2362 + * required to use generic fbdev emulation with SHMEM helpers. 2322 2363 * 2323 2364 * This function is safe to call even when there are no connectors present. 2324 2365 * Setup will be retried on the next hotplug event.
+3
drivers/gpu/drm/drm_gem.c
··· 1106 1106 return -EINVAL; 1107 1107 1108 1108 if (obj->funcs && obj->funcs->mmap) { 1109 + /* Remove the fake offset */ 1110 + vma->vm_pgoff -= drm_vma_node_start(&obj->vma_node); 1111 + 1109 1112 ret = obj->funcs->mmap(obj, vma); 1110 1113 if (ret) 1111 1114 return ret;
-3
drivers/gpu/drm/drm_gem_shmem_helper.c
··· 541 541 vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot); 542 542 vma->vm_ops = &drm_gem_shmem_vm_ops; 543 543 544 - /* Remove the fake offset */ 545 - vma->vm_pgoff -= drm_vma_node_start(&shmem->base.vma_node); 546 - 547 544 return 0; 548 545 } 549 546 EXPORT_SYMBOL_GPL(drm_gem_shmem_mmap);
+128 -3
drivers/gpu/drm/drm_gem_vram_helper.c
··· 3 3 #include <drm/drm_debugfs.h> 4 4 #include <drm/drm_device.h> 5 5 #include <drm/drm_file.h> 6 + #include <drm/drm_framebuffer.h> 6 7 #include <drm/drm_gem_ttm_helper.h> 7 8 #include <drm/drm_gem_vram_helper.h> 8 9 #include <drm/drm_mode.h> 10 + #include <drm/drm_plane.h> 9 11 #include <drm/drm_prime.h> 12 + #include <drm/drm_simple_kms_helper.h> 10 13 #include <drm/ttm/ttm_page_alloc.h> 11 14 12 15 static const struct drm_gem_object_funcs drm_gem_vram_object_funcs; ··· 650 647 EXPORT_SYMBOL(drm_gem_vram_driver_dumb_mmap_offset); 651 648 652 649 /* 650 + * Helpers for struct drm_plane_helper_funcs 651 + */ 652 + 653 + /** 654 + * drm_gem_vram_plane_helper_prepare_fb() - \ 655 + * Implements &struct drm_plane_helper_funcs.prepare_fb 656 + * @plane: a DRM plane 657 + * @new_state: the plane's new state 658 + * 659 + * During plane updates, this function pins the GEM VRAM 660 + * objects of the plane's new framebuffer to VRAM. Call 661 + * drm_gem_vram_plane_helper_cleanup_fb() to unpin them. 662 + * 663 + * Returns: 664 + * 0 on success, or 665 + * a negative errno code otherwise. 666 + */ 667 + int 668 + drm_gem_vram_plane_helper_prepare_fb(struct drm_plane *plane, 669 + struct drm_plane_state *new_state) 670 + { 671 + size_t i; 672 + struct drm_gem_vram_object *gbo; 673 + int ret; 674 + 675 + if (!new_state->fb) 676 + return 0; 677 + 678 + for (i = 0; i < ARRAY_SIZE(new_state->fb->obj); ++i) { 679 + if (!new_state->fb->obj[i]) 680 + continue; 681 + gbo = drm_gem_vram_of_gem(new_state->fb->obj[i]); 682 + ret = drm_gem_vram_pin(gbo, DRM_GEM_VRAM_PL_FLAG_VRAM); 683 + if (ret) 684 + goto err_drm_gem_vram_unpin; 685 + } 686 + 687 + return 0; 688 + 689 + err_drm_gem_vram_unpin: 690 + while (i) { 691 + --i; 692 + gbo = drm_gem_vram_of_gem(new_state->fb->obj[i]); 693 + drm_gem_vram_unpin(gbo); 694 + } 695 + return ret; 696 + } 697 + EXPORT_SYMBOL(drm_gem_vram_plane_helper_prepare_fb); 698 + 699 + /** 700 + * drm_gem_vram_plane_helper_cleanup_fb() - \ 701 + * Implements &struct drm_plane_helper_funcs.cleanup_fb 702 + * @plane: a DRM plane 703 + * @old_state: the plane's old state 704 + * 705 + * During plane updates, this function unpins the GEM VRAM 706 + * objects of the plane's old framebuffer from VRAM. Complements 707 + * drm_gem_vram_plane_helper_prepare_fb(). 708 + */ 709 + void 710 + drm_gem_vram_plane_helper_cleanup_fb(struct drm_plane *plane, 711 + struct drm_plane_state *old_state) 712 + { 713 + size_t i; 714 + struct drm_gem_vram_object *gbo; 715 + 716 + if (!old_state->fb) 717 + return; 718 + 719 + for (i = 0; i < ARRAY_SIZE(old_state->fb->obj); ++i) { 720 + if (!old_state->fb->obj[i]) 721 + continue; 722 + gbo = drm_gem_vram_of_gem(old_state->fb->obj[i]); 723 + drm_gem_vram_unpin(gbo); 724 + } 725 + } 726 + EXPORT_SYMBOL(drm_gem_vram_plane_helper_cleanup_fb); 727 + 728 + /* 729 + * Helpers for struct drm_simple_display_pipe_funcs 730 + */ 731 + 732 + /** 733 + * drm_gem_vram_simple_display_pipe_prepare_fb() - \ 734 + * Implements &struct drm_simple_display_pipe_funcs.prepare_fb 735 + * @pipe: a simple display pipe 736 + * @new_state: the plane's new state 737 + * 738 + * During plane updates, this function pins the GEM VRAM 739 + * objects of the plane's new framebuffer to VRAM. Call 740 + * drm_gem_vram_simple_display_pipe_cleanup_fb() to unpin them. 741 + * 742 + * Returns: 743 + * 0 on success, or 744 + * a negative errno code otherwise. 745 + */ 746 + int drm_gem_vram_simple_display_pipe_prepare_fb( 747 + struct drm_simple_display_pipe *pipe, 748 + struct drm_plane_state *new_state) 749 + { 750 + return drm_gem_vram_plane_helper_prepare_fb(&pipe->plane, new_state); 751 + } 752 + EXPORT_SYMBOL(drm_gem_vram_simple_display_pipe_prepare_fb); 753 + 754 + /** 755 + * drm_gem_vram_simple_display_pipe_cleanup_fb() - \ 756 + * Implements &struct drm_simple_display_pipe_funcs.cleanup_fb 757 + * @pipe: a simple display pipe 758 + * @old_state: the plane's old state 759 + * 760 + * During plane updates, this function unpins the GEM VRAM 761 + * objects of the plane's old framebuffer from VRAM. Complements 762 + * drm_gem_vram_simple_display_pipe_prepare_fb(). 763 + */ 764 + void drm_gem_vram_simple_display_pipe_cleanup_fb( 765 + struct drm_simple_display_pipe *pipe, 766 + struct drm_plane_state *old_state) 767 + { 768 + drm_gem_vram_plane_helper_cleanup_fb(&pipe->plane, old_state); 769 + } 770 + EXPORT_SYMBOL(drm_gem_vram_simple_display_pipe_cleanup_fb); 771 + 772 + /* 653 773 * PRIME helpers 654 774 */ 655 775 ··· 1013 887 struct drm_info_node *node = (struct drm_info_node *) m->private; 1014 888 struct drm_vram_mm *vmm = node->minor->dev->vram_mm; 1015 889 struct drm_mm *mm = vmm->bdev.man[TTM_PL_VRAM].priv; 1016 - struct ttm_bo_global *glob = vmm->bdev.glob; 1017 890 struct drm_printer p = drm_seq_file_printer(m); 1018 891 1019 - spin_lock(&glob->lru_lock); 892 + spin_lock(&ttm_bo_glob.lru_lock); 1020 893 drm_mm_print(mm, &p); 1021 - spin_unlock(&glob->lru_lock); 894 + spin_unlock(&ttm_bo_glob.lru_lock); 1022 895 return 0; 1023 896 } 1024 897
+1 -1
drivers/gpu/drm/drm_simple_kms_helper.c
··· 43 43 /* Anything goes */ 44 44 return MODE_OK; 45 45 46 - return pipe->funcs->mode_valid(crtc, mode); 46 + return pipe->funcs->mode_valid(pipe, mode); 47 47 } 48 48 49 49 static int drm_simple_kms_crtc_check(struct drm_crtc *crtc,
+1 -1
drivers/gpu/drm/gma500/mdfld_dsi_output.c
··· 498 498 return; 499 499 } 500 500 501 - /*create a new connetor*/ 501 + /*create a new connector*/ 502 502 dsi_connector = kzalloc(sizeof(struct mdfld_dsi_connector), GFP_KERNEL); 503 503 if (!dsi_connector) { 504 504 DRM_ERROR("No memory");
+4 -10
drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c
··· 96 96 { 97 97 struct drm_plane_state *state = plane->state; 98 98 u32 reg; 99 - int ret; 100 99 s64 gpu_addr = 0; 101 100 unsigned int line_l; 102 101 struct hibmc_drm_private *priv = plane->dev->dev_private; ··· 108 109 hibmc_fb = to_hibmc_framebuffer(state->fb); 109 110 gbo = drm_gem_vram_of_gem(hibmc_fb->obj); 110 111 111 - ret = drm_gem_vram_pin(gbo, DRM_GEM_VRAM_PL_FLAG_VRAM); 112 - if (ret) { 113 - DRM_ERROR("failed to pin bo: %d", ret); 114 - return; 115 - } 116 112 gpu_addr = drm_gem_vram_offset(gbo); 117 - if (gpu_addr < 0) { 118 - drm_gem_vram_unpin(gbo); 119 - return; 120 - } 113 + if (WARN_ON_ONCE(gpu_addr < 0)) 114 + return; /* Bug: we didn't pin the BO to VRAM in prepare_fb. */ 121 115 122 116 writel(gpu_addr, priv->mmio + HIBMC_CRT_FB_ADDRESS); 123 117 ··· 149 157 }; 150 158 151 159 static const struct drm_plane_helper_funcs hibmc_plane_helper_funcs = { 160 + .prepare_fb = drm_gem_vram_plane_helper_prepare_fb, 161 + .cleanup_fb = drm_gem_vram_plane_helper_cleanup_fb, 152 162 .atomic_check = hibmc_plane_atomic_check, 153 163 .atomic_update = hibmc_plane_atomic_update, 154 164 };
+2 -2
drivers/gpu/drm/mediatek/mtk_drm_gem.c
··· 271 271 pgprot_writecombine(PAGE_KERNEL)); 272 272 273 273 out: 274 - kfree((void *)sgt); 274 + kfree(sgt); 275 275 276 276 return mtk_gem->kvaddr; 277 277 } ··· 285 285 286 286 vunmap(vaddr); 287 287 mtk_gem->kvaddr = 0; 288 - kfree((void *)mtk_gem->pages); 288 + kfree(mtk_gem->pages); 289 289 }
+35 -89
drivers/gpu/drm/panfrost/panfrost_devfreq.c
··· 13 13 #include "panfrost_gpu.h" 14 14 #include "panfrost_regs.h" 15 15 16 - static void panfrost_devfreq_update_utilization(struct panfrost_device *pfdev, int slot); 16 + static void panfrost_devfreq_update_utilization(struct panfrost_device *pfdev); 17 17 18 18 static int panfrost_devfreq_target(struct device *dev, unsigned long *freq, 19 19 u32 flags) 20 20 { 21 - struct panfrost_device *pfdev = platform_get_drvdata(to_platform_device(dev)); 22 - struct dev_pm_opp *opp; 23 - unsigned long old_clk_rate = pfdev->devfreq.cur_freq; 24 - unsigned long target_volt, target_rate; 21 + struct panfrost_device *pfdev = dev_get_drvdata(dev); 25 22 int err; 26 23 27 - opp = devfreq_recommended_opp(dev, freq, flags); 28 - if (IS_ERR(opp)) 29 - return PTR_ERR(opp); 30 - 31 - target_rate = dev_pm_opp_get_freq(opp); 32 - target_volt = dev_pm_opp_get_voltage(opp); 33 - dev_pm_opp_put(opp); 34 - 35 - if (old_clk_rate == target_rate) 36 - return 0; 37 - 38 - /* 39 - * If frequency scaling from low to high, adjust voltage first. 40 - * If frequency scaling from high to low, adjust frequency first. 41 - */ 42 - if (old_clk_rate < target_rate) { 43 - err = regulator_set_voltage(pfdev->regulator, target_volt, 44 - target_volt); 45 - if (err) { 46 - dev_err(dev, "Cannot set voltage %lu uV\n", 47 - target_volt); 48 - return err; 49 - } 50 - } 51 - 52 - err = clk_set_rate(pfdev->clock, target_rate); 53 - if (err) { 54 - dev_err(dev, "Cannot set frequency %lu (%d)\n", target_rate, 55 - err); 56 - regulator_set_voltage(pfdev->regulator, pfdev->devfreq.cur_volt, 57 - pfdev->devfreq.cur_volt); 24 + err = dev_pm_opp_set_rate(dev, *freq); 25 + if (err) 58 26 return err; 59 - } 60 27 61 - if (old_clk_rate > target_rate) { 62 - err = regulator_set_voltage(pfdev->regulator, target_volt, 63 - target_volt); 64 - if (err) 65 - dev_err(dev, "Cannot set voltage %lu uV\n", target_volt); 66 - } 67 - 68 - pfdev->devfreq.cur_freq = target_rate; 69 - pfdev->devfreq.cur_volt = target_volt; 28 + *freq = clk_get_rate(pfdev->clock); 70 29 71 30 return 0; 72 31 } 73 32 74 33 static void panfrost_devfreq_reset(struct panfrost_device *pfdev) 75 34 { 76 - ktime_t now = ktime_get(); 77 - int i; 78 - 79 - for (i = 0; i < NUM_JOB_SLOTS; i++) { 80 - pfdev->devfreq.slot[i].busy_time = 0; 81 - pfdev->devfreq.slot[i].idle_time = 0; 82 - pfdev->devfreq.slot[i].time_last_update = now; 83 - } 35 + pfdev->devfreq.busy_time = 0; 36 + pfdev->devfreq.idle_time = 0; 37 + pfdev->devfreq.time_last_update = ktime_get(); 84 38 } 85 39 86 40 static int panfrost_devfreq_get_dev_status(struct device *dev, 87 41 struct devfreq_dev_status *status) 88 42 { 89 - struct panfrost_device *pfdev = platform_get_drvdata(to_platform_device(dev)); 90 - int i; 43 + struct panfrost_device *pfdev = dev_get_drvdata(dev); 91 44 92 - for (i = 0; i < NUM_JOB_SLOTS; i++) { 93 - panfrost_devfreq_update_utilization(pfdev, i); 94 - } 45 + panfrost_devfreq_update_utilization(pfdev); 95 46 96 47 status->current_frequency = clk_get_rate(pfdev->clock); 97 - status->total_time = ktime_to_ns(ktime_add(pfdev->devfreq.slot[0].busy_time, 98 - pfdev->devfreq.slot[0].idle_time)); 48 + status->total_time = ktime_to_ns(ktime_add(pfdev->devfreq.busy_time, 49 + pfdev->devfreq.idle_time)); 99 50 100 - status->busy_time = 0; 101 - for (i = 0; i < NUM_JOB_SLOTS; i++) { 102 - status->busy_time += ktime_to_ns(pfdev->devfreq.slot[i].busy_time); 103 - } 104 - 105 - /* We're scheduling only to one core atm, so don't divide for now */ 106 - /* status->busy_time /= NUM_JOB_SLOTS; */ 51 + status->busy_time = ktime_to_ns(pfdev->devfreq.busy_time); 107 52 108 53 panfrost_devfreq_reset(pfdev); 109 54 ··· 64 119 { 65 120 struct panfrost_device *pfdev = platform_get_drvdata(to_platform_device(dev)); 66 121 67 - *freq = pfdev->devfreq.cur_freq; 122 + *freq = clk_get_rate(pfdev->clock); 68 123 69 124 return 0; 70 125 } ··· 80 135 { 81 136 int ret; 82 137 struct dev_pm_opp *opp; 138 + unsigned long cur_freq; 83 139 84 140 ret = dev_pm_opp_of_add_table(&pfdev->pdev->dev); 85 141 if (ret == -ENODEV) /* Optional, continue without devfreq */ ··· 90 144 91 145 panfrost_devfreq_reset(pfdev); 92 146 93 - pfdev->devfreq.cur_freq = clk_get_rate(pfdev->clock); 147 + cur_freq = clk_get_rate(pfdev->clock); 94 148 95 - opp = devfreq_recommended_opp(&pfdev->pdev->dev, &pfdev->devfreq.cur_freq, 0); 149 + opp = devfreq_recommended_opp(&pfdev->pdev->dev, &cur_freq, 0); 96 150 if (IS_ERR(opp)) 97 151 return PTR_ERR(opp); 98 152 99 - panfrost_devfreq_profile.initial_freq = pfdev->devfreq.cur_freq; 153 + panfrost_devfreq_profile.initial_freq = cur_freq; 100 154 dev_pm_opp_put(opp); 101 155 102 156 pfdev->devfreq.devfreq = devm_devfreq_add_device(&pfdev->pdev->dev, ··· 120 174 121 175 void panfrost_devfreq_resume(struct panfrost_device *pfdev) 122 176 { 123 - int i; 124 - 125 177 if (!pfdev->devfreq.devfreq) 126 178 return; 127 179 128 180 panfrost_devfreq_reset(pfdev); 129 - for (i = 0; i < NUM_JOB_SLOTS; i++) 130 - pfdev->devfreq.slot[i].busy = false; 131 181 132 182 devfreq_resume_device(pfdev->devfreq.devfreq); 133 183 } ··· 136 194 devfreq_suspend_device(pfdev->devfreq.devfreq); 137 195 } 138 196 139 - static void panfrost_devfreq_update_utilization(struct panfrost_device *pfdev, int slot) 197 + static void panfrost_devfreq_update_utilization(struct panfrost_device *pfdev) 140 198 { 141 - struct panfrost_devfreq_slot *devfreq_slot = &pfdev->devfreq.slot[slot]; 142 199 ktime_t now; 143 200 ktime_t last; 144 201 ··· 145 204 return; 146 205 147 206 now = ktime_get(); 148 - last = pfdev->devfreq.slot[slot].time_last_update; 207 + last = pfdev->devfreq.time_last_update; 149 208 150 - /* If we last recorded a transition to busy, we have been idle since */ 151 - if (devfreq_slot->busy) 152 - pfdev->devfreq.slot[slot].busy_time += ktime_sub(now, last); 209 + if (atomic_read(&pfdev->devfreq.busy_count) > 0) 210 + pfdev->devfreq.busy_time += ktime_sub(now, last); 153 211 else 154 - pfdev->devfreq.slot[slot].idle_time += ktime_sub(now, last); 212 + pfdev->devfreq.idle_time += ktime_sub(now, last); 155 213 156 - pfdev->devfreq.slot[slot].time_last_update = now; 214 + pfdev->devfreq.time_last_update = now; 157 215 } 158 216 159 - /* The job scheduler is expected to call this at every transition busy <-> idle */ 160 - void panfrost_devfreq_record_transition(struct panfrost_device *pfdev, int slot) 217 + void panfrost_devfreq_record_busy(struct panfrost_device *pfdev) 161 218 { 162 - struct panfrost_devfreq_slot *devfreq_slot = &pfdev->devfreq.slot[slot]; 219 + panfrost_devfreq_update_utilization(pfdev); 220 + atomic_inc(&pfdev->devfreq.busy_count); 221 + } 163 222 164 - panfrost_devfreq_update_utilization(pfdev, slot); 165 - devfreq_slot->busy = !devfreq_slot->busy; 223 + void panfrost_devfreq_record_idle(struct panfrost_device *pfdev) 224 + { 225 + int count; 226 + 227 + panfrost_devfreq_update_utilization(pfdev); 228 + count = atomic_dec_if_positive(&pfdev->devfreq.busy_count); 229 + WARN_ON(count < 0); 166 230 }
+2 -1
drivers/gpu/drm/panfrost/panfrost_devfreq.h
··· 10 10 void panfrost_devfreq_resume(struct panfrost_device *pfdev); 11 11 void panfrost_devfreq_suspend(struct panfrost_device *pfdev); 12 12 13 - void panfrost_devfreq_record_transition(struct panfrost_device *pfdev, int slot); 13 + void panfrost_devfreq_record_busy(struct panfrost_device *pfdev); 14 + void panfrost_devfreq_record_idle(struct panfrost_device *pfdev); 14 15 15 16 #endif /* __PANFROST_DEVFREQ_H__ */
+4 -10
drivers/gpu/drm/panfrost/panfrost_device.h
··· 51 51 unsigned long hw_issues[64 / BITS_PER_LONG]; 52 52 }; 53 53 54 - struct panfrost_devfreq_slot { 55 - ktime_t busy_time; 56 - ktime_t idle_time; 57 - ktime_t time_last_update; 58 - bool busy; 59 - }; 60 - 61 54 struct panfrost_device { 62 55 struct device *dev; 63 56 struct drm_device *ddev; ··· 86 93 struct { 87 94 struct devfreq *devfreq; 88 95 struct thermal_cooling_device *cooling; 89 - unsigned long cur_freq; 90 - unsigned long cur_volt; 91 - struct panfrost_devfreq_slot slot[NUM_JOB_SLOTS]; 96 + ktime_t busy_time; 97 + ktime_t idle_time; 98 + ktime_t time_last_update; 99 + atomic_t busy_count; 92 100 } devfreq; 93 101 }; 94 102
+7 -8
drivers/gpu/drm/panfrost/panfrost_job.c
··· 155 155 } 156 156 157 157 cfg = panfrost_mmu_as_get(pfdev, &job->file_priv->mmu); 158 - 159 - panfrost_devfreq_record_transition(pfdev, js); 158 + panfrost_devfreq_record_busy(pfdev); 160 159 161 160 job_write(pfdev, JS_HEAD_NEXT_LO(js), jc_head & 0xFFFFFFFF); 162 161 job_write(pfdev, JS_HEAD_NEXT_HI(js), jc_head >> 32); ··· 403 404 } 404 405 spin_unlock_irqrestore(&pfdev->js->job_lock, flags); 405 406 406 - panfrost_devfreq_record_transition(pfdev, js); 407 + panfrost_devfreq_record_idle(pfdev); 407 408 panfrost_device_reset(pfdev); 408 409 409 410 for (i = 0; i < NUM_JOB_SLOTS; i++) ··· 466 467 pfdev->jobs[j] = NULL; 467 468 468 469 panfrost_mmu_as_put(pfdev, &job->file_priv->mmu); 469 - panfrost_devfreq_record_transition(pfdev, j); 470 + panfrost_devfreq_record_idle(pfdev); 470 471 471 472 dma_fence_signal_locked(job->done_fence); 472 473 pm_runtime_put_autosuspend(pfdev->dev); ··· 567 568 struct panfrost_job_slot *js = pfdev->js; 568 569 int i; 569 570 571 + /* Check whether the hardware is idle */ 572 + if (atomic_read(&pfdev->devfreq.busy_count)) 573 + return false; 574 + 570 575 for (i = 0; i < NUM_JOB_SLOTS; i++) { 571 576 /* If there are any jobs in the HW queue, we're not idle */ 572 577 if (atomic_read(&js->queue[i].sched.hw_rq_count)) 573 - return false; 574 - 575 - /* Check whether the hardware is idle */ 576 - if (pfdev->devfreq.slot[i].busy) 577 578 return false; 578 579 } 579 580
+2 -2
drivers/gpu/drm/pl111/pl111_display.c
··· 48 48 } 49 49 50 50 static enum drm_mode_status 51 - pl111_mode_valid(struct drm_crtc *crtc, 51 + pl111_mode_valid(struct drm_simple_display_pipe *pipe, 52 52 const struct drm_display_mode *mode) 53 53 { 54 - struct drm_device *drm = crtc->dev; 54 + struct drm_device *drm = pipe->crtc.dev; 55 55 struct pl111_drm_dev_private *priv = drm->dev_private; 56 56 u32 cpp = priv->variant->fb_bpp / 8; 57 57 u64 bw;
+2
drivers/gpu/drm/qxl/qxl_drv.h
··· 355 355 /* qxl ttm */ 356 356 int qxl_ttm_init(struct qxl_device *qdev); 357 357 void qxl_ttm_fini(struct qxl_device *qdev); 358 + int qxl_ttm_io_mem_reserve(struct ttm_bo_device *bdev, 359 + struct ttm_mem_reg *mem); 358 360 359 361 /* qxl image */ 360 362
+1 -10
drivers/gpu/drm/qxl/qxl_object.c
··· 167 167 void *qxl_bo_kmap_atomic_page(struct qxl_device *qdev, 168 168 struct qxl_bo *bo, int page_offset) 169 169 { 170 - struct ttm_mem_type_manager *man = &bo->tbo.bdev->man[bo->tbo.mem.mem_type]; 171 170 void *rptr; 172 171 int ret; 173 172 struct io_mapping *map; ··· 178 179 else 179 180 goto fallback; 180 181 181 - (void) ttm_mem_io_lock(man, false); 182 - ret = ttm_mem_io_reserve(bo->tbo.bdev, &bo->tbo.mem); 183 - ttm_mem_io_unlock(man); 182 + ret = qxl_ttm_io_mem_reserve(bo->tbo.bdev, &bo->tbo.mem); 184 183 185 184 return io_mapping_map_atomic_wc(map, bo->tbo.mem.bus.offset + page_offset); 186 185 fallback: ··· 209 212 void qxl_bo_kunmap_atomic_page(struct qxl_device *qdev, 210 213 struct qxl_bo *bo, void *pmap) 211 214 { 212 - struct ttm_mem_type_manager *man = &bo->tbo.bdev->man[bo->tbo.mem.mem_type]; 213 - 214 215 if ((bo->tbo.mem.mem_type != TTM_PL_VRAM) && 215 216 (bo->tbo.mem.mem_type != TTM_PL_PRIV)) 216 217 goto fallback; 217 218 218 219 io_mapping_unmap_atomic(pmap); 219 - 220 - (void) ttm_mem_io_lock(man, false); 221 - ttm_mem_io_free(bo->tbo.bdev, &bo->tbo.mem); 222 - ttm_mem_io_unlock(man); 223 220 return; 224 221 fallback: 225 222 qxl_bo_kunmap(bo);
+4 -7
drivers/gpu/drm/qxl/qxl_release.c
··· 260 260 return 0; 261 261 262 262 ret = ttm_eu_reserve_buffers(&release->ticket, &release->bos, 263 - !no_intr, NULL, true); 263 + !no_intr, NULL); 264 264 if (ret) 265 265 return ret; 266 266 ··· 429 429 void qxl_release_fence_buffer_objects(struct qxl_release *release) 430 430 { 431 431 struct ttm_buffer_object *bo; 432 - struct ttm_bo_global *glob; 433 432 struct ttm_bo_device *bdev; 434 433 struct ttm_validate_buffer *entry; 435 434 struct qxl_device *qdev; ··· 450 451 release->id | 0xf0000000, release->base.seqno); 451 452 trace_dma_fence_emit(&release->base); 452 453 453 - glob = bdev->glob; 454 - 455 - spin_lock(&glob->lru_lock); 454 + spin_lock(&ttm_bo_glob.lru_lock); 456 455 457 456 list_for_each_entry(entry, &release->bos, head) { 458 457 bo = entry->bo; 459 458 460 459 dma_resv_add_shared_fence(bo->base.resv, &release->base); 461 - ttm_bo_add_to_lru(bo); 460 + ttm_bo_move_to_lru_tail(bo, NULL); 462 461 dma_resv_unlock(bo->base.resv); 463 462 } 464 - spin_unlock(&glob->lru_lock); 463 + spin_unlock(&ttm_bo_glob.lru_lock); 465 464 ww_acquire_fini(&release->ticket); 466 465 } 467 466
+4 -7
drivers/gpu/drm/qxl/qxl_ttm.c
··· 110 110 *placement = qbo->placement; 111 111 } 112 112 113 - static int qxl_ttm_io_mem_reserve(struct ttm_bo_device *bdev, 114 - struct ttm_mem_reg *mem) 113 + int qxl_ttm_io_mem_reserve(struct ttm_bo_device *bdev, 114 + struct ttm_mem_reg *mem) 115 115 { 116 116 struct ttm_mem_type_manager *man = &bdev->man[mem->mem_type]; 117 117 struct qxl_device *qdev = qxl_get_qdev(bdev); ··· 319 319 { 320 320 struct drm_info_node *node = (struct drm_info_node *)m->private; 321 321 struct drm_mm *mm = (struct drm_mm *)node->info_ent->data; 322 - struct drm_device *dev = node->minor->dev; 323 - struct qxl_device *rdev = dev->dev_private; 324 - struct ttm_bo_global *glob = rdev->mman.bdev.glob; 325 322 struct drm_printer p = drm_seq_file_printer(m); 326 323 327 - spin_lock(&glob->lru_lock); 324 + spin_lock(&ttm_bo_glob.lru_lock); 328 325 drm_mm_print(mm, &p); 329 - spin_unlock(&glob->lru_lock); 326 + spin_unlock(&ttm_bo_glob.lru_lock); 330 327 return 0; 331 328 } 332 329 #endif
+1 -1
drivers/gpu/drm/radeon/radeon_gem.c
··· 566 566 if (!vm_bos) 567 567 return; 568 568 569 - r = ttm_eu_reserve_buffers(&ticket, &list, true, NULL, true); 569 + r = ttm_eu_reserve_buffers(&ticket, &list, true, NULL); 570 570 if (r) 571 571 goto error_free; 572 572
+1 -1
drivers/gpu/drm/radeon/radeon_object.c
··· 542 542 u64 bytes_moved_threshold = radeon_bo_get_threshold_for_moves(rdev); 543 543 544 544 INIT_LIST_HEAD(&duplicates); 545 - r = ttm_eu_reserve_buffers(ticket, head, true, &duplicates, true); 545 + r = ttm_eu_reserve_buffers(ticket, head, true, &duplicates); 546 546 if (unlikely(r != 0)) { 547 547 return r; 548 548 }
+24 -19
drivers/gpu/drm/scheduler/sched_main.c
··· 622 622 } 623 623 624 624 /** 625 - * drm_sched_cleanup_jobs - destroy finished jobs 625 + * drm_sched_get_cleanup_job - fetch the next finished job to be destroyed 626 626 * 627 627 * @sched: scheduler instance 628 628 * 629 - * Remove all finished jobs from the mirror list and destroy them. 629 + * Returns the next finished job from the mirror list (if there is one) 630 + * ready for it to be destroyed. 630 631 */ 631 - static void drm_sched_cleanup_jobs(struct drm_gpu_scheduler *sched) 632 + static struct drm_sched_job * 633 + drm_sched_get_cleanup_job(struct drm_gpu_scheduler *sched) 632 634 { 635 + struct drm_sched_job *job; 633 636 unsigned long flags; 634 637 635 638 /* Don't destroy jobs while the timeout worker is running */ 636 639 if (sched->timeout != MAX_SCHEDULE_TIMEOUT && 637 640 !cancel_delayed_work(&sched->work_tdr)) 638 - return; 641 + return NULL; 639 642 643 + spin_lock_irqsave(&sched->job_list_lock, flags); 640 644 641 - while (!list_empty(&sched->ring_mirror_list)) { 642 - struct drm_sched_job *job; 643 - 644 - job = list_first_entry(&sched->ring_mirror_list, 645 + job = list_first_entry_or_null(&sched->ring_mirror_list, 645 646 struct drm_sched_job, node); 646 - if (!dma_fence_is_signaled(&job->s_fence->finished)) 647 - break; 648 647 649 - spin_lock_irqsave(&sched->job_list_lock, flags); 648 + if (job && dma_fence_is_signaled(&job->s_fence->finished)) { 650 649 /* remove job from ring_mirror_list */ 651 650 list_del_init(&job->node); 652 - spin_unlock_irqrestore(&sched->job_list_lock, flags); 653 - 654 - sched->ops->free_job(job); 651 + } else { 652 + job = NULL; 653 + /* queue timeout for next job */ 654 + drm_sched_start_timeout(sched); 655 655 } 656 656 657 - /* queue timeout for next job */ 658 - spin_lock_irqsave(&sched->job_list_lock, flags); 659 - drm_sched_start_timeout(sched); 660 657 spin_unlock_irqrestore(&sched->job_list_lock, flags); 661 658 659 + return job; 662 660 } 663 661 664 662 /** ··· 696 698 struct drm_sched_fence *s_fence; 697 699 struct drm_sched_job *sched_job; 698 700 struct dma_fence *fence; 701 + struct drm_sched_job *cleanup_job = NULL; 699 702 700 703 wait_event_interruptible(sched->wake_up_worker, 701 - (drm_sched_cleanup_jobs(sched), 704 + (cleanup_job = drm_sched_get_cleanup_job(sched)) || 702 705 (!drm_sched_blocked(sched) && 703 706 (entity = drm_sched_select_entity(sched))) || 704 - kthread_should_stop())); 707 + kthread_should_stop()); 708 + 709 + if (cleanup_job) { 710 + sched->ops->free_job(cleanup_job); 711 + /* queue timeout for next job */ 712 + drm_sched_start_timeout(sched); 713 + } 705 714 706 715 if (!entity) 707 716 continue;
+1 -1
drivers/gpu/drm/ttm/ttm_agp_backend.c
··· 51 51 static int ttm_agp_bind(struct ttm_tt *ttm, struct ttm_mem_reg *bo_mem) 52 52 { 53 53 struct ttm_agp_backend *agp_be = container_of(ttm, struct ttm_agp_backend, ttm); 54 - struct page *dummy_read_page = ttm->bdev->glob->dummy_read_page; 54 + struct page *dummy_read_page = ttm_bo_glob.dummy_read_page; 55 55 struct drm_mm_node *node = bo_mem->mm_node; 56 56 struct agp_memory *mem; 57 57 int ret, cached = (bo_mem->placement & TTM_PL_FLAG_CACHED);
+36 -96
drivers/gpu/drm/ttm/ttm_bo.c
··· 51 51 DEFINE_MUTEX(ttm_global_mutex); 52 52 unsigned ttm_bo_glob_use_count; 53 53 struct ttm_bo_global ttm_bo_glob; 54 + EXPORT_SYMBOL(ttm_bo_glob); 54 55 55 56 static struct attribute ttm_bo_count = { 56 57 .name = "bo_count", ··· 149 148 { 150 149 struct ttm_buffer_object *bo = 151 150 container_of(list_kref, struct ttm_buffer_object, list_kref); 152 - struct ttm_bo_device *bdev = bo->bdev; 153 151 size_t acc_size = bo->acc_size; 154 152 155 153 BUG_ON(kref_read(&bo->list_kref)); 156 154 BUG_ON(kref_read(&bo->kref)); 157 - BUG_ON(atomic_read(&bo->cpu_writers)); 158 155 BUG_ON(bo->mem.mm_node != NULL); 159 156 BUG_ON(!list_empty(&bo->lru)); 160 157 BUG_ON(!list_empty(&bo->ddestroy)); 161 158 ttm_tt_destroy(bo->ttm); 162 - atomic_dec(&bo->bdev->glob->bo_count); 159 + atomic_dec(&ttm_bo_glob.bo_count); 163 160 dma_fence_put(bo->moving); 164 161 if (!ttm_bo_uses_embedded_gem_object(bo)) 165 162 dma_resv_fini(&bo->base._resv); 166 163 mutex_destroy(&bo->wu_mutex); 167 164 bo->destroy(bo); 168 - ttm_mem_global_free(bdev->glob->mem_glob, acc_size); 165 + ttm_mem_global_free(&ttm_mem_glob, acc_size); 169 166 } 170 167 171 168 static void ttm_bo_add_mem_to_lru(struct ttm_buffer_object *bo, ··· 187 188 if (!(man->flags & TTM_MEMTYPE_FLAG_FIXED) && bo->ttm && 188 189 !(bo->ttm->page_flags & (TTM_PAGE_FLAG_SG | 189 190 TTM_PAGE_FLAG_SWAPPED))) { 190 - list_add_tail(&bo->swap, &bdev->glob->swap_lru[bo->priority]); 191 + list_add_tail(&bo->swap, &ttm_bo_glob.swap_lru[bo->priority]); 191 192 kref_get(&bo->list_kref); 192 193 } 193 194 } 194 - 195 - void ttm_bo_add_to_lru(struct ttm_buffer_object *bo) 196 - { 197 - ttm_bo_add_mem_to_lru(bo, &bo->mem); 198 - } 199 - EXPORT_SYMBOL(ttm_bo_add_to_lru); 200 195 201 196 static void ttm_bo_ref_bug(struct kref *list_kref) 202 197 { 203 198 BUG(); 204 199 } 205 200 206 - void ttm_bo_del_from_lru(struct ttm_buffer_object *bo) 201 + static void ttm_bo_del_from_lru(struct ttm_buffer_object *bo) 207 202 { 208 203 struct ttm_bo_device *bdev = bo->bdev; 209 204 bool notify = false; ··· 217 224 bdev->driver->del_from_lru_notify(bo); 218 225 } 219 226 220 - void ttm_bo_del_sub_from_lru(struct ttm_buffer_object *bo) 221 - { 222 - struct ttm_bo_global *glob = bo->bdev->glob; 223 - 224 - spin_lock(&glob->lru_lock); 225 - ttm_bo_del_from_lru(bo); 226 - spin_unlock(&glob->lru_lock); 227 - } 228 - EXPORT_SYMBOL(ttm_bo_del_sub_from_lru); 229 - 230 227 static void ttm_bo_bulk_move_set_pos(struct ttm_lru_bulk_move_pos *pos, 231 228 struct ttm_buffer_object *bo) 232 229 { ··· 231 248 dma_resv_assert_held(bo->base.resv); 232 249 233 250 ttm_bo_del_from_lru(bo); 234 - ttm_bo_add_to_lru(bo); 251 + ttm_bo_add_mem_to_lru(bo, &bo->mem); 235 252 236 253 if (bulk && !(bo->mem.placement & TTM_PL_FLAG_NO_EVICT)) { 237 254 switch (bo->mem.mem_type) { ··· 294 311 dma_resv_assert_held(pos->first->base.resv); 295 312 dma_resv_assert_held(pos->last->base.resv); 296 313 297 - lru = &pos->first->bdev->glob->swap_lru[i]; 314 + lru = &ttm_bo_glob.swap_lru[i]; 298 315 list_bulk_move_tail(lru, &pos->first->swap, &pos->last->swap); 299 316 } 300 317 } ··· 458 475 static void ttm_bo_cleanup_refs_or_queue(struct ttm_buffer_object *bo) 459 476 { 460 477 struct ttm_bo_device *bdev = bo->bdev; 461 - struct ttm_bo_global *glob = bdev->glob; 462 478 int ret; 463 479 464 480 ret = ttm_bo_individualize_resv(bo); ··· 467 485 */ 468 486 dma_resv_wait_timeout_rcu(bo->base.resv, true, false, 469 487 30 * HZ); 470 - spin_lock(&glob->lru_lock); 488 + spin_lock(&ttm_bo_glob.lru_lock); 471 489 goto error; 472 490 } 473 491 474 - spin_lock(&glob->lru_lock); 492 + spin_lock(&ttm_bo_glob.lru_lock); 475 493 ret = dma_resv_trylock(bo->base.resv) ? 0 : -EBUSY; 476 494 if (!ret) { 477 495 if (dma_resv_test_signaled_rcu(&bo->base._resv, true)) { 478 496 ttm_bo_del_from_lru(bo); 479 - spin_unlock(&glob->lru_lock); 497 + spin_unlock(&ttm_bo_glob.lru_lock); 480 498 if (bo->base.resv != &bo->base._resv) 481 499 dma_resv_unlock(&bo->base._resv); 482 500 ··· 494 512 */ 495 513 if (bo->mem.placement & TTM_PL_FLAG_NO_EVICT) { 496 514 bo->mem.placement &= ~TTM_PL_FLAG_NO_EVICT; 497 - ttm_bo_add_to_lru(bo); 515 + ttm_bo_move_to_lru_tail(bo, NULL); 498 516 } 499 517 500 518 dma_resv_unlock(bo->base.resv); ··· 505 523 error: 506 524 kref_get(&bo->list_kref); 507 525 list_add_tail(&bo->ddestroy, &bdev->ddestroy); 508 - spin_unlock(&glob->lru_lock); 526 + spin_unlock(&ttm_bo_glob.lru_lock); 509 527 510 528 schedule_delayed_work(&bdev->wq, 511 529 ((HZ / 100) < 1) ? 1 : HZ / 100); ··· 528 546 bool interruptible, bool no_wait_gpu, 529 547 bool unlock_resv) 530 548 { 531 - struct ttm_bo_global *glob = bo->bdev->glob; 532 549 struct dma_resv *resv; 533 550 int ret; 534 551 ··· 546 565 547 566 if (unlock_resv) 548 567 dma_resv_unlock(bo->base.resv); 549 - spin_unlock(&glob->lru_lock); 568 + spin_unlock(&ttm_bo_glob.lru_lock); 550 569 551 570 lret = dma_resv_wait_timeout_rcu(resv, true, 552 571 interruptible, ··· 557 576 else if (lret == 0) 558 577 return -EBUSY; 559 578 560 - spin_lock(&glob->lru_lock); 579 + spin_lock(&ttm_bo_glob.lru_lock); 561 580 if (unlock_resv && !dma_resv_trylock(bo->base.resv)) { 562 581 /* 563 582 * We raced, and lost, someone else holds the reservation now, ··· 567 586 * delayed destruction would succeed, so just return success 568 587 * here. 569 588 */ 570 - spin_unlock(&glob->lru_lock); 589 + spin_unlock(&ttm_bo_glob.lru_lock); 571 590 return 0; 572 591 } 573 592 ret = 0; ··· 576 595 if (ret || unlikely(list_empty(&bo->ddestroy))) { 577 596 if (unlock_resv) 578 597 dma_resv_unlock(bo->base.resv); 579 - spin_unlock(&glob->lru_lock); 598 + spin_unlock(&ttm_bo_glob.lru_lock); 580 599 return ret; 581 600 } 582 601 ··· 584 603 list_del_init(&bo->ddestroy); 585 604 kref_put(&bo->list_kref, ttm_bo_ref_bug); 586 605 587 - spin_unlock(&glob->lru_lock); 606 + spin_unlock(&ttm_bo_glob.lru_lock); 588 607 ttm_bo_cleanup_memtype_use(bo); 589 608 590 609 if (unlock_resv) ··· 599 618 */ 600 619 static bool ttm_bo_delayed_delete(struct ttm_bo_device *bdev, bool remove_all) 601 620 { 602 - struct ttm_bo_global *glob = bdev->glob; 621 + struct ttm_bo_global *glob = &ttm_bo_glob; 603 622 struct list_head removed; 604 623 bool empty; 605 624 ··· 823 842 struct ww_acquire_ctx *ticket) 824 843 { 825 844 struct ttm_buffer_object *bo = NULL, *busy_bo = NULL; 826 - struct ttm_bo_global *glob = bdev->glob; 827 845 struct ttm_mem_type_manager *man = &bdev->man[mem_type]; 828 846 bool locked = false; 829 847 unsigned i; 830 848 int ret; 831 849 832 - spin_lock(&glob->lru_lock); 850 + spin_lock(&ttm_bo_glob.lru_lock); 833 851 for (i = 0; i < TTM_MAX_BO_PRIORITY; ++i) { 834 852 list_for_each_entry(bo, &man->lru[i], lru) { 835 853 bool busy; ··· 860 880 if (!bo) { 861 881 if (busy_bo) 862 882 kref_get(&busy_bo->list_kref); 863 - spin_unlock(&glob->lru_lock); 883 + spin_unlock(&ttm_bo_glob.lru_lock); 864 884 ret = ttm_mem_evict_wait_busy(busy_bo, ctx, ticket); 865 885 if (busy_bo) 866 886 kref_put(&busy_bo->list_kref, ttm_bo_release_list); ··· 876 896 return ret; 877 897 } 878 898 879 - ttm_bo_del_from_lru(bo); 880 - spin_unlock(&glob->lru_lock); 899 + spin_unlock(&ttm_bo_glob.lru_lock); 881 900 882 901 ret = ttm_bo_evict(bo, ctx); 883 - if (locked) { 902 + if (locked) 884 903 ttm_bo_unreserve(bo); 885 - } else { 886 - spin_lock(&glob->lru_lock); 887 - ttm_bo_add_to_lru(bo); 888 - spin_unlock(&glob->lru_lock); 889 - } 890 904 891 905 kref_put(&bo->list_kref, ttm_bo_release_list); 892 906 return ret; ··· 1046 1072 mem->mem_type = mem_type; 1047 1073 mem->placement = cur_flags; 1048 1074 1049 - if (bo->mem.mem_type < mem_type && !list_empty(&bo->lru)) { 1050 - spin_lock(&bo->bdev->glob->lru_lock); 1051 - ttm_bo_del_from_lru(bo); 1052 - ttm_bo_add_mem_to_lru(bo, mem); 1053 - spin_unlock(&bo->bdev->glob->lru_lock); 1054 - } 1075 + spin_lock(&ttm_bo_glob.lru_lock); 1076 + ttm_bo_del_from_lru(bo); 1077 + ttm_bo_add_mem_to_lru(bo, mem); 1078 + spin_unlock(&ttm_bo_glob.lru_lock); 1055 1079 1056 1080 return 0; 1057 1081 } ··· 1140 1168 1141 1169 error: 1142 1170 if (bo->mem.mem_type == TTM_PL_SYSTEM && !list_empty(&bo->lru)) { 1143 - spin_lock(&bo->bdev->glob->lru_lock); 1171 + spin_lock(&ttm_bo_glob.lru_lock); 1144 1172 ttm_bo_move_to_lru_tail(bo, NULL); 1145 - spin_unlock(&bo->bdev->glob->lru_lock); 1173 + spin_unlock(&ttm_bo_glob.lru_lock); 1146 1174 } 1147 1175 1148 1176 return ret; ··· 1266 1294 struct dma_resv *resv, 1267 1295 void (*destroy) (struct ttm_buffer_object *)) 1268 1296 { 1297 + struct ttm_mem_global *mem_glob = &ttm_mem_glob; 1269 1298 int ret = 0; 1270 1299 unsigned long num_pages; 1271 - struct ttm_mem_global *mem_glob = bdev->glob->mem_glob; 1272 1300 bool locked; 1273 1301 1274 1302 ret = ttm_mem_global_alloc(mem_glob, acc_size, ctx); ··· 1295 1323 1296 1324 kref_init(&bo->kref); 1297 1325 kref_init(&bo->list_kref); 1298 - atomic_set(&bo->cpu_writers, 0); 1299 1326 INIT_LIST_HEAD(&bo->lru); 1300 1327 INIT_LIST_HEAD(&bo->ddestroy); 1301 1328 INIT_LIST_HEAD(&bo->swap); ··· 1328 1357 dma_resv_init(&bo->base._resv); 1329 1358 drm_vma_node_reset(&bo->base.vma_node); 1330 1359 } 1331 - atomic_inc(&bo->bdev->glob->bo_count); 1360 + atomic_inc(&ttm_bo_glob.bo_count); 1332 1361 1333 1362 /* 1334 1363 * For ttm_bo_type_device buffers, allocate ··· 1358 1387 return ret; 1359 1388 } 1360 1389 1361 - if (resv && !(bo->mem.placement & TTM_PL_FLAG_NO_EVICT)) { 1362 - spin_lock(&bdev->glob->lru_lock); 1363 - ttm_bo_add_to_lru(bo); 1364 - spin_unlock(&bdev->glob->lru_lock); 1365 - } 1390 + spin_lock(&ttm_bo_glob.lru_lock); 1391 + ttm_bo_move_to_lru_tail(bo, NULL); 1392 + spin_unlock(&ttm_bo_glob.lru_lock); 1366 1393 1367 1394 return ret; 1368 1395 } ··· 1458 1489 .flags = TTM_OPT_FLAG_FORCE_ALLOC 1459 1490 }; 1460 1491 struct ttm_mem_type_manager *man = &bdev->man[mem_type]; 1461 - struct ttm_bo_global *glob = bdev->glob; 1492 + struct ttm_bo_global *glob = &ttm_bo_glob; 1462 1493 struct dma_fence *fence; 1463 1494 int ret; 1464 1495 unsigned i; ··· 1627 1658 goto out; 1628 1659 1629 1660 spin_lock_init(&glob->lru_lock); 1630 - glob->mem_glob = &ttm_mem_glob; 1631 - glob->mem_glob->bo_glob = glob; 1632 1661 glob->dummy_read_page = alloc_page(__GFP_ZERO | GFP_DMA32); 1633 1662 1634 1663 if (unlikely(glob->dummy_read_page == NULL)) { ··· 1650 1683 1651 1684 int ttm_bo_device_release(struct ttm_bo_device *bdev) 1652 1685 { 1686 + struct ttm_bo_global *glob = &ttm_bo_glob; 1653 1687 int ret = 0; 1654 1688 unsigned i = TTM_NUM_MEM_TYPES; 1655 1689 struct ttm_mem_type_manager *man; 1656 - struct ttm_bo_global *glob = bdev->glob; 1657 1690 1658 1691 while (i--) { 1659 1692 man = &bdev->man[i]; ··· 1722 1755 INIT_DELAYED_WORK(&bdev->wq, ttm_bo_delayed_workqueue); 1723 1756 INIT_LIST_HEAD(&bdev->ddestroy); 1724 1757 bdev->dev_mapping = mapping; 1725 - bdev->glob = glob; 1726 1758 bdev->need_dma32 = need_dma32; 1727 1759 mutex_lock(&ttm_global_mutex); 1728 1760 list_add_tail(&bdev->device_list, &glob->device_list); ··· 1800 1834 return 0; 1801 1835 } 1802 1836 EXPORT_SYMBOL(ttm_bo_wait); 1803 - 1804 - int ttm_bo_synccpu_write_grab(struct ttm_buffer_object *bo, bool no_wait) 1805 - { 1806 - int ret = 0; 1807 - 1808 - /* 1809 - * Using ttm_bo_reserve makes sure the lru lists are updated. 1810 - */ 1811 - 1812 - ret = ttm_bo_reserve(bo, true, no_wait, NULL); 1813 - if (unlikely(ret != 0)) 1814 - return ret; 1815 - ret = ttm_bo_wait(bo, true, no_wait); 1816 - if (likely(ret == 0)) 1817 - atomic_inc(&bo->cpu_writers); 1818 - ttm_bo_unreserve(bo); 1819 - return ret; 1820 - } 1821 - EXPORT_SYMBOL(ttm_bo_synccpu_write_grab); 1822 - 1823 - void ttm_bo_synccpu_write_release(struct ttm_buffer_object *bo) 1824 - { 1825 - atomic_dec(&bo->cpu_writers); 1826 - } 1827 - EXPORT_SYMBOL(ttm_bo_synccpu_write_release); 1828 1837 1829 1838 /** 1830 1839 * A buffer object shrink method that tries to swap out the first ··· 1900 1959 .no_wait_gpu = false 1901 1960 }; 1902 1961 1903 - while (ttm_bo_swapout(bdev->glob, &ctx) == 0) 1904 - ; 1962 + while (ttm_bo_swapout(&ttm_bo_glob, &ctx) == 0); 1905 1963 } 1906 1964 EXPORT_SYMBOL(ttm_bo_swapout_all); 1907 1965
+12 -15
drivers/gpu/drm/ttm/ttm_bo_util.c
··· 102 102 mutex_lock(&man->io_reserve_mutex); 103 103 return 0; 104 104 } 105 - EXPORT_SYMBOL(ttm_mem_io_lock); 106 105 107 106 void ttm_mem_io_unlock(struct ttm_mem_type_manager *man) 108 107 { ··· 110 111 111 112 mutex_unlock(&man->io_reserve_mutex); 112 113 } 113 - EXPORT_SYMBOL(ttm_mem_io_unlock); 114 114 115 115 static int ttm_mem_io_evict(struct ttm_mem_type_manager *man) 116 116 { ··· 151 153 } 152 154 return ret; 153 155 } 154 - EXPORT_SYMBOL(ttm_mem_io_reserve); 155 156 156 157 void ttm_mem_io_free(struct ttm_bo_device *bdev, 157 158 struct ttm_mem_reg *mem) ··· 166 169 bdev->driver->io_mem_free(bdev, mem); 167 170 168 171 } 169 - EXPORT_SYMBOL(ttm_mem_io_free); 170 172 171 173 int ttm_mem_io_reserve_vm(struct ttm_buffer_object *bo) 172 174 { ··· 499 503 * TODO: Explicit member copy would probably be better here. 500 504 */ 501 505 502 - atomic_inc(&bo->bdev->glob->bo_count); 506 + atomic_inc(&ttm_bo_glob.bo_count); 503 507 INIT_LIST_HEAD(&fbo->base.ddestroy); 504 508 INIT_LIST_HEAD(&fbo->base.lru); 505 509 INIT_LIST_HEAD(&fbo->base.swap); ··· 507 511 mutex_init(&fbo->base.wu_mutex); 508 512 fbo->base.moving = NULL; 509 513 drm_vma_node_reset(&fbo->base.base.vma_node); 510 - atomic_set(&fbo->base.cpu_writers, 0); 511 514 512 515 kref_init(&fbo->base.list_kref); 513 516 kref_init(&fbo->base.kref); 514 517 fbo->base.destroy = &ttm_transfered_destroy; 515 518 fbo->base.acc_size = 0; 516 - fbo->base.base.resv = &fbo->base.base._resv; 517 - dma_resv_init(fbo->base.base.resv); 518 - ret = dma_resv_trylock(fbo->base.base.resv); 519 + if (bo->base.resv == &bo->base._resv) 520 + fbo->base.base.resv = &fbo->base.base._resv; 521 + 522 + dma_resv_init(&fbo->base.base._resv); 523 + ret = dma_resv_trylock(&fbo->base.base._resv); 519 524 WARN_ON(!ret); 520 525 521 526 *new_obj = &fbo->base; ··· 713 716 if (ret) 714 717 return ret; 715 718 716 - dma_resv_add_excl_fence(ghost_obj->base.resv, fence); 719 + dma_resv_add_excl_fence(&ghost_obj->base._resv, fence); 717 720 718 721 /** 719 722 * If we're not moving to fixed memory, the TTM object ··· 726 729 else 727 730 bo->ttm = NULL; 728 731 729 - ttm_bo_unreserve(ghost_obj); 732 + dma_resv_unlock(&ghost_obj->base._resv); 730 733 ttm_bo_put(ghost_obj); 731 734 } 732 735 ··· 769 772 if (ret) 770 773 return ret; 771 774 772 - dma_resv_add_excl_fence(ghost_obj->base.resv, fence); 775 + dma_resv_add_excl_fence(&ghost_obj->base._resv, fence); 773 776 774 777 /** 775 778 * If we're not moving to fixed memory, the TTM object ··· 782 785 else 783 786 bo->ttm = NULL; 784 787 785 - ttm_bo_unreserve(ghost_obj); 788 + dma_resv_unlock(&ghost_obj->base._resv); 786 789 ttm_bo_put(ghost_obj); 787 790 788 791 } else if (from->flags & TTM_MEMTYPE_FLAG_FIXED) { ··· 838 841 if (ret) 839 842 return ret; 840 843 841 - ret = dma_resv_copy_fences(ghost->base.resv, bo->base.resv); 844 + ret = dma_resv_copy_fences(&ghost->base._resv, bo->base.resv); 842 845 /* Last resort, wait for the BO to be idle when we are OOM */ 843 846 if (ret) 844 847 ttm_bo_wait(bo, false, false); ··· 847 850 bo->mem.mem_type = TTM_PL_SYSTEM; 848 851 bo->ttm = NULL; 849 852 850 - ttm_bo_unreserve(ghost); 853 + dma_resv_unlock(&ghost->base._resv); 851 854 ttm_bo_put(ghost); 852 855 853 856 return 0;
+9 -2
drivers/gpu/drm/ttm/ttm_bo_vm.c
··· 177 177 } 178 178 179 179 if (bo->moving != moving) { 180 - spin_lock(&bdev->glob->lru_lock); 180 + spin_lock(&ttm_bo_glob.lru_lock); 181 181 ttm_bo_move_to_lru_tail(bo, NULL); 182 - spin_unlock(&bdev->glob->lru_lock); 182 + spin_unlock(&ttm_bo_glob.lru_lock); 183 183 } 184 184 dma_fence_put(moving); 185 185 } ··· 480 480 int ttm_bo_mmap_obj(struct vm_area_struct *vma, struct ttm_buffer_object *bo) 481 481 { 482 482 ttm_bo_get(bo); 483 + 484 + /* 485 + * FIXME: &drm_gem_object_funcs.mmap is called with the fake offset 486 + * removed. Add it back here until the rest of TTM works without it. 487 + */ 488 + vma->vm_pgoff += drm_vma_node_start(&bo->base.vma_node); 489 + 483 490 ttm_bo_mmap_vma_setup(bo, vma); 484 491 return 0; 485 492 }
+10 -47
drivers/gpu/drm/ttm/ttm_execbuf_util.c
··· 43 43 } 44 44 } 45 45 46 - static void ttm_eu_del_from_lru_locked(struct list_head *list) 47 - { 48 - struct ttm_validate_buffer *entry; 49 - 50 - list_for_each_entry(entry, list, head) { 51 - struct ttm_buffer_object *bo = entry->bo; 52 - ttm_bo_del_from_lru(bo); 53 - } 54 - } 55 - 56 46 void ttm_eu_backoff_reservation(struct ww_acquire_ctx *ticket, 57 47 struct list_head *list) 58 48 { 59 49 struct ttm_validate_buffer *entry; 60 - struct ttm_bo_global *glob; 61 50 62 51 if (list_empty(list)) 63 52 return; 64 53 65 - entry = list_first_entry(list, struct ttm_validate_buffer, head); 66 - glob = entry->bo->bdev->glob; 67 - 68 - spin_lock(&glob->lru_lock); 54 + spin_lock(&ttm_bo_glob.lru_lock); 69 55 list_for_each_entry(entry, list, head) { 70 56 struct ttm_buffer_object *bo = entry->bo; 71 57 72 - if (list_empty(&bo->lru)) 73 - ttm_bo_add_to_lru(bo); 58 + ttm_bo_move_to_lru_tail(bo, NULL); 74 59 dma_resv_unlock(bo->base.resv); 75 60 } 76 - spin_unlock(&glob->lru_lock); 61 + spin_unlock(&ttm_bo_glob.lru_lock); 77 62 78 63 if (ticket) 79 64 ww_acquire_fini(ticket); ··· 79 94 80 95 int ttm_eu_reserve_buffers(struct ww_acquire_ctx *ticket, 81 96 struct list_head *list, bool intr, 82 - struct list_head *dups, bool del_lru) 97 + struct list_head *dups) 83 98 { 84 - struct ttm_bo_global *glob; 85 99 struct ttm_validate_buffer *entry; 86 100 int ret; 87 101 88 102 if (list_empty(list)) 89 103 return 0; 90 - 91 - entry = list_first_entry(list, struct ttm_validate_buffer, head); 92 - glob = entry->bo->bdev->glob; 93 104 94 105 if (ticket) 95 106 ww_acquire_init(ticket, &reservation_ww_class); ··· 94 113 struct ttm_buffer_object *bo = entry->bo; 95 114 96 115 ret = __ttm_bo_reserve(bo, intr, (ticket == NULL), ticket); 97 - if (!ret && unlikely(atomic_read(&bo->cpu_writers) > 0)) { 98 - dma_resv_unlock(bo->base.resv); 99 - 100 - ret = -EBUSY; 101 - 102 - } else if (ret == -EALREADY && dups) { 116 + if (ret == -EALREADY && dups) { 103 117 struct ttm_validate_buffer *safe = entry; 104 118 entry = list_prev_entry(entry, head); 105 119 list_del(&safe->head); ··· 149 173 list_add(&entry->head, list); 150 174 } 151 175 152 - if (del_lru) { 153 - spin_lock(&glob->lru_lock); 154 - ttm_eu_del_from_lru_locked(list); 155 - spin_unlock(&glob->lru_lock); 156 - } 157 176 return 0; 158 177 } 159 178 EXPORT_SYMBOL(ttm_eu_reserve_buffers); ··· 158 187 struct dma_fence *fence) 159 188 { 160 189 struct ttm_validate_buffer *entry; 161 - struct ttm_buffer_object *bo; 162 - struct ttm_bo_global *glob; 163 190 164 191 if (list_empty(list)) 165 192 return; 166 193 167 - bo = list_first_entry(list, struct ttm_validate_buffer, head)->bo; 168 - glob = bo->bdev->glob; 169 - 170 - spin_lock(&glob->lru_lock); 171 - 194 + spin_lock(&ttm_bo_glob.lru_lock); 172 195 list_for_each_entry(entry, list, head) { 173 - bo = entry->bo; 196 + struct ttm_buffer_object *bo = entry->bo; 197 + 174 198 if (entry->num_shared) 175 199 dma_resv_add_shared_fence(bo->base.resv, fence); 176 200 else 177 201 dma_resv_add_excl_fence(bo->base.resv, fence); 178 - if (list_empty(&bo->lru)) 179 - ttm_bo_add_to_lru(bo); 180 - else 181 - ttm_bo_move_to_lru_tail(bo, NULL); 202 + ttm_bo_move_to_lru_tail(bo, NULL); 182 203 dma_resv_unlock(bo->base.resv); 183 204 } 184 - spin_unlock(&glob->lru_lock); 205 + spin_unlock(&ttm_bo_glob.lru_lock); 185 206 if (ticket) 186 207 ww_acquire_fini(ticket); 187 208 }
+1 -1
drivers/gpu/drm/ttm/ttm_memory.c
··· 275 275 276 276 while (ttm_zones_above_swap_target(glob, from_wq, extra)) { 277 277 spin_unlock(&glob->lock); 278 - ret = ttm_bo_swapout(glob->bo_glob, ctx); 278 + ret = ttm_bo_swapout(&ttm_bo_glob, ctx); 279 279 spin_lock(&glob->lock); 280 280 if (unlikely(ret != 0)) 281 281 break;
+2 -2
drivers/gpu/drm/ttm/ttm_page_alloc.c
··· 1028 1028 static void 1029 1029 ttm_pool_unpopulate_helper(struct ttm_tt *ttm, unsigned mem_count_update) 1030 1030 { 1031 - struct ttm_mem_global *mem_glob = ttm->bdev->glob->mem_glob; 1031 + struct ttm_mem_global *mem_glob = &ttm_mem_glob; 1032 1032 unsigned i; 1033 1033 1034 1034 if (mem_count_update == 0) ··· 1049 1049 1050 1050 int ttm_pool_populate(struct ttm_tt *ttm, struct ttm_operation_ctx *ctx) 1051 1051 { 1052 - struct ttm_mem_global *mem_glob = ttm->bdev->glob->mem_glob; 1052 + struct ttm_mem_global *mem_glob = &ttm_mem_glob; 1053 1053 unsigned i; 1054 1054 int ret; 1055 1055
+2 -2
drivers/gpu/drm/ttm/ttm_page_alloc_dma.c
··· 886 886 int ttm_dma_populate(struct ttm_dma_tt *ttm_dma, struct device *dev, 887 887 struct ttm_operation_ctx *ctx) 888 888 { 889 + struct ttm_mem_global *mem_glob = &ttm_mem_glob; 889 890 struct ttm_tt *ttm = &ttm_dma->ttm; 890 - struct ttm_mem_global *mem_glob = ttm->bdev->glob->mem_glob; 891 891 unsigned long num_pages = ttm->num_pages; 892 892 struct dma_pool *pool; 893 893 struct dma_page *d_page; ··· 991 991 /* Put all pages in pages list to correct pool to wait for reuse */ 992 992 void ttm_dma_unpopulate(struct ttm_dma_tt *ttm_dma, struct device *dev) 993 993 { 994 + struct ttm_mem_global *mem_glob = &ttm_mem_glob; 994 995 struct ttm_tt *ttm = &ttm_dma->ttm; 995 - struct ttm_mem_global *mem_glob = ttm->bdev->glob->mem_glob; 996 996 struct dma_pool *pool; 997 997 struct dma_page *d_page, *next; 998 998 enum pool_type type;
+5 -58
drivers/gpu/drm/vboxvideo/vbox_mode.c
··· 334 334 old_state->src_y >> 16); 335 335 } 336 336 337 - static int vbox_primary_prepare_fb(struct drm_plane *plane, 338 - struct drm_plane_state *new_state) 339 - { 340 - struct drm_gem_vram_object *gbo; 341 - int ret; 342 - 343 - if (!new_state->fb) 344 - return 0; 345 - 346 - gbo = drm_gem_vram_of_gem(new_state->fb->obj[0]); 347 - ret = drm_gem_vram_pin(gbo, DRM_GEM_VRAM_PL_FLAG_VRAM); 348 - if (ret) 349 - DRM_WARN("Error %d pinning new fb, out of video mem?\n", ret); 350 - 351 - return ret; 352 - } 353 - 354 - static void vbox_primary_cleanup_fb(struct drm_plane *plane, 355 - struct drm_plane_state *old_state) 356 - { 357 - struct drm_gem_vram_object *gbo; 358 - 359 - if (!old_state->fb) 360 - return; 361 - 362 - gbo = drm_gem_vram_of_gem(old_state->fb->obj[0]); 363 - drm_gem_vram_unpin(gbo); 364 - } 365 - 366 337 static int vbox_cursor_atomic_check(struct drm_plane *plane, 367 338 struct drm_plane_state *new_state) 368 339 { ··· 463 492 mutex_unlock(&vbox->hw_mutex); 464 493 } 465 494 466 - static int vbox_cursor_prepare_fb(struct drm_plane *plane, 467 - struct drm_plane_state *new_state) 468 - { 469 - struct drm_gem_vram_object *gbo; 470 - 471 - if (!new_state->fb) 472 - return 0; 473 - 474 - gbo = drm_gem_vram_of_gem(new_state->fb->obj[0]); 475 - return drm_gem_vram_pin(gbo, DRM_GEM_VRAM_PL_FLAG_SYSTEM); 476 - } 477 - 478 - static void vbox_cursor_cleanup_fb(struct drm_plane *plane, 479 - struct drm_plane_state *old_state) 480 - { 481 - struct drm_gem_vram_object *gbo; 482 - 483 - if (!plane->state->fb) 484 - return; 485 - 486 - gbo = drm_gem_vram_of_gem(plane->state->fb->obj[0]); 487 - drm_gem_vram_unpin(gbo); 488 - } 489 - 490 495 static const u32 vbox_cursor_plane_formats[] = { 491 496 DRM_FORMAT_ARGB8888, 492 497 }; ··· 471 524 .atomic_check = vbox_cursor_atomic_check, 472 525 .atomic_update = vbox_cursor_atomic_update, 473 526 .atomic_disable = vbox_cursor_atomic_disable, 474 - .prepare_fb = vbox_cursor_prepare_fb, 475 - .cleanup_fb = vbox_cursor_cleanup_fb, 527 + .prepare_fb = drm_gem_vram_plane_helper_prepare_fb, 528 + .cleanup_fb = drm_gem_vram_plane_helper_cleanup_fb, 476 529 }; 477 530 478 531 static const struct drm_plane_funcs vbox_cursor_plane_funcs = { ··· 493 546 .atomic_check = vbox_primary_atomic_check, 494 547 .atomic_update = vbox_primary_atomic_update, 495 548 .atomic_disable = vbox_primary_atomic_disable, 496 - .prepare_fb = vbox_primary_prepare_fb, 497 - .cleanup_fb = vbox_primary_cleanup_fb, 549 + .prepare_fb = drm_gem_vram_plane_helper_prepare_fb, 550 + .cleanup_fb = drm_gem_vram_plane_helper_cleanup_fb, 498 551 }; 499 552 500 553 static const struct drm_plane_funcs vbox_primary_plane_funcs = { ··· 837 890 } 838 891 839 892 static const struct drm_mode_config_funcs vbox_mode_funcs = { 840 - .fb_create = drm_gem_fb_create, 893 + .fb_create = drm_gem_fb_create_with_dirty, 841 894 .atomic_check = drm_atomic_helper_check, 842 895 .atomic_commit = drm_atomic_helper_commit, 843 896 };
+12 -5
drivers/gpu/drm/vmwgfx/vmwgfx_bo.c
··· 566 566 567 567 switch (ref_type) { 568 568 case TTM_REF_SYNCCPU_WRITE: 569 - ttm_bo_synccpu_write_release(&user_bo->vbo.base); 569 + atomic_dec(&user_bo->vbo.cpu_writers); 570 570 break; 571 571 default: 572 572 WARN_ONCE(true, "Undefined buffer object reference release.\n"); ··· 682 682 struct ttm_object_file *tfile, 683 683 uint32_t flags) 684 684 { 685 + bool nonblock = !!(flags & drm_vmw_synccpu_dontblock); 685 686 struct ttm_buffer_object *bo = &user_bo->vbo.base; 686 687 bool existed; 687 688 int ret; 688 689 689 690 if (flags & drm_vmw_synccpu_allow_cs) { 690 - bool nonblock = !!(flags & drm_vmw_synccpu_dontblock); 691 691 long lret; 692 692 693 693 lret = dma_resv_wait_timeout_rcu ··· 700 700 return 0; 701 701 } 702 702 703 - ret = ttm_bo_synccpu_write_grab 704 - (bo, !!(flags & drm_vmw_synccpu_dontblock)); 703 + ret = ttm_bo_reserve(bo, true, nonblock, NULL); 704 + if (unlikely(ret != 0)) 705 + return ret; 706 + 707 + ret = ttm_bo_wait(bo, true, nonblock); 708 + if (likely(ret == 0)) 709 + atomic_inc(&user_bo->vbo.cpu_writers); 710 + 711 + ttm_bo_unreserve(bo); 705 712 if (unlikely(ret != 0)) 706 713 return ret; 707 714 708 715 ret = ttm_ref_object_add(tfile, &user_bo->prime.base, 709 716 TTM_REF_SYNCCPU_WRITE, &existed, false); 710 717 if (ret != 0 || existed) 711 - ttm_bo_synccpu_write_release(&user_bo->vbo.base); 718 + atomic_dec(&user_bo->vbo.cpu_writers); 712 719 713 720 return ret; 714 721 }
+3
drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
··· 102 102 * @base: The TTM buffer object 103 103 * @res_list: List of resources using this buffer object as a backing MOB 104 104 * @pin_count: pin depth 105 + * @cpu_writers: Number of synccpu write grabs. Protected by reservation when 106 + * increased. May be decreased without reservation. 105 107 * @dx_query_ctx: DX context if this buffer object is used as a DX query MOB 106 108 * @map: Kmap object for semi-persistent mappings 107 109 * @res_prios: Eviction priority counts for attached resources ··· 112 110 struct ttm_buffer_object base; 113 111 struct list_head res_list; 114 112 s32 pin_count; 113 + atomic_t cpu_writers; 115 114 /* Not ref-counted. Protected by binding_mutex */ 116 115 struct vmw_resource *dx_query_ctx; 117 116 /* Protected by reservation */
+1 -2
drivers/gpu/drm/vmwgfx/vmwgfx_resource.c
··· 492 492 val_buf->bo = &res->backup->base; 493 493 val_buf->num_shared = 0; 494 494 list_add_tail(&val_buf->head, &val_list); 495 - ret = ttm_eu_reserve_buffers(ticket, &val_list, interruptible, NULL, 496 - true); 495 + ret = ttm_eu_reserve_buffers(ticket, &val_list, interruptible, NULL); 497 496 if (unlikely(ret != 0)) 498 497 goto out_no_reserve; 499 498
+3
drivers/gpu/drm/vmwgfx/vmwgfx_validation.c
··· 521 521 }; 522 522 int ret; 523 523 524 + if (atomic_read(&vbo->cpu_writers)) 525 + return -EBUSY; 526 + 524 527 if (vbo->pin_count > 0) 525 528 return 0; 526 529
+1 -1
drivers/gpu/drm/vmwgfx/vmwgfx_validation.h
··· 170 170 bool intr) 171 171 { 172 172 return ttm_eu_reserve_buffers(&ctx->ticket, &ctx->bo_list, intr, 173 - NULL, true); 173 + NULL); 174 174 } 175 175 176 176 /**
+4 -3
drivers/gpu/drm/xen/xen_drm_front_kms.c
··· 270 270 } 271 271 272 272 static enum drm_mode_status 273 - display_mode_valid(struct drm_crtc *crtc, const struct drm_display_mode *mode) 273 + display_mode_valid(struct drm_simple_display_pipe *pipe, 274 + const struct drm_display_mode *mode) 274 275 { 275 276 struct xen_drm_front_drm_pipeline *pipeline = 276 - container_of(crtc, struct xen_drm_front_drm_pipeline, 277 - pipe.crtc); 277 + container_of(pipe, struct xen_drm_front_drm_pipeline, 278 + pipe); 278 279 279 280 if (mode->hdisplay != pipeline->width) 280 281 return MODE_ERROR;
-1
include/drm/drm_fb_helper.h
··· 235 235 236 236 void drm_fb_helper_deferred_io(struct fb_info *info, 237 237 struct list_head *pagelist); 238 - int drm_fb_helper_defio_init(struct drm_fb_helper *fb_helper); 239 238 240 239 ssize_t drm_fb_helper_sys_read(struct fb_info *info, char __user *buf, 241 240 size_t count, loff_t *ppos);
+3 -2
include/drm/drm_gem.h
··· 159 159 * 160 160 * The callback is used by by both drm_gem_mmap_obj() and 161 161 * drm_gem_prime_mmap(). When @mmap is present @vm_ops is not 162 - * used, the @mmap callback must set vma->vm_ops instead. 163 - * 162 + * used, the @mmap callback must set vma->vm_ops instead. The @mmap 163 + * callback is always called with a 0 offset. The caller will remove 164 + * the fake offset as necessary. 164 165 */ 165 166 int (*mmap)(struct drm_gem_object *obj, struct vm_area_struct *vma); 166 167
+25
include/drm/drm_gem_vram_helper.h
··· 13 13 #include <linux/kernel.h> /* for container_of() */ 14 14 15 15 struct drm_mode_create_dumb; 16 + struct drm_plane; 17 + struct drm_plane_state; 18 + struct drm_simple_display_pipe; 16 19 struct drm_vram_mm_funcs; 17 20 struct filp; 18 21 struct vm_area_struct; ··· 126 123 int drm_gem_vram_driver_dumb_mmap_offset(struct drm_file *file, 127 124 struct drm_device *dev, 128 125 uint32_t handle, uint64_t *offset); 126 + 127 + /* 128 + * Helpers for struct drm_plane_helper_funcs 129 + */ 130 + int 131 + drm_gem_vram_plane_helper_prepare_fb(struct drm_plane *plane, 132 + struct drm_plane_state *new_state); 133 + void 134 + drm_gem_vram_plane_helper_cleanup_fb(struct drm_plane *plane, 135 + struct drm_plane_state *old_state); 136 + 137 + /* 138 + * Helpers for struct drm_simple_display_pipe_funcs 139 + */ 140 + 141 + int drm_gem_vram_simple_display_pipe_prepare_fb( 142 + struct drm_simple_display_pipe *pipe, 143 + struct drm_plane_state *new_state); 144 + 145 + void drm_gem_vram_simple_display_pipe_cleanup_fb( 146 + struct drm_simple_display_pipe *pipe, 147 + struct drm_plane_state *old_state); 129 148 130 149 /** 131 150 * define DRM_GEM_VRAM_DRIVER - default callback functions for \
+1 -1
include/drm/drm_simple_kms_helper.h
··· 49 49 * 50 50 * drm_mode_status Enum 51 51 */ 52 - enum drm_mode_status (*mode_valid)(struct drm_crtc *crtc, 52 + enum drm_mode_status (*mode_valid)(struct drm_simple_display_pipe *pipe, 53 53 const struct drm_display_mode *mode); 54 54 55 55 /**
-56
include/drm/ttm/ttm_bo_api.h
··· 147 147 * holds a pointer to a persistent shmem object. 148 148 * @ttm: TTM structure holding system pages. 149 149 * @evicted: Whether the object was evicted without user-space knowing. 150 - * @cpu_writes: For synchronization. Number of cpu writers. 151 150 * @lru: List head for the lru list. 152 151 * @ddestroy: List head for the delayed destroy list. 153 152 * @swap: List head for swap LRU list. ··· 196 197 struct file *persistent_swap_storage; 197 198 struct ttm_tt *ttm; 198 199 bool evicted; 199 - 200 - /** 201 - * Members protected by the bo::reserved lock only when written to. 202 - */ 203 - 204 - atomic_t cpu_writers; 205 200 206 201 /** 207 202 * Members protected by the bdev::lru_lock. ··· 361 368 void ttm_bo_put(struct ttm_buffer_object *bo); 362 369 363 370 /** 364 - * ttm_bo_add_to_lru 365 - * 366 - * @bo: The buffer object. 367 - * 368 - * Add this bo to the relevant mem type lru and, if it's backed by 369 - * system pages (ttms) to the swap list. 370 - * This function must be called with struct ttm_bo_global::lru_lock held, and 371 - * is typically called immediately prior to unreserving a bo. 372 - */ 373 - void ttm_bo_add_to_lru(struct ttm_buffer_object *bo); 374 - 375 - /** 376 - * ttm_bo_del_from_lru 377 - * 378 - * @bo: The buffer object. 379 - * 380 - * Remove this bo from all lru lists used to lookup and reserve an object. 381 - * This function must be called with struct ttm_bo_global::lru_lock held, 382 - * and is usually called just immediately after the bo has been reserved to 383 - * avoid recursive reservation from lru lists. 384 - */ 385 - void ttm_bo_del_from_lru(struct ttm_buffer_object *bo); 386 - 387 - /** 388 371 * ttm_bo_move_to_lru_tail 389 372 * 390 373 * @bo: The buffer object. ··· 409 440 */ 410 441 bool ttm_bo_eviction_valuable(struct ttm_buffer_object *bo, 411 442 const struct ttm_place *place); 412 - 413 - /** 414 - * ttm_bo_synccpu_write_grab 415 - * 416 - * @bo: The buffer object: 417 - * @no_wait: Return immediately if buffer is busy. 418 - * 419 - * Synchronizes a buffer object for CPU RW access. This means 420 - * command submission that affects the buffer will return -EBUSY 421 - * until ttm_bo_synccpu_write_release is called. 422 - * 423 - * Returns 424 - * -EBUSY if the buffer is busy and no_wait is true. 425 - * -ERESTARTSYS if interrupted by a signal. 426 - */ 427 - int ttm_bo_synccpu_write_grab(struct ttm_buffer_object *bo, bool no_wait); 428 - 429 - /** 430 - * ttm_bo_synccpu_write_release: 431 - * 432 - * @bo : The buffer object. 433 - * 434 - * Releases a synccpu lock. 435 - */ 436 - void ttm_bo_synccpu_write_release(struct ttm_buffer_object *bo); 437 443 438 444 /** 439 445 * ttm_bo_acc_size
+5 -21
include/drm/ttm/ttm_bo_driver.h
··· 423 423 */ 424 424 425 425 struct kobject kobj; 426 - struct ttm_mem_global *mem_glob; 427 426 struct page *dummy_read_page; 428 427 spinlock_t lru_lock; 429 428 ··· 466 467 * Constant after bo device init / atomic. 467 468 */ 468 469 struct list_head device_list; 469 - struct ttm_bo_global *glob; 470 470 struct ttm_bo_driver *driver; 471 471 struct ttm_mem_type_manager man[TTM_NUM_MEM_TYPES]; 472 472 ··· 629 631 int ttm_mem_io_lock(struct ttm_mem_type_manager *man, bool interruptible); 630 632 void ttm_mem_io_unlock(struct ttm_mem_type_manager *man); 631 633 632 - void ttm_bo_del_sub_from_lru(struct ttm_buffer_object *bo); 633 - void ttm_bo_add_to_lru(struct ttm_buffer_object *bo); 634 - 635 634 /** 636 635 * __ttm_bo_reserve: 637 636 * ··· 722 727 bool interruptible, bool no_wait, 723 728 struct ww_acquire_ctx *ticket) 724 729 { 725 - int ret; 726 - 727 730 WARN_ON(!kref_read(&bo->kref)); 728 731 729 - ret = __ttm_bo_reserve(bo, interruptible, no_wait, ticket); 730 - if (likely(ret == 0)) 731 - ttm_bo_del_sub_from_lru(bo); 732 - 733 - return ret; 732 + return __ttm_bo_reserve(bo, interruptible, no_wait, ticket); 734 733 } 735 734 736 735 /** ··· 751 762 else 752 763 dma_resv_lock_slow(bo->base.resv, ticket); 753 764 754 - if (likely(ret == 0)) 755 - ttm_bo_del_sub_from_lru(bo); 756 - else if (ret == -EINTR) 765 + if (ret == -EINTR) 757 766 ret = -ERESTARTSYS; 758 767 759 768 return ret; ··· 766 779 */ 767 780 static inline void ttm_bo_unreserve(struct ttm_buffer_object *bo) 768 781 { 769 - spin_lock(&bo->bdev->glob->lru_lock); 770 - if (list_empty(&bo->lru)) 771 - ttm_bo_add_to_lru(bo); 772 - else 773 - ttm_bo_move_to_lru_tail(bo, NULL); 774 - spin_unlock(&bo->bdev->glob->lru_lock); 782 + spin_lock(&ttm_bo_glob.lru_lock); 783 + ttm_bo_move_to_lru_tail(bo, NULL); 784 + spin_unlock(&ttm_bo_glob.lru_lock); 775 785 dma_resv_unlock(bo->base.resv); 776 786 } 777 787
+1 -1
include/drm/ttm/ttm_execbuf_util.h
··· 99 99 100 100 extern int ttm_eu_reserve_buffers(struct ww_acquire_ctx *ticket, 101 101 struct list_head *list, bool intr, 102 - struct list_head *dups, bool del_lru); 102 + struct list_head *dups); 103 103 104 104 /** 105 105 * function ttm_eu_fence_buffer_objects.
-1
include/drm/ttm/ttm_memory.h
··· 65 65 struct ttm_mem_zone; 66 66 extern struct ttm_mem_global { 67 67 struct kobject kobj; 68 - struct ttm_bo_global *bo_glob; 69 68 struct workqueue_struct *swap_queue; 70 69 struct work_struct work; 71 70 spinlock_t lock;
+57 -6
include/linux/dma-buf.h
··· 43 43 bool cache_sgt_mapping; 44 44 45 45 /** 46 + * @dynamic_mapping: 47 + * 48 + * If true the framework makes sure that the map/unmap_dma_buf 49 + * callbacks are always called with the dma_resv object locked. 50 + * 51 + * If false the framework makes sure that the map/unmap_dma_buf 52 + * callbacks are always called without the dma_resv object locked. 53 + * Mutual exclusive with @cache_sgt_mapping. 54 + */ 55 + bool dynamic_mapping; 56 + 57 + /** 46 58 * @attach: 47 59 * 48 60 * This is called from dma_buf_attach() to make sure that a given ··· 120 108 * multiple users accessing at the same time (for reading, maybe), or 121 109 * any other kind of sharing that the exporter might wish to make 122 110 * available to buffer-users. 111 + * 112 + * This is always called with the dmabuf->resv object locked when 113 + * the dynamic_mapping flag is true. 123 114 * 124 115 * Returns: 125 116 * ··· 282 267 * struct dma_buf - shared buffer object 283 268 * @size: size of the buffer 284 269 * @file: file pointer used for sharing buffers across, and for refcounting. 285 - * @attachments: list of dma_buf_attachment that denotes all devices attached. 270 + * @attachments: list of dma_buf_attachment that denotes all devices attached, 271 + * protected by dma_resv lock. 286 272 * @ops: dma_buf_ops associated with this buffer object. 287 273 * @lock: used internally to serialize list manipulation, attach/detach and 288 - * vmap/unmap, and accesses to name 274 + * vmap/unmap 289 275 * @vmapping_counter: used internally to refcnt the vmaps 290 276 * @vmap_ptr: the current vmap ptr if vmapping_counter > 0 291 277 * @exp_name: name of the exporter; useful for debugging. 292 - * @name: userspace-provided name; useful for accounting and debugging. 278 + * @name: userspace-provided name; useful for accounting and debugging, 279 + * protected by @resv. 293 280 * @owner: pointer to exporter module; used for refcounting when exporter is a 294 281 * kernel module. 295 282 * @list_node: node for dma_buf accounting and debugging. ··· 340 323 * struct dma_buf_attachment - holds device-buffer attachment data 341 324 * @dmabuf: buffer for this attachment. 342 325 * @dev: device attached to the buffer. 343 - * @node: list of dma_buf_attachment. 326 + * @node: list of dma_buf_attachment, protected by dma_resv lock of the dmabuf. 344 327 * @sgt: cached mapping. 345 328 * @dir: direction of cached mapping. 346 329 * @priv: exporter specific attachment data. 330 + * @dynamic_mapping: true if dma_buf_map/unmap_attachment() is called with the 331 + * dma_resv lock held. 347 332 * 348 333 * This structure holds the attachment information between the dma_buf buffer 349 334 * and its user device(s). The list contains one attachment struct per device ··· 362 343 struct list_head node; 363 344 struct sg_table *sgt; 364 345 enum dma_data_direction dir; 346 + bool dynamic_mapping; 365 347 void *priv; 366 348 }; 367 349 ··· 414 394 get_file(dmabuf->file); 415 395 } 416 396 397 + /** 398 + * dma_buf_is_dynamic - check if a DMA-buf uses dynamic mappings. 399 + * @dmabuf: the DMA-buf to check 400 + * 401 + * Returns true if a DMA-buf exporter wants to be called with the dma_resv 402 + * locked for the map/unmap callbacks, false if it doesn't wants to be called 403 + * with the lock held. 404 + */ 405 + static inline bool dma_buf_is_dynamic(struct dma_buf *dmabuf) 406 + { 407 + return dmabuf->ops->dynamic_mapping; 408 + } 409 + 410 + /** 411 + * dma_buf_attachment_is_dynamic - check if a DMA-buf attachment uses dynamic 412 + * mappinsg 413 + * @attach: the DMA-buf attachment to check 414 + * 415 + * Returns true if a DMA-buf importer wants to call the map/unmap functions with 416 + * the dma_resv lock held. 417 + */ 418 + static inline bool 419 + dma_buf_attachment_is_dynamic(struct dma_buf_attachment *attach) 420 + { 421 + return attach->dynamic_mapping; 422 + } 423 + 417 424 struct dma_buf_attachment *dma_buf_attach(struct dma_buf *dmabuf, 418 - struct device *dev); 425 + struct device *dev); 426 + struct dma_buf_attachment * 427 + dma_buf_dynamic_attach(struct dma_buf *dmabuf, struct device *dev, 428 + bool dynamic_mapping); 419 429 void dma_buf_detach(struct dma_buf *dmabuf, 420 - struct dma_buf_attachment *dmabuf_attach); 430 + struct dma_buf_attachment *attach); 421 431 422 432 struct dma_buf *dma_buf_export(const struct dma_buf_export_info *exp_info); 423 433 ··· 459 409 enum dma_data_direction); 460 410 void dma_buf_unmap_attachment(struct dma_buf_attachment *, struct sg_table *, 461 411 enum dma_data_direction); 412 + void dma_buf_move_notify(struct dma_buf *dma_buf); 462 413 int dma_buf_begin_cpu_access(struct dma_buf *dma_buf, 463 414 enum dma_data_direction dir); 464 415 int dma_buf_end_cpu_access(struct dma_buf *dma_buf,
+1 -1
include/uapi/drm/exynos_drm.h
··· 68 68 /** 69 69 * A structure for user connection request of virtual display. 70 70 * 71 - * @connection: indicate whether doing connetion or not by user. 71 + * @connection: indicate whether doing connection or not by user. 72 72 * @extensions: if this value is 1 then the vidi driver would need additional 73 73 * 128bytes edid data. 74 74 * @edid: the edid data pointer from user side.