brintos

brintos / linux-shallow public Read only

0
0
Text · 8.6 KiB · 3a45a20 Raw
236 lines · plain
1==================================================2page owner: Tracking about who allocated each page3==================================================4 5Introduction6============7 8page owner is for the tracking about who allocated each page.9It can be used to debug memory leak or to find a memory hogger.10When allocation happens, information about allocation such as call stack11and order of pages is stored into certain storage for each page.12When we need to know about status of all pages, we can get and analyze13this information.14 15Although we already have tracepoint for tracing page allocation/free,16using it for analyzing who allocate each page is rather complex. We need17to enlarge the trace buffer for preventing overlapping until userspace18program launched. And, launched program continually dump out the trace19buffer for later analysis and it would change system behaviour with more20possibility rather than just keeping it in memory, so bad for debugging.21 22page owner can also be used for various purposes. For example, accurate23fragmentation statistics can be obtained through gfp flag information of24each page. It is already implemented and activated if page owner is25enabled. Other usages are more than welcome.26 27It can also be used to show all the stacks and their current number of28allocated base pages, which gives us a quick overview of where the memory29is going without the need to screen through all the pages and match the30allocation and free operation.31 32page owner is disabled by default. So, if you'd like to use it, you need33to add "page_owner=on" to your boot cmdline. If the kernel is built34with page owner and page owner is disabled in runtime due to not enabling35boot option, runtime overhead is marginal. If disabled in runtime, it36doesn't require memory to store owner information, so there is no runtime37memory overhead. And, page owner inserts just two unlikely branches into38the page allocator hotpath and if not enabled, then allocation is done39like as the kernel without page owner. These two unlikely branches should40not affect to allocation performance, especially if the static keys jump41label patching functionality is available. Following is the kernel's code42size change due to this facility.43 44Although enabling page owner increases kernel size by several kilobytes,45most of this code is outside page allocator and its hot path. Building46the kernel with page owner and turning it on if needed would be great47option to debug kernel memory problem.48 49There is one notice that is caused by implementation detail. page owner50stores information into the memory from struct page extension. This memory51is initialized some time later than that page allocator starts in sparse52memory system, so, until initialization, many pages can be allocated and53they would have no owner information. To fix it up, these early allocated54pages are investigated and marked as allocated in initialization phase.55Although it doesn't mean that they have the right owner information,56at least, we can tell whether the page is allocated or not,57more accurately. On 2GB memory x86-64 VM box, 13343 early allocated pages58are caught and marked, although they are mostly allocated from struct59page extension feature. Anyway, after that, no page is left in60un-tracking state.61 62Usage63=====64 651) Build user-space helper::66 67	cd tools/mm68	make page_owner_sort69 702) Enable page owner: add "page_owner=on" to boot cmdline.71 723) Do the job that you want to debug.73 744) Analyze information from page owner::75 76	cat /sys/kernel/debug/page_owner_stacks/show_stacks > stacks.txt77	cat stacks.txt78	 post_alloc_hook+0x177/0x1a079	 get_page_from_freelist+0xd01/0xd8080	 __alloc_pages+0x39e/0x7e081	 allocate_slab+0xbc/0x3f082	 ___slab_alloc+0x528/0x8a083	 kmem_cache_alloc+0x224/0x3b084	 sk_prot_alloc+0x58/0x1a085	 sk_alloc+0x32/0x4f086	 inet_create+0x427/0xb5087	 __sock_create+0x2e4/0x65088	 inet_ctl_sock_create+0x30/0x18089	 igmp_net_init+0xc1/0x13090	 ops_init+0x167/0x41091	 setup_net+0x304/0xa6092	 copy_net_ns+0x29b/0x4a093	 create_new_namespaces+0x4a1/0x82094	nr_base_pages: 1695	...96	...97	echo 7000 > /sys/kernel/debug/page_owner_stacks/count_threshold98	cat /sys/kernel/debug/page_owner_stacks/show_stacks> stacks_7000.txt99	cat stacks_7000.txt100	 post_alloc_hook+0x177/0x1a0101	 get_page_from_freelist+0xd01/0xd80102	 __alloc_pages+0x39e/0x7e0103	 alloc_pages_mpol+0x22e/0x490104	 folio_alloc+0xd5/0x110105	 filemap_alloc_folio+0x78/0x230106	 page_cache_ra_order+0x287/0x6f0107	 filemap_get_pages+0x517/0x1160108	 filemap_read+0x304/0x9f0109	 xfs_file_buffered_read+0xe6/0x1d0 [xfs]110	 xfs_file_read_iter+0x1f0/0x380 [xfs]111	 __kernel_read+0x3b9/0x730112	 kernel_read_file+0x309/0x4d0113	 __do_sys_finit_module+0x381/0x730114	 do_syscall_64+0x8d/0x150115	 entry_SYSCALL_64_after_hwframe+0x62/0x6a116	nr_base_pages: 20824117	...118 119	cat /sys/kernel/debug/page_owner > page_owner_full.txt120	./page_owner_sort page_owner_full.txt sorted_page_owner.txt121 122   The general output of ``page_owner_full.txt`` is as follows::123 124	Page allocated via order XXX, ...125	PFN XXX ...126	// Detailed stack127 128	Page allocated via order XXX, ...129	PFN XXX ...130	// Detailed stack131    By default, it will do full pfn dump, to start with a given pfn,132    page_owner supports fseek.133 134    FILE *fp = fopen("/sys/kernel/debug/page_owner", "r");135    fseek(fp, pfn_start, SEEK_SET);136 137   The ``page_owner_sort`` tool ignores ``PFN`` rows, puts the remaining rows138   in buf, uses regexp to extract the page order value, counts the times139   and pages of buf, and finally sorts them according to the parameter(s).140 141   See the result about who allocated each page142   in the ``sorted_page_owner.txt``. General output::143 144	XXX times, XXX pages:145	Page allocated via order XXX, ...146	// Detailed stack147 148   By default, ``page_owner_sort`` is sorted according to the times of buf.149   If you want to sort by the page nums of buf, use the ``-m`` parameter.150   The detailed parameters are:151 152   fundamental function::153 154	Sort:155		-a		Sort by memory allocation time.156		-m		Sort by total memory.157		-p		Sort by pid.158		-P		Sort by tgid.159		-n		Sort by task command name.160		-r		Sort by memory release time.161		-s		Sort by stack trace.162		-t		Sort by times (default).163		--sort <order>	Specify sorting order.  Sorting syntax is [+|-]key[,[+|-]key[,...]].164				Choose a key from the **STANDARD FORMAT SPECIFIERS** section. The "+" is165				optional since default direction is increasing numerical or lexicographic166				order. Mixed use of abbreviated and complete-form of keys is allowed.167 168		Examples:169				./page_owner_sort <input> <output> --sort=n,+pid,-tgid170				./page_owner_sort <input> <output> --sort=at171 172   additional function::173 174	Cull:175		--cull <rules>176				Specify culling rules.Culling syntax is key[,key[,...]].Choose a177				multi-letter key from the **STANDARD FORMAT SPECIFIERS** section.178 179		<rules> is a single argument in the form of a comma-separated list,180		which offers a way to specify individual culling rules.  The recognized181		keywords are described in the **STANDARD FORMAT SPECIFIERS** section below.182		<rules> can be specified by the sequence of keys k1,k2, ..., as described in183		the STANDARD SORT KEYS section below. Mixed use of abbreviated and184		complete-form of keys is allowed.185 186		Examples:187				./page_owner_sort <input> <output> --cull=stacktrace188				./page_owner_sort <input> <output> --cull=st,pid,name189				./page_owner_sort <input> <output> --cull=n,f190 191	Filter:192		-f		Filter out the information of blocks whose memory has been released.193 194	Select:195		--pid <pidlist>		Select by pid. This selects the blocks whose process ID196					numbers appear in <pidlist>.197		--tgid <tgidlist>	Select by tgid. This selects the blocks whose thread198					group ID numbers appear in <tgidlist>.199		--name <cmdlist>	Select by task command name. This selects the blocks whose200					task command name appear in <cmdlist>.201 202		<pidlist>, <tgidlist>, <cmdlist> are single arguments in the form of a comma-separated list,203		which offers a way to specify individual selecting rules.204 205 206		Examples:207				./page_owner_sort <input> <output> --pid=1208				./page_owner_sort <input> <output> --tgid=1,2,3209				./page_owner_sort <input> <output> --name name1,name2210 211STANDARD FORMAT SPECIFIERS212==========================213::214 215  For --sort option:216 217	KEY		LONG		DESCRIPTION218	p		pid		process ID219	tg		tgid		thread group ID220	n		name		task command name221	st		stacktrace	stack trace of the page allocation222	T		txt		full text of block223	ft		free_ts		timestamp of the page when it was released224	at		alloc_ts	timestamp of the page when it was allocated225	ator		allocator	memory allocator for pages226 227  For --cull option:228 229	KEY		LONG		DESCRIPTION230	p		pid		process ID231	tg		tgid		thread group ID232	n		name		task command name233	f		free		whether the page has been released or not234	st		stacktrace	stack trace of the page allocation235	ator		allocator	memory allocator for pages236