.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * Copyright © 2015 Broadcom |
---|
3 | | - * |
---|
4 | | - * This program is free software; you can redistribute it and/or modify |
---|
5 | | - * it under the terms of the GNU General Public License version 2 as |
---|
6 | | - * published by the Free Software Foundation. |
---|
7 | 4 | */ |
---|
8 | 5 | |
---|
9 | 6 | /** |
---|
.. | .. |
---|
40 | 37 | return label >= VC4_BO_TYPE_COUNT; |
---|
41 | 38 | } |
---|
42 | 39 | |
---|
43 | | -static void vc4_bo_stats_dump(struct vc4_dev *vc4) |
---|
| 40 | +static void vc4_bo_stats_print(struct drm_printer *p, struct vc4_dev *vc4) |
---|
44 | 41 | { |
---|
45 | 42 | int i; |
---|
46 | 43 | |
---|
.. | .. |
---|
48 | 45 | if (!vc4->bo_labels[i].num_allocated) |
---|
49 | 46 | continue; |
---|
50 | 47 | |
---|
51 | | - DRM_INFO("%30s: %6dkb BOs (%d)\n", |
---|
52 | | - vc4->bo_labels[i].name, |
---|
53 | | - vc4->bo_labels[i].size_allocated / 1024, |
---|
54 | | - vc4->bo_labels[i].num_allocated); |
---|
55 | | - } |
---|
56 | | - |
---|
57 | | - mutex_lock(&vc4->purgeable.lock); |
---|
58 | | - if (vc4->purgeable.num) |
---|
59 | | - DRM_INFO("%30s: %6zdkb BOs (%d)\n", "userspace BO cache", |
---|
60 | | - vc4->purgeable.size / 1024, vc4->purgeable.num); |
---|
61 | | - |
---|
62 | | - if (vc4->purgeable.purged_num) |
---|
63 | | - DRM_INFO("%30s: %6zdkb BOs (%d)\n", "total purged BO", |
---|
64 | | - vc4->purgeable.purged_size / 1024, |
---|
65 | | - vc4->purgeable.purged_num); |
---|
66 | | - mutex_unlock(&vc4->purgeable.lock); |
---|
67 | | -} |
---|
68 | | - |
---|
69 | | -#ifdef CONFIG_DEBUG_FS |
---|
70 | | -int vc4_bo_stats_debugfs(struct seq_file *m, void *unused) |
---|
71 | | -{ |
---|
72 | | - struct drm_info_node *node = (struct drm_info_node *)m->private; |
---|
73 | | - struct drm_device *dev = node->minor->dev; |
---|
74 | | - struct vc4_dev *vc4 = to_vc4_dev(dev); |
---|
75 | | - int i; |
---|
76 | | - |
---|
77 | | - mutex_lock(&vc4->bo_lock); |
---|
78 | | - for (i = 0; i < vc4->num_labels; i++) { |
---|
79 | | - if (!vc4->bo_labels[i].num_allocated) |
---|
80 | | - continue; |
---|
81 | | - |
---|
82 | | - seq_printf(m, "%30s: %6dkb BOs (%d)\n", |
---|
| 48 | + drm_printf(p, "%30s: %6dkb BOs (%d)\n", |
---|
83 | 49 | vc4->bo_labels[i].name, |
---|
84 | 50 | vc4->bo_labels[i].size_allocated / 1024, |
---|
85 | 51 | vc4->bo_labels[i].num_allocated); |
---|
86 | 52 | } |
---|
87 | | - mutex_unlock(&vc4->bo_lock); |
---|
88 | 53 | |
---|
89 | 54 | mutex_lock(&vc4->purgeable.lock); |
---|
90 | 55 | if (vc4->purgeable.num) |
---|
91 | | - seq_printf(m, "%30s: %6zdkb BOs (%d)\n", "userspace BO cache", |
---|
| 56 | + drm_printf(p, "%30s: %6zdkb BOs (%d)\n", "userspace BO cache", |
---|
92 | 57 | vc4->purgeable.size / 1024, vc4->purgeable.num); |
---|
93 | 58 | |
---|
94 | 59 | if (vc4->purgeable.purged_num) |
---|
95 | | - seq_printf(m, "%30s: %6zdkb BOs (%d)\n", "total purged BO", |
---|
| 60 | + drm_printf(p, "%30s: %6zdkb BOs (%d)\n", "total purged BO", |
---|
96 | 61 | vc4->purgeable.purged_size / 1024, |
---|
97 | 62 | vc4->purgeable.purged_num); |
---|
98 | 63 | mutex_unlock(&vc4->purgeable.lock); |
---|
| 64 | +} |
---|
| 65 | + |
---|
| 66 | +static int vc4_bo_stats_debugfs(struct seq_file *m, void *unused) |
---|
| 67 | +{ |
---|
| 68 | + struct drm_info_node *node = (struct drm_info_node *)m->private; |
---|
| 69 | + struct drm_device *dev = node->minor->dev; |
---|
| 70 | + struct vc4_dev *vc4 = to_vc4_dev(dev); |
---|
| 71 | + struct drm_printer p = drm_seq_file_printer(m); |
---|
| 72 | + |
---|
| 73 | + vc4_bo_stats_print(&p, vc4); |
---|
99 | 74 | |
---|
100 | 75 | return 0; |
---|
101 | 76 | } |
---|
102 | | -#endif |
---|
103 | 77 | |
---|
104 | 78 | /* Takes ownership of *name and returns the appropriate slot for it in |
---|
105 | 79 | * the bo_labels[] array, extending it as necessary. |
---|
.. | .. |
---|
200 | 174 | kfree(bo->validated_shader); |
---|
201 | 175 | bo->validated_shader = NULL; |
---|
202 | 176 | } |
---|
203 | | - |
---|
204 | | - reservation_object_fini(&bo->_resv); |
---|
205 | 177 | |
---|
206 | 178 | drm_gem_cma_free_object(obj); |
---|
207 | 179 | } |
---|
.. | .. |
---|
427 | 399 | vc4->bo_labels[VC4_BO_TYPE_KERNEL].num_allocated++; |
---|
428 | 400 | vc4->bo_labels[VC4_BO_TYPE_KERNEL].size_allocated += size; |
---|
429 | 401 | mutex_unlock(&vc4->bo_lock); |
---|
430 | | - bo->resv = &bo->_resv; |
---|
431 | | - reservation_object_init(bo->resv); |
---|
432 | 402 | |
---|
433 | 403 | return &bo->base.base; |
---|
434 | 404 | } |
---|
.. | .. |
---|
479 | 449 | } |
---|
480 | 450 | |
---|
481 | 451 | if (IS_ERR(cma_obj)) { |
---|
| 452 | + struct drm_printer p = drm_info_printer(vc4->base.dev); |
---|
482 | 453 | DRM_ERROR("Failed to allocate from CMA:\n"); |
---|
483 | | - vc4_bo_stats_dump(vc4); |
---|
| 454 | + vc4_bo_stats_print(&p, vc4); |
---|
484 | 455 | return ERR_PTR(-ENOMEM); |
---|
485 | 456 | } |
---|
486 | 457 | bo = to_vc4_bo(&cma_obj->base); |
---|
.. | .. |
---|
519 | 490 | bo->madv = VC4_MADV_WILLNEED; |
---|
520 | 491 | |
---|
521 | 492 | ret = drm_gem_handle_create(file_priv, &bo->base.base, &args->handle); |
---|
522 | | - drm_gem_object_put_unlocked(&bo->base.base); |
---|
| 493 | + drm_gem_object_put(&bo->base.base); |
---|
523 | 494 | |
---|
524 | 495 | return ret; |
---|
525 | 496 | } |
---|
.. | .. |
---|
619 | 590 | { |
---|
620 | 591 | struct vc4_dev *vc4 = |
---|
621 | 592 | container_of(work, struct vc4_dev, bo_cache.time_work); |
---|
622 | | - struct drm_device *dev = vc4->dev; |
---|
| 593 | + struct drm_device *dev = &vc4->base; |
---|
623 | 594 | |
---|
624 | 595 | mutex_lock(&vc4->bo_lock); |
---|
625 | 596 | vc4_bo_cache_free_old(dev); |
---|
.. | .. |
---|
684 | 655 | schedule_work(&vc4->bo_cache.time_work); |
---|
685 | 656 | } |
---|
686 | 657 | |
---|
687 | | -struct reservation_object *vc4_prime_res_obj(struct drm_gem_object *obj) |
---|
688 | | -{ |
---|
689 | | - struct vc4_bo *bo = to_vc4_bo(obj); |
---|
690 | | - |
---|
691 | | - return bo->resv; |
---|
692 | | -} |
---|
693 | | - |
---|
694 | | -struct dma_buf * |
---|
695 | | -vc4_prime_export(struct drm_device *dev, struct drm_gem_object *obj, int flags) |
---|
| 658 | +struct dma_buf * vc4_prime_export(struct drm_gem_object *obj, int flags) |
---|
696 | 659 | { |
---|
697 | 660 | struct vc4_bo *bo = to_vc4_bo(obj); |
---|
698 | 661 | struct dma_buf *dmabuf; |
---|
.. | .. |
---|
714 | 677 | return ERR_PTR(ret); |
---|
715 | 678 | } |
---|
716 | 679 | |
---|
717 | | - dmabuf = drm_gem_prime_export(dev, obj, flags); |
---|
| 680 | + dmabuf = drm_gem_prime_export(obj, flags); |
---|
718 | 681 | if (IS_ERR(dmabuf)) |
---|
719 | 682 | vc4_bo_dec_usecnt(bo); |
---|
720 | 683 | |
---|
.. | .. |
---|
822 | 785 | struct sg_table *sgt) |
---|
823 | 786 | { |
---|
824 | 787 | struct drm_gem_object *obj; |
---|
825 | | - struct vc4_bo *bo; |
---|
826 | 788 | |
---|
827 | 789 | obj = drm_gem_cma_prime_import_sg_table(dev, attach, sgt); |
---|
828 | 790 | if (IS_ERR(obj)) |
---|
829 | 791 | return obj; |
---|
830 | 792 | |
---|
831 | | - bo = to_vc4_bo(obj); |
---|
832 | | - bo->resv = attach->dmabuf->resv; |
---|
833 | | - |
---|
834 | 793 | return obj; |
---|
| 794 | +} |
---|
| 795 | + |
---|
| 796 | +static int vc4_grab_bin_bo(struct vc4_dev *vc4, struct vc4_file *vc4file) |
---|
| 797 | +{ |
---|
| 798 | + int ret; |
---|
| 799 | + |
---|
| 800 | + if (!vc4->v3d) |
---|
| 801 | + return -ENODEV; |
---|
| 802 | + |
---|
| 803 | + if (vc4file->bin_bo_used) |
---|
| 804 | + return 0; |
---|
| 805 | + |
---|
| 806 | + ret = vc4_v3d_bin_bo_get(vc4, &vc4file->bin_bo_used); |
---|
| 807 | + if (ret) |
---|
| 808 | + return ret; |
---|
| 809 | + |
---|
| 810 | + return 0; |
---|
835 | 811 | } |
---|
836 | 812 | |
---|
837 | 813 | int vc4_create_bo_ioctl(struct drm_device *dev, void *data, |
---|
838 | 814 | struct drm_file *file_priv) |
---|
839 | 815 | { |
---|
840 | 816 | struct drm_vc4_create_bo *args = data; |
---|
| 817 | + struct vc4_file *vc4file = file_priv->driver_priv; |
---|
| 818 | + struct vc4_dev *vc4 = to_vc4_dev(dev); |
---|
841 | 819 | struct vc4_bo *bo = NULL; |
---|
842 | 820 | int ret; |
---|
| 821 | + |
---|
| 822 | + ret = vc4_grab_bin_bo(vc4, vc4file); |
---|
| 823 | + if (ret) |
---|
| 824 | + return ret; |
---|
843 | 825 | |
---|
844 | 826 | /* |
---|
845 | 827 | * We can't allocate from the BO cache, because the BOs don't |
---|
.. | .. |
---|
852 | 834 | bo->madv = VC4_MADV_WILLNEED; |
---|
853 | 835 | |
---|
854 | 836 | ret = drm_gem_handle_create(file_priv, &bo->base.base, &args->handle); |
---|
855 | | - drm_gem_object_put_unlocked(&bo->base.base); |
---|
| 837 | + drm_gem_object_put(&bo->base.base); |
---|
856 | 838 | |
---|
857 | 839 | return ret; |
---|
858 | 840 | } |
---|
.. | .. |
---|
872 | 854 | /* The mmap offset was set up at BO allocation time. */ |
---|
873 | 855 | args->offset = drm_vma_node_offset_addr(&gem_obj->vma_node); |
---|
874 | 856 | |
---|
875 | | - drm_gem_object_put_unlocked(gem_obj); |
---|
| 857 | + drm_gem_object_put(gem_obj); |
---|
876 | 858 | return 0; |
---|
877 | 859 | } |
---|
878 | 860 | |
---|
.. | .. |
---|
881 | 863 | struct drm_file *file_priv) |
---|
882 | 864 | { |
---|
883 | 865 | struct drm_vc4_create_shader_bo *args = data; |
---|
| 866 | + struct vc4_file *vc4file = file_priv->driver_priv; |
---|
| 867 | + struct vc4_dev *vc4 = to_vc4_dev(dev); |
---|
884 | 868 | struct vc4_bo *bo = NULL; |
---|
885 | 869 | int ret; |
---|
886 | 870 | |
---|
.. | .. |
---|
899 | 883 | DRM_INFO("Pad set: 0x%08x\n", args->pad); |
---|
900 | 884 | return -EINVAL; |
---|
901 | 885 | } |
---|
| 886 | + |
---|
| 887 | + ret = vc4_grab_bin_bo(vc4, vc4file); |
---|
| 888 | + if (ret) |
---|
| 889 | + return ret; |
---|
902 | 890 | |
---|
903 | 891 | bo = vc4_bo_create(dev, args->size, true, VC4_BO_TYPE_V3D_SHADER); |
---|
904 | 892 | if (IS_ERR(bo)) |
---|
.. | .. |
---|
929 | 917 | */ |
---|
930 | 918 | ret = drm_gem_handle_create(file_priv, &bo->base.base, &args->handle); |
---|
931 | 919 | |
---|
932 | | - fail: |
---|
933 | | - drm_gem_object_put_unlocked(&bo->base.base); |
---|
| 920 | +fail: |
---|
| 921 | + drm_gem_object_put(&bo->base.base); |
---|
934 | 922 | |
---|
935 | 923 | return ret; |
---|
936 | 924 | } |
---|
.. | .. |
---|
977 | 965 | bo = to_vc4_bo(gem_obj); |
---|
978 | 966 | bo->t_format = t_format; |
---|
979 | 967 | |
---|
980 | | - drm_gem_object_put_unlocked(gem_obj); |
---|
| 968 | + drm_gem_object_put(gem_obj); |
---|
981 | 969 | |
---|
982 | 970 | return 0; |
---|
983 | 971 | } |
---|
.. | .. |
---|
1012 | 1000 | else |
---|
1013 | 1001 | args->modifier = DRM_FORMAT_MOD_NONE; |
---|
1014 | 1002 | |
---|
1015 | | - drm_gem_object_put_unlocked(gem_obj); |
---|
| 1003 | + drm_gem_object_put(gem_obj); |
---|
1016 | 1004 | |
---|
1017 | 1005 | return 0; |
---|
1018 | 1006 | } |
---|
1019 | 1007 | |
---|
| 1008 | +static void vc4_bo_cache_destroy(struct drm_device *dev, void *unused); |
---|
1020 | 1009 | int vc4_bo_cache_init(struct drm_device *dev) |
---|
1021 | 1010 | { |
---|
1022 | 1011 | struct vc4_dev *vc4 = to_vc4_dev(dev); |
---|
.. | .. |
---|
1038 | 1027 | |
---|
1039 | 1028 | mutex_init(&vc4->bo_lock); |
---|
1040 | 1029 | |
---|
| 1030 | + vc4_debugfs_add_file(dev, "bo_stats", vc4_bo_stats_debugfs, NULL); |
---|
| 1031 | + |
---|
1041 | 1032 | INIT_LIST_HEAD(&vc4->bo_cache.time_list); |
---|
1042 | 1033 | |
---|
1043 | 1034 | INIT_WORK(&vc4->bo_cache.time_work, vc4_bo_cache_time_work); |
---|
1044 | 1035 | timer_setup(&vc4->bo_cache.time_timer, vc4_bo_cache_time_timer, 0); |
---|
1045 | 1036 | |
---|
1046 | | - return 0; |
---|
| 1037 | + return drmm_add_action_or_reset(dev, vc4_bo_cache_destroy, NULL); |
---|
1047 | 1038 | } |
---|
1048 | 1039 | |
---|
1049 | | -void vc4_bo_cache_destroy(struct drm_device *dev) |
---|
| 1040 | +static void vc4_bo_cache_destroy(struct drm_device *dev, void *unused) |
---|
1050 | 1041 | { |
---|
1051 | 1042 | struct vc4_dev *vc4 = to_vc4_dev(dev); |
---|
1052 | 1043 | int i; |
---|
.. | .. |
---|
1101 | 1092 | ret = -ENOMEM; |
---|
1102 | 1093 | mutex_unlock(&vc4->bo_lock); |
---|
1103 | 1094 | |
---|
1104 | | - drm_gem_object_put_unlocked(gem_obj); |
---|
| 1095 | + drm_gem_object_put(gem_obj); |
---|
1105 | 1096 | |
---|
1106 | 1097 | return ret; |
---|
1107 | 1098 | } |
---|