Skip to content

Commit 24e44cc

Browse files
surenbaghdasaryanakpm00
authored andcommitted
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]>
1 parent 60fa4a9 commit 24e44cc

File tree

2 files changed

+22
-63
lines changed

2 files changed

+22
-63
lines changed

include/linux/percpu.h

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,15 @@
22
#ifndef __LINUX_PERCPU_H
33
#define __LINUX_PERCPU_H
44

5+
#include <linux/alloc_tag.h>
56
#include <linux/mmdebug.h>
67
#include <linux/preempt.h>
78
#include <linux/smp.h>
89
#include <linux/cpumask.h>
910
#include <linux/pfn.h>
1011
#include <linux/init.h>
1112
#include <linux/cleanup.h>
13+
#include <linux/sched.h>
1214

1315
#include <asm/percpu.h>
1416

@@ -125,22 +127,23 @@ extern int __init pcpu_page_first_chunk(size_t reserved_size,
125127
pcpu_fc_cpu_to_node_fn_t cpu_to_nd_fn);
126128
#endif
127129

128-
extern void __percpu *__alloc_reserved_percpu(size_t size, size_t align) __alloc_size(1);
129130
extern bool __is_kernel_percpu_address(unsigned long addr, unsigned long *can_addr);
130131
extern bool is_kernel_percpu_address(unsigned long addr);
131132

132133
#if !defined(CONFIG_SMP) || !defined(CONFIG_HAVE_SETUP_PER_CPU_AREA)
133134
extern void __init setup_per_cpu_areas(void);
134135
#endif
135136

136-
extern void __percpu *__alloc_percpu_gfp(size_t size, size_t align, gfp_t gfp) __alloc_size(1);
137-
extern void __percpu *__alloc_percpu(size_t size, size_t align) __alloc_size(1);
138-
extern void free_percpu(void __percpu *__pdata);
137+
extern void __percpu *pcpu_alloc_noprof(size_t size, size_t align, bool reserved,
138+
gfp_t gfp) __alloc_size(1);
139139
extern size_t pcpu_alloc_size(void __percpu *__pdata);
140140

141-
DEFINE_FREE(free_percpu, void __percpu *, free_percpu(_T))
142-
143-
extern phys_addr_t per_cpu_ptr_to_phys(void *addr);
141+
#define __alloc_percpu_gfp(_size, _align, _gfp) \
142+
alloc_hooks(pcpu_alloc_noprof(_size, _align, false, _gfp))
143+
#define __alloc_percpu(_size, _align) \
144+
alloc_hooks(pcpu_alloc_noprof(_size, _align, false, GFP_KERNEL))
145+
#define __alloc_reserved_percpu(_size, _align) \
146+
alloc_hooks(pcpu_alloc_noprof(_size, _align, true, GFP_KERNEL))
144147

145148
#define alloc_percpu_gfp(type, gfp) \
146149
(typeof(type) __percpu *)__alloc_percpu_gfp(sizeof(type), \
@@ -149,6 +152,12 @@ extern phys_addr_t per_cpu_ptr_to_phys(void *addr);
149152
(typeof(type) __percpu *)__alloc_percpu(sizeof(type), \
150153
__alignof__(type))
151154

155+
extern void free_percpu(void __percpu *__pdata);
156+
157+
DEFINE_FREE(free_percpu, void __percpu *, free_percpu(_T))
158+
159+
extern phys_addr_t per_cpu_ptr_to_phys(void *addr);
160+
152161
extern unsigned long pcpu_nr_pages(void);
153162

154163
#endif /* __LINUX_PERCPU_H */

mm/percpu.c

Lines changed: 6 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1740,7 +1740,7 @@ static void pcpu_alloc_tag_free_hook(struct pcpu_chunk *chunk, int off, size_t s
17401740
* RETURNS:
17411741
* Percpu pointer to the allocated area on success, NULL on failure.
17421742
*/
1743-
static void __percpu *pcpu_alloc(size_t size, size_t align, bool reserved,
1743+
void __percpu *pcpu_alloc_noprof(size_t size, size_t align, bool reserved,
17441744
gfp_t gfp)
17451745
{
17461746
gfp_t pcpu_gfp;
@@ -1907,6 +1907,8 @@ static void __percpu *pcpu_alloc(size_t size, size_t align, bool reserved,
19071907

19081908
pcpu_memcg_post_alloc_hook(objcg, chunk, off, size);
19091909

1910+
pcpu_alloc_tag_alloc_hook(chunk, off, size);
1911+
19101912
return ptr;
19111913

19121914
fail_unlock:
@@ -1935,61 +1937,7 @@ static void __percpu *pcpu_alloc(size_t size, size_t align, bool reserved,
19351937

19361938
return NULL;
19371939
}
1938-
1939-
/**
1940-
* __alloc_percpu_gfp - allocate dynamic percpu area
1941-
* @size: size of area to allocate in bytes
1942-
* @align: alignment of area (max PAGE_SIZE)
1943-
* @gfp: allocation flags
1944-
*
1945-
* Allocate zero-filled percpu area of @size bytes aligned at @align. If
1946-
* @gfp doesn't contain %GFP_KERNEL, the allocation doesn't block and can
1947-
* be called from any context but is a lot more likely to fail. If @gfp
1948-
* has __GFP_NOWARN then no warning will be triggered on invalid or failed
1949-
* allocation requests.
1950-
*
1951-
* RETURNS:
1952-
* Percpu pointer to the allocated area on success, NULL on failure.
1953-
*/
1954-
void __percpu *__alloc_percpu_gfp(size_t size, size_t align, gfp_t gfp)
1955-
{
1956-
return pcpu_alloc(size, align, false, gfp);
1957-
}
1958-
EXPORT_SYMBOL_GPL(__alloc_percpu_gfp);
1959-
1960-
/**
1961-
* __alloc_percpu - allocate dynamic percpu area
1962-
* @size: size of area to allocate in bytes
1963-
* @align: alignment of area (max PAGE_SIZE)
1964-
*
1965-
* Equivalent to __alloc_percpu_gfp(size, align, %GFP_KERNEL).
1966-
*/
1967-
void __percpu *__alloc_percpu(size_t size, size_t align)
1968-
{
1969-
return pcpu_alloc(size, align, false, GFP_KERNEL);
1970-
}
1971-
EXPORT_SYMBOL_GPL(__alloc_percpu);
1972-
1973-
/**
1974-
* __alloc_reserved_percpu - allocate reserved percpu area
1975-
* @size: size of area to allocate in bytes
1976-
* @align: alignment of area (max PAGE_SIZE)
1977-
*
1978-
* Allocate zero-filled percpu area of @size bytes aligned at @align
1979-
* from reserved percpu area if arch has set it up; otherwise,
1980-
* allocation is served from the same dynamic area. Might sleep.
1981-
* Might trigger writeouts.
1982-
*
1983-
* CONTEXT:
1984-
* Does GFP_KERNEL allocation.
1985-
*
1986-
* RETURNS:
1987-
* Percpu pointer to the allocated area on success, NULL on failure.
1988-
*/
1989-
void __percpu *__alloc_reserved_percpu(size_t size, size_t align)
1990-
{
1991-
return pcpu_alloc(size, align, true, GFP_KERNEL);
1992-
}
1940+
EXPORT_SYMBOL_GPL(pcpu_alloc_noprof);
19931941

19941942
/**
19951943
* pcpu_balance_free - manage the amount of free chunks
@@ -2328,6 +2276,8 @@ void free_percpu(void __percpu *ptr)
23282276
spin_lock_irqsave(&pcpu_lock, flags);
23292277
size = pcpu_free_area(chunk, off);
23302278

2279+
pcpu_alloc_tag_free_hook(chunk, off, size);
2280+
23312281
pcpu_memcg_free_hook(chunk, off, size);
23322282

23332283
/*

0 commit comments

Comments
 (0)