Subversion Repositories Kolibri OS

Rev

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

Rev 5271 Rev 6104
Line 329... Line 329...
329
	bo_va->vm = vm;
329
	bo_va->vm = vm;
330
	bo_va->bo = bo;
330
	bo_va->bo = bo;
331
	bo_va->it.start = 0;
331
	bo_va->it.start = 0;
332
	bo_va->it.last = 0;
332
	bo_va->it.last = 0;
333
	bo_va->flags = 0;
333
	bo_va->flags = 0;
334
	bo_va->addr = 0;
-
 
335
	bo_va->ref_count = 1;
334
	bo_va->ref_count = 1;
336
	INIT_LIST_HEAD(&bo_va->bo_list);
335
	INIT_LIST_HEAD(&bo_va->bo_list);
337
	INIT_LIST_HEAD(&bo_va->vm_status);
336
	INIT_LIST_HEAD(&bo_va->vm_status);
Line 338... Line 337...
338
 
337
 
Line 456... Line 455...
456
 
455
 
457
	if (soffset) {
456
	if (soffset) {
458
		/* make sure object fit at this offset */
457
		/* make sure object fit at this offset */
459
		eoffset = soffset + size;
458
		eoffset = soffset + size;
460
		if (soffset >= eoffset) {
459
		if (soffset >= eoffset) {
-
 
460
			r = -EINVAL;
461
			return -EINVAL;
461
			goto error_unreserve;
Line 462... Line 462...
462
		}
462
		}
463
 
463
 
464
		last_pfn = eoffset / RADEON_GPU_PAGE_SIZE;
464
		last_pfn = eoffset / RADEON_GPU_PAGE_SIZE;
465
		if (last_pfn > rdev->vm_manager.max_pfn) {
465
		if (last_pfn > rdev->vm_manager.max_pfn) {
466
			dev_err(rdev->dev, "va above limit (0x%08X > 0x%08X)\n",
466
			dev_err(rdev->dev, "va above limit (0x%08X > 0x%08X)\n",
-
 
467
				last_pfn, rdev->vm_manager.max_pfn);
467
				last_pfn, rdev->vm_manager.max_pfn);
468
			r = -EINVAL;
Line 468... Line 469...
468
			return -EINVAL;
469
			goto error_unreserve;
469
		}
470
		}
470
 
471
 
Line 471... Line 472...
471
	} else {
472
	} else {
-
 
473
		eoffset = last_pfn = 0;
-
 
474
	}
-
 
475
 
-
 
476
	mutex_lock(&vm->mutex);
-
 
477
	soffset /= RADEON_GPU_PAGE_SIZE;
-
 
478
	eoffset /= RADEON_GPU_PAGE_SIZE;
-
 
479
	if (soffset || eoffset) {
-
 
480
		struct interval_tree_node *it;
-
 
481
		it = interval_tree_iter_first(&vm->va, soffset, eoffset - 1);
-
 
482
		if (it && it != &bo_va->it) {
-
 
483
			struct radeon_bo_va *tmp;
-
 
484
			tmp = container_of(it, struct radeon_bo_va, it);
-
 
485
			/* bo and tmp overlap, invalid offset */
-
 
486
			dev_err(rdev->dev, "bo %p va 0x%010Lx conflict with "
-
 
487
				"(bo %p 0x%010lx 0x%010lx)\n", bo_va->bo,
-
 
488
				soffset, tmp->bo, tmp->it.start, tmp->it.last);
-
 
489
			mutex_unlock(&vm->mutex);
-
 
490
			r = -EINVAL;
472
		eoffset = last_pfn = 0;
491
			goto error_unreserve;
473
	}
-
 
474
 
492
		}
475
	mutex_lock(&vm->mutex);
493
	}
476
	if (bo_va->it.start || bo_va->it.last) {
494
 
477
		if (bo_va->addr) {
495
	if (bo_va->it.start || bo_va->it.last) {
478
			/* add a clone of the bo_va to clear the old address */
496
		/* add a clone of the bo_va to clear the old address */
479
			struct radeon_bo_va *tmp;
497
		struct radeon_bo_va *tmp;
-
 
498
		tmp = kzalloc(sizeof(struct radeon_bo_va), GFP_KERNEL);
480
			tmp = kzalloc(sizeof(struct radeon_bo_va), GFP_KERNEL);
499
		if (!tmp) {
481
			if (!tmp) {
500
			mutex_unlock(&vm->mutex);
482
				mutex_unlock(&vm->mutex);
501
			r = -ENOMEM;
483
				return -ENOMEM;
502
			goto error_unreserve;
484
			}
-
 
485
			tmp->it.start = bo_va->it.start;
503
		}
486
			tmp->it.last = bo_va->it.last;
-
 
487
			tmp->vm = vm;
-
 
488
			tmp->addr = bo_va->addr;
-
 
489
			tmp->bo = radeon_bo_ref(bo_va->bo);
-
 
Line 490... Line 504...
490
			spin_lock(&vm->status_lock);
504
		tmp->it.start = bo_va->it.start;
-
 
505
		tmp->it.last = bo_va->it.last;
491
			list_add(&tmp->vm_status, &vm->freed);
506
		tmp->vm = vm;
492
			spin_unlock(&vm->status_lock);
507
		tmp->bo = radeon_bo_ref(bo_va->bo);
-
 
508
 
-
 
509
		interval_tree_remove(&bo_va->it, &vm->va);
-
 
510
		spin_lock(&vm->status_lock);
493
		}
511
		bo_va->it.start = 0;
Line 494... Line -...
494
 
-
 
495
		interval_tree_remove(&bo_va->it, &vm->va);
-
 
496
		bo_va->it.start = 0;
512
		bo_va->it.last = 0;
497
		bo_va->it.last = 0;
-
 
498
	}
-
 
499
 
-
 
500
	soffset /= RADEON_GPU_PAGE_SIZE;
-
 
501
	eoffset /= RADEON_GPU_PAGE_SIZE;
-
 
502
	if (soffset || eoffset) {
-
 
503
		struct interval_tree_node *it;
-
 
504
		it = interval_tree_iter_first(&vm->va, soffset, eoffset - 1);
-
 
505
		if (it) {
-
 
506
			struct radeon_bo_va *tmp;
513
		list_del_init(&bo_va->vm_status);
507
			tmp = container_of(it, struct radeon_bo_va, it);
-
 
508
			/* bo and tmp overlap, invalid offset */
-
 
509
			dev_err(rdev->dev, "bo %p va 0x%010Lx conflict with "
514
		list_add(&tmp->vm_status, &vm->freed);
510
				"(bo %p 0x%010lx 0x%010lx)\n", bo_va->bo,
515
		spin_unlock(&vm->status_lock);
-
 
516
	}
-
 
517
 
511
				soffset, tmp->bo, tmp->it.start, tmp->it.last);
518
	if (soffset || eoffset) {
512
			mutex_unlock(&vm->mutex);
519
		spin_lock(&vm->status_lock);
Line 513... Line 520...
513
			return -EINVAL;
520
		bo_va->it.start = soffset;
514
		}
-
 
Line 515... Line 521...
515
		bo_va->it.start = soffset;
521
		bo_va->it.last = eoffset - 1;
516
		bo_va->it.last = eoffset - 1;
522
		list_add(&bo_va->vm_status, &vm->cleared);
Line 517... Line 523...
517
		interval_tree_insert(&bo_va->it, &vm->va);
523
		spin_unlock(&vm->status_lock);
Line 548... Line 554...
548
			return r;
554
			return r;
Line 549... Line 555...
549
 
555
 
550
		r = radeon_vm_clear_bo(rdev, pt);
556
		r = radeon_vm_clear_bo(rdev, pt);
551
		if (r) {
557
		if (r) {
552
			radeon_bo_unref(&pt);
-
 
553
			radeon_bo_reserve(bo_va->bo, false);
558
			radeon_bo_unref(&pt);
554
			return r;
559
			return r;
Line 555... Line 560...
555
		}
560
		}
556
 
561
 
Line 568... Line 573...
568
		vm->page_tables[pt_idx].bo = pt;
573
		vm->page_tables[pt_idx].bo = pt;
569
	}
574
	}
Line 570... Line 575...
570
 
575
 
571
	mutex_unlock(&vm->mutex);
576
	mutex_unlock(&vm->mutex);
-
 
577
	return 0;
-
 
578
 
-
 
579
error_unreserve:
-
 
580
	radeon_bo_unreserve(bo_va->bo);
572
	return 0;
581
	return r;
Line 573... Line 582...
573
}
582
}
574
 
583
 
575
/**
584
/**
Line 585... Line 594...
585
uint64_t radeon_vm_map_gart(struct radeon_device *rdev, uint64_t addr)
594
uint64_t radeon_vm_map_gart(struct radeon_device *rdev, uint64_t addr)
586
{
595
{
587
	uint64_t result;
596
	uint64_t result;
Line 588... Line 597...
588
 
597
 
589
	/* page table offset */
598
	/* page table offset */
590
	result = rdev->gart.pages_addr[addr >> PAGE_SHIFT];
-
 
591
 
-
 
592
	/* in case cpu page size != gpu page size*/
599
	result = rdev->gart.pages_entry[addr >> RADEON_GPU_PAGE_SHIFT];
Line 593... Line 600...
593
	result |= addr & (~PAGE_MASK);
600
	result &= ~RADEON_GPU_PAGE_MASK;
594
 
601
 
Line 595... Line 602...
595
	return result;
602
	return result;
Line 743... Line 750...
743
	 * Userspace can support this by aligning virtual base address and
750
	 * Userspace can support this by aligning virtual base address and
744
	 * allocation size to the fragment size.
751
	 * allocation size to the fragment size.
745
	 */
752
	 */
Line 746... Line 753...
746
 
753
 
747
	/* NI is optimized for 256KB fragments, SI and newer for 64KB */
754
	/* NI is optimized for 256KB fragments, SI and newer for 64KB */
-
 
755
	uint64_t frag_flags = ((rdev->family == CHIP_CAYMAN) ||
748
	uint64_t frag_flags = rdev->family == CHIP_CAYMAN ?
756
			       (rdev->family == CHIP_ARUBA)) ?
749
			R600_PTE_FRAG_256KB : R600_PTE_FRAG_64KB;
757
			R600_PTE_FRAG_256KB : R600_PTE_FRAG_64KB;
-
 
758
	uint64_t frag_align = ((rdev->family == CHIP_CAYMAN) ||
Line 750... Line 759...
750
	uint64_t frag_align = rdev->family == CHIP_CAYMAN ? 0x200 : 0x80;
759
			       (rdev->family == CHIP_ARUBA)) ? 0x200 : 0x80;
751
 
760
 
Line 752... Line 761...
752
	uint64_t frag_start = ALIGN(pe_start, frag_align);
761
	uint64_t frag_start = ALIGN(pe_start, frag_align);
Line 914... Line 923...
914
			bo_va->bo, vm);
923
			bo_va->bo, vm);
915
		return -EINVAL;
924
		return -EINVAL;
916
	}
925
	}
Line 917... Line 926...
917
 
926
 
-
 
927
	spin_lock(&vm->status_lock);
-
 
928
	if (mem) {
-
 
929
		if (list_empty(&bo_va->vm_status)) {
-
 
930
			spin_unlock(&vm->status_lock);
-
 
931
			return 0;
918
	spin_lock(&vm->status_lock);
932
		}
-
 
933
		list_del_init(&bo_va->vm_status);
-
 
934
	} else {
-
 
935
		list_del(&bo_va->vm_status);
-
 
936
		list_add(&bo_va->vm_status, &vm->cleared);
919
	list_del_init(&bo_va->vm_status);
937
	}
Line 920... Line 938...
920
	spin_unlock(&vm->status_lock);
938
	spin_unlock(&vm->status_lock);
921
 
939
 
922
	bo_va->flags &= ~RADEON_VM_PAGE_VALID;
940
	bo_va->flags &= ~RADEON_VM_PAGE_VALID;
Line 940... Line 958...
940
		}
958
		}
941
	} else {
959
	} else {
942
		addr = 0;
960
		addr = 0;
943
	}
961
	}
Line 944... Line -...
944
 
-
 
945
	if (addr == bo_va->addr)
-
 
946
		return 0;
-
 
947
	bo_va->addr = addr;
-
 
948
 
962
 
Line 949... Line 963...
949
	trace_radeon_vm_bo_update(bo_va);
963
	trace_radeon_vm_bo_update(bo_va);
Line 950... Line 964...
950
 
964
 
Line 1031... Line 1045...
1031
 */
1045
 */
1032
int radeon_vm_clear_freed(struct radeon_device *rdev,
1046
int radeon_vm_clear_freed(struct radeon_device *rdev,
1033
			  struct radeon_vm *vm)
1047
			  struct radeon_vm *vm)
1034
{
1048
{
1035
	struct radeon_bo_va *bo_va;
1049
	struct radeon_bo_va *bo_va;
1036
	int r;
1050
	int r = 0;
Line 1037... Line 1051...
1037
 
1051
 
1038
	spin_lock(&vm->status_lock);
1052
	spin_lock(&vm->status_lock);
1039
	while (!list_empty(&vm->freed)) {
1053
	while (!list_empty(&vm->freed)) {
1040
		bo_va = list_first_entry(&vm->freed,
1054
		bo_va = list_first_entry(&vm->freed,
1041
			struct radeon_bo_va, vm_status);
1055
			struct radeon_bo_va, vm_status);
Line 1042... Line 1056...
1042
		spin_unlock(&vm->status_lock);
1056
		spin_unlock(&vm->status_lock);
1043
 
1057
 
1044
		r = radeon_vm_bo_update(rdev, bo_va, NULL);
1058
		r = radeon_vm_bo_update(rdev, bo_va, NULL);
-
 
1059
		radeon_bo_unref(&bo_va->bo);
-
 
1060
		radeon_fence_unref(&bo_va->last_pt_update);
1045
		radeon_bo_unref(&bo_va->bo);
1061
		spin_lock(&vm->status_lock);
1046
		radeon_fence_unref(&bo_va->last_pt_update);
1062
		list_del(&bo_va->vm_status);
1047
		kfree(bo_va);
1063
		kfree(bo_va);
Line 1048... Line -...
1048
		if (r)
-
 
1049
			return r;
1064
		if (r)
1050
 
1065
			break;
1051
		spin_lock(&vm->status_lock);
1066
 
Line 1052... Line 1067...
1052
	}
1067
	}
Line 1053... Line 1068...
1053
	spin_unlock(&vm->status_lock);
1068
	spin_unlock(&vm->status_lock);
1054
	return 0;
1069
	return r;
Line 1105... Line 1120...
1105
	struct radeon_vm *vm = bo_va->vm;
1120
	struct radeon_vm *vm = bo_va->vm;
Line 1106... Line 1121...
1106
 
1121
 
Line 1107... Line 1122...
1107
	list_del(&bo_va->bo_list);
1122
	list_del(&bo_va->bo_list);
-
 
1123
 
1108
 
1124
	mutex_lock(&vm->mutex);
-
 
1125
	if (bo_va->it.start || bo_va->it.last)
1109
	mutex_lock(&vm->mutex);
1126
		interval_tree_remove(&bo_va->it, &vm->va);
1110
	interval_tree_remove(&bo_va->it, &vm->va);
1127
 
1111
	spin_lock(&vm->status_lock);
-
 
1112
	list_del(&bo_va->vm_status);
1128
	spin_lock(&vm->status_lock);
1113
 
1129
	list_del(&bo_va->vm_status);
1114
	if (bo_va->addr) {
1130
	if (bo_va->it.start || bo_va->it.last) {
1115
		bo_va->bo = radeon_bo_ref(bo_va->bo);
1131
		bo_va->bo = radeon_bo_ref(bo_va->bo);
1116
		list_add(&bo_va->vm_status, &vm->freed);
1132
		list_add(&bo_va->vm_status, &vm->freed);
1117
	} else {
1133
	} else {
Line 1136... Line 1152...
1136
			     struct radeon_bo *bo)
1152
			     struct radeon_bo *bo)
1137
{
1153
{
1138
	struct radeon_bo_va *bo_va;
1154
	struct radeon_bo_va *bo_va;
Line 1139... Line 1155...
1139
 
1155
 
1140
	list_for_each_entry(bo_va, &bo->va, bo_list) {
-
 
1141
		if (bo_va->addr) {
1156
	list_for_each_entry(bo_va, &bo->va, bo_list) {
1142
			spin_lock(&bo_va->vm->status_lock);
1157
		spin_lock(&bo_va->vm->status_lock);
-
 
1158
		if (list_empty(&bo_va->vm_status) &&
1143
			list_del(&bo_va->vm_status);
1159
		    (bo_va->it.start || bo_va->it.last))
1144
			list_add(&bo_va->vm_status, &bo_va->vm->invalidated);
1160
			list_add(&bo_va->vm_status, &bo_va->vm->invalidated);
1145
			spin_unlock(&bo_va->vm->status_lock);
1161
		spin_unlock(&bo_va->vm->status_lock);
1146
		}
1162
	}
1147
	}
-
 
Line 1148... Line 1163...
1148
}
1163
}
1149
 
1164
 
1150
/**
1165
/**
1151
 * radeon_vm_init - initialize a vm instance
1166
 * radeon_vm_init - initialize a vm instance
Line 1171... Line 1186...
1171
	mutex_init(&vm->mutex);
1186
	mutex_init(&vm->mutex);
1172
	vm->va = RB_ROOT;
1187
	vm->va = RB_ROOT;
1173
	spin_lock_init(&vm->status_lock);
1188
	spin_lock_init(&vm->status_lock);
1174
	INIT_LIST_HEAD(&vm->invalidated);
1189
	INIT_LIST_HEAD(&vm->invalidated);
1175
	INIT_LIST_HEAD(&vm->freed);
1190
	INIT_LIST_HEAD(&vm->freed);
-
 
1191
	INIT_LIST_HEAD(&vm->cleared);
Line 1176... Line 1192...
1176
 
1192
 
1177
	pd_size = radeon_vm_directory_size(rdev);
1193
	pd_size = radeon_vm_directory_size(rdev);
Line 1178... Line 1194...
1178
	pd_entries = radeon_vm_num_pdes(rdev);
1194
	pd_entries = radeon_vm_num_pdes(rdev);