1 /* 2 * Copyright (c) Red Hat Inc. 3 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sub license, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the 12 * next paragraph) shall be included in all copies or substantial portions 13 * of the Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21 * DEALINGS IN THE SOFTWARE. 22 * 23 * Authors: Dave Airlie <airlied@redhat.com> 24 * Jerome Glisse <jglisse@redhat.com> 25 * Pauli Nieminen <suokkos@gmail.com> 26 */ 27 /* 28 * Copyright (c) 2013 The FreeBSD Foundation 29 * All rights reserved. 30 * 31 * Portions of this software were developed by Konstantin Belousov 32 * <kib@FreeBSD.org> under sponsorship from the FreeBSD Foundation. 33 */ 34 35 /* simple list based uncached page pool 36 * - Pool collects resently freed pages for reuse 37 * - Use page->lru to keep a free list 38 * - doesn't track currently in use pages 39 */ 40 41 #include <sys/cdefs.h> 42 #include <dev/drm2/drmP.h> 43 #include <dev/drm2/ttm/ttm_bo_driver.h> 44 #include <dev/drm2/ttm/ttm_page_alloc.h> 45 #include <sys/eventhandler.h> 46 #include <vm/vm_pageout.h> 47 48 #define NUM_PAGES_TO_ALLOC (PAGE_SIZE/sizeof(vm_page_t)) 49 #define SMALL_ALLOCATION 16 50 #define FREE_ALL_PAGES (~0U) 51 /* times are in msecs */ 52 #define PAGE_FREE_INTERVAL 1000 53 54 /** 55 * struct ttm_page_pool - Pool to reuse recently allocated uc/wc pages. 56 * 57 * @lock: Protects the shared pool from concurrnet access. Must be used with 58 * irqsave/irqrestore variants because pool allocator maybe called from 59 * delayed work. 60 * @fill_lock: Prevent concurrent calls to fill. 61 * @list: Pool of free uc/wc pages for fast reuse. 62 * @gfp_flags: Flags to pass for alloc_page. 63 * @npages: Number of pages in pool. 64 */ 65 struct ttm_page_pool { 66 struct mtx lock; 67 bool fill_lock; 68 bool dma32; 69 struct pglist list; 70 int ttm_page_alloc_flags; 71 unsigned npages; 72 char *name; 73 unsigned long nfrees; 74 unsigned long nrefills; 75 }; 76 77 /** 78 * Limits for the pool. They are handled without locks because only place where 79 * they may change is in sysfs store. They won't have immediate effect anyway 80 * so forcing serialization to access them is pointless. 81 */ 82 83 struct ttm_pool_opts { 84 unsigned alloc_size; 85 unsigned max_size; 86 unsigned small; 87 }; 88 89 #define NUM_POOLS 4 90 91 /** 92 * struct ttm_pool_manager - Holds memory pools for fst allocation 93 * 94 * Manager is read only object for pool code so it doesn't need locking. 95 * 96 * @free_interval: minimum number of jiffies between freeing pages from pool. 97 * @page_alloc_inited: reference counting for pool allocation. 98 * @work: Work that is used to shrink the pool. Work is only run when there is 99 * some pages to free. 100 * @small_allocation: Limit in number of pages what is small allocation. 101 * 102 * @pools: All pool objects in use. 103 **/ 104 struct ttm_pool_manager { 105 unsigned int kobj_ref; 106 eventhandler_tag lowmem_handler; 107 struct ttm_pool_opts options; 108 109 union { 110 struct ttm_page_pool u_pools[NUM_POOLS]; 111 struct _utag { 112 struct ttm_page_pool u_wc_pool; 113 struct ttm_page_pool u_uc_pool; 114 struct ttm_page_pool u_wc_pool_dma32; 115 struct ttm_page_pool u_uc_pool_dma32; 116 } _ut; 117 } _u; 118 }; 119 120 #define pools _u.u_pools 121 #define wc_pool _u._ut.u_wc_pool 122 #define uc_pool _u._ut.u_uc_pool 123 #define wc_pool_dma32 _u._ut.u_wc_pool_dma32 124 #define uc_pool_dma32 _u._ut.u_uc_pool_dma32 125 126 MALLOC_DEFINE(M_TTM_POOLMGR, "ttm_poolmgr", "TTM Pool Manager"); 127 128 static void 129 ttm_vm_page_free(vm_page_t m) 130 { 131 132 KASSERT(m->object == NULL, ("ttm page %p is owned", m)); 133 KASSERT(vm_page_wired(m), ("ttm lost wire %p", m)); 134 KASSERT((m->flags & PG_FICTITIOUS) != 0, ("ttm lost fictitious %p", m)); 135 KASSERT((m->oflags & VPO_UNMANAGED) == 0, ("ttm got unmanaged %p", m)); 136 m->flags &= ~PG_FICTITIOUS; 137 m->oflags |= VPO_UNMANAGED; 138 vm_page_unwire_noq(m); 139 vm_page_free(m); 140 } 141 142 static vm_memattr_t 143 ttm_caching_state_to_vm(enum ttm_caching_state cstate) 144 { 145 146 switch (cstate) { 147 case tt_uncached: 148 return (VM_MEMATTR_UNCACHEABLE); 149 case tt_wc: 150 return (VM_MEMATTR_WRITE_COMBINING); 151 case tt_cached: 152 return (VM_MEMATTR_WRITE_BACK); 153 } 154 panic("caching state %d\n", cstate); 155 } 156 157 static vm_page_t 158 ttm_vm_page_alloc_dma32(int req, vm_memattr_t memattr) 159 { 160 vm_page_t p; 161 int tries; 162 163 for (tries = 0; ; tries++) { 164 p = vm_page_alloc_noobj_contig(req, 1, 0, 0xffffffff, PAGE_SIZE, 165 0, memattr); 166 if (p != NULL || tries > 2) 167 return (p); 168 if (!vm_page_reclaim_contig(req, 1, 0, 0xffffffff, 169 PAGE_SIZE, 0)) 170 vm_wait(NULL); 171 } 172 } 173 174 static vm_page_t 175 ttm_vm_page_alloc_any(int req, vm_memattr_t memattr) 176 { 177 vm_page_t p; 178 179 p = vm_page_alloc_noobj(req | VM_ALLOC_WAITOK); 180 pmap_page_set_memattr(p, memattr); 181 return (p); 182 } 183 184 static vm_page_t 185 ttm_vm_page_alloc(int flags, enum ttm_caching_state cstate) 186 { 187 vm_page_t p; 188 vm_memattr_t memattr; 189 int req; 190 191 memattr = ttm_caching_state_to_vm(cstate); 192 req = VM_ALLOC_WIRED; 193 if ((flags & TTM_PAGE_FLAG_ZERO_ALLOC) != 0) 194 req |= VM_ALLOC_ZERO; 195 196 if ((flags & TTM_PAGE_FLAG_DMA32) != 0) 197 p = ttm_vm_page_alloc_dma32(req, memattr); 198 else 199 p = ttm_vm_page_alloc_any(req, memattr); 200 201 if (p != NULL) { 202 p->oflags &= ~VPO_UNMANAGED; 203 p->flags |= PG_FICTITIOUS; 204 } 205 return (p); 206 } 207 208 static void ttm_pool_kobj_release(struct ttm_pool_manager *m) 209 { 210 211 free(m, M_TTM_POOLMGR); 212 } 213 214 #if 0 215 /* XXXKIB sysctl */ 216 static ssize_t ttm_pool_store(struct ttm_pool_manager *m, 217 struct attribute *attr, const char *buffer, size_t size) 218 { 219 int chars; 220 unsigned val; 221 chars = sscanf(buffer, "%u", &val); 222 if (chars == 0) 223 return size; 224 225 /* Convert kb to number of pages */ 226 val = val / (PAGE_SIZE >> 10); 227 228 if (attr == &ttm_page_pool_max) 229 m->options.max_size = val; 230 else if (attr == &ttm_page_pool_small) 231 m->options.small = val; 232 else if (attr == &ttm_page_pool_alloc_size) { 233 if (val > NUM_PAGES_TO_ALLOC*8) { 234 pr_err("Setting allocation size to %lu is not allowed. Recommended size is %lu\n", 235 NUM_PAGES_TO_ALLOC*(PAGE_SIZE >> 7), 236 NUM_PAGES_TO_ALLOC*(PAGE_SIZE >> 10)); 237 return size; 238 } else if (val > NUM_PAGES_TO_ALLOC) { 239 pr_warn("Setting allocation size to larger than %lu is not recommended\n", 240 NUM_PAGES_TO_ALLOC*(PAGE_SIZE >> 10)); 241 } 242 m->options.alloc_size = val; 243 } 244 245 return size; 246 } 247 248 static ssize_t ttm_pool_show(struct ttm_pool_manager *m, 249 struct attribute *attr, char *buffer) 250 { 251 unsigned val = 0; 252 253 if (attr == &ttm_page_pool_max) 254 val = m->options.max_size; 255 else if (attr == &ttm_page_pool_small) 256 val = m->options.small; 257 else if (attr == &ttm_page_pool_alloc_size) 258 val = m->options.alloc_size; 259 260 val = val * (PAGE_SIZE >> 10); 261 262 return snprintf(buffer, PAGE_SIZE, "%u\n", val); 263 } 264 #endif 265 266 static struct ttm_pool_manager *_manager; 267 268 static int set_pages_array_wb(vm_page_t *pages, int addrinarray) 269 { 270 #ifdef TTM_HAS_AGP 271 int i; 272 273 for (i = 0; i < addrinarray; i++) 274 pmap_page_set_memattr(pages[i], VM_MEMATTR_WRITE_BACK); 275 #endif 276 return 0; 277 } 278 279 static int set_pages_array_wc(vm_page_t *pages, int addrinarray) 280 { 281 #ifdef TTM_HAS_AGP 282 int i; 283 284 for (i = 0; i < addrinarray; i++) 285 pmap_page_set_memattr(pages[i], VM_MEMATTR_WRITE_COMBINING); 286 #endif 287 return 0; 288 } 289 290 static int set_pages_array_uc(vm_page_t *pages, int addrinarray) 291 { 292 #ifdef TTM_HAS_AGP 293 int i; 294 295 for (i = 0; i < addrinarray; i++) 296 pmap_page_set_memattr(pages[i], VM_MEMATTR_UNCACHEABLE); 297 #endif 298 return 0; 299 } 300 301 /** 302 * Select the right pool or requested caching state and ttm flags. */ 303 static struct ttm_page_pool *ttm_get_pool(int flags, 304 enum ttm_caching_state cstate) 305 { 306 int pool_index; 307 308 if (cstate == tt_cached) 309 return NULL; 310 311 if (cstate == tt_wc) 312 pool_index = 0x0; 313 else 314 pool_index = 0x1; 315 316 if (flags & TTM_PAGE_FLAG_DMA32) 317 pool_index |= 0x2; 318 319 return &_manager->pools[pool_index]; 320 } 321 322 /* set memory back to wb and free the pages. */ 323 static void ttm_pages_put(vm_page_t *pages, unsigned npages) 324 { 325 unsigned i; 326 327 /* Our VM handles vm memattr automatically on the page free. */ 328 if (set_pages_array_wb(pages, npages)) 329 printf("[TTM] Failed to set %d pages to wb!\n", npages); 330 for (i = 0; i < npages; ++i) 331 ttm_vm_page_free(pages[i]); 332 } 333 334 static void ttm_pool_update_free_locked(struct ttm_page_pool *pool, 335 unsigned freed_pages) 336 { 337 pool->npages -= freed_pages; 338 pool->nfrees += freed_pages; 339 } 340 341 /** 342 * Free pages from pool. 343 * 344 * To prevent hogging the ttm_swap process we only free NUM_PAGES_TO_ALLOC 345 * number of pages in one go. 346 * 347 * @pool: to free the pages from 348 * @free_all: If set to true will free all pages in pool 349 **/ 350 static int ttm_page_pool_free(struct ttm_page_pool *pool, unsigned nr_free) 351 { 352 vm_page_t p, p1; 353 vm_page_t *pages_to_free; 354 unsigned freed_pages = 0, 355 npages_to_free = nr_free; 356 unsigned i; 357 358 if (NUM_PAGES_TO_ALLOC < nr_free) 359 npages_to_free = NUM_PAGES_TO_ALLOC; 360 361 pages_to_free = malloc(npages_to_free * sizeof(vm_page_t), 362 M_TEMP, M_WAITOK | M_ZERO); 363 364 restart: 365 mtx_lock(&pool->lock); 366 367 TAILQ_FOREACH_REVERSE_SAFE(p, &pool->list, pglist, plinks.q, p1) { 368 if (freed_pages >= npages_to_free) 369 break; 370 371 pages_to_free[freed_pages++] = p; 372 /* We can only remove NUM_PAGES_TO_ALLOC at a time. */ 373 if (freed_pages >= NUM_PAGES_TO_ALLOC) { 374 /* remove range of pages from the pool */ 375 for (i = 0; i < freed_pages; i++) 376 TAILQ_REMOVE(&pool->list, pages_to_free[i], plinks.q); 377 378 ttm_pool_update_free_locked(pool, freed_pages); 379 /** 380 * Because changing page caching is costly 381 * we unlock the pool to prevent stalling. 382 */ 383 mtx_unlock(&pool->lock); 384 385 ttm_pages_put(pages_to_free, freed_pages); 386 if (likely(nr_free != FREE_ALL_PAGES)) 387 nr_free -= freed_pages; 388 389 if (NUM_PAGES_TO_ALLOC >= nr_free) 390 npages_to_free = nr_free; 391 else 392 npages_to_free = NUM_PAGES_TO_ALLOC; 393 394 freed_pages = 0; 395 396 /* free all so restart the processing */ 397 if (nr_free) 398 goto restart; 399 400 /* Not allowed to fall through or break because 401 * following context is inside spinlock while we are 402 * outside here. 403 */ 404 goto out; 405 406 } 407 } 408 409 /* remove range of pages from the pool */ 410 if (freed_pages) { 411 for (i = 0; i < freed_pages; i++) 412 TAILQ_REMOVE(&pool->list, pages_to_free[i], plinks.q); 413 414 ttm_pool_update_free_locked(pool, freed_pages); 415 nr_free -= freed_pages; 416 } 417 418 mtx_unlock(&pool->lock); 419 420 if (freed_pages) 421 ttm_pages_put(pages_to_free, freed_pages); 422 out: 423 free(pages_to_free, M_TEMP); 424 return nr_free; 425 } 426 427 /* Get good estimation how many pages are free in pools */ 428 static int ttm_pool_get_num_unused_pages(void) 429 { 430 unsigned i; 431 int total = 0; 432 for (i = 0; i < NUM_POOLS; ++i) 433 total += _manager->pools[i].npages; 434 435 return total; 436 } 437 438 /** 439 * Callback for mm to request pool to reduce number of page held. 440 */ 441 static int ttm_pool_mm_shrink(void *arg) 442 { 443 static unsigned int start_pool = 0; 444 unsigned i; 445 unsigned pool_offset = atomic_fetchadd_int(&start_pool, 1); 446 struct ttm_page_pool *pool; 447 int shrink_pages = 100; /* XXXKIB */ 448 449 pool_offset = pool_offset % NUM_POOLS; 450 /* select start pool in round robin fashion */ 451 for (i = 0; i < NUM_POOLS; ++i) { 452 unsigned nr_free = shrink_pages; 453 if (shrink_pages == 0) 454 break; 455 pool = &_manager->pools[(i + pool_offset)%NUM_POOLS]; 456 shrink_pages = ttm_page_pool_free(pool, nr_free); 457 } 458 /* return estimated number of unused pages in pool */ 459 return ttm_pool_get_num_unused_pages(); 460 } 461 462 static void ttm_pool_mm_shrink_init(struct ttm_pool_manager *manager) 463 { 464 465 manager->lowmem_handler = EVENTHANDLER_REGISTER(vm_lowmem, 466 ttm_pool_mm_shrink, manager, EVENTHANDLER_PRI_ANY); 467 } 468 469 static void ttm_pool_mm_shrink_fini(struct ttm_pool_manager *manager) 470 { 471 472 EVENTHANDLER_DEREGISTER(vm_lowmem, manager->lowmem_handler); 473 } 474 475 static int ttm_set_pages_caching(vm_page_t *pages, 476 enum ttm_caching_state cstate, unsigned cpages) 477 { 478 int r = 0; 479 /* Set page caching */ 480 switch (cstate) { 481 case tt_uncached: 482 r = set_pages_array_uc(pages, cpages); 483 if (r) 484 printf("[TTM] Failed to set %d pages to uc!\n", cpages); 485 break; 486 case tt_wc: 487 r = set_pages_array_wc(pages, cpages); 488 if (r) 489 printf("[TTM] Failed to set %d pages to wc!\n", cpages); 490 break; 491 default: 492 break; 493 } 494 return r; 495 } 496 497 /** 498 * Free pages the pages that failed to change the caching state. If there is 499 * any pages that have changed their caching state already put them to the 500 * pool. 501 */ 502 static void ttm_handle_caching_state_failure(struct pglist *pages, 503 int ttm_flags, enum ttm_caching_state cstate, 504 vm_page_t *failed_pages, unsigned cpages) 505 { 506 unsigned i; 507 /* Failed pages have to be freed */ 508 for (i = 0; i < cpages; ++i) { 509 TAILQ_REMOVE(pages, failed_pages[i], plinks.q); 510 ttm_vm_page_free(failed_pages[i]); 511 } 512 } 513 514 /** 515 * Allocate new pages with correct caching. 516 * 517 * This function is reentrant if caller updates count depending on number of 518 * pages returned in pages array. 519 */ 520 static int ttm_alloc_new_pages(struct pglist *pages, int ttm_alloc_flags, 521 int ttm_flags, enum ttm_caching_state cstate, unsigned count) 522 { 523 vm_page_t *caching_array; 524 vm_page_t p; 525 int r = 0; 526 unsigned i, cpages; 527 unsigned max_cpages = min(count, 528 (unsigned)(PAGE_SIZE/sizeof(vm_page_t))); 529 530 /* allocate array for page caching change */ 531 caching_array = malloc(max_cpages * sizeof(vm_page_t), M_TEMP, 532 M_WAITOK | M_ZERO); 533 534 for (i = 0, cpages = 0; i < count; ++i) { 535 p = ttm_vm_page_alloc(ttm_alloc_flags, cstate); 536 if (!p) { 537 printf("[TTM] Unable to get page %u\n", i); 538 539 /* store already allocated pages in the pool after 540 * setting the caching state */ 541 if (cpages) { 542 r = ttm_set_pages_caching(caching_array, 543 cstate, cpages); 544 if (r) 545 ttm_handle_caching_state_failure(pages, 546 ttm_flags, cstate, 547 caching_array, cpages); 548 } 549 r = -ENOMEM; 550 goto out; 551 } 552 553 #ifdef CONFIG_HIGHMEM /* KIB: nop */ 554 /* gfp flags of highmem page should never be dma32 so we 555 * we should be fine in such case 556 */ 557 if (!PageHighMem(p)) 558 #endif 559 { 560 caching_array[cpages++] = p; 561 if (cpages == max_cpages) { 562 563 r = ttm_set_pages_caching(caching_array, 564 cstate, cpages); 565 if (r) { 566 ttm_handle_caching_state_failure(pages, 567 ttm_flags, cstate, 568 caching_array, cpages); 569 goto out; 570 } 571 cpages = 0; 572 } 573 } 574 575 TAILQ_INSERT_HEAD(pages, p, plinks.q); 576 } 577 578 if (cpages) { 579 r = ttm_set_pages_caching(caching_array, cstate, cpages); 580 if (r) 581 ttm_handle_caching_state_failure(pages, 582 ttm_flags, cstate, 583 caching_array, cpages); 584 } 585 out: 586 free(caching_array, M_TEMP); 587 588 return r; 589 } 590 591 /** 592 * Fill the given pool if there aren't enough pages and the requested number of 593 * pages is small. 594 */ 595 static void ttm_page_pool_fill_locked(struct ttm_page_pool *pool, 596 int ttm_flags, enum ttm_caching_state cstate, unsigned count) 597 { 598 vm_page_t p; 599 int r; 600 unsigned cpages = 0; 601 /** 602 * Only allow one pool fill operation at a time. 603 * If pool doesn't have enough pages for the allocation new pages are 604 * allocated from outside of pool. 605 */ 606 if (pool->fill_lock) 607 return; 608 609 pool->fill_lock = true; 610 611 /* If allocation request is small and there are not enough 612 * pages in a pool we fill the pool up first. */ 613 if (count < _manager->options.small 614 && count > pool->npages) { 615 struct pglist new_pages; 616 unsigned alloc_size = _manager->options.alloc_size; 617 618 /** 619 * Can't change page caching if in irqsave context. We have to 620 * drop the pool->lock. 621 */ 622 mtx_unlock(&pool->lock); 623 624 TAILQ_INIT(&new_pages); 625 r = ttm_alloc_new_pages(&new_pages, pool->ttm_page_alloc_flags, 626 ttm_flags, cstate, alloc_size); 627 mtx_lock(&pool->lock); 628 629 if (!r) { 630 TAILQ_CONCAT(&pool->list, &new_pages, plinks.q); 631 ++pool->nrefills; 632 pool->npages += alloc_size; 633 } else { 634 printf("[TTM] Failed to fill pool (%p)\n", pool); 635 /* If we have any pages left put them to the pool. */ 636 TAILQ_FOREACH(p, &pool->list, plinks.q) { 637 ++cpages; 638 } 639 TAILQ_CONCAT(&pool->list, &new_pages, plinks.q); 640 pool->npages += cpages; 641 } 642 643 } 644 pool->fill_lock = false; 645 } 646 647 /** 648 * Cut 'count' number of pages from the pool and put them on the return list. 649 * 650 * @return count of pages still required to fulfill the request. 651 */ 652 static unsigned ttm_page_pool_get_pages(struct ttm_page_pool *pool, 653 struct pglist *pages, 654 int ttm_flags, 655 enum ttm_caching_state cstate, 656 unsigned count) 657 { 658 vm_page_t p; 659 unsigned i; 660 661 mtx_lock(&pool->lock); 662 ttm_page_pool_fill_locked(pool, ttm_flags, cstate, count); 663 664 if (count >= pool->npages) { 665 /* take all pages from the pool */ 666 TAILQ_CONCAT(pages, &pool->list, plinks.q); 667 count -= pool->npages; 668 pool->npages = 0; 669 goto out; 670 } 671 for (i = 0; i < count; i++) { 672 p = TAILQ_FIRST(&pool->list); 673 TAILQ_REMOVE(&pool->list, p, plinks.q); 674 TAILQ_INSERT_TAIL(pages, p, plinks.q); 675 } 676 pool->npages -= count; 677 count = 0; 678 out: 679 mtx_unlock(&pool->lock); 680 return count; 681 } 682 683 /* Put all pages in pages list to correct pool to wait for reuse */ 684 static void ttm_put_pages(vm_page_t *pages, unsigned npages, int flags, 685 enum ttm_caching_state cstate) 686 { 687 struct ttm_page_pool *pool = ttm_get_pool(flags, cstate); 688 unsigned i; 689 690 if (pool == NULL) { 691 /* No pool for this memory type so free the pages */ 692 for (i = 0; i < npages; i++) { 693 if (pages[i]) { 694 ttm_vm_page_free(pages[i]); 695 pages[i] = NULL; 696 } 697 } 698 return; 699 } 700 701 mtx_lock(&pool->lock); 702 for (i = 0; i < npages; i++) { 703 if (pages[i]) { 704 TAILQ_INSERT_TAIL(&pool->list, pages[i], plinks.q); 705 pages[i] = NULL; 706 pool->npages++; 707 } 708 } 709 /* Check that we don't go over the pool limit */ 710 npages = 0; 711 if (pool->npages > _manager->options.max_size) { 712 npages = pool->npages - _manager->options.max_size; 713 /* free at least NUM_PAGES_TO_ALLOC number of pages 714 * to reduce calls to set_memory_wb */ 715 if (npages < NUM_PAGES_TO_ALLOC) 716 npages = NUM_PAGES_TO_ALLOC; 717 } 718 mtx_unlock(&pool->lock); 719 if (npages) 720 ttm_page_pool_free(pool, npages); 721 } 722 723 /* 724 * On success pages list will hold count number of correctly 725 * cached pages. 726 */ 727 static int ttm_get_pages(vm_page_t *pages, unsigned npages, int flags, 728 enum ttm_caching_state cstate) 729 { 730 struct ttm_page_pool *pool = ttm_get_pool(flags, cstate); 731 struct pglist plist; 732 vm_page_t p = NULL; 733 int gfp_flags; 734 unsigned count; 735 int r; 736 737 /* No pool for cached pages */ 738 if (pool == NULL) { 739 for (r = 0; r < npages; ++r) { 740 p = ttm_vm_page_alloc(flags, cstate); 741 if (!p) { 742 printf("[TTM] Unable to allocate page\n"); 743 return -ENOMEM; 744 } 745 pages[r] = p; 746 } 747 return 0; 748 } 749 750 /* combine zero flag to pool flags */ 751 gfp_flags = flags | pool->ttm_page_alloc_flags; 752 753 /* First we take pages from the pool */ 754 TAILQ_INIT(&plist); 755 npages = ttm_page_pool_get_pages(pool, &plist, flags, cstate, npages); 756 count = 0; 757 TAILQ_FOREACH(p, &plist, plinks.q) { 758 pages[count++] = p; 759 } 760 761 /* clear the pages coming from the pool if requested */ 762 if (flags & TTM_PAGE_FLAG_ZERO_ALLOC) { 763 TAILQ_FOREACH(p, &plist, plinks.q) { 764 pmap_zero_page(p); 765 } 766 } 767 768 /* If pool didn't have enough pages allocate new one. */ 769 if (npages > 0) { 770 /* ttm_alloc_new_pages doesn't reference pool so we can run 771 * multiple requests in parallel. 772 **/ 773 TAILQ_INIT(&plist); 774 r = ttm_alloc_new_pages(&plist, gfp_flags, flags, cstate, 775 npages); 776 TAILQ_FOREACH(p, &plist, plinks.q) { 777 pages[count++] = p; 778 } 779 if (r) { 780 /* If there is any pages in the list put them back to 781 * the pool. */ 782 printf("[TTM] Failed to allocate extra pages for large request\n"); 783 ttm_put_pages(pages, count, flags, cstate); 784 return r; 785 } 786 } 787 788 return 0; 789 } 790 791 static void ttm_page_pool_init_locked(struct ttm_page_pool *pool, int flags, 792 char *name) 793 { 794 mtx_init(&pool->lock, "ttmpool", NULL, MTX_DEF); 795 pool->fill_lock = false; 796 TAILQ_INIT(&pool->list); 797 pool->npages = pool->nfrees = 0; 798 pool->ttm_page_alloc_flags = flags; 799 pool->name = name; 800 } 801 802 int ttm_page_alloc_init(struct ttm_mem_global *glob, unsigned max_pages) 803 { 804 805 if (_manager != NULL) 806 printf("[TTM] manager != NULL\n"); 807 printf("[TTM] Initializing pool allocator\n"); 808 809 _manager = malloc(sizeof(*_manager), M_TTM_POOLMGR, M_WAITOK | M_ZERO); 810 811 ttm_page_pool_init_locked(&_manager->wc_pool, 0, "wc"); 812 ttm_page_pool_init_locked(&_manager->uc_pool, 0, "uc"); 813 ttm_page_pool_init_locked(&_manager->wc_pool_dma32, 814 TTM_PAGE_FLAG_DMA32, "wc dma"); 815 ttm_page_pool_init_locked(&_manager->uc_pool_dma32, 816 TTM_PAGE_FLAG_DMA32, "uc dma"); 817 818 _manager->options.max_size = max_pages; 819 _manager->options.small = SMALL_ALLOCATION; 820 _manager->options.alloc_size = NUM_PAGES_TO_ALLOC; 821 822 refcount_init(&_manager->kobj_ref, 1); 823 ttm_pool_mm_shrink_init(_manager); 824 825 return 0; 826 } 827 828 void ttm_page_alloc_fini(void) 829 { 830 int i; 831 832 printf("[TTM] Finalizing pool allocator\n"); 833 ttm_pool_mm_shrink_fini(_manager); 834 835 for (i = 0; i < NUM_POOLS; ++i) 836 ttm_page_pool_free(&_manager->pools[i], FREE_ALL_PAGES); 837 838 if (refcount_release(&_manager->kobj_ref)) 839 ttm_pool_kobj_release(_manager); 840 _manager = NULL; 841 } 842 843 int ttm_pool_populate(struct ttm_tt *ttm) 844 { 845 struct ttm_mem_global *mem_glob = ttm->glob->mem_glob; 846 unsigned i; 847 int ret; 848 849 if (ttm->state != tt_unpopulated) 850 return 0; 851 852 for (i = 0; i < ttm->num_pages; ++i) { 853 ret = ttm_get_pages(&ttm->pages[i], 1, 854 ttm->page_flags, 855 ttm->caching_state); 856 if (ret != 0) { 857 ttm_pool_unpopulate(ttm); 858 return -ENOMEM; 859 } 860 861 ret = ttm_mem_global_alloc_page(mem_glob, ttm->pages[i], 862 false, false); 863 if (unlikely(ret != 0)) { 864 ttm_pool_unpopulate(ttm); 865 return -ENOMEM; 866 } 867 } 868 869 if (unlikely(ttm->page_flags & TTM_PAGE_FLAG_SWAPPED)) { 870 ret = ttm_tt_swapin(ttm); 871 if (unlikely(ret != 0)) { 872 ttm_pool_unpopulate(ttm); 873 return ret; 874 } 875 } 876 877 ttm->state = tt_unbound; 878 return 0; 879 } 880 881 void ttm_pool_unpopulate(struct ttm_tt *ttm) 882 { 883 unsigned i; 884 885 for (i = 0; i < ttm->num_pages; ++i) { 886 if (ttm->pages[i]) { 887 ttm_mem_global_free_page(ttm->glob->mem_glob, 888 ttm->pages[i]); 889 ttm_put_pages(&ttm->pages[i], 1, 890 ttm->page_flags, 891 ttm->caching_state); 892 } 893 } 894 ttm->state = tt_unpopulated; 895 } 896 897 #if 0 898 /* XXXKIB sysctl */ 899 int ttm_page_alloc_debugfs(struct seq_file *m, void *data) 900 { 901 struct ttm_page_pool *p; 902 unsigned i; 903 char *h[] = {"pool", "refills", "pages freed", "size"}; 904 if (!_manager) { 905 seq_printf(m, "No pool allocator running.\n"); 906 return 0; 907 } 908 seq_printf(m, "%6s %12s %13s %8s\n", 909 h[0], h[1], h[2], h[3]); 910 for (i = 0; i < NUM_POOLS; ++i) { 911 p = &_manager->pools[i]; 912 913 seq_printf(m, "%6s %12ld %13ld %8d\n", 914 p->name, p->nrefills, 915 p->nfrees, p->npages); 916 } 917 return 0; 918 } 919 #endif 920