ttm_bo.c 41.9 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
/**************************************************************************
 *
 * Copyright (c) 2006-2009 VMware, Inc., Palo Alto, CA., USA
 * All Rights Reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sub license, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice (including the
 * next paragraph) shall be included in all copies or substantial portions
 * of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
 * USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 **************************************************************************/
/*
 * Authors: Thomas Hellstrom <thellstrom-at-vmware-dot-com>
 */

J
Joe Perches 已提交
31 32
#define pr_fmt(fmt) "[TTM] " fmt

33 34 35
#include <drm/ttm/ttm_module.h>
#include <drm/ttm/ttm_bo_driver.h>
#include <drm/ttm/ttm_placement.h>
36 37 38 39 40 41
#include <linux/jiffies.h>
#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/file.h>
#include <linux/module.h>
A
Arun Sharma 已提交
42
#include <linux/atomic.h>
43
#include <linux/reservation.h>
44 45 46 47 48 49

#define TTM_ASSERT_LOCKED(param)
#define TTM_DEBUG(fmt, arg...)
#define TTM_BO_HASH_ORDER 13

static int ttm_bo_swapout(struct ttm_mem_shrink *shrink);
50 51 52 53 54 55 56
static void ttm_bo_global_kobj_release(struct kobject *kobj);

static struct attribute ttm_bo_count = {
	.name = "bo_count",
	.mode = S_IRUGO
};

57 58
static inline int ttm_mem_type_from_place(const struct ttm_place *place,
					  uint32_t *mem_type)
59 60 61 62
{
	int i;

	for (i = 0; i <= TTM_PL_PRIV5; i++)
63
		if (place->flags & (1 << i)) {
64 65 66 67 68 69
			*mem_type = i;
			return 0;
		}
	return -EINVAL;
}

70
static void ttm_mem_type_debug(struct ttm_bo_device *bdev, int mem_type)
71
{
72 73
	struct ttm_mem_type_manager *man = &bdev->man[mem_type];

J
Joe Perches 已提交
74 75 76 77 78 79 80
	pr_err("    has_type: %d\n", man->has_type);
	pr_err("    use_type: %d\n", man->use_type);
	pr_err("    flags: 0x%08X\n", man->flags);
	pr_err("    gpu_offset: 0x%08lX\n", man->gpu_offset);
	pr_err("    size: %llu\n", man->size);
	pr_err("    available_caching: 0x%08X\n", man->available_caching);
	pr_err("    default_caching: 0x%08X\n", man->default_caching);
81 82
	if (mem_type != TTM_PL_SYSTEM)
		(*man->func->debug)(man, TTM_PFX);
83 84 85 86 87 88 89
}

static void ttm_bo_mem_space_debug(struct ttm_buffer_object *bo,
					struct ttm_placement *placement)
{
	int i, ret, mem_type;

J
Joe Perches 已提交
90 91 92
	pr_err("No space for %p (%lu pages, %luK, %luM)\n",
	       bo, bo->mem.num_pages, bo->mem.size >> 10,
	       bo->mem.size >> 20);
93
	for (i = 0; i < placement->num_placement; i++) {
94
		ret = ttm_mem_type_from_place(&placement->placement[i],
95 96 97
						&mem_type);
		if (ret)
			return;
J
Joe Perches 已提交
98
		pr_err("  placement[%d]=0x%08X (%d)\n",
99
		       i, placement->placement[i].flags, mem_type);
100
		ttm_mem_type_debug(bo->bdev, mem_type);
101 102 103
	}
}

104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
static ssize_t ttm_bo_global_show(struct kobject *kobj,
				  struct attribute *attr,
				  char *buffer)
{
	struct ttm_bo_global *glob =
		container_of(kobj, struct ttm_bo_global, kobj);

	return snprintf(buffer, PAGE_SIZE, "%lu\n",
			(unsigned long) atomic_read(&glob->bo_count));
}

static struct attribute *ttm_bo_global_attrs[] = {
	&ttm_bo_count,
	NULL
};

120
static const struct sysfs_ops ttm_bo_global_ops = {
121 122 123 124 125 126 127 128 129
	.show = &ttm_bo_global_show
};

static struct kobj_type ttm_bo_glob_kobj_type  = {
	.release = &ttm_bo_global_kobj_release,
	.sysfs_ops = &ttm_bo_global_ops,
	.default_attrs = ttm_bo_global_attrs
};

130 131 132 133 134 135 136 137 138 139 140

static inline uint32_t ttm_bo_type_flags(unsigned type)
{
	return 1 << (type);
}

static void ttm_bo_release_list(struct kref *list_kref)
{
	struct ttm_buffer_object *bo =
	    container_of(list_kref, struct ttm_buffer_object, list_kref);
	struct ttm_bo_device *bdev = bo->bdev;
141
	size_t acc_size = bo->acc_size;
142 143 144 145 146 147 148 149 150 151

	BUG_ON(atomic_read(&bo->list_kref.refcount));
	BUG_ON(atomic_read(&bo->kref.refcount));
	BUG_ON(atomic_read(&bo->cpu_writers));
	BUG_ON(bo->mem.mm_node != NULL);
	BUG_ON(!list_empty(&bo->lru));
	BUG_ON(!list_empty(&bo->ddestroy));

	if (bo->ttm)
		ttm_tt_destroy(bo->ttm);
152
	atomic_dec(&bo->glob->bo_count);
153 154
	if (bo->resv == &bo->ttm_resv)
		reservation_object_fini(&bo->ttm_resv);
155
	mutex_destroy(&bo->wu_mutex);
156 157 158 159 160
	if (bo->destroy)
		bo->destroy(bo);
	else {
		kfree(bo);
	}
161
	ttm_mem_global_free(bdev->glob->mem_glob, acc_size);
162 163
}

164
void ttm_bo_add_to_lru(struct ttm_buffer_object *bo)
165 166 167 168
{
	struct ttm_bo_device *bdev = bo->bdev;
	struct ttm_mem_type_manager *man;

169
	lockdep_assert_held(&bo->resv->lock.base);
170 171 172 173 174 175 176 177 178 179

	if (!(bo->mem.placement & TTM_PL_FLAG_NO_EVICT)) {

		BUG_ON(!list_empty(&bo->lru));

		man = &bdev->man[bo->mem.mem_type];
		list_add_tail(&bo->lru, &man->lru);
		kref_get(&bo->list_kref);

		if (bo->ttm != NULL) {
180
			list_add_tail(&bo->swap, &bo->glob->swap_lru);
181 182 183 184
			kref_get(&bo->list_kref);
		}
	}
}
185
EXPORT_SYMBOL(ttm_bo_add_to_lru);
186

187
int ttm_bo_del_from_lru(struct ttm_buffer_object *bo)
188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212
{
	int put_count = 0;

	if (!list_empty(&bo->swap)) {
		list_del_init(&bo->swap);
		++put_count;
	}
	if (!list_empty(&bo->lru)) {
		list_del_init(&bo->lru);
		++put_count;
	}

	/*
	 * TODO: Add a driver hook to delete from
	 * driver-specific LRU's here.
	 */

	return put_count;
}

static void ttm_bo_ref_bug(struct kref *list_kref)
{
	BUG();
}

213 214 215
void ttm_bo_list_ref_sub(struct ttm_buffer_object *bo, int count,
			 bool never_free)
{
216 217
	kref_sub(&bo->list_kref, count,
		 (never_free) ? ttm_bo_ref_bug : ttm_bo_release_list);
218 219
}

220
void ttm_bo_del_sub_from_lru(struct ttm_buffer_object *bo)
221
{
222
	int put_count;
223

224 225 226 227
	spin_lock(&bo->glob->lru_lock);
	put_count = ttm_bo_del_from_lru(bo);
	spin_unlock(&bo->glob->lru_lock);
	ttm_bo_list_ref_sub(bo, put_count, true);
228
}
229
EXPORT_SYMBOL(ttm_bo_del_sub_from_lru);
230

231 232 233 234 235 236
/*
 * Call bo->mutex locked.
 */
static int ttm_bo_add_ttm(struct ttm_buffer_object *bo, bool zero_alloc)
{
	struct ttm_bo_device *bdev = bo->bdev;
237
	struct ttm_bo_global *glob = bo->glob;
238 239 240 241 242 243
	int ret = 0;
	uint32_t page_flags = 0;

	TTM_ASSERT_LOCKED(&bo->mutex);
	bo->ttm = NULL;

D
Dave Airlie 已提交
244 245 246
	if (bdev->need_dma32)
		page_flags |= TTM_PAGE_FLAG_DMA32;

247 248 249 250 251
	switch (bo->type) {
	case ttm_bo_type_device:
		if (zero_alloc)
			page_flags |= TTM_PAGE_FLAG_ZERO_ALLOC;
	case ttm_bo_type_kernel:
252 253
		bo->ttm = bdev->driver->ttm_tt_create(bdev, bo->num_pages << PAGE_SHIFT,
						      page_flags, glob->dummy_read_page);
254 255 256
		if (unlikely(bo->ttm == NULL))
			ret = -ENOMEM;
		break;
257 258 259 260 261 262 263 264 265 266
	case ttm_bo_type_sg:
		bo->ttm = bdev->driver->ttm_tt_create(bdev, bo->num_pages << PAGE_SHIFT,
						      page_flags | TTM_PAGE_FLAG_SG,
						      glob->dummy_read_page);
		if (unlikely(bo->ttm == NULL)) {
			ret = -ENOMEM;
			break;
		}
		bo->ttm->sg = bo->sg;
		break;
267
	default:
J
Joe Perches 已提交
268
		pr_err("Illegal buffer object type\n");
269 270 271 272 273 274 275 276 277
		ret = -EINVAL;
		break;
	}

	return ret;
}

static int ttm_bo_handle_move_mem(struct ttm_buffer_object *bo,
				  struct ttm_mem_reg *mem,
278
				  bool evict, bool interruptible,
279
				  bool no_wait_gpu)
280 281 282 283 284 285 286 287 288
{
	struct ttm_bo_device *bdev = bo->bdev;
	bool old_is_pci = ttm_mem_reg_is_pci(bdev, &bo->mem);
	bool new_is_pci = ttm_mem_reg_is_pci(bdev, mem);
	struct ttm_mem_type_manager *old_man = &bdev->man[bo->mem.mem_type];
	struct ttm_mem_type_manager *new_man = &bdev->man[mem->mem_type];
	int ret = 0;

	if (old_is_pci || new_is_pci ||
289 290 291 292 293 294 295
	    ((mem->placement & bo->mem.placement & TTM_PL_MASK_CACHING) == 0)) {
		ret = ttm_mem_io_lock(old_man, true);
		if (unlikely(ret != 0))
			goto out_err;
		ttm_bo_unmap_virtual_locked(bo);
		ttm_mem_io_unlock(old_man);
	}
296 297 298 299 300

	/*
	 * Create and bind a ttm if required.
	 */

301 302
	if (!(new_man->flags & TTM_MEMTYPE_FLAG_FIXED)) {
		if (bo->ttm == NULL) {
303 304
			bool zero = !(old_man->flags & TTM_MEMTYPE_FLAG_FIXED);
			ret = ttm_bo_add_ttm(bo, zero);
305 306 307
			if (ret)
				goto out_err;
		}
308 309 310

		ret = ttm_tt_set_placement_caching(bo->ttm, mem->placement);
		if (ret)
311
			goto out_err;
312 313 314 315 316 317 318 319

		if (mem->mem_type != TTM_PL_SYSTEM) {
			ret = ttm_tt_bind(bo->ttm, mem);
			if (ret)
				goto out_err;
		}

		if (bo->mem.mem_type == TTM_PL_SYSTEM) {
320 321
			if (bdev->driver->move_notify)
				bdev->driver->move_notify(bo, mem);
322
			bo->mem = *mem;
323 324 325 326 327
			mem->mm_node = NULL;
			goto moved;
		}
	}

328 329 330
	if (bdev->driver->move_notify)
		bdev->driver->move_notify(bo, mem);

331 332
	if (!(old_man->flags & TTM_MEMTYPE_FLAG_FIXED) &&
	    !(new_man->flags & TTM_MEMTYPE_FLAG_FIXED))
333
		ret = ttm_bo_move_ttm(bo, evict, no_wait_gpu, mem);
334 335
	else if (bdev->driver->move)
		ret = bdev->driver->move(bo, evict, interruptible,
336
					 no_wait_gpu, mem);
337
	else
338
		ret = ttm_bo_move_memcpy(bo, evict, no_wait_gpu, mem);
339

340 341 342 343 344 345 346
	if (ret) {
		if (bdev->driver->move_notify) {
			struct ttm_mem_reg tmp_mem = *mem;
			*mem = bo->mem;
			bo->mem = tmp_mem;
			bdev->driver->move_notify(bo, mem);
			bo->mem = *mem;
347
			*mem = tmp_mem;
348
		}
349

350 351
		goto out_err;
	}
352

353 354
moved:
	if (bo->evicted) {
355 356 357 358 359
		if (bdev->driver->invalidate_caches) {
			ret = bdev->driver->invalidate_caches(bdev, bo->mem.placement);
			if (ret)
				pr_err("Can not flush read caches\n");
		}
360 361 362 363
		bo->evicted = false;
	}

	if (bo->mem.mm_node) {
364
		bo->offset = (bo->mem.start << PAGE_SHIFT) +
365 366
		    bdev->man[bo->mem.mem_type].gpu_offset;
		bo->cur_placement = bo->mem.placement;
367 368
	} else
		bo->offset = 0;
369 370 371 372 373 374 375 376 377 378 379 380 381 382

	return 0;

out_err:
	new_man = &bdev->man[bo->mem.mem_type];
	if ((new_man->flags & TTM_MEMTYPE_FLAG_FIXED) && bo->ttm) {
		ttm_tt_unbind(bo->ttm);
		ttm_tt_destroy(bo->ttm);
		bo->ttm = NULL;
	}

	return ret;
}

383
/**
384
 * Call bo::reserved.
385
 * Will release GPU memory type usage on destruction.
386 387 388
 * This is the place to put in driver specific hooks to release
 * driver private resources.
 * Will release the bo::reserved lock.
389 390 391 392
 */

static void ttm_bo_cleanup_memtype_use(struct ttm_buffer_object *bo)
{
393 394 395
	if (bo->bdev->driver->move_notify)
		bo->bdev->driver->move_notify(bo, NULL);

396 397 398 399 400
	if (bo->ttm) {
		ttm_tt_unbind(bo->ttm);
		ttm_tt_destroy(bo->ttm);
		bo->ttm = NULL;
	}
401
	ttm_bo_mem_put(bo, &bo->mem);
402

403
	ww_mutex_unlock (&bo->resv->lock);
404 405
}

406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425
static void ttm_bo_flush_all_fences(struct ttm_buffer_object *bo)
{
	struct reservation_object_list *fobj;
	struct fence *fence;
	int i;

	fobj = reservation_object_get_list(bo->resv);
	fence = reservation_object_get_excl(bo->resv);
	if (fence && !fence->ops->signaled)
		fence_enable_sw_signaling(fence);

	for (i = 0; fobj && i < fobj->shared_count; ++i) {
		fence = rcu_dereference_protected(fobj->shared[i],
					reservation_object_held(bo->resv));

		if (!fence->ops->signaled)
			fence_enable_sw_signaling(fence);
	}
}

426
static void ttm_bo_cleanup_refs_or_queue(struct ttm_buffer_object *bo)
427 428
{
	struct ttm_bo_device *bdev = bo->bdev;
429
	struct ttm_bo_global *glob = bo->glob;
430
	int put_count;
431 432
	int ret;

433
	spin_lock(&glob->lru_lock);
434
	ret = __ttm_bo_reserve(bo, false, true, false, NULL);
435

M
Maarten Lankhorst 已提交
436
	if (!ret) {
437
		if (!ttm_bo_wait(bo, false, false, true)) {
M
Maarten Lankhorst 已提交
438
			put_count = ttm_bo_del_from_lru(bo);
439

M
Maarten Lankhorst 已提交
440 441
			spin_unlock(&glob->lru_lock);
			ttm_bo_cleanup_memtype_use(bo);
442

M
Maarten Lankhorst 已提交
443
			ttm_bo_list_ref_sub(bo, put_count, true);
444

M
Maarten Lankhorst 已提交
445
			return;
446 447
		} else
			ttm_bo_flush_all_fences(bo);
448 449 450 451 452 453 454 455 456 457 458

		/*
		 * Make NO_EVICT bos immediately available to
		 * shrinkers, now that they are queued for
		 * destruction.
		 */
		if (bo->mem.placement & TTM_PL_FLAG_NO_EVICT) {
			bo->mem.placement &= ~TTM_PL_FLAG_NO_EVICT;
			ttm_bo_add_to_lru(bo);
		}

459
		__ttm_bo_unreserve(bo);
460
	}
461 462 463 464 465 466 467 468 469

	kref_get(&bo->list_kref);
	list_add_tail(&bo->ddestroy, &bdev->ddestroy);
	spin_unlock(&glob->lru_lock);

	schedule_delayed_work(&bdev->wq,
			      ((HZ / 100) < 1) ? 1 : HZ / 100);
}

470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529
static int ttm_bo_unreserve_and_wait(struct ttm_buffer_object *bo,
				     bool interruptible)
{
	struct ttm_bo_global *glob = bo->glob;
	struct reservation_object_list *fobj;
	struct fence *excl = NULL;
	struct fence **shared = NULL;
	u32 shared_count = 0, i;
	int ret = 0;

	fobj = reservation_object_get_list(bo->resv);
	if (fobj && fobj->shared_count) {
		shared = kmalloc(sizeof(*shared) * fobj->shared_count,
				 GFP_KERNEL);

		if (!shared) {
			ret = -ENOMEM;
			__ttm_bo_unreserve(bo);
			spin_unlock(&glob->lru_lock);
			return ret;
		}

		for (i = 0; i < fobj->shared_count; ++i) {
			if (!fence_is_signaled(fobj->shared[i])) {
				fence_get(fobj->shared[i]);
				shared[shared_count++] = fobj->shared[i];
			}
		}
		if (!shared_count) {
			kfree(shared);
			shared = NULL;
		}
	}

	excl = reservation_object_get_excl(bo->resv);
	if (excl && !fence_is_signaled(excl))
		fence_get(excl);
	else
		excl = NULL;

	__ttm_bo_unreserve(bo);
	spin_unlock(&glob->lru_lock);

	if (excl) {
		ret = fence_wait(excl, interruptible);
		fence_put(excl);
	}

	if (shared_count > 0) {
		for (i = 0; i < shared_count; ++i) {
			if (!ret)
				ret = fence_wait(shared[i], interruptible);
			fence_put(shared[i]);
		}
		kfree(shared);
	}

	return ret;
}

530
/**
531
 * function ttm_bo_cleanup_refs_and_unlock
532 533 534
 * If bo idle, remove from delayed- and lru lists, and unref.
 * If not idle, do nothing.
 *
535 536 537
 * Must be called with lru_lock and reservation held, this function
 * will drop both before returning.
 *
538 539 540 541
 * @interruptible         Any sleeps should occur interruptibly.
 * @no_wait_gpu           Never wait for gpu. Return -EBUSY instead.
 */

542 543 544
static int ttm_bo_cleanup_refs_and_unlock(struct ttm_buffer_object *bo,
					  bool interruptible,
					  bool no_wait_gpu)
545 546 547
{
	struct ttm_bo_global *glob = bo->glob;
	int put_count;
548
	int ret;
549

550
	ret = ttm_bo_wait(bo, false, false, true);
551

552
	if (ret && !no_wait_gpu) {
553
		ret = ttm_bo_unreserve_and_wait(bo, interruptible);
554
		if (ret)
555 556
			return ret;

557
		spin_lock(&glob->lru_lock);
558
		ret = __ttm_bo_reserve(bo, false, true, false, NULL);
559

560 561 562 563 564 565 566 567 568 569 570 571
		/*
		 * We raced, and lost, someone else holds the reservation now,
		 * and is probably busy in ttm_bo_cleanup_memtype_use.
		 *
		 * Even if it's not the case, because we finished waiting any
		 * delayed destruction would succeed, so just return success
		 * here.
		 */
		if (ret) {
			spin_unlock(&glob->lru_lock);
			return 0;
		}
572 573 574 575 576 577 578 579

		/*
		 * remove sync_obj with ttm_bo_wait, the wait should be
		 * finished, and no new wait object should have been added.
		 */
		ret = ttm_bo_wait(bo, false, false, true);
		WARN_ON(ret);
	}
580

581
	if (ret || unlikely(list_empty(&bo->ddestroy))) {
582
		__ttm_bo_unreserve(bo);
583
		spin_unlock(&glob->lru_lock);
584
		return ret;
585 586
	}

587 588 589 590 591 592 593
	put_count = ttm_bo_del_from_lru(bo);
	list_del_init(&bo->ddestroy);
	++put_count;

	spin_unlock(&glob->lru_lock);
	ttm_bo_cleanup_memtype_use(bo);

594
	ttm_bo_list_ref_sub(bo, put_count, true);
595 596

	return 0;
597 598 599 600 601 602 603 604 605
}

/**
 * Traverse the delayed list, and call ttm_bo_cleanup_refs on all
 * encountered buffers.
 */

static int ttm_bo_delayed_delete(struct ttm_bo_device *bdev, bool remove_all)
{
606
	struct ttm_bo_global *glob = bdev->glob;
607 608
	struct ttm_buffer_object *entry = NULL;
	int ret = 0;
609

610
	spin_lock(&glob->lru_lock);
611 612 613 614 615 616 617 618 619 620 621 622 623
	if (list_empty(&bdev->ddestroy))
		goto out_unlock;

	entry = list_first_entry(&bdev->ddestroy,
		struct ttm_buffer_object, ddestroy);
	kref_get(&entry->list_kref);

	for (;;) {
		struct ttm_buffer_object *nentry = NULL;

		if (entry->ddestroy.next != &bdev->ddestroy) {
			nentry = list_first_entry(&entry->ddestroy,
				struct ttm_buffer_object, ddestroy);
624 625 626
			kref_get(&nentry->list_kref);
		}

627
		ret = __ttm_bo_reserve(entry, false, true, false, NULL);
628 629
		if (remove_all && ret) {
			spin_unlock(&glob->lru_lock);
630
			ret = __ttm_bo_reserve(entry, false, false,
631
					       false, NULL);
632 633 634
			spin_lock(&glob->lru_lock);
		}

635 636 637 638 639 640
		if (!ret)
			ret = ttm_bo_cleanup_refs_and_unlock(entry, false,
							     !remove_all);
		else
			spin_unlock(&glob->lru_lock);

641
		kref_put(&entry->list_kref, ttm_bo_release_list);
642 643 644 645
		entry = nentry;

		if (ret || !entry)
			goto out;
646

647
		spin_lock(&glob->lru_lock);
648
		if (list_empty(&entry->ddestroy))
649 650 651
			break;
	}

652 653 654 655 656
out_unlock:
	spin_unlock(&glob->lru_lock);
out:
	if (entry)
		kref_put(&entry->list_kref, ttm_bo_release_list);
657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675
	return ret;
}

static void ttm_bo_delayed_workqueue(struct work_struct *work)
{
	struct ttm_bo_device *bdev =
	    container_of(work, struct ttm_bo_device, wq.work);

	if (ttm_bo_delayed_delete(bdev, false)) {
		schedule_delayed_work(&bdev->wq,
				      ((HZ / 100) < 1) ? 1 : HZ / 100);
	}
}

static void ttm_bo_release(struct kref *kref)
{
	struct ttm_buffer_object *bo =
	    container_of(kref, struct ttm_buffer_object, kref);
	struct ttm_bo_device *bdev = bo->bdev;
676
	struct ttm_mem_type_manager *man = &bdev->man[bo->mem.mem_type];
677

678
	drm_vma_offset_remove(&bdev->vma_manager, &bo->vma_node);
679 680 681
	ttm_mem_io_lock(man, false);
	ttm_mem_io_free_vm(bo);
	ttm_mem_io_unlock(man);
682
	ttm_bo_cleanup_refs_or_queue(bo);
683 684 685 686 687 688 689 690 691 692 693 694
	kref_put(&bo->list_kref, ttm_bo_release_list);
}

void ttm_bo_unref(struct ttm_buffer_object **p_bo)
{
	struct ttm_buffer_object *bo = *p_bo;

	*p_bo = NULL;
	kref_put(&bo->kref, ttm_bo_release);
}
EXPORT_SYMBOL(ttm_bo_unref);

695 696 697 698 699 700 701 702 703 704 705 706 707 708
int ttm_bo_lock_delayed_workqueue(struct ttm_bo_device *bdev)
{
	return cancel_delayed_work_sync(&bdev->wq);
}
EXPORT_SYMBOL(ttm_bo_lock_delayed_workqueue);

void ttm_bo_unlock_delayed_workqueue(struct ttm_bo_device *bdev, int resched)
{
	if (resched)
		schedule_delayed_work(&bdev->wq,
				      ((HZ / 100) < 1) ? 1 : HZ / 100);
}
EXPORT_SYMBOL(ttm_bo_unlock_delayed_workqueue);

709
static int ttm_bo_evict(struct ttm_buffer_object *bo, bool interruptible,
710
			bool no_wait_gpu)
711 712 713
{
	struct ttm_bo_device *bdev = bo->bdev;
	struct ttm_mem_reg evict_mem;
714 715
	struct ttm_placement placement;
	int ret = 0;
716

717
	ret = ttm_bo_wait(bo, false, interruptible, no_wait_gpu);
718

719
	if (unlikely(ret != 0)) {
720
		if (ret != -ERESTARTSYS) {
J
Joe Perches 已提交
721
			pr_err("Failed to expire sync object before buffer eviction\n");
722
		}
723 724 725
		goto out;
	}

726
	lockdep_assert_held(&bo->resv->lock.base);
727 728 729

	evict_mem = bo->mem;
	evict_mem.mm_node = NULL;
730 731
	evict_mem.bus.io_reserved_vm = false;
	evict_mem.bus.io_reserved_count = 0;
732

733 734
	placement.num_placement = 0;
	placement.num_busy_placement = 0;
735 736
	bdev->driver->evict_flags(bo, &placement);
	ret = ttm_bo_mem_space(bo, &placement, &evict_mem, interruptible,
737
				no_wait_gpu);
738
	if (ret) {
739
		if (ret != -ERESTARTSYS) {
J
Joe Perches 已提交
740 741
			pr_err("Failed to find memory space for buffer 0x%p eviction\n",
			       bo);
742 743
			ttm_bo_mem_space_debug(bo, &placement);
		}
744 745 746 747
		goto out;
	}

	ret = ttm_bo_handle_move_mem(bo, &evict_mem, true, interruptible,
748
				     no_wait_gpu);
749
	if (ret) {
750
		if (ret != -ERESTARTSYS)
J
Joe Perches 已提交
751
			pr_err("Buffer eviction failed\n");
752
		ttm_bo_mem_put(bo, &evict_mem);
753 754
		goto out;
	}
755 756 757 758 759 760 761
	bo->evicted = true;
out:
	return ret;
}

static int ttm_mem_evict_first(struct ttm_bo_device *bdev,
				uint32_t mem_type,
762
				bool interruptible,
763
				bool no_wait_gpu)
764 765 766 767
{
	struct ttm_bo_global *glob = bdev->glob;
	struct ttm_mem_type_manager *man = &bdev->man[mem_type];
	struct ttm_buffer_object *bo;
768
	int ret = -EBUSY, put_count;
769

770
	spin_lock(&glob->lru_lock);
771
	list_for_each_entry(bo, &man->lru, lru) {
772
		ret = __ttm_bo_reserve(bo, false, true, false, NULL);
773 774 775 776 777
		if (!ret)
			break;
	}

	if (ret) {
778
		spin_unlock(&glob->lru_lock);
779
		return ret;
780 781
	}

782
	kref_get(&bo->list_kref);
783

784
	if (!list_empty(&bo->ddestroy)) {
785 786
		ret = ttm_bo_cleanup_refs_and_unlock(bo, interruptible,
						     no_wait_gpu);
787
		kref_put(&bo->list_kref, ttm_bo_release_list);
788
		return ret;
789 790
	}

791
	put_count = ttm_bo_del_from_lru(bo);
792
	spin_unlock(&glob->lru_lock);
793 794 795

	BUG_ON(ret != 0);

796
	ttm_bo_list_ref_sub(bo, put_count, true);
797

798
	ret = ttm_bo_evict(bo, interruptible, no_wait_gpu);
799
	ttm_bo_unreserve(bo);
800

801
	kref_put(&bo->list_kref, ttm_bo_release_list);
802 803 804
	return ret;
}

805 806
void ttm_bo_mem_put(struct ttm_buffer_object *bo, struct ttm_mem_reg *mem)
{
807
	struct ttm_mem_type_manager *man = &bo->bdev->man[mem->mem_type];
808

809 810
	if (mem->mm_node)
		(*man->func->put_node)(man, mem);
811 812 813
}
EXPORT_SYMBOL(ttm_bo_mem_put);

814 815 816 817
/**
 * Repeatedly evict memory from the LRU for @mem_type until we create enough
 * space, or we've evicted everything and there isn't enough space.
 */
818 819
static int ttm_bo_mem_force_space(struct ttm_buffer_object *bo,
					uint32_t mem_type,
820
					const struct ttm_place *place,
821
					struct ttm_mem_reg *mem,
822 823
					bool interruptible,
					bool no_wait_gpu)
824
{
825
	struct ttm_bo_device *bdev = bo->bdev;
826 827 828 829
	struct ttm_mem_type_manager *man = &bdev->man[mem_type];
	int ret;

	do {
830
		ret = (*man->func->get_node)(man, bo, place, mem);
831 832
		if (unlikely(ret != 0))
			return ret;
833
		if (mem->mm_node)
834
			break;
835 836
		ret = ttm_mem_evict_first(bdev, mem_type,
					  interruptible, no_wait_gpu);
837 838 839
		if (unlikely(ret != 0))
			return ret;
	} while (1);
840
	if (mem->mm_node == NULL)
841 842 843 844 845
		return -ENOMEM;
	mem->mem_type = mem_type;
	return 0;
}

846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870
static uint32_t ttm_bo_select_caching(struct ttm_mem_type_manager *man,
				      uint32_t cur_placement,
				      uint32_t proposed_placement)
{
	uint32_t caching = proposed_placement & TTM_PL_MASK_CACHING;
	uint32_t result = proposed_placement & ~TTM_PL_MASK_CACHING;

	/**
	 * Keep current caching if possible.
	 */

	if ((cur_placement & caching) != 0)
		result |= (cur_placement & caching);
	else if ((man->default_caching & caching) != 0)
		result |= man->default_caching;
	else if ((TTM_PL_FLAG_CACHED & caching) != 0)
		result |= TTM_PL_FLAG_CACHED;
	else if ((TTM_PL_FLAG_WC & caching) != 0)
		result |= TTM_PL_FLAG_WC;
	else if ((TTM_PL_FLAG_UNCACHED & caching) != 0)
		result |= TTM_PL_FLAG_UNCACHED;

	return result;
}

871 872
static bool ttm_bo_mt_compatible(struct ttm_mem_type_manager *man,
				 uint32_t mem_type,
873
				 const struct ttm_place *place,
874
				 uint32_t *masked_placement)
875 876 877
{
	uint32_t cur_flags = ttm_bo_type_flags(mem_type);

878
	if ((cur_flags & place->flags & TTM_PL_MASK_MEM) == 0)
879 880
		return false;

881
	if ((place->flags & man->available_caching) == 0)
882 883
		return false;

884
	cur_flags |= (place->flags & man->available_caching);
885 886

	*masked_placement = cur_flags;
887 888 889 890 891 892 893 894 895 896 897 898
	return true;
}

/**
 * Creates space for memory region @mem according to its type.
 *
 * This function first searches for free space in compatible memory types in
 * the priority order defined by the driver.  If free space isn't found, then
 * ttm_bo_mem_force_space is attempted in priority order to evict and find
 * space.
 */
int ttm_bo_mem_space(struct ttm_buffer_object *bo,
899 900
			struct ttm_placement *placement,
			struct ttm_mem_reg *mem,
901
			bool interruptible,
902
			bool no_wait_gpu)
903 904 905 906 907 908 909
{
	struct ttm_bo_device *bdev = bo->bdev;
	struct ttm_mem_type_manager *man;
	uint32_t mem_type = TTM_PL_SYSTEM;
	uint32_t cur_flags = 0;
	bool type_found = false;
	bool type_ok = false;
910
	bool has_erestartsys = false;
911
	int i, ret;
912 913

	mem->mm_node = NULL;
914
	for (i = 0; i < placement->num_placement; ++i) {
915 916 917
		const struct ttm_place *place = &placement->placement[i];

		ret = ttm_mem_type_from_place(place, &mem_type);
918 919
		if (ret)
			return ret;
920 921
		man = &bdev->man[mem_type];

922
		type_ok = ttm_bo_mt_compatible(man, mem_type, place,
923
						&cur_flags);
924 925 926 927

		if (!type_ok)
			continue;

928 929
		cur_flags = ttm_bo_select_caching(man, bo->mem.placement,
						  cur_flags);
930 931 932 933
		/*
		 * Use the access and other non-mapping-related flag bits from
		 * the memory placement flags to the current flags
		 */
934
		ttm_flag_masked(&cur_flags, place->flags,
935
				~TTM_PL_MASK_MEMTYPE);
936

937 938 939 940 941
		if (mem_type == TTM_PL_SYSTEM)
			break;

		if (man->has_type && man->use_type) {
			type_found = true;
942
			ret = (*man->func->get_node)(man, bo, place, mem);
943 944
			if (unlikely(ret))
				return ret;
945
		}
946
		if (mem->mm_node)
947 948 949
			break;
	}

950
	if ((type_ok && (mem_type == TTM_PL_SYSTEM)) || mem->mm_node) {
951 952 953 954 955 956 957 958
		mem->mem_type = mem_type;
		mem->placement = cur_flags;
		return 0;
	}

	if (!type_found)
		return -EINVAL;

959
	for (i = 0; i < placement->num_busy_placement; ++i) {
960 961 962
		const struct ttm_place *place = &placement->busy_placement[i];

		ret = ttm_mem_type_from_place(place, &mem_type);
963 964
		if (ret)
			return ret;
965 966 967
		man = &bdev->man[mem_type];
		if (!man->has_type)
			continue;
968
		if (!ttm_bo_mt_compatible(man, mem_type, place, &cur_flags))
969 970
			continue;

971 972
		cur_flags = ttm_bo_select_caching(man, bo->mem.placement,
						  cur_flags);
973 974 975 976
		/*
		 * Use the access and other non-mapping-related flag bits from
		 * the memory placement flags to the current flags
		 */
977
		ttm_flag_masked(&cur_flags, place->flags,
978
				~TTM_PL_MASK_MEMTYPE);
979

980 981 982 983 984 985 986
		if (mem_type == TTM_PL_SYSTEM) {
			mem->mem_type = mem_type;
			mem->placement = cur_flags;
			mem->mm_node = NULL;
			return 0;
		}

987
		ret = ttm_bo_mem_force_space(bo, mem_type, place, mem,
988
						interruptible, no_wait_gpu);
989 990 991 992
		if (ret == 0 && mem->mm_node) {
			mem->placement = cur_flags;
			return 0;
		}
993 994
		if (ret == -ERESTARTSYS)
			has_erestartsys = true;
995
	}
996
	ret = (has_erestartsys) ? -ERESTARTSYS : -ENOMEM;
997 998 999 1000
	return ret;
}
EXPORT_SYMBOL(ttm_bo_mem_space);

1001
static int ttm_bo_move_buffer(struct ttm_buffer_object *bo,
1002
			struct ttm_placement *placement,
1003
			bool interruptible,
1004
			bool no_wait_gpu)
1005 1006 1007 1008
{
	int ret = 0;
	struct ttm_mem_reg mem;

1009
	lockdep_assert_held(&bo->resv->lock.base);
1010 1011 1012 1013 1014 1015

	/*
	 * FIXME: It's possible to pipeline buffer moves.
	 * Have the driver move function wait for idle when necessary,
	 * instead of doing it here.
	 */
1016
	ret = ttm_bo_wait(bo, false, interruptible, no_wait_gpu);
1017 1018 1019 1020 1021
	if (ret)
		return ret;
	mem.num_pages = bo->num_pages;
	mem.size = mem.num_pages << PAGE_SHIFT;
	mem.page_alignment = bo->mem.page_alignment;
1022 1023
	mem.bus.io_reserved_vm = false;
	mem.bus.io_reserved_count = 0;
1024 1025 1026
	/*
	 * Determine where to move the buffer.
	 */
1027 1028
	ret = ttm_bo_mem_space(bo, placement, &mem,
			       interruptible, no_wait_gpu);
1029 1030
	if (ret)
		goto out_unlock;
1031 1032
	ret = ttm_bo_handle_move_mem(bo, &mem, false,
				     interruptible, no_wait_gpu);
1033
out_unlock:
1034 1035
	if (ret && mem.mm_node)
		ttm_bo_mem_put(bo, &mem);
1036 1037 1038
	return ret;
}

1039 1040 1041
static bool ttm_bo_mem_compat(struct ttm_placement *placement,
			      struct ttm_mem_reg *mem,
			      uint32_t *new_flags)
1042
{
1043
	int i;
1044

1045
	for (i = 0; i < placement->num_placement; i++) {
1046 1047 1048 1049 1050 1051 1052
		const struct ttm_place *heap = &placement->placement[i];
		if (mem->mm_node && heap->lpfn != 0 &&
		    (mem->start < heap->fpfn ||
		     mem->start + mem->num_pages > heap->lpfn))
			continue;

		*new_flags = heap->flags;
1053 1054 1055 1056 1057 1058
		if ((*new_flags & mem->placement & TTM_PL_MASK_CACHING) &&
		    (*new_flags & mem->placement & TTM_PL_MASK_MEM))
			return true;
	}

	for (i = 0; i < placement->num_busy_placement; i++) {
1059 1060 1061 1062 1063 1064 1065
		const struct ttm_place *heap = &placement->busy_placement[i];
		if (mem->mm_node && heap->lpfn != 0 &&
		    (mem->start < heap->fpfn ||
		     mem->start + mem->num_pages > heap->lpfn))
			continue;

		*new_flags = heap->flags;
1066 1067 1068
		if ((*new_flags & mem->placement & TTM_PL_MASK_CACHING) &&
		    (*new_flags & mem->placement & TTM_PL_MASK_MEM))
			return true;
1069
	}
1070 1071

	return false;
1072 1073
}

1074 1075
int ttm_bo_validate(struct ttm_buffer_object *bo,
			struct ttm_placement *placement,
1076
			bool interruptible,
1077
			bool no_wait_gpu)
1078 1079
{
	int ret;
1080
	uint32_t new_flags;
1081

1082
	lockdep_assert_held(&bo->resv->lock.base);
1083 1084 1085
	/*
	 * Check whether we need to move buffer.
	 */
1086
	if (!ttm_bo_mem_compat(placement, &bo->mem, &new_flags)) {
1087 1088
		ret = ttm_bo_move_buffer(bo, placement, interruptible,
					 no_wait_gpu);
1089
		if (ret)
1090
			return ret;
1091 1092 1093 1094 1095
	} else {
		/*
		 * Use the access and other non-mapping-related flag bits from
		 * the compatible memory placement flags to the active flags
		 */
1096
		ttm_flag_masked(&bo->mem.placement, new_flags,
1097
				~TTM_PL_MASK_MEMTYPE);
1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108
	}
	/*
	 * We might need to add a TTM.
	 */
	if (bo->mem.mem_type == TTM_PL_SYSTEM && bo->ttm == NULL) {
		ret = ttm_bo_add_ttm(bo, true);
		if (ret)
			return ret;
	}
	return 0;
}
1109
EXPORT_SYMBOL(ttm_bo_validate);
1110

1111 1112 1113 1114 1115 1116 1117
int ttm_bo_init(struct ttm_bo_device *bdev,
		struct ttm_buffer_object *bo,
		unsigned long size,
		enum ttm_bo_type type,
		struct ttm_placement *placement,
		uint32_t page_alignment,
		bool interruptible,
J
Jan Engelhardt 已提交
1118
		struct file *persistent_swap_storage,
1119
		size_t acc_size,
1120
		struct sg_table *sg,
1121
		void (*destroy) (struct ttm_buffer_object *))
1122
{
1123
	int ret = 0;
1124
	unsigned long num_pages;
1125
	struct ttm_mem_global *mem_glob = bdev->glob->mem_glob;
1126
	bool locked;
1127 1128 1129

	ret = ttm_mem_global_alloc(mem_glob, acc_size, false, false);
	if (ret) {
J
Joe Perches 已提交
1130
		pr_err("Out of kernel memory\n");
1131 1132 1133 1134 1135 1136
		if (destroy)
			(*destroy)(bo);
		else
			kfree(bo);
		return -ENOMEM;
	}
1137 1138 1139

	num_pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
	if (num_pages == 0) {
J
Joe Perches 已提交
1140
		pr_err("Illegal buffer object size\n");
1141 1142 1143 1144
		if (destroy)
			(*destroy)(bo);
		else
			kfree(bo);
1145
		ttm_mem_global_free(mem_glob, acc_size);
1146 1147 1148 1149 1150 1151 1152 1153 1154 1155
		return -EINVAL;
	}
	bo->destroy = destroy;

	kref_init(&bo->kref);
	kref_init(&bo->list_kref);
	atomic_set(&bo->cpu_writers, 0);
	INIT_LIST_HEAD(&bo->lru);
	INIT_LIST_HEAD(&bo->ddestroy);
	INIT_LIST_HEAD(&bo->swap);
1156
	INIT_LIST_HEAD(&bo->io_reserve_lru);
1157
	mutex_init(&bo->wu_mutex);
1158
	bo->bdev = bdev;
1159
	bo->glob = bdev->glob;
1160 1161
	bo->type = type;
	bo->num_pages = num_pages;
1162
	bo->mem.size = num_pages << PAGE_SHIFT;
1163 1164 1165 1166
	bo->mem.mem_type = TTM_PL_SYSTEM;
	bo->mem.num_pages = bo->num_pages;
	bo->mem.mm_node = NULL;
	bo->mem.page_alignment = page_alignment;
1167 1168
	bo->mem.bus.io_reserved_vm = false;
	bo->mem.bus.io_reserved_count = 0;
1169 1170
	bo->priv_flags = 0;
	bo->mem.placement = (TTM_PL_FLAG_SYSTEM | TTM_PL_FLAG_CACHED);
J
Jan Engelhardt 已提交
1171
	bo->persistent_swap_storage = persistent_swap_storage;
1172
	bo->acc_size = acc_size;
1173
	bo->sg = sg;
1174 1175
	bo->resv = &bo->ttm_resv;
	reservation_object_init(bo->resv);
1176
	atomic_inc(&bo->glob->bo_count);
1177
	drm_vma_node_reset(&bo->vma_node);
1178 1179 1180 1181 1182

	/*
	 * For ttm_bo_type_device buffers, allocate
	 * address space from the device.
	 */
1183 1184
	if (bo->type == ttm_bo_type_device ||
	    bo->type == ttm_bo_type_sg)
1185 1186
		ret = drm_vma_offset_add(&bdev->vma_manager, &bo->vma_node,
					 bo->mem.num_pages);
1187

1188 1189
	locked = ww_mutex_trylock(&bo->resv->lock);
	WARN_ON(!locked);
1190

1191 1192
	if (likely(!ret))
		ret = ttm_bo_validate(bo, placement, interruptible, false);
1193 1194

	ttm_bo_unreserve(bo);
1195 1196 1197

	if (unlikely(ret))
		ttm_bo_unref(&bo);
1198 1199 1200

	return ret;
}
1201
EXPORT_SYMBOL(ttm_bo_init);
1202

1203 1204 1205
size_t ttm_bo_acc_size(struct ttm_bo_device *bdev,
		       unsigned long bo_size,
		       unsigned struct_size)
1206
{
1207 1208
	unsigned npages = (PAGE_ALIGN(bo_size)) >> PAGE_SHIFT;
	size_t size = 0;
1209

1210 1211 1212 1213
	size += ttm_round_pot(struct_size);
	size += PAGE_ALIGN(npages * sizeof(void *));
	size += ttm_round_pot(sizeof(struct ttm_tt));
	return size;
1214
}
1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230
EXPORT_SYMBOL(ttm_bo_acc_size);

size_t ttm_bo_dma_acc_size(struct ttm_bo_device *bdev,
			   unsigned long bo_size,
			   unsigned struct_size)
{
	unsigned npages = (PAGE_ALIGN(bo_size)) >> PAGE_SHIFT;
	size_t size = 0;

	size += ttm_round_pot(struct_size);
	size += PAGE_ALIGN(npages * sizeof(void *));
	size += PAGE_ALIGN(npages * sizeof(dma_addr_t));
	size += ttm_round_pot(sizeof(struct ttm_dma_tt));
	return size;
}
EXPORT_SYMBOL(ttm_bo_dma_acc_size);
1231

1232 1233 1234 1235 1236 1237
int ttm_bo_create(struct ttm_bo_device *bdev,
			unsigned long size,
			enum ttm_bo_type type,
			struct ttm_placement *placement,
			uint32_t page_alignment,
			bool interruptible,
J
Jan Engelhardt 已提交
1238
			struct file *persistent_swap_storage,
1239
			struct ttm_buffer_object **p_bo)
1240 1241
{
	struct ttm_buffer_object *bo;
1242
	size_t acc_size;
1243
	int ret;
1244 1245

	bo = kzalloc(sizeof(*bo), GFP_KERNEL);
1246
	if (unlikely(bo == NULL))
1247 1248
		return -ENOMEM;

1249
	acc_size = ttm_bo_acc_size(bdev, size, sizeof(struct ttm_buffer_object));
1250
	ret = ttm_bo_init(bdev, bo, size, type, placement, page_alignment,
1251 1252
			  interruptible, persistent_swap_storage, acc_size,
			  NULL, NULL);
1253 1254 1255 1256 1257
	if (likely(ret == 0))
		*p_bo = bo;

	return ret;
}
T
Thomas Hellstrom 已提交
1258
EXPORT_SYMBOL(ttm_bo_create);
1259 1260

static int ttm_bo_force_list_clean(struct ttm_bo_device *bdev,
1261
					unsigned mem_type, bool allow_errors)
1262
{
1263
	struct ttm_mem_type_manager *man = &bdev->man[mem_type];
1264
	struct ttm_bo_global *glob = bdev->glob;
1265 1266 1267 1268 1269 1270
	int ret;

	/*
	 * Can't use standard list traversal since we're unlocking.
	 */

1271
	spin_lock(&glob->lru_lock);
1272
	while (!list_empty(&man->lru)) {
1273
		spin_unlock(&glob->lru_lock);
1274
		ret = ttm_mem_evict_first(bdev, mem_type, false, false);
1275 1276 1277 1278
		if (ret) {
			if (allow_errors) {
				return ret;
			} else {
J
Joe Perches 已提交
1279
				pr_err("Cleanup eviction failed\n");
1280 1281
			}
		}
1282
		spin_lock(&glob->lru_lock);
1283
	}
1284
	spin_unlock(&glob->lru_lock);
1285 1286 1287 1288 1289
	return 0;
}

int ttm_bo_clean_mm(struct ttm_bo_device *bdev, unsigned mem_type)
{
R
Roel Kluin 已提交
1290
	struct ttm_mem_type_manager *man;
1291 1292 1293
	int ret = -EINVAL;

	if (mem_type >= TTM_NUM_MEM_TYPES) {
J
Joe Perches 已提交
1294
		pr_err("Illegal memory type %d\n", mem_type);
1295 1296
		return ret;
	}
R
Roel Kluin 已提交
1297
	man = &bdev->man[mem_type];
1298 1299

	if (!man->has_type) {
J
Joe Perches 已提交
1300 1301
		pr_err("Trying to take down uninitialized memory manager type %u\n",
		       mem_type);
1302 1303 1304 1305 1306 1307 1308 1309
		return ret;
	}

	man->use_type = false;
	man->has_type = false;

	ret = 0;
	if (mem_type > 0) {
1310
		ttm_bo_force_list_clean(bdev, mem_type, false);
1311

1312
		ret = (*man->func->takedown)(man);
1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323
	}

	return ret;
}
EXPORT_SYMBOL(ttm_bo_clean_mm);

int ttm_bo_evict_mm(struct ttm_bo_device *bdev, unsigned mem_type)
{
	struct ttm_mem_type_manager *man = &bdev->man[mem_type];

	if (mem_type == 0 || mem_type >= TTM_NUM_MEM_TYPES) {
J
Joe Perches 已提交
1324
		pr_err("Illegal memory manager memory type %u\n", mem_type);
1325 1326 1327 1328
		return -EINVAL;
	}

	if (!man->has_type) {
J
Joe Perches 已提交
1329
		pr_err("Memory type %u has not been initialized\n", mem_type);
1330 1331 1332
		return 0;
	}

1333
	return ttm_bo_force_list_clean(bdev, mem_type, true);
1334 1335 1336 1337
}
EXPORT_SYMBOL(ttm_bo_evict_mm);

int ttm_bo_init_mm(struct ttm_bo_device *bdev, unsigned type,
1338
			unsigned long p_size)
1339 1340 1341 1342
{
	int ret = -EINVAL;
	struct ttm_mem_type_manager *man;

1343
	BUG_ON(type >= TTM_NUM_MEM_TYPES);
1344
	man = &bdev->man[type];
1345
	BUG_ON(man->has_type);
1346 1347 1348 1349
	man->io_reserve_fastpath = true;
	man->use_io_reserve_lru = false;
	mutex_init(&man->io_reserve_mutex);
	INIT_LIST_HEAD(&man->io_reserve_lru);
1350 1351 1352 1353

	ret = bdev->driver->init_mem_type(bdev, type, man);
	if (ret)
		return ret;
1354
	man->bdev = bdev;
1355 1356 1357

	ret = 0;
	if (type != TTM_PL_SYSTEM) {
1358
		ret = (*man->func->init)(man, p_size);
1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371
		if (ret)
			return ret;
	}
	man->has_type = true;
	man->use_type = true;
	man->size = p_size;

	INIT_LIST_HEAD(&man->lru);

	return 0;
}
EXPORT_SYMBOL(ttm_bo_init_mm);

1372 1373 1374 1375 1376 1377 1378 1379 1380 1381
static void ttm_bo_global_kobj_release(struct kobject *kobj)
{
	struct ttm_bo_global *glob =
		container_of(kobj, struct ttm_bo_global, kobj);

	ttm_mem_unregister_shrink(glob->mem_glob, &glob->shrink);
	__free_page(glob->dummy_read_page);
	kfree(glob);
}

1382
void ttm_bo_global_release(struct drm_global_reference *ref)
1383 1384 1385 1386 1387 1388 1389 1390
{
	struct ttm_bo_global *glob = ref->object;

	kobject_del(&glob->kobj);
	kobject_put(&glob->kobj);
}
EXPORT_SYMBOL(ttm_bo_global_release);

1391
int ttm_bo_global_init(struct drm_global_reference *ref)
1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413
{
	struct ttm_bo_global_ref *bo_ref =
		container_of(ref, struct ttm_bo_global_ref, ref);
	struct ttm_bo_global *glob = ref->object;
	int ret;

	mutex_init(&glob->device_list_mutex);
	spin_lock_init(&glob->lru_lock);
	glob->mem_glob = bo_ref->mem_glob;
	glob->dummy_read_page = alloc_page(__GFP_ZERO | GFP_DMA32);

	if (unlikely(glob->dummy_read_page == NULL)) {
		ret = -ENOMEM;
		goto out_no_drp;
	}

	INIT_LIST_HEAD(&glob->swap_lru);
	INIT_LIST_HEAD(&glob->device_list);

	ttm_mem_init_shrink(&glob->shrink, ttm_bo_swapout);
	ret = ttm_mem_register_shrink(glob->mem_glob, &glob->shrink);
	if (unlikely(ret != 0)) {
J
Joe Perches 已提交
1414
		pr_err("Could not register buffer object swapout\n");
1415 1416 1417 1418 1419
		goto out_no_shrink;
	}

	atomic_set(&glob->bo_count, 0);

1420 1421
	ret = kobject_init_and_add(
		&glob->kobj, &ttm_bo_glob_kobj_type, ttm_get_kobj(), "buffer_objects");
1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433
	if (unlikely(ret != 0))
		kobject_put(&glob->kobj);
	return ret;
out_no_shrink:
	__free_page(glob->dummy_read_page);
out_no_drp:
	kfree(glob);
	return ret;
}
EXPORT_SYMBOL(ttm_bo_global_init);


1434 1435 1436 1437 1438
int ttm_bo_device_release(struct ttm_bo_device *bdev)
{
	int ret = 0;
	unsigned i = TTM_NUM_MEM_TYPES;
	struct ttm_mem_type_manager *man;
1439
	struct ttm_bo_global *glob = bdev->glob;
1440 1441 1442 1443 1444 1445 1446

	while (i--) {
		man = &bdev->man[i];
		if (man->has_type) {
			man->use_type = false;
			if ((i != TTM_PL_SYSTEM) && ttm_bo_clean_mm(bdev, i)) {
				ret = -EBUSY;
J
Joe Perches 已提交
1447 1448
				pr_err("DRM memory manager type %d is not clean\n",
				       i);
1449 1450 1451 1452 1453
			}
			man->has_type = false;
		}
	}

1454 1455 1456 1457
	mutex_lock(&glob->device_list_mutex);
	list_del(&bdev->device_list);
	mutex_unlock(&glob->device_list_mutex);

1458
	cancel_delayed_work_sync(&bdev->wq);
1459 1460 1461 1462

	while (ttm_bo_delayed_delete(bdev, true))
		;

1463
	spin_lock(&glob->lru_lock);
1464 1465 1466 1467 1468
	if (list_empty(&bdev->ddestroy))
		TTM_DEBUG("Delayed destroy list was clean\n");

	if (list_empty(&bdev->man[0].lru))
		TTM_DEBUG("Swap list was clean\n");
1469
	spin_unlock(&glob->lru_lock);
1470

1471
	drm_vma_offset_manager_destroy(&bdev->vma_manager);
1472 1473 1474 1475 1476 1477

	return ret;
}
EXPORT_SYMBOL(ttm_bo_device_release);

int ttm_bo_device_init(struct ttm_bo_device *bdev,
1478 1479
		       struct ttm_bo_global *glob,
		       struct ttm_bo_driver *driver,
1480
		       struct address_space *mapping,
D
Dave Airlie 已提交
1481
		       uint64_t file_page_offset,
D
Dave Airlie 已提交
1482
		       bool need_dma32)
1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493
{
	int ret = -EINVAL;

	bdev->driver = driver;

	memset(bdev->man, 0, sizeof(bdev->man));

	/*
	 * Initialize the system memory buffer type.
	 * Other types need to be driver / IOCTL initialized.
	 */
1494
	ret = ttm_bo_init_mm(bdev, TTM_PL_SYSTEM, 0);
1495
	if (unlikely(ret != 0))
1496
		goto out_no_sys;
1497

1498 1499
	drm_vma_offset_manager_init(&bdev->vma_manager, file_page_offset,
				    0x10000000);
1500 1501
	INIT_DELAYED_WORK(&bdev->wq, ttm_bo_delayed_workqueue);
	INIT_LIST_HEAD(&bdev->ddestroy);
1502
	bdev->dev_mapping = mapping;
1503
	bdev->glob = glob;
D
Dave Airlie 已提交
1504
	bdev->need_dma32 = need_dma32;
1505
	bdev->val_seq = 0;
1506 1507 1508
	mutex_lock(&glob->device_list_mutex);
	list_add_tail(&bdev->device_list, &glob->device_list);
	mutex_unlock(&glob->device_list_mutex);
1509 1510

	return 0;
1511
out_no_sys:
1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536
	return ret;
}
EXPORT_SYMBOL(ttm_bo_device_init);

/*
 * buffer object vm functions.
 */

bool ttm_mem_reg_is_pci(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem)
{
	struct ttm_mem_type_manager *man = &bdev->man[mem->mem_type];

	if (!(man->flags & TTM_MEMTYPE_FLAG_FIXED)) {
		if (mem->mem_type == TTM_PL_SYSTEM)
			return false;

		if (man->flags & TTM_MEMTYPE_FLAG_CMA)
			return false;

		if (mem->placement & TTM_PL_FLAG_CACHED)
			return false;
	}
	return true;
}

1537
void ttm_bo_unmap_virtual_locked(struct ttm_buffer_object *bo)
1538 1539 1540
{
	struct ttm_bo_device *bdev = bo->bdev;

1541
	drm_vma_node_unmap(&bo->vma_node, bdev->dev_mapping);
1542
	ttm_mem_io_free_vm(bo);
1543
}
1544 1545 1546 1547 1548 1549 1550 1551 1552

void ttm_bo_unmap_virtual(struct ttm_buffer_object *bo)
{
	struct ttm_bo_device *bdev = bo->bdev;
	struct ttm_mem_type_manager *man = &bdev->man[bo->mem.mem_type];

	ttm_mem_io_lock(man, false);
	ttm_bo_unmap_virtual_locked(bo);
	ttm_mem_io_unlock(man);
1553
}
1554 1555


1556
EXPORT_SYMBOL(ttm_bo_unmap_virtual);
1557 1558

int ttm_bo_wait(struct ttm_buffer_object *bo,
1559
		bool lazy, bool interruptible, bool no_wait)
1560
{
1561 1562 1563 1564 1565
	struct reservation_object_list *fobj;
	struct reservation_object *resv;
	struct fence *excl;
	long timeout = 15 * HZ;
	int i;
1566

1567 1568 1569 1570 1571 1572 1573
	resv = bo->resv;
	fobj = reservation_object_get_list(resv);
	excl = reservation_object_get_excl(resv);
	if (excl) {
		if (!fence_is_signaled(excl)) {
			if (no_wait)
				return -EBUSY;
1574

1575 1576
			timeout = fence_wait_timeout(excl,
						     interruptible, timeout);
1577
		}
1578
	}
1579

1580 1581 1582 1583
	for (i = 0; fobj && timeout > 0 && i < fobj->shared_count; ++i) {
		struct fence *fence;
		fence = rcu_dereference_protected(fobj->shared[i],
						reservation_object_held(resv));
1584

1585 1586 1587
		if (!fence_is_signaled(fence)) {
			if (no_wait)
				return -EBUSY;
M
Maarten Lankhorst 已提交
1588

1589 1590
			timeout = fence_wait_timeout(fence,
						     interruptible, timeout);
1591 1592
		}
	}
1593 1594 1595 1596 1597 1598 1599 1600 1601 1602

	if (timeout < 0)
		return timeout;

	if (timeout == 0)
		return -EBUSY;

	reservation_object_add_excl_fence(resv, NULL);
	clear_bit(TTM_BO_PRIV_FLAG_MOVING, &bo->priv_flags);
	return 0;
1603 1604 1605 1606 1607 1608 1609 1610
}
EXPORT_SYMBOL(ttm_bo_wait);

int ttm_bo_synccpu_write_grab(struct ttm_buffer_object *bo, bool no_wait)
{
	int ret = 0;

	/*
1611
	 * Using ttm_bo_reserve makes sure the lru lists are updated.
1612 1613
	 */

1614
	ret = ttm_bo_reserve(bo, true, no_wait, false, NULL);
1615 1616
	if (unlikely(ret != 0))
		return ret;
1617
	ret = ttm_bo_wait(bo, false, true, no_wait);
1618 1619 1620 1621 1622
	if (likely(ret == 0))
		atomic_inc(&bo->cpu_writers);
	ttm_bo_unreserve(bo);
	return ret;
}
1623
EXPORT_SYMBOL(ttm_bo_synccpu_write_grab);
1624 1625 1626

void ttm_bo_synccpu_write_release(struct ttm_buffer_object *bo)
{
1627
	atomic_dec(&bo->cpu_writers);
1628
}
1629
EXPORT_SYMBOL(ttm_bo_synccpu_write_release);
1630 1631 1632 1633 1634 1635 1636 1637

/**
 * A buffer object shrink method that tries to swap out the first
 * buffer object on the bo_global::swap_lru list.
 */

static int ttm_bo_swapout(struct ttm_mem_shrink *shrink)
{
1638 1639
	struct ttm_bo_global *glob =
	    container_of(shrink, struct ttm_bo_global, shrink);
1640 1641 1642 1643 1644
	struct ttm_buffer_object *bo;
	int ret = -EBUSY;
	int put_count;
	uint32_t swap_placement = (TTM_PL_FLAG_CACHED | TTM_PL_FLAG_SYSTEM);

1645
	spin_lock(&glob->lru_lock);
1646
	list_for_each_entry(bo, &glob->swap_lru, swap) {
1647
		ret = __ttm_bo_reserve(bo, false, true, false, NULL);
1648 1649 1650
		if (!ret)
			break;
	}
1651

1652 1653 1654 1655
	if (ret) {
		spin_unlock(&glob->lru_lock);
		return ret;
	}
1656

1657
	kref_get(&bo->list_kref);
1658

1659 1660 1661 1662
	if (!list_empty(&bo->ddestroy)) {
		ret = ttm_bo_cleanup_refs_and_unlock(bo, false, false);
		kref_put(&bo->list_kref, ttm_bo_release_list);
		return ret;
1663 1664 1665
	}

	put_count = ttm_bo_del_from_lru(bo);
1666
	spin_unlock(&glob->lru_lock);
1667

1668
	ttm_bo_list_ref_sub(bo, put_count, true);
1669 1670 1671 1672 1673

	/**
	 * Wait for GPU, then move to system cached.
	 */

1674
	ret = ttm_bo_wait(bo, false, false, false);
1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687

	if (unlikely(ret != 0))
		goto out;

	if ((bo->mem.placement & swap_placement) != swap_placement) {
		struct ttm_mem_reg evict_mem;

		evict_mem = bo->mem;
		evict_mem.mm_node = NULL;
		evict_mem.placement = TTM_PL_FLAG_SYSTEM | TTM_PL_FLAG_CACHED;
		evict_mem.mem_type = TTM_PL_SYSTEM;

		ret = ttm_bo_handle_move_mem(bo, &evict_mem, true,
1688
					     false, false);
1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699
		if (unlikely(ret != 0))
			goto out;
	}

	ttm_bo_unmap_virtual(bo);

	/**
	 * Swap out. Buffer will be swapped in again as soon as
	 * anyone tries to access a ttm page.
	 */

1700 1701 1702
	if (bo->bdev->driver->swap_notify)
		bo->bdev->driver->swap_notify(bo);

J
Jan Engelhardt 已提交
1703
	ret = ttm_tt_swapout(bo->ttm, bo->persistent_swap_storage);
1704 1705 1706 1707 1708 1709 1710 1711
out:

	/**
	 *
	 * Unreserve without putting on LRU to avoid swapping out an
	 * already swapped buffer.
	 */

1712
	__ttm_bo_unreserve(bo);
1713 1714 1715 1716 1717 1718
	kref_put(&bo->list_kref, ttm_bo_release_list);
	return ret;
}

void ttm_bo_swapout_all(struct ttm_bo_device *bdev)
{
1719
	while (ttm_bo_swapout(&bdev->glob->shrink) == 0)
1720 1721
		;
}
1722
EXPORT_SYMBOL(ttm_bo_swapout_all);
1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745

/**
 * ttm_bo_wait_unreserved - interruptible wait for a buffer object to become
 * unreserved
 *
 * @bo: Pointer to buffer
 */
int ttm_bo_wait_unreserved(struct ttm_buffer_object *bo)
{
	int ret;

	/*
	 * In the absense of a wait_unlocked API,
	 * Use the bo::wu_mutex to avoid triggering livelocks due to
	 * concurrent use of this function. Note that this use of
	 * bo::wu_mutex can go away if we change locking order to
	 * mmap_sem -> bo::reserve.
	 */
	ret = mutex_lock_interruptible(&bo->wu_mutex);
	if (unlikely(ret != 0))
		return -ERESTARTSYS;
	if (!ww_mutex_is_locked(&bo->resv->lock))
		goto out_unlock;
1746
	ret = __ttm_bo_reserve(bo, true, false, false, NULL);
1747 1748
	if (unlikely(ret != 0))
		goto out_unlock;
1749
	__ttm_bo_unreserve(bo);
1750 1751 1752 1753 1754

out_unlock:
	mutex_unlock(&bo->wu_mutex);
	return ret;
}