On Tue, Oct 19, 2010 at 8:55 AM, Andriy Gapon <avg_at_freebsd.org> wrote: > on 19/10/2010 00:01 Giovanni Trematerra said the following: >> >> Your patch seems just a work around about initial slab size where the >> keg is backed. > > Well, setting aside my confusion with the terminology - yes, the patch is just > that, and precisely because I only tried to solve that particular problem. > >> Having dynamic slab sizes would allow to have the keg backed on a larger slab >> without going OFFPAGE. > > I agree in principle. > But without seeing code that implements that I can't guess if it would really be > more efficient or more maintainable, i.e. more useful in general. > Still a very good idea. > Here the patch that was in my mind. The patch doesn't implement dynamic slab size just allow to have a multipage slab to back uma_zone objects. I'm going to work more on the topic "dynamic slab size" soon. I tested the patch on qemu with -smp 32. I'm looking for real hw to test the patch on. here some interesting output: qemulab# vmstat -z | more ITEM SIZE LIMIT USED FREE REQ FAIL SLEEP UMA Kegs: 208, 0, 149, 4, 149, 0, 0 UMA Zones: 4480, 0, 149, 0, 149, 0, 0 UMA Slabs: 568, 0, 836, 4, 1187, 0, 0 UMA RCntSlabs: 568, 0, 202, 1, 202, 0, 0 UMA Hash: 256, 0, 2, 13, 3, 0, 0 qemulab# sysctl kern | grep cpu kern.ccpu: 0 <cpu count="32" mask="0xffffffff">0, 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, 31</cpu> kern.smp.cpus: 32 kern.smp.maxcpus: 32 Any feedback will be appreciate. -- Giovanni Trematerra ============================================================== diff -r 36572cbc6817 sys/vm/uma_core.c --- a/sys/vm/uma_core.c Tue Oct 05 04:49:04 2010 -0400 +++ b/sys/vm/uma_core.c Mon Nov 01 11:54:38 2010 -0400 _at__at_ -930,27 +930,36 _at__at_ startup_alloc(uma_zone_t zone, int bytes { uma_keg_t keg; uma_slab_t tmps; - - keg = zone_first_keg(zone); + u_int16_t pages; + + keg = zone_first_keg(zone); + pages = bytes / PAGE_SIZE; + + /* Account for remainder */ + if ((pages * PAGE_SIZE) < bytes) + pages++; + KASSERT(pages > 0, ("startup_alloc can't reserve 0 pages\n")); /* * Check our small startup cache to see if it has pages remaining. */ mtx_lock(&uma_boot_pages_mtx); - if ((tmps = LIST_FIRST(&uma_boot_pages)) != NULL) { - LIST_REMOVE(tmps, us_link); + do { + if ((tmps = LIST_FIRST(&uma_boot_pages)) != NULL) + LIST_REMOVE(tmps, us_link); + } while (--pages && tmps != NULL); + if (tmps != NULL) { mtx_unlock(&uma_boot_pages_mtx); *pflag = tmps->us_flags; return (tmps->us_data); - } + } else if (booted == 0) + panic("UMA: Increase vm.boot_pages"); mtx_unlock(&uma_boot_pages_mtx); - if (booted == 0) - panic("UMA: Increase vm.boot_pages"); /* * Now that we've booted reset these users to their real allocator. */ #ifdef UMA_MD_SMALL_ALLOC - keg->uk_allocf = uma_small_alloc; + keg->uk_allocf = (keg->uk_ppera > 1) ? page_alloc : uma_small_alloc; #else keg->uk_allocf = page_alloc; #endif _at__at_ -1163,7 +1172,7 _at__at_ keg_small_init(uma_keg_t keg) static void keg_large_init(uma_keg_t keg) { - int pages; + u_int16_t pages; KASSERT(keg != NULL, ("Keg is null in keg_large_init")); KASSERT((keg->uk_flags & UMA_ZFLAG_CACHEONLY) == 0, _at__at_ -1177,12 +1186,15 _at__at_ keg_large_init(uma_keg_t keg) keg->uk_ppera = pages; keg->uk_ipers = 1; + keg->uk_rsize = keg->uk_size; + + /* We can't do OFFPAGE if we're internal, bail out here. */ + if (keg->uk_flags & UMA_ZFLAG_INTERNAL) + return; keg->uk_flags |= UMA_ZONE_OFFPAGE; if ((keg->uk_flags & UMA_ZONE_VTOSLAB) == 0) keg->uk_flags |= UMA_ZONE_HASH; - - keg->uk_rsize = keg->uk_size; } static void _at__at_ -1301,7 +1313,8 _at__at_ keg_ctor(void *mem, int size, void *udat #endif if (booted == 0) keg->uk_allocf = startup_alloc; - } + } else if (booted == 0 && (keg->uk_flags & UMA_ZFLAG_INTERNAL)) + keg->uk_allocf = startup_alloc; /* * Initialize keg's lock (shared among zones). _at__at_ -1330,7 +1343,7 _at__at_ keg_ctor(void *mem, int size, void *udat if (totsize & UMA_ALIGN_PTR) totsize = (totsize & ~UMA_ALIGN_PTR) + (UMA_ALIGN_PTR + 1); - keg->uk_pgoff = UMA_SLAB_SIZE - totsize; + keg->uk_pgoff = (UMA_SLAB_SIZE * keg->uk_ppera) - totsize; if (keg->uk_flags & UMA_ZONE_REFCNT) totsize = keg->uk_pgoff + sizeof(struct uma_slab_refcnt) _at__at_ -1346,7 +1359,7 _at__at_ keg_ctor(void *mem, int size, void *udat * mathematically possible for all cases, so we make * sure here anyway. */ - if (totsize > UMA_SLAB_SIZE) { + if (totsize > UMA_SLAB_SIZE * keg->uk_ppera) { printf("zone %s ipers %d rsize %d size %d\n", zone->uz_name, keg->uk_ipers, keg->uk_rsize, keg->uk_size);Received on Mon Nov 01 2010 - 16:09:27 UTC
This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:40:08 UTC