Page MenuHomeFreeBSD

uma: report waste per slab
ClosedPublic

Authored by rlibby on Dec 11 2019, 6:55 PM.
Tags
None
Referenced Files
Unknown Object (File)
Jan 16 2024, 10:45 AM
Unknown Object (File)
Dec 20 2023, 7:00 AM
Unknown Object (File)
Aug 31 2023, 3:52 PM
Unknown Object (File)
Jun 16 2023, 3:25 AM
Unknown Object (File)
Jun 3 2023, 8:08 AM
Unknown Object (File)
May 23 2023, 11:13 AM
Unknown Object (File)
Jan 12 2023, 9:24 PM
Unknown Object (File)
Jan 7 2023, 3:13 AM
Subscribers

Details

Summary

This is a definition of waste that lets us see the differences between
alternate slab layouts. I am not sure it is the best or the most
intuitive measurement, but it at least allows for comparison. I am open
to other definitions.

Test Plan

sysctl vm.uma | grep waste

Diff Detail

Repository
rS FreeBSD src repository - subversion
Lint
Lint Not Applicable
Unit
Tests Not Applicable

Event Timeline

Sample output:

vali% sysctl $(sysctl -N vm.uma | grep waste) | sort -k 2 -n -r | head -n 20
vm.uma.mbuf_jumbo_9k.keg.waste: 3384
vm.uma.tfo.keg.waste: 2184
vm.uma.int_pcpu.keg.waste: 2159
vm.uma.64_pcpu.keg.waste: 2159
vm.uma.sctp_asoc.keg.waste: 1792
vm.uma.65536.keg.waste: 1720
vm.uma.VMSPACE.keg.waste: 1664
vm.uma.Mountpoints.keg.waste: 1384
vm.uma.UMA_Zones.keg.waste: 1256
vm.uma.filedesc0.keg.waste: 888
vm.uma.32768.keg.waste: 888
vm.uma.FPU_save_area.keg.waste: 872
vm.uma.THREAD.keg.waste: 680
vm.uma.NCLNODE.keg.waste: 648
vm.uma.socket.keg.waste: 584
vm.uma.sctp_raddr.keg.waste: 520
vm.uma.vmem.keg.waste: 488
vm.uma.mbuf_jumbo_16k.keg.waste: 472
vm.uma.16384.keg.waste: 472
vm.uma.g_bio.keg.waste: 440

vali% sysctl $(sysctl -N vm.uma | grep waste) | sort -k 2 -n -r | tail      
vm.uma.64.keg.waste: 104
vm.uma.512.keg.waste: 104
vm.uma.32_Bucket.keg.waste: 104
vm.uma.256_Bucket.keg.waste: 104
vm.uma.256.keg.waste: 104
vm.uma.2048.keg.waste: 104
vm.uma.16_Bucket.keg.waste: 104
vm.uma.128_Bucket.keg.waste: 104
vm.uma.128.keg.waste: 104
vm.uma.1024.keg.waste: 104

I see you are not counting alignment as waste, which I agree with. The comment could be better though. It took me a while to realize how that was different from rsize (again).

I would not consider the allocator's own fields waste. I would just consider the unused bit size waste for offpage. So possibly subtract the minimum size slab header that would work and add the difference between that and the offpage slab header if necessary.

I understand why you want to count the page but for people coming after you it will be a confusing definition.

I wonder if the resulting metric is the right one. Another alternative is % of an item wasted. Or % of a page. In many cases waste may be high but addressing that would require allocating quite a few contiguous pages.

Here's what it would look like without sizeof(struct vm_page):

vali% sysctl $(sysctl -N vm.uma | grep waste) | sort -k 2 -n -r | head -n 20
vm.uma.mbuf_jumbo_9k.keg.waste: 3072
vm.uma.tfo.keg.waste: 2080
vm.uma.int_pcpu.keg.waste: 2055
vm.uma.64_pcpu.keg.waste: 2055
vm.uma.sctp_asoc.keg.waste: 1688
vm.uma.VMSPACE.keg.waste: 1560
vm.uma.Mountpoints.keg.waste: 1280
vm.uma.UMA_Zones.keg.waste: 1152
vm.uma.filedesc0.keg.waste: 784
vm.uma.FPU_save_area.keg.waste: 768
vm.uma.THREAD.keg.waste: 576
vm.uma.NCLNODE.keg.waste: 544
vm.uma.socket.keg.waste: 480
vm.uma.sctp_raddr.keg.waste: 416
vm.uma.vmem.keg.waste: 384
vm.uma.g_bio.keg.waste: 336
vm.uma.AIOCB.keg.waste: 336
vm.uma.pipe.keg.waste: 296
vm.uma.sctp_ep.keg.waste: 256
vm.uma.audit_record.keg.waste: 256

vali% sysctl $(sysctl -N vm.uma | grep waste) | sort -k 2 -n -r | tail      
vm.uma.64.keg.waste: 0
vm.uma.512.keg.waste: 0
vm.uma.32_Bucket.keg.waste: 0
vm.uma.256_Bucket.keg.waste: 0
vm.uma.256.keg.waste: 0
vm.uma.2048.keg.waste: 0
vm.uma.16_Bucket.keg.waste: 0
vm.uma.128_Bucket.keg.waste: 0
vm.uma.128.keg.waste: 0
vm.uma.1024.keg.waste: 0
sys/vm/uma_core.c
4454 ↗(On Diff #65503)

Maybe we should not add sizeof(struct vm_page). I was worried not having it would make page-embedded slabs look better than they are, but now I think having it is confusing.

In D22766#498263, @jeff wrote:

I see you are not counting alignment as waste, which I agree with. The comment could be better though. It took me a while to realize how that was different from rsize (again).

Will rephrase.

I would not consider the allocator's own fields waste. I would just consider the unused bit size waste for offpage. So possibly subtract the minimum size slab header that would work and add the difference between that and the offpage slab header if necessary.

I think it's appropriate to count the whole offpage slab, because otherwise slabzone memory could have been put to good use. I do see how it's interesting to count the wasted slab bits specifically though (especially if one is interested in optimizing wasted bits or kegs of very small objects).

I understand why you want to count the page but for people coming after you it will be a confusing definition.

Yeah, I think I agree. I'll remove it. Justification: the vm page structures couldn't be reallocated and put to use to store client data in any case.

I wonder if the resulting metric is the right one. Another alternative is % of an item wasted. Or % of a page. In many cases waste may be high but addressing that would require allocating quite a few contiguous pages.

I think we can consider two basic parameters, _total_ space consumption by a slab, and space _available_ in the slab for allocations by clients. Let us say this might be a way to compute those:

	total = keg->uk_ppera * PAGE_SIZE;
	if ((keg->uk_flags & UMA_ZONE_OFFPAGE) != 0)
		total += slab_sizeof(SLAB_MAX_SETSIZE);
	avail = keg->uk_ipers * roundup2(keg->uk_size, keg->uk_align + 1);
	if ((keg->uk_flags & UMA_ZONE_PCPU) != 0)
		avail *= mp_maxid + 1;

Then, what to display?

  • waste: total - avail
  • wastepct: 100 * (total - avail) / total
  • efficiency: 100 * avail / total
  • overhead: 100 * (total - avail) / avail
  • inefficiency: 100 - 100 * avail / total

Out of these, I think I like "efficiency" best. I think it's easiest to understand in terms of how it scales with more items. But I think any could work. Thoughts?

Sample output:

vali% sysctl $(sysctl -N vm.uma | grep efficiency) | sort -k 2 -n | head -n 20
vm.uma.64_pcpu.keg.efficiency: 49
vm.uma.int_pcpu.keg.efficiency: 49
vm.uma.tfo.keg.efficiency: 49
vm.uma.sctp_asoc.keg.efficiency: 58
vm.uma.VMSPACE.keg.efficiency: 61
vm.uma.Mountpoints.keg.efficiency: 68
vm.uma.UMA_Zones.keg.efficiency: 71
vm.uma.mbuf_jumbo_9k.keg.efficiency: 75
vm.uma.filedesc0.keg.efficiency: 80
vm.uma.FPU_save_area.keg.efficiency: 81
vm.uma.THREAD.keg.efficiency: 85
vm.uma.NCLNODE.keg.efficiency: 86
vm.uma.socket.keg.efficiency: 88
vm.uma.sctp_raddr.keg.efficiency: 89
vm.uma.vmem.keg.efficiency: 90
vm.uma.AIOCB.keg.efficiency: 91
vm.uma.g_bio.keg.efficiency: 91
vm.uma.pipe.keg.efficiency: 92
vm.uma.UMA_Hash.keg.efficiency: 93
vm.uma.VNODE.keg.efficiency: 93

vali% sysctl $(sysctl -N vm.uma | grep efficiency) | sort -k 2 -n | tail      
vm.uma.mbuf.keg.efficiency: 100
vm.uma.mbuf_cluster.keg.efficiency: 100
vm.uma.mbuf_extpgs.keg.efficiency: 100
vm.uma.mbuf_packet.keg.efficiency: 100
vm.uma.nvme_request.keg.efficiency: 100
vm.uma.pf_frags.keg.efficiency: 100
vm.uma.selfd.keg.efficiency: 100
vm.uma.tfo_ccache_entries.keg.efficiency: 100
vm.uma.ttyoutq.keg.efficiency: 100
vm.uma.unpcb.keg.efficiency: 100
This revision is now accepted and ready to land.Dec 13 2019, 6:59 AM
This revision was automatically updated to reflect the committed changes.