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