forked from mirrors/linux
		
	mm, vmalloc: properly track vmalloc users
__vmalloc_node_flags used to be static inline but this has changed by "mm: introduce kv[mz]alloc helpers" because kvmalloc_node needs to use it as well and the code is outside of the vmalloc proper. I haven't realized that changing this will lead to a subtle bug though. The function is responsible to track the caller as well. This caller is then printed by /proc/vmallocinfo. If __vmalloc_node_flags is not inline then we would get only direct users of __vmalloc_node_flags as callers (e.g. v[mz]alloc) which reduces usefulness of this debugging feature considerably. It simply doesn't help to see that the given range belongs to vmalloc as a caller: 0xffffc90002c79000-0xffffc90002c7d000 16384 vmalloc+0x16/0x18 pages=3 vmalloc N0=3 0xffffc90002c81000-0xffffc90002c85000 16384 vmalloc+0x16/0x18 pages=3 vmalloc N1=3 0xffffc90002c8d000-0xffffc90002c91000 16384 vmalloc+0x16/0x18 pages=3 vmalloc N1=3 0xffffc90002c95000-0xffffc90002c99000 16384 vmalloc+0x16/0x18 pages=3 vmalloc N1=3 We really want to catch the _caller_ of the vmalloc function. Fix this issue by making __vmalloc_node_flags static inline again. Link: http://lkml.kernel.org/r/20170502134657.12381-1-mhocko@kernel.org Signed-off-by: Michal Hocko <mhocko@suse.com> Cc: Vlastimil Babka <vbabka@suse.cz> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
		
							parent
							
								
									a7c3e901a4
								
							
						
					
					
						commit
						1f5307b1e0
					
				
					 2 changed files with 20 additions and 11 deletions
				
			
		|  | @ -6,6 +6,7 @@ | ||||||
| #include <linux/list.h> | #include <linux/list.h> | ||||||
| #include <linux/llist.h> | #include <linux/llist.h> | ||||||
| #include <asm/page.h>		/* pgprot_t */ | #include <asm/page.h>		/* pgprot_t */ | ||||||
|  | #include <asm/pgtable.h>	/* PAGE_KERNEL */ | ||||||
| #include <linux/rbtree.h> | #include <linux/rbtree.h> | ||||||
| 
 | 
 | ||||||
| struct vm_area_struct;		/* vma defining user mapping in mm_types.h */ | struct vm_area_struct;		/* vma defining user mapping in mm_types.h */ | ||||||
|  | @ -80,7 +81,25 @@ extern void *__vmalloc_node_range(unsigned long size, unsigned long align, | ||||||
| 			unsigned long start, unsigned long end, gfp_t gfp_mask, | 			unsigned long start, unsigned long end, gfp_t gfp_mask, | ||||||
| 			pgprot_t prot, unsigned long vm_flags, int node, | 			pgprot_t prot, unsigned long vm_flags, int node, | ||||||
| 			const void *caller); | 			const void *caller); | ||||||
|  | #ifndef CONFIG_MMU | ||||||
| extern void *__vmalloc_node_flags(unsigned long size, int node, gfp_t flags); | extern void *__vmalloc_node_flags(unsigned long size, int node, gfp_t flags); | ||||||
|  | #else | ||||||
|  | extern void *__vmalloc_node(unsigned long size, unsigned long align, | ||||||
|  | 			    gfp_t gfp_mask, pgprot_t prot, | ||||||
|  | 			    int node, const void *caller); | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * We really want to have this inlined due to caller tracking. This | ||||||
|  |  * function is used by the highlevel vmalloc apis and so we want to track | ||||||
|  |  * their callers and inlining will achieve that. | ||||||
|  |  */ | ||||||
|  | static inline void *__vmalloc_node_flags(unsigned long size, | ||||||
|  | 					int node, gfp_t flags) | ||||||
|  | { | ||||||
|  | 	return __vmalloc_node(size, 1, flags, PAGE_KERNEL, | ||||||
|  | 					node, __builtin_return_address(0)); | ||||||
|  | } | ||||||
|  | #endif | ||||||
| 
 | 
 | ||||||
| extern void vfree(const void *addr); | extern void vfree(const void *addr); | ||||||
| extern void vfree_atomic(const void *addr); | extern void vfree_atomic(const void *addr); | ||||||
|  |  | ||||||
							
								
								
									
										12
									
								
								mm/vmalloc.c
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								mm/vmalloc.c
									
									
									
									
									
								
							|  | @ -1649,9 +1649,6 @@ void *vmap(struct page **pages, unsigned int count, | ||||||
| } | } | ||||||
| EXPORT_SYMBOL(vmap); | EXPORT_SYMBOL(vmap); | ||||||
| 
 | 
 | ||||||
| static void *__vmalloc_node(unsigned long size, unsigned long align, |  | ||||||
| 			    gfp_t gfp_mask, pgprot_t prot, |  | ||||||
| 			    int node, const void *caller); |  | ||||||
| static void *__vmalloc_area_node(struct vm_struct *area, gfp_t gfp_mask, | static void *__vmalloc_area_node(struct vm_struct *area, gfp_t gfp_mask, | ||||||
| 				 pgprot_t prot, int node) | 				 pgprot_t prot, int node) | ||||||
| { | { | ||||||
|  | @ -1794,7 +1791,7 @@ void *__vmalloc_node_range(unsigned long size, unsigned long align, | ||||||
|  *	with mm people. |  *	with mm people. | ||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
| static void *__vmalloc_node(unsigned long size, unsigned long align, | void *__vmalloc_node(unsigned long size, unsigned long align, | ||||||
| 			    gfp_t gfp_mask, pgprot_t prot, | 			    gfp_t gfp_mask, pgprot_t prot, | ||||||
| 			    int node, const void *caller) | 			    int node, const void *caller) | ||||||
| { | { | ||||||
|  | @ -1809,13 +1806,6 @@ void *__vmalloc(unsigned long size, gfp_t gfp_mask, pgprot_t prot) | ||||||
| } | } | ||||||
| EXPORT_SYMBOL(__vmalloc); | EXPORT_SYMBOL(__vmalloc); | ||||||
| 
 | 
 | ||||||
| void *__vmalloc_node_flags(unsigned long size, |  | ||||||
| 					int node, gfp_t flags) |  | ||||||
| { |  | ||||||
| 	return __vmalloc_node(size, 1, flags, PAGE_KERNEL, |  | ||||||
| 					node, __builtin_return_address(0)); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /**
 | /**
 | ||||||
|  *	vmalloc  -  allocate virtually contiguous memory |  *	vmalloc  -  allocate virtually contiguous memory | ||||||
|  *	@size:		allocation size |  *	@size:		allocation size | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Michal Hocko
						Michal Hocko