Subversion Repositories Kolibri OS

Rev

Rev 5078 | Rev 6104 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 5078 Rev 5271
Line 123... Line 123...
123
 * @head: head of validation list
123
 * @head: head of validation list
124
 *
124
 *
125
 * Add the page directory to the list of BOs to
125
 * Add the page directory to the list of BOs to
126
 * validate for command submission (cayman+).
126
 * validate for command submission (cayman+).
127
 */
127
 */
128
struct radeon_cs_reloc *radeon_vm_get_bos(struct radeon_device *rdev,
128
struct radeon_bo_list *radeon_vm_get_bos(struct radeon_device *rdev,
129
					  struct radeon_vm *vm,
129
					  struct radeon_vm *vm,
130
					  struct list_head *head)
130
					  struct list_head *head)
131
{
131
{
132
	struct radeon_cs_reloc *list;
132
	struct radeon_bo_list *list;
133
	unsigned i, idx;
133
	unsigned i, idx;
Line 134... Line 134...
134
 
134
 
135
	list = kmalloc_array(vm->max_pde_used + 2,
135
	list = kmalloc_array(vm->max_pde_used + 2,
136
			     sizeof(struct radeon_cs_reloc), GFP_KERNEL);
136
			     sizeof(struct radeon_bo_list), GFP_KERNEL);
137
	if (!list)
137
	if (!list)
Line 138... Line 138...
138
		return NULL;
138
		return NULL;
139
 
-
 
140
	/* add the vm page table to the list */
139
 
141
	list[0].gobj = NULL;
140
	/* add the vm page table to the list */
142
	list[0].robj = vm->page_directory;
141
	list[0].robj = vm->page_directory;
143
	list[0].prefered_domains = RADEON_GEM_DOMAIN_VRAM;
142
	list[0].prefered_domains = RADEON_GEM_DOMAIN_VRAM;
-
 
143
	list[0].allowed_domains = RADEON_GEM_DOMAIN_VRAM;
144
	list[0].allowed_domains = RADEON_GEM_DOMAIN_VRAM;
144
	list[0].tv.bo = &vm->page_directory->tbo;
145
	list[0].tv.bo = &vm->page_directory->tbo;
-
 
146
	list[0].tiling_flags = 0;
145
	list[0].tv.shared = true;
Line 147... Line 146...
147
	list[0].handle = 0;
146
	list[0].tiling_flags = 0;
148
	list_add(&list[0].tv.head, head);
147
	list_add(&list[0].tv.head, head);
149
 
148
 
Line 150... Line -...
150
	for (i = 0, idx = 1; i <= vm->max_pde_used; i++) {
-
 
151
		if (!vm->page_tables[i].bo)
149
	for (i = 0, idx = 1; i <= vm->max_pde_used; i++) {
152
			continue;
150
		if (!vm->page_tables[i].bo)
153
 
151
			continue;
154
		list[idx].gobj = NULL;
152
 
-
 
153
		list[idx].robj = vm->page_tables[i].bo;
155
		list[idx].robj = vm->page_tables[i].bo;
154
		list[idx].prefered_domains = RADEON_GEM_DOMAIN_VRAM;
156
		list[idx].prefered_domains = RADEON_GEM_DOMAIN_VRAM;
-
 
157
		list[idx].allowed_domains = RADEON_GEM_DOMAIN_VRAM;
155
		list[idx].allowed_domains = RADEON_GEM_DOMAIN_VRAM;
158
		list[idx].tv.bo = &list[idx].robj->tbo;
156
		list[idx].tv.bo = &list[idx].robj->tbo;
Line 159... Line 157...
159
		list[idx].tiling_flags = 0;
157
		list[idx].tv.shared = true;
160
		list[idx].handle = 0;
158
		list[idx].tiling_flags = 0;
Line 178... Line 176...
178
 */
176
 */
179
struct radeon_fence *radeon_vm_grab_id(struct radeon_device *rdev,
177
struct radeon_fence *radeon_vm_grab_id(struct radeon_device *rdev,
180
				       struct radeon_vm *vm, int ring)
178
				       struct radeon_vm *vm, int ring)
181
{
179
{
182
	struct radeon_fence *best[RADEON_NUM_RINGS] = {};
180
	struct radeon_fence *best[RADEON_NUM_RINGS] = {};
-
 
181
	struct radeon_vm_id *vm_id = &vm->ids[ring];
-
 
182
 
183
	unsigned choices[2] = {};
183
	unsigned choices[2] = {};
184
	unsigned i;
184
	unsigned i;
Line 185... Line 185...
185
 
185
 
-
 
186
	/* check if the id is still valid */
186
	/* check if the id is still valid */
187
	if (vm_id->id && vm_id->last_id_use &&
187
	if (vm->last_id_use && vm->last_id_use == rdev->vm_manager.active[vm->id])
188
	    vm_id->last_id_use == rdev->vm_manager.active[vm_id->id])
Line 188... Line 189...
188
		return NULL;
189
		return NULL;
189
 
190
 
Line 190... Line 191...
190
	/* we definately need to flush */
191
	/* we definately need to flush */
191
	radeon_fence_unref(&vm->last_flush);
192
	vm_id->pd_gpu_addr = ~0ll;
192
 
193
 
Line 193... Line 194...
193
	/* skip over VMID 0, since it is the system VM */
194
	/* skip over VMID 0, since it is the system VM */
194
	for (i = 1; i < rdev->vm_manager.nvm; ++i) {
195
	for (i = 1; i < rdev->vm_manager.nvm; ++i) {
195
		struct radeon_fence *fence = rdev->vm_manager.active[i];
196
		struct radeon_fence *fence = rdev->vm_manager.active[i];
196
 
197
 
197
		if (fence == NULL) {
198
		if (fence == NULL) {
198
			/* found a free one */
199
			/* found a free one */
Line 199... Line 200...
199
			vm->id = i;
200
			vm_id->id = i;
200
			trace_radeon_vm_grab_id(vm->id, ring);
201
			trace_radeon_vm_grab_id(i, ring);
Line 207... Line 208...
207
		}
208
		}
208
	}
209
	}
Line 209... Line 210...
209
 
210
 
210
	for (i = 0; i < 2; ++i) {
211
	for (i = 0; i < 2; ++i) {
211
		if (choices[i]) {
212
		if (choices[i]) {
212
			vm->id = choices[i];
213
			vm_id->id = choices[i];
213
			trace_radeon_vm_grab_id(vm->id, ring);
214
			trace_radeon_vm_grab_id(choices[i], ring);
214
			return rdev->vm_manager.active[choices[i]];
215
			return rdev->vm_manager.active[choices[i]];
215
		}
216
		}
Line 216... Line 217...
216
	}
217
	}
Line 224... Line 225...
224
 * radeon_vm_flush - hardware flush the vm
225
 * radeon_vm_flush - hardware flush the vm
225
 *
226
 *
226
 * @rdev: radeon_device pointer
227
 * @rdev: radeon_device pointer
227
 * @vm: vm we want to flush
228
 * @vm: vm we want to flush
228
 * @ring: ring to use for flush
229
 * @ring: ring to use for flush
-
 
230
 * @updates: last vm update that is waited for
229
 *
231
 *
230
 * Flush the vm (cayman+).
232
 * Flush the vm (cayman+).
231
 *
233
 *
232
 * Global and local mutex must be locked!
234
 * Global and local mutex must be locked!
233
 */
235
 */
234
void radeon_vm_flush(struct radeon_device *rdev,
236
void radeon_vm_flush(struct radeon_device *rdev,
235
		     struct radeon_vm *vm,
237
		     struct radeon_vm *vm,
236
		     int ring)
238
		     int ring, struct radeon_fence *updates)
237
{
239
{
238
	uint64_t pd_addr = radeon_bo_gpu_offset(vm->page_directory);
240
	uint64_t pd_addr = radeon_bo_gpu_offset(vm->page_directory);
-
 
241
	struct radeon_vm_id *vm_id = &vm->ids[ring];
-
 
242
 
-
 
243
	if (pd_addr != vm_id->pd_gpu_addr || !vm_id->flushed_updates ||
-
 
244
	    radeon_fence_is_earlier(vm_id->flushed_updates, updates)) {
-
 
245
 
-
 
246
		trace_radeon_vm_flush(pd_addr, ring, vm->ids[ring].id);
-
 
247
		radeon_fence_unref(&vm_id->flushed_updates);
-
 
248
		vm_id->flushed_updates = radeon_fence_ref(updates);
-
 
249
		vm_id->pd_gpu_addr = pd_addr;
-
 
250
		radeon_ring_vm_flush(rdev, &rdev->ring[ring],
-
 
251
				     vm_id->id, vm_id->pd_gpu_addr);
Line 239... Line -...
239
 
-
 
240
	/* if we can't remember our last VM flush then flush now! */
-
 
241
	if (!vm->last_flush || pd_addr != vm->pd_gpu_addr) {
-
 
242
		trace_radeon_vm_flush(pd_addr, ring, vm->id);
-
 
243
		vm->pd_gpu_addr = pd_addr;
-
 
244
		radeon_ring_vm_flush(rdev, ring, vm);
252
 
245
	}
253
	}
Line 246... Line 254...
246
}
254
}
247
 
255
 
Line 259... Line 267...
259
 */
267
 */
260
void radeon_vm_fence(struct radeon_device *rdev,
268
void radeon_vm_fence(struct radeon_device *rdev,
261
		     struct radeon_vm *vm,
269
		     struct radeon_vm *vm,
262
		     struct radeon_fence *fence)
270
		     struct radeon_fence *fence)
263
{
271
{
264
	radeon_fence_unref(&vm->fence);
-
 
265
	vm->fence = radeon_fence_ref(fence);
272
	unsigned vm_id = vm->ids[fence->ring].id;
266
 
-
 
267
	radeon_fence_unref(&rdev->vm_manager.active[vm->id]);
-
 
268
	rdev->vm_manager.active[vm->id] = radeon_fence_ref(fence);
-
 
Line 269... Line 273...
269
 
273
 
270
	radeon_fence_unref(&vm->last_id_use);
274
	radeon_fence_unref(&rdev->vm_manager.active[vm_id]);
Line 271... Line 275...
271
	vm->last_id_use = radeon_fence_ref(fence);
275
	rdev->vm_manager.active[vm_id] = radeon_fence_ref(fence);
272
 
-
 
273
        /* we just flushed the VM, remember that */
276
 
274
        if (!vm->last_flush)
277
	radeon_fence_unref(&vm->ids[fence->ring].last_id_use);
Line 275... Line 278...
275
                vm->last_flush = radeon_fence_ref(fence);
278
	vm->ids[fence->ring].last_id_use = radeon_fence_ref(fence);
276
}
279
}
277
 
280
 
Line 383... Line 386...
383
 * @bo: bo to clear
386
 * @bo: bo to clear
384
 */
387
 */
385
static int radeon_vm_clear_bo(struct radeon_device *rdev,
388
static int radeon_vm_clear_bo(struct radeon_device *rdev,
386
			      struct radeon_bo *bo)
389
			      struct radeon_bo *bo)
387
{
390
{
388
        struct ttm_validate_buffer tv;
-
 
389
        struct ww_acquire_ctx ticket;
-
 
390
        struct list_head head;
-
 
391
	struct radeon_ib ib;
391
	struct radeon_ib ib;
392
	unsigned entries;
392
	unsigned entries;
393
	uint64_t addr;
393
	uint64_t addr;
394
	int r;
394
	int r;
Line 395... Line -...
395
 
-
 
396
        memset(&tv, 0, sizeof(tv));
-
 
397
        tv.bo = &bo->tbo;
-
 
398
 
-
 
399
        INIT_LIST_HEAD(&head);
395
 
400
        list_add(&tv.head, &head);
-
 
401
 
-
 
402
        r = ttm_eu_reserve_buffers(&ticket, &head);
396
	r = radeon_bo_reserve(bo, false);
403
        if (r)
397
        if (r)
Line 404... Line 398...
404
		return r;
398
		return r;
405
 
399
 
406
        r = ttm_bo_validate(&bo->tbo, &bo->placement, true, false);
400
        r = ttm_bo_validate(&bo->tbo, &bo->placement, true, false);
Line 407... Line 401...
407
        if (r)
401
        if (r)
408
                goto error;
402
		goto error_unreserve;
Line 409... Line 403...
409
 
403
 
410
	addr = radeon_bo_gpu_offset(bo);
404
	addr = radeon_bo_gpu_offset(bo);
411
	entries = radeon_bo_size(bo) / 8;
405
	entries = radeon_bo_size(bo) / 8;
Line 412... Line 406...
412
 
406
 
Line 413... Line 407...
413
	r = radeon_ib_get(rdev, R600_RING_TYPE_DMA_INDEX, &ib, NULL, 256);
407
	r = radeon_ib_get(rdev, R600_RING_TYPE_DMA_INDEX, &ib, NULL, 256);
414
	if (r)
408
	if (r)
415
                goto error;
409
		goto error_unreserve;
Line 416... Line 410...
416
 
410
 
417
	ib.length_dw = 0;
411
	ib.length_dw = 0;
418
 
412
 
Line 419... Line 413...
419
	radeon_vm_set_pages(rdev, &ib, addr, 0, entries, 0, 0);
413
	radeon_vm_set_pages(rdev, &ib, addr, 0, entries, 0, 0);
420
	radeon_asic_vm_pad_ib(rdev, &ib);
414
	radeon_asic_vm_pad_ib(rdev, &ib);
Line 421... Line 415...
421
	WARN_ON(ib.length_dw > 64);
415
	WARN_ON(ib.length_dw > 64);
-
 
416
 
Line 422... Line 417...
422
 
417
	r = radeon_ib_schedule(rdev, &ib, NULL, false);
423
	r = radeon_ib_schedule(rdev, &ib, NULL, false);
418
	if (r)
424
	if (r)
419
		goto error_free;
425
                goto error;
420
 
Line 426... Line 421...
426
 
421
	ib.fence->is_vm_update = true;
427
	ttm_eu_fence_buffer_objects(&ticket, &head, ib.fence);
422
	radeon_bo_fence(bo, ib.fence, false);
Line 444... Line 439...
444
 *
439
 *
445
 * Set offset of @bo_va (cayman+).
440
 * Set offset of @bo_va (cayman+).
446
 * Validate and set the offset requested within the vm address space.
441
 * Validate and set the offset requested within the vm address space.
447
 * Returns 0 for success, error for failure.
442
 * Returns 0 for success, error for failure.
448
 *
443
 *
449
 * Object has to be reserved!
444
 * Object has to be reserved and gets unreserved by this function!
450
 */
445
 */
451
int radeon_vm_bo_set_addr(struct radeon_device *rdev,
446
int radeon_vm_bo_set_addr(struct radeon_device *rdev,
452
			  struct radeon_bo_va *bo_va,
447
			  struct radeon_bo_va *bo_va,
453
			  uint64_t soffset,
448
			  uint64_t soffset,
454
			  uint32_t flags)
449
			  uint32_t flags)
Line 490... Line 485...
490
			tmp->it.start = bo_va->it.start;
485
			tmp->it.start = bo_va->it.start;
491
			tmp->it.last = bo_va->it.last;
486
			tmp->it.last = bo_va->it.last;
492
			tmp->vm = vm;
487
			tmp->vm = vm;
493
			tmp->addr = bo_va->addr;
488
			tmp->addr = bo_va->addr;
494
			tmp->bo = radeon_bo_ref(bo_va->bo);
489
			tmp->bo = radeon_bo_ref(bo_va->bo);
-
 
490
			spin_lock(&vm->status_lock);
495
			list_add(&tmp->vm_status, &vm->freed);
491
			list_add(&tmp->vm_status, &vm->freed);
-
 
492
			spin_unlock(&vm->status_lock);
496
		}
493
		}
Line 497... Line 494...
497
 
494
 
498
		interval_tree_remove(&bo_va->it, &vm->va);
495
		interval_tree_remove(&bo_va->it, &vm->va);
499
		bo_va->it.start = 0;
496
		bo_va->it.start = 0;
Line 543... Line 540...
543
		/* drop mutex to allocate and clear page table */
540
		/* drop mutex to allocate and clear page table */
544
		mutex_unlock(&vm->mutex);
541
		mutex_unlock(&vm->mutex);
Line 545... Line 542...
545
 
542
 
546
		r = radeon_bo_create(rdev, RADEON_VM_PTE_COUNT * 8,
543
		r = radeon_bo_create(rdev, RADEON_VM_PTE_COUNT * 8,
547
				     RADEON_GPU_PAGE_SIZE, true,
544
				     RADEON_GPU_PAGE_SIZE, true,
-
 
545
				     RADEON_GEM_DOMAIN_VRAM, 0,
548
				     RADEON_GEM_DOMAIN_VRAM, 0, NULL, &pt);
546
				     NULL, NULL, &pt);
549
		if (r)
547
		if (r)
Line 550... Line 548...
550
			return r;
548
			return r;
551
 
549
 
Line 569... Line 567...
569
		vm->page_tables[pt_idx].addr = 0;
567
		vm->page_tables[pt_idx].addr = 0;
570
		vm->page_tables[pt_idx].bo = pt;
568
		vm->page_tables[pt_idx].bo = pt;
571
	}
569
	}
Line 572... Line 570...
572
 
570
 
573
	mutex_unlock(&vm->mutex);
571
	mutex_unlock(&vm->mutex);
574
	return radeon_bo_reserve(bo_va->bo, false);
572
	return 0;
Line 575... Line 573...
575
}
573
}
576
 
574
 
577
/**
575
/**
Line 692... Line 690...
692
		radeon_vm_set_pages(rdev, &ib, last_pde, last_pt, count,
690
		radeon_vm_set_pages(rdev, &ib, last_pde, last_pt, count,
693
					incr, R600_PTE_VALID);
691
					incr, R600_PTE_VALID);
Line 694... Line 692...
694
 
692
 
695
	if (ib.length_dw != 0) {
693
	if (ib.length_dw != 0) {
-
 
694
		radeon_asic_vm_pad_ib(rdev, &ib);
696
		radeon_asic_vm_pad_ib(rdev, &ib);
695
 
697
		radeon_semaphore_sync_to(ib.semaphore, pd->tbo.sync_obj);
-
 
698
		radeon_semaphore_sync_to(ib.semaphore, vm->last_id_use);
696
		radeon_sync_resv(rdev, &ib.sync, pd->tbo.resv, true);
699
		WARN_ON(ib.length_dw > ndw);
697
		WARN_ON(ib.length_dw > ndw);
700
		r = radeon_ib_schedule(rdev, &ib, NULL, false);
698
		r = radeon_ib_schedule(rdev, &ib, NULL, false);
701
		if (r) {
699
		if (r) {
702
			radeon_ib_free(rdev, &ib);
700
			radeon_ib_free(rdev, &ib);
703
			return r;
701
			return r;
704
		}
-
 
705
		radeon_fence_unref(&vm->fence);
702
		}
706
		vm->fence = radeon_fence_ref(ib.fence);
703
		ib.fence->is_vm_update = true;
707
		radeon_fence_unref(&vm->last_flush);
704
		radeon_bo_fence(pd, ib.fence, false);
708
	}
705
	}
Line 709... Line 706...
709
	radeon_ib_free(rdev, &ib);
706
	radeon_ib_free(rdev, &ib);
710
 
707
 
Line 801... Line 798...
801
 *
798
 *
802
 * Update the page tables in the range @start - @end (cayman+).
799
 * Update the page tables in the range @start - @end (cayman+).
803
 *
800
 *
804
 * Global and local mutex must be locked!
801
 * Global and local mutex must be locked!
805
 */
802
 */
806
static void radeon_vm_update_ptes(struct radeon_device *rdev,
803
static int radeon_vm_update_ptes(struct radeon_device *rdev,
807
				  struct radeon_vm *vm,
804
				  struct radeon_vm *vm,
808
				  struct radeon_ib *ib,
805
				  struct radeon_ib *ib,
809
				  uint64_t start, uint64_t end,
806
				  uint64_t start, uint64_t end,
810
				  uint64_t dst, uint32_t flags)
807
				  uint64_t dst, uint32_t flags)
811
{
808
{
Line 818... Line 815...
818
	for (addr = start; addr < end; ) {
815
	for (addr = start; addr < end; ) {
819
		uint64_t pt_idx = addr >> radeon_vm_block_size;
816
		uint64_t pt_idx = addr >> radeon_vm_block_size;
820
		struct radeon_bo *pt = vm->page_tables[pt_idx].bo;
817
		struct radeon_bo *pt = vm->page_tables[pt_idx].bo;
821
		unsigned nptes;
818
		unsigned nptes;
822
		uint64_t pte;
819
		uint64_t pte;
-
 
820
		int r;
Line 823... Line 821...
823
 
821
 
-
 
822
		radeon_sync_resv(rdev, &ib->sync, pt->tbo.resv, true);
-
 
823
		r = reservation_object_reserve_shared(pt->tbo.resv);
-
 
824
		if (r)
Line 824... Line 825...
824
		radeon_semaphore_sync_to(ib->semaphore, pt->tbo.sync_obj);
825
			return r;
825
 
826
 
826
		if ((addr & ~mask) == (end & ~mask))
827
		if ((addr & ~mask) == (end & ~mask))
827
			nptes = end - addr;
828
			nptes = end - addr;
Line 853... Line 854...
853
	if (count) {
854
	if (count) {
854
		radeon_vm_frag_ptes(rdev, ib, last_pte,
855
		radeon_vm_frag_ptes(rdev, ib, last_pte,
855
				    last_pte + 8 * count,
856
				    last_pte + 8 * count,
856
				    last_dst, flags);
857
				    last_dst, flags);
857
	}
858
	}
-
 
859
 
-
 
860
	return 0;
-
 
861
}
-
 
862
 
-
 
863
/**
-
 
864
 * radeon_vm_fence_pts - fence page tables after an update
-
 
865
 *
-
 
866
 * @vm: requested vm
-
 
867
 * @start: start of GPU address range
-
 
868
 * @end: end of GPU address range
-
 
869
 * @fence: fence to use
-
 
870
 *
-
 
871
 * Fence the page tables in the range @start - @end (cayman+).
-
 
872
 *
-
 
873
 * Global and local mutex must be locked!
-
 
874
 */
-
 
875
static void radeon_vm_fence_pts(struct radeon_vm *vm,
-
 
876
				uint64_t start, uint64_t end,
-
 
877
				struct radeon_fence *fence)
-
 
878
{
-
 
879
	unsigned i;
-
 
880
 
-
 
881
	start >>= radeon_vm_block_size;
-
 
882
	end >>= radeon_vm_block_size;
-
 
883
 
-
 
884
	for (i = start; i <= end; ++i)
-
 
885
		radeon_bo_fence(vm->page_tables[i].bo, fence, true);
858
}
886
}
Line 859... Line 887...
859
 
887
 
860
/**
888
/**
861
 * radeon_vm_bo_update - map a bo into the vm page table
889
 * radeon_vm_bo_update - map a bo into the vm page table
Line 885... Line 913...
885
		dev_err(rdev->dev, "bo %p don't has a mapping in vm %p\n",
913
		dev_err(rdev->dev, "bo %p don't has a mapping in vm %p\n",
886
			bo_va->bo, vm);
914
			bo_va->bo, vm);
887
		return -EINVAL;
915
		return -EINVAL;
888
	}
916
	}
Line -... Line 917...
-
 
917
 
889
 
918
	spin_lock(&vm->status_lock);
-
 
919
	list_del_init(&bo_va->vm_status);
Line 890... Line 920...
890
	list_del_init(&bo_va->vm_status);
920
	spin_unlock(&vm->status_lock);
891
 
921
 
892
	bo_va->flags &= ~RADEON_VM_PAGE_VALID;
922
	bo_va->flags &= ~RADEON_VM_PAGE_VALID;
-
 
923
	bo_va->flags &= ~RADEON_VM_PAGE_SYSTEM;
-
 
924
	bo_va->flags &= ~RADEON_VM_PAGE_SNOOPED;
-
 
925
//   if (bo_va->bo && radeon_ttm_tt_is_readonly(bo_va->bo->tbo.ttm))
893
	bo_va->flags &= ~RADEON_VM_PAGE_SYSTEM;
926
//       bo_va->flags &= ~RADEON_VM_PAGE_WRITEABLE;
894
	bo_va->flags &= ~RADEON_VM_PAGE_SNOOPED;
927
 
895
	if (mem) {
928
	if (mem) {
896
		addr = mem->start << PAGE_SHIFT;
929
		addr = mem->start << PAGE_SHIFT;
897
		if (mem->mem_type != TTM_PL_SYSTEM) {
930
		if (mem->mem_type != TTM_PL_SYSTEM) {
Line 951... Line 984...
951
	r = radeon_ib_get(rdev, R600_RING_TYPE_DMA_INDEX, &ib, NULL, ndw * 4);
984
	r = radeon_ib_get(rdev, R600_RING_TYPE_DMA_INDEX, &ib, NULL, ndw * 4);
952
	if (r)
985
	if (r)
953
		return r;
986
		return r;
954
	ib.length_dw = 0;
987
	ib.length_dw = 0;
Line -... Line 988...
-
 
988
 
-
 
989
	if (!(bo_va->flags & RADEON_VM_PAGE_VALID)) {
-
 
990
		unsigned i;
-
 
991
 
-
 
992
		for (i = 0; i < RADEON_NUM_RINGS; ++i)
-
 
993
			radeon_sync_fence(&ib.sync, vm->ids[i].last_id_use);
-
 
994
	}
955
 
995
 
956
	radeon_vm_update_ptes(rdev, vm, &ib, bo_va->it.start,
996
	r = radeon_vm_update_ptes(rdev, vm, &ib, bo_va->it.start,
957
			      bo_va->it.last + 1, addr,
997
			      bo_va->it.last + 1, addr,
-
 
998
			      radeon_vm_page_flags(bo_va->flags));
-
 
999
	if (r) {
-
 
1000
		radeon_ib_free(rdev, &ib);
-
 
1001
		return r;
Line 958... Line 1002...
958
			      radeon_vm_page_flags(bo_va->flags));
1002
	}
959
 
1003
 
Line 960... Line -...
960
	radeon_asic_vm_pad_ib(rdev, &ib);
-
 
961
	WARN_ON(ib.length_dw > ndw);
1004
	radeon_asic_vm_pad_ib(rdev, &ib);
962
 
1005
	WARN_ON(ib.length_dw > ndw);
963
	radeon_semaphore_sync_to(ib.semaphore, vm->fence);
1006
 
964
	r = radeon_ib_schedule(rdev, &ib, NULL, false);
1007
	r = radeon_ib_schedule(rdev, &ib, NULL, false);
965
	if (r) {
1008
	if (r) {
-
 
1009
		radeon_ib_free(rdev, &ib);
-
 
1010
		return r;
966
		radeon_ib_free(rdev, &ib);
1011
	}
967
		return r;
1012
	ib.fence->is_vm_update = true;
968
	}
1013
	radeon_vm_fence_pts(vm, bo_va->it.start, bo_va->it.last + 1, ib.fence);
969
	radeon_fence_unref(&vm->fence);
-
 
Line 970... Line 1014...
970
	vm->fence = radeon_fence_ref(ib.fence);
1014
	radeon_fence_unref(&bo_va->last_pt_update);
971
	radeon_ib_free(rdev, &ib);
1015
	bo_va->last_pt_update = radeon_fence_ref(ib.fence);
Line 972... Line 1016...
972
	radeon_fence_unref(&vm->last_flush);
1016
	radeon_ib_free(rdev, &ib);
Line 986... Line 1030...
986
 * PTs have to be reserved and mutex must be locked!
1030
 * PTs have to be reserved and mutex must be locked!
987
 */
1031
 */
988
int radeon_vm_clear_freed(struct radeon_device *rdev,
1032
int radeon_vm_clear_freed(struct radeon_device *rdev,
989
			  struct radeon_vm *vm)
1033
			  struct radeon_vm *vm)
990
{
1034
{
991
	struct radeon_bo_va *bo_va, *tmp;
1035
	struct radeon_bo_va *bo_va;
992
	int r;
1036
	int r;
Line -... Line 1037...
-
 
1037
 
-
 
1038
	spin_lock(&vm->status_lock);
-
 
1039
	while (!list_empty(&vm->freed)) {
993
 
1040
		bo_va = list_first_entry(&vm->freed,
-
 
1041
			struct radeon_bo_va, vm_status);
-
 
1042
		spin_unlock(&vm->status_lock);
994
	list_for_each_entry_safe(bo_va, tmp, &vm->freed, vm_status) {
1043
 
995
		r = radeon_vm_bo_update(rdev, bo_va, NULL);
1044
		r = radeon_vm_bo_update(rdev, bo_va, NULL);
-
 
1045
		radeon_bo_unref(&bo_va->bo);
996
		radeon_bo_unref(&bo_va->bo);
1046
		radeon_fence_unref(&bo_va->last_pt_update);
997
		kfree(bo_va);
1047
		kfree(bo_va);
998
		if (r)
1048
		if (r)
-
 
1049
			return r;
-
 
1050
 
999
			return r;
1051
		spin_lock(&vm->status_lock);
-
 
1052
	}
1000
	}
1053
	spin_unlock(&vm->status_lock);
Line 1001... Line 1054...
1001
	return 0;
1054
	return 0;
Line 1002... Line 1055...
1002
 
1055
 
Line 1014... Line 1067...
1014
 * PTs have to be reserved and mutex must be locked!
1067
 * PTs have to be reserved and mutex must be locked!
1015
 */
1068
 */
1016
int radeon_vm_clear_invalids(struct radeon_device *rdev,
1069
int radeon_vm_clear_invalids(struct radeon_device *rdev,
1017
			     struct radeon_vm *vm)
1070
			     struct radeon_vm *vm)
1018
{
1071
{
1019
	struct radeon_bo_va *bo_va, *tmp;
1072
	struct radeon_bo_va *bo_va;
1020
	int r;
1073
	int r;
Line -... Line 1074...
-
 
1074
 
-
 
1075
	spin_lock(&vm->status_lock);
1021
 
1076
	while (!list_empty(&vm->invalidated)) {
-
 
1077
		bo_va = list_first_entry(&vm->invalidated,
-
 
1078
			struct radeon_bo_va, vm_status);
-
 
1079
		spin_unlock(&vm->status_lock);
1022
	list_for_each_entry_safe(bo_va, tmp, &vm->invalidated, vm_status) {
1080
 
1023
		r = radeon_vm_bo_update(rdev, bo_va, NULL);
1081
		r = radeon_vm_bo_update(rdev, bo_va, NULL);
1024
		if (r)
1082
		if (r)
-
 
1083
			return r;
-
 
1084
 
1025
			return r;
1085
		spin_lock(&vm->status_lock);
-
 
1086
	}
-
 
1087
	spin_unlock(&vm->status_lock);
1026
	}
1088
 
1027
	return 0;
1089
	return 0;
Line 1028... Line 1090...
1028
}
1090
}
1029
 
1091
 
Line 1044... Line 1106...
1044
 
1106
 
Line 1045... Line 1107...
1045
	list_del(&bo_va->bo_list);
1107
	list_del(&bo_va->bo_list);
1046
 
1108
 
-
 
1109
	mutex_lock(&vm->mutex);
1047
	mutex_lock(&vm->mutex);
1110
	interval_tree_remove(&bo_va->it, &vm->va);
Line 1048... Line 1111...
1048
	interval_tree_remove(&bo_va->it, &vm->va);
1111
	spin_lock(&vm->status_lock);
1049
	list_del(&bo_va->vm_status);
1112
	list_del(&bo_va->vm_status);
1050
 
1113
 
1051
	if (bo_va->addr) {
1114
	if (bo_va->addr) {
-
 
1115
		bo_va->bo = radeon_bo_ref(bo_va->bo);
1052
		bo_va->bo = radeon_bo_ref(bo_va->bo);
1116
		list_add(&bo_va->vm_status, &vm->freed);
1053
		list_add(&bo_va->vm_status, &vm->freed);
1117
	} else {
-
 
1118
		radeon_fence_unref(&bo_va->last_pt_update);
Line 1054... Line 1119...
1054
	} else {
1119
	kfree(bo_va);
1055
	kfree(bo_va);
1120
	}
Line 1056... Line 1121...
1056
	}
1121
	spin_unlock(&vm->status_lock);
Line 1072... Line 1137...
1072
{
1137
{
1073
	struct radeon_bo_va *bo_va;
1138
	struct radeon_bo_va *bo_va;
Line 1074... Line 1139...
1074
 
1139
 
1075
	list_for_each_entry(bo_va, &bo->va, bo_list) {
1140
	list_for_each_entry(bo_va, &bo->va, bo_list) {
1076
		if (bo_va->addr) {
1141
		if (bo_va->addr) {
1077
			mutex_lock(&bo_va->vm->mutex);
1142
			spin_lock(&bo_va->vm->status_lock);
1078
			list_del(&bo_va->vm_status);
1143
			list_del(&bo_va->vm_status);
1079
			list_add(&bo_va->vm_status, &bo_va->vm->invalidated);
1144
			list_add(&bo_va->vm_status, &bo_va->vm->invalidated);
1080
			mutex_unlock(&bo_va->vm->mutex);
1145
			spin_unlock(&bo_va->vm->status_lock);
1081
		}
1146
		}
1082
	}
1147
	}
Line 1083... Line 1148...
1083
}
1148
}
Line 1093... Line 1158...
1093
int radeon_vm_init(struct radeon_device *rdev, struct radeon_vm *vm)
1158
int radeon_vm_init(struct radeon_device *rdev, struct radeon_vm *vm)
1094
{
1159
{
1095
	const unsigned align = min(RADEON_VM_PTB_ALIGN_SIZE,
1160
	const unsigned align = min(RADEON_VM_PTB_ALIGN_SIZE,
1096
		RADEON_VM_PTE_COUNT * 8);
1161
		RADEON_VM_PTE_COUNT * 8);
1097
	unsigned pd_size, pd_entries, pts_size;
1162
	unsigned pd_size, pd_entries, pts_size;
1098
	int r;
1163
	int i, r;
Line 1099... Line -...
1099
 
-
 
1100
	vm->id = 0;
1164
 
-
 
1165
	vm->ib_bo_va = NULL;
1101
	vm->ib_bo_va = NULL;
1166
	for (i = 0; i < RADEON_NUM_RINGS; ++i) {
1102
	vm->fence = NULL;
1167
		vm->ids[i].id = 0;
1103
	vm->last_flush = NULL;
1168
		vm->ids[i].flushed_updates = NULL;
-
 
1169
		vm->ids[i].last_id_use = NULL;
1104
	vm->last_id_use = NULL;
1170
	}
1105
	mutex_init(&vm->mutex);
1171
	mutex_init(&vm->mutex);
-
 
1172
	vm->va = RB_ROOT;
1106
	vm->va = RB_ROOT;
1173
	spin_lock_init(&vm->status_lock);
1107
	INIT_LIST_HEAD(&vm->invalidated);
1174
	INIT_LIST_HEAD(&vm->invalidated);
Line 1108... Line 1175...
1108
	INIT_LIST_HEAD(&vm->freed);
1175
	INIT_LIST_HEAD(&vm->freed);
1109
 
1176
 
Line 1118... Line 1185...
1118
		return -ENOMEM;
1185
		return -ENOMEM;
1119
	}
1186
	}
Line 1120... Line 1187...
1120
 
1187
 
1121
	r = radeon_bo_create(rdev, pd_size, align, true,
1188
	r = radeon_bo_create(rdev, pd_size, align, true,
1122
			     RADEON_GEM_DOMAIN_VRAM, 0, NULL,
1189
			     RADEON_GEM_DOMAIN_VRAM, 0, NULL,
1123
			     &vm->page_directory);
1190
			     NULL, &vm->page_directory);
1124
	if (r)
1191
	if (r)
Line 1125... Line 1192...
1125
		return r;
1192
		return r;
1126
 
1193
 
Line 1155... Line 1222...
1155
		interval_tree_remove(&bo_va->it, &vm->va);
1222
		interval_tree_remove(&bo_va->it, &vm->va);
1156
		r = radeon_bo_reserve(bo_va->bo, false);
1223
		r = radeon_bo_reserve(bo_va->bo, false);
1157
		if (!r) {
1224
		if (!r) {
1158
			list_del_init(&bo_va->bo_list);
1225
			list_del_init(&bo_va->bo_list);
1159
			radeon_bo_unreserve(bo_va->bo);
1226
			radeon_bo_unreserve(bo_va->bo);
-
 
1227
			radeon_fence_unref(&bo_va->last_pt_update);
1160
			kfree(bo_va);
1228
			kfree(bo_va);
1161
		}
1229
		}
1162
	}
1230
	}
1163
	list_for_each_entry_safe(bo_va, tmp, &vm->freed, vm_status) {
1231
	list_for_each_entry_safe(bo_va, tmp, &vm->freed, vm_status) {
1164
		radeon_bo_unref(&bo_va->bo);
1232
		radeon_bo_unref(&bo_va->bo);
-
 
1233
		radeon_fence_unref(&bo_va->last_pt_update);
1165
		kfree(bo_va);
1234
		kfree(bo_va);
1166
	}
1235
	}
Line 1167... Line 1236...
1167
 
1236
 
1168
	for (i = 0; i < radeon_vm_num_pdes(rdev); i++)
1237
	for (i = 0; i < radeon_vm_num_pdes(rdev); i++)
1169
		radeon_bo_unref(&vm->page_tables[i].bo);
1238
		radeon_bo_unref(&vm->page_tables[i].bo);
Line 1170... Line 1239...
1170
	kfree(vm->page_tables);
1239
	kfree(vm->page_tables);
Line 1171... Line 1240...
1171
 
1240
 
1172
	radeon_bo_unref(&vm->page_directory);
1241
	radeon_bo_unref(&vm->page_directory);
1173
 
1242
 
-
 
1243
	for (i = 0; i < RADEON_NUM_RINGS; ++i) {
Line 1174... Line 1244...
1174
	radeon_fence_unref(&vm->fence);
1244
		radeon_fence_unref(&vm->ids[i].flushed_updates);
1175
	radeon_fence_unref(&vm->last_flush);
1245
		radeon_fence_unref(&vm->ids[i].last_id_use);