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

Configure Feed

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

drm/ttm/tests: Add eviction testing

Add tests for ttm_bo_validate that focus on BO eviction and swapout.
Update device funcs definition with eviction-related callbacks. Add
alternative funcs where evict_flags() routes eviction to a domain
that can't allocate resources (dubbed "busy manager" in the tests).
Extract the common path of ttm_device init into a function.

Signed-off-by: Karolina Stolarek <karolina.stolarek@intel.com>
Reviewed-by: Somalapuram, Amaranath <asomalap@amd.com>
Tested-by: Somalapuram, Amaranath <asomalap@amd.com>
Signed-off-by: Arunpravin Paneer Selvam <Arunpravin.PaneerSelvam@amd.com>
Link: https://patchwork.freedesktop.org/patch/msgid/ae8e284d6c7e6bd0be259052bd4f42e07ce24641.1718192625.git.karolina.stolarek@intel.com

authored by

Karolina Stolarek and committed by
Arunpravin Paneer Selvam
5fe39433 8eda41df

+569 -10
+433
drivers/gpu/drm/ttm/tests/ttm_bo_validate_test.c
··· 757 757 ttm_mock_manager_fini(priv->ttm_dev, snd_mem); 758 758 } 759 759 760 + static void ttm_bo_validate_swapout(struct kunit *test) 761 + { 762 + unsigned long size_big, size = ALIGN(BO_SIZE, PAGE_SIZE); 763 + enum ttm_bo_type bo_type = ttm_bo_type_device; 764 + struct ttm_buffer_object *bo_small, *bo_big; 765 + struct ttm_test_devices *priv = test->priv; 766 + struct ttm_operation_ctx ctx = { }; 767 + struct ttm_placement *placement; 768 + u32 mem_type = TTM_PL_TT; 769 + struct ttm_place *place; 770 + struct sysinfo si; 771 + int err; 772 + 773 + si_meminfo(&si); 774 + size_big = ALIGN(((u64)si.totalram * si.mem_unit / 2), PAGE_SIZE); 775 + 776 + ttm_mock_manager_init(priv->ttm_dev, mem_type, size_big + size); 777 + 778 + place = ttm_place_kunit_init(test, mem_type, 0); 779 + placement = ttm_placement_kunit_init(test, place, 1); 780 + 781 + bo_small = kunit_kzalloc(test, sizeof(*bo_small), GFP_KERNEL); 782 + KUNIT_ASSERT_NOT_NULL(test, bo_small); 783 + 784 + drm_gem_private_object_init(priv->drm, &bo_small->base, size); 785 + 786 + err = ttm_bo_init_reserved(priv->ttm_dev, bo_small, bo_type, placement, 787 + PAGE_SIZE, &ctx, NULL, NULL, 788 + &dummy_ttm_bo_destroy); 789 + KUNIT_EXPECT_EQ(test, err, 0); 790 + dma_resv_unlock(bo_small->base.resv); 791 + 792 + bo_big = ttm_bo_kunit_init(test, priv, size_big, NULL); 793 + 794 + dma_resv_lock(bo_big->base.resv, NULL); 795 + err = ttm_bo_validate(bo_big, placement, &ctx); 796 + dma_resv_unlock(bo_big->base.resv); 797 + 798 + KUNIT_EXPECT_EQ(test, err, 0); 799 + KUNIT_EXPECT_NOT_NULL(test, bo_big->resource); 800 + KUNIT_EXPECT_EQ(test, bo_big->resource->mem_type, mem_type); 801 + KUNIT_EXPECT_EQ(test, bo_small->resource->mem_type, TTM_PL_SYSTEM); 802 + KUNIT_EXPECT_TRUE(test, bo_small->ttm->page_flags & TTM_TT_FLAG_SWAPPED); 803 + 804 + ttm_bo_put(bo_big); 805 + ttm_bo_put(bo_small); 806 + 807 + ttm_mock_manager_fini(priv->ttm_dev, mem_type); 808 + } 809 + 810 + static void ttm_bo_validate_happy_evict(struct kunit *test) 811 + { 812 + u32 mem_type = TTM_PL_VRAM, mem_multihop = TTM_PL_TT, 813 + mem_type_evict = TTM_PL_SYSTEM; 814 + struct ttm_operation_ctx ctx_init = { }, ctx_val = { }; 815 + enum ttm_bo_type bo_type = ttm_bo_type_device; 816 + u32 small = SZ_8K, medium = SZ_512K, 817 + big = MANAGER_SIZE - (small + medium); 818 + u32 bo_sizes[] = { small, medium, big }; 819 + struct ttm_test_devices *priv = test->priv; 820 + struct ttm_buffer_object *bos, *bo_val; 821 + struct ttm_placement *placement; 822 + struct ttm_place *place; 823 + u32 bo_no = 3; 824 + int i, err; 825 + 826 + ttm_mock_manager_init(priv->ttm_dev, mem_type, MANAGER_SIZE); 827 + ttm_mock_manager_init(priv->ttm_dev, mem_multihop, MANAGER_SIZE); 828 + 829 + place = ttm_place_kunit_init(test, mem_type, 0); 830 + placement = ttm_placement_kunit_init(test, place, 1); 831 + 832 + bos = kunit_kmalloc_array(test, bo_no, sizeof(*bos), GFP_KERNEL); 833 + KUNIT_ASSERT_NOT_NULL(test, bos); 834 + 835 + memset(bos, 0, sizeof(*bos) * bo_no); 836 + for (i = 0; i < bo_no; i++) { 837 + drm_gem_private_object_init(priv->drm, &bos[i].base, bo_sizes[i]); 838 + err = ttm_bo_init_reserved(priv->ttm_dev, &bos[i], bo_type, placement, 839 + PAGE_SIZE, &ctx_init, NULL, NULL, 840 + &dummy_ttm_bo_destroy); 841 + dma_resv_unlock(bos[i].base.resv); 842 + } 843 + 844 + bo_val = ttm_bo_kunit_init(test, test->priv, BO_SIZE, NULL); 845 + bo_val->type = bo_type; 846 + 847 + ttm_bo_reserve(bo_val, false, false, NULL); 848 + err = ttm_bo_validate(bo_val, placement, &ctx_val); 849 + ttm_bo_unreserve(bo_val); 850 + 851 + KUNIT_EXPECT_EQ(test, err, 0); 852 + KUNIT_EXPECT_EQ(test, bos[0].resource->mem_type, mem_type_evict); 853 + KUNIT_EXPECT_TRUE(test, bos[0].ttm->page_flags & TTM_TT_FLAG_ZERO_ALLOC); 854 + KUNIT_EXPECT_TRUE(test, bos[0].ttm->page_flags & TTM_TT_FLAG_PRIV_POPULATED); 855 + KUNIT_EXPECT_EQ(test, ctx_val.bytes_moved, small * 2 + BO_SIZE); 856 + KUNIT_EXPECT_EQ(test, bos[1].resource->mem_type, mem_type); 857 + 858 + for (i = 0; i < bo_no; i++) 859 + ttm_bo_put(&bos[i]); 860 + ttm_bo_put(bo_val); 861 + 862 + ttm_mock_manager_fini(priv->ttm_dev, mem_type); 863 + ttm_mock_manager_fini(priv->ttm_dev, mem_multihop); 864 + } 865 + 866 + static void ttm_bo_validate_all_pinned_evict(struct kunit *test) 867 + { 868 + struct ttm_operation_ctx ctx_init = { }, ctx_val = { }; 869 + enum ttm_bo_type bo_type = ttm_bo_type_device; 870 + struct ttm_buffer_object *bo_big, *bo_small; 871 + struct ttm_test_devices *priv = test->priv; 872 + struct ttm_placement *placement; 873 + u32 mem_type = TTM_PL_VRAM, mem_multihop = TTM_PL_TT; 874 + struct ttm_place *place; 875 + int err; 876 + 877 + ttm_mock_manager_init(priv->ttm_dev, mem_type, MANAGER_SIZE); 878 + ttm_mock_manager_init(priv->ttm_dev, mem_multihop, MANAGER_SIZE); 879 + 880 + place = ttm_place_kunit_init(test, mem_type, 0); 881 + placement = ttm_placement_kunit_init(test, place, 1); 882 + 883 + bo_big = kunit_kzalloc(test, sizeof(*bo_big), GFP_KERNEL); 884 + KUNIT_ASSERT_NOT_NULL(test, bo_big); 885 + 886 + drm_gem_private_object_init(priv->drm, &bo_big->base, MANAGER_SIZE); 887 + err = ttm_bo_init_reserved(priv->ttm_dev, bo_big, bo_type, placement, 888 + PAGE_SIZE, &ctx_init, NULL, NULL, 889 + &dummy_ttm_bo_destroy); 890 + KUNIT_EXPECT_EQ(test, err, 0); 891 + 892 + ttm_bo_pin(bo_big); 893 + dma_resv_unlock(bo_big->base.resv); 894 + 895 + bo_small = ttm_bo_kunit_init(test, test->priv, BO_SIZE, NULL); 896 + bo_small->type = bo_type; 897 + 898 + ttm_bo_reserve(bo_small, false, false, NULL); 899 + err = ttm_bo_validate(bo_small, placement, &ctx_val); 900 + ttm_bo_unreserve(bo_small); 901 + 902 + KUNIT_EXPECT_EQ(test, err, -ENOMEM); 903 + 904 + ttm_bo_put(bo_small); 905 + 906 + ttm_bo_reserve(bo_big, false, false, NULL); 907 + ttm_bo_unpin(bo_big); 908 + dma_resv_unlock(bo_big->base.resv); 909 + ttm_bo_put(bo_big); 910 + 911 + ttm_mock_manager_fini(priv->ttm_dev, mem_type); 912 + ttm_mock_manager_fini(priv->ttm_dev, mem_multihop); 913 + } 914 + 915 + static void ttm_bo_validate_allowed_only_evict(struct kunit *test) 916 + { 917 + u32 mem_type = TTM_PL_VRAM, mem_multihop = TTM_PL_TT, 918 + mem_type_evict = TTM_PL_SYSTEM; 919 + struct ttm_buffer_object *bo, *bo_evictable, *bo_pinned; 920 + struct ttm_operation_ctx ctx_init = { }, ctx_val = { }; 921 + enum ttm_bo_type bo_type = ttm_bo_type_device; 922 + struct ttm_test_devices *priv = test->priv; 923 + struct ttm_placement *placement; 924 + struct ttm_place *place; 925 + u32 size = SZ_512K; 926 + int err; 927 + 928 + ttm_mock_manager_init(priv->ttm_dev, mem_type, MANAGER_SIZE); 929 + ttm_mock_manager_init(priv->ttm_dev, mem_multihop, MANAGER_SIZE); 930 + 931 + place = ttm_place_kunit_init(test, mem_type, 0); 932 + placement = ttm_placement_kunit_init(test, place, 1); 933 + 934 + bo_pinned = kunit_kzalloc(test, sizeof(*bo_pinned), GFP_KERNEL); 935 + KUNIT_ASSERT_NOT_NULL(test, bo_pinned); 936 + 937 + drm_gem_private_object_init(priv->drm, &bo_pinned->base, size); 938 + err = ttm_bo_init_reserved(priv->ttm_dev, bo_pinned, bo_type, placement, 939 + PAGE_SIZE, &ctx_init, NULL, NULL, 940 + &dummy_ttm_bo_destroy); 941 + KUNIT_EXPECT_EQ(test, err, 0); 942 + ttm_bo_pin(bo_pinned); 943 + dma_resv_unlock(bo_pinned->base.resv); 944 + 945 + bo_evictable = kunit_kzalloc(test, sizeof(*bo_evictable), GFP_KERNEL); 946 + KUNIT_ASSERT_NOT_NULL(test, bo_evictable); 947 + 948 + drm_gem_private_object_init(priv->drm, &bo_evictable->base, size); 949 + err = ttm_bo_init_reserved(priv->ttm_dev, bo_evictable, bo_type, placement, 950 + PAGE_SIZE, &ctx_init, NULL, NULL, 951 + &dummy_ttm_bo_destroy); 952 + KUNIT_EXPECT_EQ(test, err, 0); 953 + dma_resv_unlock(bo_evictable->base.resv); 954 + 955 + bo = ttm_bo_kunit_init(test, test->priv, BO_SIZE, NULL); 956 + bo->type = bo_type; 957 + 958 + ttm_bo_reserve(bo, false, false, NULL); 959 + err = ttm_bo_validate(bo, placement, &ctx_val); 960 + ttm_bo_unreserve(bo); 961 + 962 + KUNIT_EXPECT_EQ(test, err, 0); 963 + KUNIT_EXPECT_EQ(test, bo->resource->mem_type, mem_type); 964 + KUNIT_EXPECT_EQ(test, bo_pinned->resource->mem_type, mem_type); 965 + KUNIT_EXPECT_EQ(test, bo_evictable->resource->mem_type, mem_type_evict); 966 + KUNIT_EXPECT_EQ(test, ctx_val.bytes_moved, size * 2 + BO_SIZE); 967 + 968 + ttm_bo_put(bo); 969 + ttm_bo_put(bo_evictable); 970 + 971 + ttm_bo_reserve(bo_pinned, false, false, NULL); 972 + ttm_bo_unpin(bo_pinned); 973 + dma_resv_unlock(bo_pinned->base.resv); 974 + ttm_bo_put(bo_pinned); 975 + 976 + ttm_mock_manager_fini(priv->ttm_dev, mem_type); 977 + ttm_mock_manager_fini(priv->ttm_dev, mem_multihop); 978 + } 979 + 980 + static void ttm_bo_validate_deleted_evict(struct kunit *test) 981 + { 982 + struct ttm_operation_ctx ctx_init = { }, ctx_val = { }; 983 + u32 small = SZ_8K, big = MANAGER_SIZE - BO_SIZE; 984 + enum ttm_bo_type bo_type = ttm_bo_type_device; 985 + struct ttm_buffer_object *bo_big, *bo_small; 986 + struct ttm_test_devices *priv = test->priv; 987 + struct ttm_resource_manager *man; 988 + u32 mem_type = TTM_PL_VRAM; 989 + struct ttm_placement *placement; 990 + struct ttm_place *place; 991 + int err; 992 + 993 + ttm_mock_manager_init(priv->ttm_dev, mem_type, MANAGER_SIZE); 994 + man = ttm_manager_type(priv->ttm_dev, mem_type); 995 + 996 + place = ttm_place_kunit_init(test, mem_type, 0); 997 + placement = ttm_placement_kunit_init(test, place, 1); 998 + 999 + bo_big = kunit_kzalloc(test, sizeof(*bo_big), GFP_KERNEL); 1000 + KUNIT_ASSERT_NOT_NULL(test, bo_big); 1001 + 1002 + drm_gem_private_object_init(priv->drm, &bo_big->base, big); 1003 + err = ttm_bo_init_reserved(priv->ttm_dev, bo_big, bo_type, placement, 1004 + PAGE_SIZE, &ctx_init, NULL, NULL, 1005 + &dummy_ttm_bo_destroy); 1006 + KUNIT_EXPECT_EQ(test, err, 0); 1007 + KUNIT_EXPECT_EQ(test, ttm_resource_manager_usage(man), big); 1008 + 1009 + dma_resv_unlock(bo_big->base.resv); 1010 + bo_big->deleted = true; 1011 + 1012 + bo_small = ttm_bo_kunit_init(test, test->priv, small, NULL); 1013 + bo_small->type = bo_type; 1014 + 1015 + ttm_bo_reserve(bo_small, false, false, NULL); 1016 + err = ttm_bo_validate(bo_small, placement, &ctx_val); 1017 + ttm_bo_unreserve(bo_small); 1018 + 1019 + KUNIT_EXPECT_EQ(test, err, 0); 1020 + KUNIT_EXPECT_EQ(test, bo_small->resource->mem_type, mem_type); 1021 + KUNIT_EXPECT_EQ(test, ttm_resource_manager_usage(man), small); 1022 + KUNIT_EXPECT_NULL(test, bo_big->ttm); 1023 + KUNIT_EXPECT_NULL(test, bo_big->resource); 1024 + 1025 + ttm_bo_put(bo_small); 1026 + ttm_bo_put(bo_big); 1027 + ttm_mock_manager_fini(priv->ttm_dev, mem_type); 1028 + } 1029 + 1030 + static void ttm_bo_validate_busy_domain_evict(struct kunit *test) 1031 + { 1032 + u32 mem_type = TTM_PL_VRAM, mem_type_evict = TTM_PL_MOCK1; 1033 + struct ttm_operation_ctx ctx_init = { }, ctx_val = { }; 1034 + enum ttm_bo_type bo_type = ttm_bo_type_device; 1035 + struct ttm_test_devices *priv = test->priv; 1036 + struct ttm_buffer_object *bo_init, *bo_val; 1037 + struct ttm_placement *placement; 1038 + struct ttm_place *place; 1039 + int err; 1040 + 1041 + /* 1042 + * Drop the default device and setup a new one that points to busy 1043 + * thus unsuitable eviction domain 1044 + */ 1045 + ttm_device_fini(priv->ttm_dev); 1046 + 1047 + err = ttm_device_kunit_init_bad_evict(test->priv, priv->ttm_dev, false, false); 1048 + KUNIT_ASSERT_EQ(test, err, 0); 1049 + 1050 + ttm_mock_manager_init(priv->ttm_dev, mem_type, MANAGER_SIZE); 1051 + ttm_busy_manager_init(priv->ttm_dev, mem_type_evict, MANAGER_SIZE); 1052 + 1053 + place = ttm_place_kunit_init(test, mem_type, 0); 1054 + placement = ttm_placement_kunit_init(test, place, 1); 1055 + 1056 + bo_init = kunit_kzalloc(test, sizeof(*bo_init), GFP_KERNEL); 1057 + KUNIT_ASSERT_NOT_NULL(test, bo_init); 1058 + 1059 + drm_gem_private_object_init(priv->drm, &bo_init->base, MANAGER_SIZE); 1060 + err = ttm_bo_init_reserved(priv->ttm_dev, bo_init, bo_type, placement, 1061 + PAGE_SIZE, &ctx_init, NULL, NULL, 1062 + &dummy_ttm_bo_destroy); 1063 + KUNIT_EXPECT_EQ(test, err, 0); 1064 + dma_resv_unlock(bo_init->base.resv); 1065 + 1066 + bo_val = ttm_bo_kunit_init(test, test->priv, BO_SIZE, NULL); 1067 + bo_val->type = bo_type; 1068 + 1069 + ttm_bo_reserve(bo_val, false, false, NULL); 1070 + err = ttm_bo_validate(bo_val, placement, &ctx_val); 1071 + ttm_bo_unreserve(bo_val); 1072 + 1073 + KUNIT_EXPECT_EQ(test, err, -ENOMEM); 1074 + KUNIT_EXPECT_EQ(test, bo_init->resource->mem_type, mem_type); 1075 + KUNIT_EXPECT_NULL(test, bo_val->resource); 1076 + 1077 + ttm_bo_put(bo_init); 1078 + ttm_bo_put(bo_val); 1079 + 1080 + ttm_mock_manager_fini(priv->ttm_dev, mem_type); 1081 + ttm_bad_manager_fini(priv->ttm_dev, mem_type_evict); 1082 + } 1083 + 1084 + static void ttm_bo_validate_evict_gutting(struct kunit *test) 1085 + { 1086 + struct ttm_operation_ctx ctx_init = { }, ctx_val = { }; 1087 + enum ttm_bo_type bo_type = ttm_bo_type_device; 1088 + struct ttm_test_devices *priv = test->priv; 1089 + struct ttm_buffer_object *bo, *bo_evict; 1090 + u32 mem_type = TTM_PL_MOCK1; 1091 + struct ttm_placement *placement; 1092 + struct ttm_place *place; 1093 + int err; 1094 + 1095 + ttm_mock_manager_init(priv->ttm_dev, mem_type, MANAGER_SIZE); 1096 + 1097 + place = ttm_place_kunit_init(test, mem_type, 0); 1098 + placement = ttm_placement_kunit_init(test, place, 1); 1099 + 1100 + bo_evict = kunit_kzalloc(test, sizeof(*bo_evict), GFP_KERNEL); 1101 + KUNIT_ASSERT_NOT_NULL(test, bo_evict); 1102 + 1103 + drm_gem_private_object_init(priv->drm, &bo_evict->base, MANAGER_SIZE); 1104 + err = ttm_bo_init_reserved(priv->ttm_dev, bo_evict, bo_type, placement, 1105 + PAGE_SIZE, &ctx_init, NULL, NULL, 1106 + &dummy_ttm_bo_destroy); 1107 + KUNIT_EXPECT_EQ(test, err, 0); 1108 + dma_resv_unlock(bo_evict->base.resv); 1109 + 1110 + bo = ttm_bo_kunit_init(test, test->priv, BO_SIZE, NULL); 1111 + bo->type = bo_type; 1112 + 1113 + ttm_bo_reserve(bo, false, false, NULL); 1114 + err = ttm_bo_validate(bo, placement, &ctx_val); 1115 + ttm_bo_unreserve(bo); 1116 + 1117 + KUNIT_EXPECT_EQ(test, err, 0); 1118 + KUNIT_EXPECT_EQ(test, bo->resource->mem_type, mem_type); 1119 + KUNIT_ASSERT_NULL(test, bo_evict->resource); 1120 + KUNIT_ASSERT_TRUE(test, bo_evict->ttm->page_flags & TTM_TT_FLAG_ZERO_ALLOC); 1121 + 1122 + ttm_bo_put(bo_evict); 1123 + ttm_bo_put(bo); 1124 + 1125 + ttm_mock_manager_fini(priv->ttm_dev, mem_type); 1126 + } 1127 + 1128 + static void ttm_bo_validate_recrusive_evict(struct kunit *test) 1129 + { 1130 + u32 mem_type = TTM_PL_TT, mem_type_evict = TTM_PL_MOCK2; 1131 + struct ttm_operation_ctx ctx_init = { }, ctx_val = { }; 1132 + struct ttm_placement *placement_tt, *placement_mock; 1133 + struct ttm_buffer_object *bo_tt, *bo_mock, *bo_val; 1134 + enum ttm_bo_type bo_type = ttm_bo_type_device; 1135 + struct ttm_test_devices *priv = test->priv; 1136 + struct ttm_place *place_tt, *place_mock; 1137 + int err; 1138 + 1139 + ttm_mock_manager_init(priv->ttm_dev, mem_type, MANAGER_SIZE); 1140 + ttm_mock_manager_init(priv->ttm_dev, mem_type_evict, MANAGER_SIZE); 1141 + 1142 + place_tt = ttm_place_kunit_init(test, mem_type, 0); 1143 + place_mock = ttm_place_kunit_init(test, mem_type_evict, 0); 1144 + 1145 + placement_tt = ttm_placement_kunit_init(test, place_tt, 1); 1146 + placement_mock = ttm_placement_kunit_init(test, place_mock, 1); 1147 + 1148 + bo_tt = kunit_kzalloc(test, sizeof(*bo_tt), GFP_KERNEL); 1149 + KUNIT_ASSERT_NOT_NULL(test, bo_tt); 1150 + 1151 + bo_mock = kunit_kzalloc(test, sizeof(*bo_mock), GFP_KERNEL); 1152 + KUNIT_ASSERT_NOT_NULL(test, bo_mock); 1153 + 1154 + drm_gem_private_object_init(priv->drm, &bo_tt->base, MANAGER_SIZE); 1155 + err = ttm_bo_init_reserved(priv->ttm_dev, bo_tt, bo_type, placement_tt, 1156 + PAGE_SIZE, &ctx_init, NULL, NULL, 1157 + &dummy_ttm_bo_destroy); 1158 + KUNIT_EXPECT_EQ(test, err, 0); 1159 + dma_resv_unlock(bo_tt->base.resv); 1160 + 1161 + drm_gem_private_object_init(priv->drm, &bo_mock->base, MANAGER_SIZE); 1162 + err = ttm_bo_init_reserved(priv->ttm_dev, bo_mock, bo_type, placement_mock, 1163 + PAGE_SIZE, &ctx_init, NULL, NULL, 1164 + &dummy_ttm_bo_destroy); 1165 + KUNIT_EXPECT_EQ(test, err, 0); 1166 + dma_resv_unlock(bo_mock->base.resv); 1167 + 1168 + bo_val = ttm_bo_kunit_init(test, test->priv, BO_SIZE, NULL); 1169 + bo_val->type = bo_type; 1170 + 1171 + ttm_bo_reserve(bo_val, false, false, NULL); 1172 + err = ttm_bo_validate(bo_val, placement_tt, &ctx_val); 1173 + ttm_bo_unreserve(bo_val); 1174 + 1175 + KUNIT_EXPECT_EQ(test, err, 0); 1176 + 1177 + ttm_mock_manager_fini(priv->ttm_dev, mem_type); 1178 + ttm_mock_manager_fini(priv->ttm_dev, mem_type_evict); 1179 + 1180 + ttm_bo_put(bo_val); 1181 + ttm_bo_put(bo_tt); 1182 + ttm_bo_put(bo_mock); 1183 + } 1184 + 760 1185 static struct kunit_case ttm_bo_validate_test_cases[] = { 761 1186 KUNIT_CASE_PARAM(ttm_bo_init_reserved_sys_man, ttm_bo_types_gen_params), 762 1187 KUNIT_CASE_PARAM(ttm_bo_init_reserved_mock_man, ttm_bo_types_gen_params), ··· 1201 776 KUNIT_CASE(ttm_bo_validate_move_fence_signaled), 1202 777 KUNIT_CASE_PARAM(ttm_bo_validate_move_fence_not_signaled, 1203 778 ttm_bo_validate_wait_gen_params), 779 + KUNIT_CASE(ttm_bo_validate_swapout), 780 + KUNIT_CASE(ttm_bo_validate_happy_evict), 781 + KUNIT_CASE(ttm_bo_validate_all_pinned_evict), 782 + KUNIT_CASE(ttm_bo_validate_allowed_only_evict), 783 + KUNIT_CASE(ttm_bo_validate_deleted_evict), 784 + KUNIT_CASE(ttm_bo_validate_busy_domain_evict), 785 + KUNIT_CASE(ttm_bo_validate_evict_gutting), 786 + KUNIT_CASE(ttm_bo_validate_recrusive_evict), 1204 787 {} 1205 788 }; 1206 789
+99 -9
drivers/gpu/drm/ttm/tests/ttm_kunit_helpers.c
··· 6 6 7 7 #include "ttm_kunit_helpers.h" 8 8 9 + static const struct ttm_place sys_place = { 10 + .fpfn = 0, 11 + .lpfn = 0, 12 + .mem_type = TTM_PL_SYSTEM, 13 + .flags = TTM_PL_FLAG_FALLBACK, 14 + }; 15 + 16 + static const struct ttm_place mock1_place = { 17 + .fpfn = 0, 18 + .lpfn = 0, 19 + .mem_type = TTM_PL_MOCK1, 20 + .flags = TTM_PL_FLAG_FALLBACK, 21 + }; 22 + 23 + static const struct ttm_place mock2_place = { 24 + .fpfn = 0, 25 + .lpfn = 0, 26 + .mem_type = TTM_PL_MOCK2, 27 + .flags = TTM_PL_FLAG_FALLBACK, 28 + }; 29 + 30 + static struct ttm_placement sys_placement = { 31 + .num_placement = 1, 32 + .placement = &sys_place, 33 + }; 34 + 35 + static struct ttm_placement bad_placement = { 36 + .num_placement = 1, 37 + .placement = &mock1_place, 38 + }; 39 + 40 + static struct ttm_placement mock_placement = { 41 + .num_placement = 1, 42 + .placement = &mock2_place, 43 + }; 44 + 9 45 static struct ttm_tt *ttm_tt_simple_create(struct ttm_buffer_object *bo, 10 46 uint32_t page_flags) 11 47 { ··· 90 54 return ttm_bo_move_memcpy(bo, ctx, new_mem); 91 55 } 92 56 57 + static void mock_evict_flags(struct ttm_buffer_object *bo, 58 + struct ttm_placement *placement) 59 + { 60 + switch (bo->resource->mem_type) { 61 + case TTM_PL_VRAM: 62 + case TTM_PL_SYSTEM: 63 + *placement = sys_placement; 64 + break; 65 + case TTM_PL_TT: 66 + *placement = mock_placement; 67 + break; 68 + case TTM_PL_MOCK1: 69 + /* Purge objects coming from this domain */ 70 + break; 71 + } 72 + } 73 + 74 + static void bad_evict_flags(struct ttm_buffer_object *bo, 75 + struct ttm_placement *placement) 76 + { 77 + *placement = bad_placement; 78 + } 79 + 80 + static int ttm_device_kunit_init_with_funcs(struct ttm_test_devices *priv, 81 + struct ttm_device *ttm, 82 + bool use_dma_alloc, 83 + bool use_dma32, 84 + struct ttm_device_funcs *funcs) 85 + { 86 + struct drm_device *drm = priv->drm; 87 + int err; 88 + 89 + err = ttm_device_init(ttm, funcs, drm->dev, 90 + drm->anon_inode->i_mapping, 91 + drm->vma_offset_manager, 92 + use_dma_alloc, use_dma32); 93 + 94 + return err; 95 + } 96 + 93 97 struct ttm_device_funcs ttm_dev_funcs = { 94 98 .ttm_tt_create = ttm_tt_simple_create, 95 99 .ttm_tt_destroy = ttm_tt_simple_destroy, 96 100 .move = mock_move, 101 + .eviction_valuable = ttm_bo_eviction_valuable, 102 + .evict_flags = mock_evict_flags, 97 103 }; 98 104 EXPORT_SYMBOL_GPL(ttm_dev_funcs); 99 105 ··· 144 66 bool use_dma_alloc, 145 67 bool use_dma32) 146 68 { 147 - struct drm_device *drm = priv->drm; 148 - int err; 149 - 150 - err = ttm_device_init(ttm, &ttm_dev_funcs, drm->dev, 151 - drm->anon_inode->i_mapping, 152 - drm->vma_offset_manager, 153 - use_dma_alloc, use_dma32); 154 - 155 - return err; 69 + return ttm_device_kunit_init_with_funcs(priv, ttm, use_dma_alloc, 70 + use_dma32, &ttm_dev_funcs); 156 71 } 157 72 EXPORT_SYMBOL_GPL(ttm_device_kunit_init); 73 + 74 + struct ttm_device_funcs ttm_dev_funcs_bad_evict = { 75 + .ttm_tt_create = ttm_tt_simple_create, 76 + .ttm_tt_destroy = ttm_tt_simple_destroy, 77 + .move = mock_move, 78 + .eviction_valuable = ttm_bo_eviction_valuable, 79 + .evict_flags = bad_evict_flags, 80 + }; 81 + EXPORT_SYMBOL_GPL(ttm_dev_funcs_bad_evict); 82 + 83 + int ttm_device_kunit_init_bad_evict(struct ttm_test_devices *priv, 84 + struct ttm_device *ttm, 85 + bool use_dma_alloc, 86 + bool use_dma32) 87 + { 88 + return ttm_device_kunit_init_with_funcs(priv, ttm, use_dma_alloc, 89 + use_dma32, &ttm_dev_funcs_bad_evict); 90 + } 91 + EXPORT_SYMBOL_GPL(ttm_device_kunit_init_bad_evict); 158 92 159 93 struct ttm_buffer_object *ttm_bo_kunit_init(struct kunit *test, 160 94 struct ttm_test_devices *devs,
+8
drivers/gpu/drm/ttm/tests/ttm_kunit_helpers.h
··· 13 13 #include <drm/drm_kunit_helpers.h> 14 14 #include <kunit/test.h> 15 15 16 + #define TTM_PL_MOCK1 (TTM_PL_PRIV + 1) 17 + #define TTM_PL_MOCK2 (TTM_PL_PRIV + 2) 18 + 16 19 extern struct ttm_device_funcs ttm_dev_funcs; 20 + extern struct ttm_device_funcs ttm_dev_funcs_bad_evict; 17 21 18 22 struct ttm_test_devices { 19 23 struct drm_device *drm; ··· 30 26 struct ttm_device *ttm, 31 27 bool use_dma_alloc, 32 28 bool use_dma32); 29 + int ttm_device_kunit_init_bad_evict(struct ttm_test_devices *priv, 30 + struct ttm_device *ttm, 31 + bool use_dma_alloc, 32 + bool use_dma32); 33 33 struct ttm_buffer_object *ttm_bo_kunit_init(struct kunit *test, 34 34 struct ttm_test_devices *devs, 35 35 size_t size,
+28 -1
drivers/gpu/drm/ttm/tests/ttm_mock_manager.c
··· 153 153 return -ENOSPC; 154 154 } 155 155 156 + static int ttm_busy_manager_alloc(struct ttm_resource_manager *man, 157 + struct ttm_buffer_object *bo, 158 + const struct ttm_place *place, 159 + struct ttm_resource **res) 160 + { 161 + return -EBUSY; 162 + } 163 + 156 164 static void ttm_bad_manager_free(struct ttm_resource_manager *man, 157 165 struct ttm_resource *res) 158 166 { ··· 176 168 177 169 static const struct ttm_resource_manager_func ttm_bad_manager_funcs = { 178 170 .alloc = ttm_bad_manager_alloc, 171 + .free = ttm_bad_manager_free, 172 + .compatible = ttm_bad_manager_compatible 173 + }; 174 + 175 + static const struct ttm_resource_manager_func ttm_bad_busy_manager_funcs = { 176 + .alloc = ttm_busy_manager_alloc, 179 177 .free = ttm_bad_manager_free, 180 178 .compatible = ttm_bad_manager_compatible 181 179 }; ··· 204 190 } 205 191 EXPORT_SYMBOL_GPL(ttm_bad_manager_init); 206 192 207 - void ttm_bad_manager_fini(struct ttm_device *bdev, u32 mem_type) 193 + int ttm_busy_manager_init(struct ttm_device *bdev, u32 mem_type, u32 size) 194 + { 195 + struct ttm_resource_manager *man; 196 + 197 + ttm_bad_manager_init(bdev, mem_type, size); 198 + man = ttm_manager_type(bdev, mem_type); 199 + 200 + man->func = &ttm_bad_busy_manager_funcs; 201 + 202 + return 0; 203 + } 204 + EXPORT_SYMBOL_GPL(ttm_busy_manager_init); 205 + 206 + void ttm_bad_manager_fini(struct ttm_device *bdev, uint32_t mem_type) 208 207 { 209 208 struct ttm_resource_manager *man; 210 209
+1
drivers/gpu/drm/ttm/tests/ttm_mock_manager.h
··· 23 23 24 24 int ttm_mock_manager_init(struct ttm_device *bdev, u32 mem_type, u32 size); 25 25 int ttm_bad_manager_init(struct ttm_device *bdev, u32 mem_type, u32 size); 26 + int ttm_busy_manager_init(struct ttm_device *bdev, u32 mem_type, u32 size); 26 27 void ttm_mock_manager_fini(struct ttm_device *bdev, u32 mem_type); 27 28 void ttm_bad_manager_fini(struct ttm_device *bdev, u32 mem_type); 28 29