mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs.git
synced 2026-11-01 06:46:35 +01:00
mm: percpu: enable per-cpu allocation tagging
Redefine __alloc_percpu, __alloc_percpu_gfp and __alloc_reserved_percpu to record allocations and deallocations done by these functions. [[email protected]: undo _noprof additions in the documentation] Link: https://lkml.kernel.org/r/[email protected] Link: https://lkml.kernel.org/r/[email protected] Signed-off-by: Kent Overstreet <[email protected]> Signed-off-by: Suren Baghdasaryan <[email protected]> Tested-by: Kees Cook <[email protected]> Cc: Alexander Viro <[email protected]> Cc: Alex Gaynor <[email protected]> Cc: Alice Ryhl <[email protected]> Cc: Andreas Hindborg <[email protected]> Cc: Benno Lossin <[email protected]> Cc: "Björn Roy Baron" <[email protected]> Cc: Boqun Feng <[email protected]> Cc: Christoph Lameter <[email protected]> Cc: Dennis Zhou <[email protected]> Cc: Gary Guo <[email protected]> Cc: Miguel Ojeda <[email protected]> Cc: Pasha Tatashin <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Tejun Heo <[email protected]> Cc: Vlastimil Babka <[email protected]> Cc: Wedson Almeida Filho <[email protected]> Signed-off-by: Andrew Morton <[email protected]>
This commit is contained in:
1 parent
60fa4a9e23
commit
24e44cc22a
2 files changed
+22
-63
No files matched your search
+16
-7
@@ -2,6 +2,7 @@
|
||||
#ifndef __LINUX_PERCPU_H
|
||||
#define __LINUX_PERCPU_H
|
||||
|
||||
#include <linux/alloc_tag.h>
|
||||
#include <linux/mmdebug.h>
|
||||
#include <linux/preempt.h>
|
||||
#include <linux/smp.h>
|
||||
@@ -9,6 +10,7 @@
|
||||
#include <linux/pfn.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/cleanup.h>
|
||||
#include <linux/sched.h>
|
||||
|
||||
#include <asm/percpu.h>
|
||||
|
||||
@@ -125,7 +127,6 @@ extern int __init pcpu_page_first_chunk(size_t reserved_size,
|
||||
pcpu_fc_cpu_to_node_fn_t cpu_to_nd_fn);
|
||||
#endif
|
||||
|
||||
extern void __percpu *__alloc_reserved_percpu(size_t size, size_t align) __alloc_size(1);
|
||||
extern bool __is_kernel_percpu_address(unsigned long addr, unsigned long *can_addr);
|
||||
extern bool is_kernel_percpu_address(unsigned long addr);
|
||||
|
||||
@@ -133,14 +134,16 @@ extern bool is_kernel_percpu_address(unsigned long addr);
|
||||
extern void __init setup_per_cpu_areas(void);
|
||||
#endif
|
||||
|
||||
extern void __percpu *__alloc_percpu_gfp(size_t size, size_t align, gfp_t gfp) __alloc_size(1);
|
||||
extern void __percpu *__alloc_percpu(size_t size, size_t align) __alloc_size(1);
|
||||
extern void free_percpu(void __percpu *__pdata);
|
||||
extern void __percpu *pcpu_alloc_noprof(size_t size, size_t align, bool reserved,
|
||||
gfp_t gfp) __alloc_size(1);
|
||||
extern size_t pcpu_alloc_size(void __percpu *__pdata);
|
||||
|
||||
DEFINE_FREE(free_percpu, void __percpu *, free_percpu(_T))
|
||||
|
||||
extern phys_addr_t per_cpu_ptr_to_phys(void *addr);
|
||||
#define __alloc_percpu_gfp(_size, _align, _gfp) \
|
||||
alloc_hooks(pcpu_alloc_noprof(_size, _align, false, _gfp))
|
||||
#define __alloc_percpu(_size, _align) \
|
||||
alloc_hooks(pcpu_alloc_noprof(_size, _align, false, GFP_KERNEL))
|
||||
#define __alloc_reserved_percpu(_size, _align) \
|
||||
alloc_hooks(pcpu_alloc_noprof(_size, _align, true, GFP_KERNEL))
|
||||
|
||||
#define alloc_percpu_gfp(type, gfp) \
|
||||
(typeof(type) __percpu *)__alloc_percpu_gfp(sizeof(type), \
|
||||
@@ -149,6 +152,12 @@ extern phys_addr_t per_cpu_ptr_to_phys(void *addr);
|
||||
(typeof(type) __percpu *)__alloc_percpu(sizeof(type), \
|
||||
__alignof__(type))
|
||||
|
||||
extern void free_percpu(void __percpu *__pdata);
|
||||
|
||||
DEFINE_FREE(free_percpu, void __percpu *, free_percpu(_T))
|
||||
|
||||
extern phys_addr_t per_cpu_ptr_to_phys(void *addr);
|
||||
|
||||
extern unsigned long pcpu_nr_pages(void);
|
||||
|
||||
#endif /* __LINUX_PERCPU_H */
|
||||
+6
-56
@@ -1740,7 +1740,7 @@ static void pcpu_alloc_tag_free_hook(struct pcpu_chunk *chunk, int off, size_t s
|
||||
* RETURNS:
|
||||
* Percpu pointer to the allocated area on success, NULL on failure.
|
||||
*/
|
||||
static void __percpu *pcpu_alloc(size_t size, size_t align, bool reserved,
|
||||
void __percpu *pcpu_alloc_noprof(size_t size, size_t align, bool reserved,
|
||||
gfp_t gfp)
|
||||
{
|
||||
gfp_t pcpu_gfp;
|
||||
@@ -1907,6 +1907,8 @@ area_found:
|
||||
|
||||
pcpu_memcg_post_alloc_hook(objcg, chunk, off, size);
|
||||
|
||||
pcpu_alloc_tag_alloc_hook(chunk, off, size);
|
||||
|
||||
return ptr;
|
||||
|
||||
fail_unlock:
|
||||
@@ -1935,61 +1937,7 @@ fail:
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* __alloc_percpu_gfp - allocate dynamic percpu area
|
||||
* @size: size of area to allocate in bytes
|
||||
* @align: alignment of area (max PAGE_SIZE)
|
||||
* @gfp: allocation flags
|
||||
*
|
||||
* Allocate zero-filled percpu area of @size bytes aligned at @align. If
|
||||
* @gfp doesn't contain %GFP_KERNEL, the allocation doesn't block and can
|
||||
* be called from any context but is a lot more likely to fail. If @gfp
|
||||
* has __GFP_NOWARN then no warning will be triggered on invalid or failed
|
||||
* allocation requests.
|
||||
*
|
||||
* RETURNS:
|
||||
* Percpu pointer to the allocated area on success, NULL on failure.
|
||||
*/
|
||||
void __percpu *__alloc_percpu_gfp(size_t size, size_t align, gfp_t gfp)
|
||||
{
|
||||
return pcpu_alloc(size, align, false, gfp);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(__alloc_percpu_gfp);
|
||||
|
||||
/**
|
||||
* __alloc_percpu - allocate dynamic percpu area
|
||||
* @size: size of area to allocate in bytes
|
||||
* @align: alignment of area (max PAGE_SIZE)
|
||||
*
|
||||
* Equivalent to __alloc_percpu_gfp(size, align, %GFP_KERNEL).
|
||||
*/
|
||||
void __percpu *__alloc_percpu(size_t size, size_t align)
|
||||
{
|
||||
return pcpu_alloc(size, align, false, GFP_KERNEL);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(__alloc_percpu);
|
||||
|
||||
/**
|
||||
* __alloc_reserved_percpu - allocate reserved percpu area
|
||||
* @size: size of area to allocate in bytes
|
||||
* @align: alignment of area (max PAGE_SIZE)
|
||||
*
|
||||
* Allocate zero-filled percpu area of @size bytes aligned at @align
|
||||
* from reserved percpu area if arch has set it up; otherwise,
|
||||
* allocation is served from the same dynamic area. Might sleep.
|
||||
* Might trigger writeouts.
|
||||
*
|
||||
* CONTEXT:
|
||||
* Does GFP_KERNEL allocation.
|
||||
*
|
||||
* RETURNS:
|
||||
* Percpu pointer to the allocated area on success, NULL on failure.
|
||||
*/
|
||||
void __percpu *__alloc_reserved_percpu(size_t size, size_t align)
|
||||
{
|
||||
return pcpu_alloc(size, align, true, GFP_KERNEL);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pcpu_alloc_noprof);
|
||||
|
||||
/**
|
||||
* pcpu_balance_free - manage the amount of free chunks
|
||||
@@ -2328,6 +2276,8 @@ void free_percpu(void __percpu *ptr)
|
||||
spin_lock_irqsave(&pcpu_lock, flags);
|
||||
size = pcpu_free_area(chunk, off);
|
||||
|
||||
pcpu_alloc_tag_free_hook(chunk, off, size);
|
||||
|
||||
pcpu_memcg_free_hook(chunk, off, size);
|
||||
|
||||
/*
|
||||
|
||||
Reference in new issue
Block a user