diff options
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem_gtt.c | 30 |
1 files changed, 26 insertions, 4 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index afe45cbcd762..9ea024395d49 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c | |||
@@ -580,10 +580,9 @@ setup_scratch_page(struct i915_address_space *vm, gfp_t gfp) | |||
580 | * region, including any PTEs which happen to point to scratch. | 580 | * region, including any PTEs which happen to point to scratch. |
581 | * | 581 | * |
582 | * This is only relevant for the 48b PPGTT where we support | 582 | * This is only relevant for the 48b PPGTT where we support |
583 | * huge-gtt-pages, see also i915_vma_insert(). | 583 | * huge-gtt-pages, see also i915_vma_insert(). However, as we share the |
584 | * | 584 | * scratch (read-only) between all vm, we create one 64k scratch page |
585 | * TODO: we should really consider write-protecting the scratch-page and | 585 | * for all. |
586 | * sharing between ppgtt | ||
587 | */ | 586 | */ |
588 | size = I915_GTT_PAGE_SIZE_4K; | 587 | size = I915_GTT_PAGE_SIZE_4K; |
589 | if (i915_vm_is_48bit(vm) && | 588 | if (i915_vm_is_48bit(vm) && |
@@ -1209,6 +1208,26 @@ static int gen8_init_scratch(struct i915_address_space *vm) | |||
1209 | { | 1208 | { |
1210 | int ret; | 1209 | int ret; |
1211 | 1210 | ||
1211 | /* | ||
1212 | * If everybody agrees to not to write into the scratch page, | ||
1213 | * we can reuse it for all vm, keeping contexts and processes separate. | ||
1214 | */ | ||
1215 | if (vm->has_read_only && | ||
1216 | vm->i915->kernel_context && | ||
1217 | vm->i915->kernel_context->ppgtt) { | ||
1218 | struct i915_address_space *clone = | ||
1219 | &vm->i915->kernel_context->ppgtt->vm; | ||
1220 | |||
1221 | GEM_BUG_ON(!clone->has_read_only); | ||
1222 | |||
1223 | vm->scratch_page.order = clone->scratch_page.order; | ||
1224 | vm->scratch_pte = clone->scratch_pte; | ||
1225 | vm->scratch_pt = clone->scratch_pt; | ||
1226 | vm->scratch_pd = clone->scratch_pd; | ||
1227 | vm->scratch_pdp = clone->scratch_pdp; | ||
1228 | return 0; | ||
1229 | } | ||
1230 | |||
1212 | ret = setup_scratch_page(vm, __GFP_HIGHMEM); | 1231 | ret = setup_scratch_page(vm, __GFP_HIGHMEM); |
1213 | if (ret) | 1232 | if (ret) |
1214 | return ret; | 1233 | return ret; |
@@ -1289,6 +1308,9 @@ static int gen8_ppgtt_notify_vgt(struct i915_hw_ppgtt *ppgtt, bool create) | |||
1289 | 1308 | ||
1290 | static void gen8_free_scratch(struct i915_address_space *vm) | 1309 | static void gen8_free_scratch(struct i915_address_space *vm) |
1291 | { | 1310 | { |
1311 | if (!vm->scratch_page.daddr) | ||
1312 | return; | ||
1313 | |||
1292 | if (use_4lvl(vm)) | 1314 | if (use_4lvl(vm)) |
1293 | free_pdp(vm, vm->scratch_pdp); | 1315 | free_pdp(vm, vm->scratch_pdp); |
1294 | free_pd(vm, vm->scratch_pd); | 1316 | free_pd(vm, vm->scratch_pd); |