Bitmap patches for v6.0-rc1
This branch consists of: Qu Wenruo: lib: bitmap: fix the duplicated comments on bitmap_to_arr64() https://lore.kernel.org/lkml/0d85e1dbad52ad7fb5787c4432bdb36cbd24f632.1656063005.git.wqu@suse.com/ Alexander Lobakin: bitops: let optimize out non-atomic bitops on compile-time constants https://lore.kernel.org/lkml/20220624121313.2382500-1-alexandr.lobakin@intel.com/T/ Yury Norov: lib: cleanup bitmap-related headers https://lore.kernel.org/linux-arm-kernel/YtCVeOGLiQ4gNPSf@yury-laptop/T/#m305522194c4d38edfdaffa71fcaaf2e2ca00a961 Alexander Lobakin: x86/olpc: fix 'logical not is only applied to the left hand side' https://www.spinics.net/lists/kernel/msg4440064.html Yury Norov: lib/nodemask: inline wrappers around bitmap https://lore.kernel.org/all/20220723214537.2054208-1-yury.norov@gmail.com/ -----BEGIN PGP SIGNATURE----- iQGzBAABCgAdFiEEi8GdvG6xMhdgpu/4sUSA/TofvsgFAmLpVvwACgkQsUSA/Tof vsiAHgwAwS9pl8GJ+fKYnue2CYo9349d2oT6BBUs/Rv8uqYEa4QkpYsR7NS733TG pos0hhoRvSOzrUP4qppXUjfJ+NkzLgpnKFOeWfFoNAKlHuaaMRvF3Y0Q/P8g0/Kg HPWcCQLHyCH9Wjs3e2TTgRjxTrHuruD2VJ401/PX/lw0DicUhmev5mUFa10uwFkP ZJRprjoFn9HJ0Hk16pFZDi36d3YumhACOcWRiJdoBDrEPV3S6lm9EeOy/yHBNp5k 9bKj+RboeT2t70KaZcKv+M5j1nu0cAhl7kRkjcxcmGyimI0l82Vgq9yFxhGqvWg8 RnCrJ5EaO08FGCAKG9GEwzdiNa24Gdq5XZSpQA7JZHmhmchpnnlNenJicyv0gOQi abChZeWSEsyA+78l2+kk9nezfVKUOnKDEZQxBVTOyWsmZYxHZV94oam340VjQDaY 4/fETdOy/qqPIxnpxAeFGWxZjcVaYiYPLj7KLPMsB0aAAF7pZrem465vSfgbrE81 +gCdqrWd =4dTW -----END PGP SIGNATURE----- Merge tag 'bitmap-6.0-rc1' of https://github.com/norov/linux Pull bitmap updates from Yury Norov: - fix the duplicated comments on bitmap_to_arr64() (Qu Wenruo) - optimize out non-atomic bitops on compile-time constants (Alexander Lobakin) - cleanup bitmap-related headers (Yury Norov) - x86/olpc: fix 'logical not is only applied to the left hand side' (Alexander Lobakin) - lib/nodemask: inline wrappers around bitmap (Yury Norov) * tag 'bitmap-6.0-rc1' of https://github.com/norov/linux: (26 commits) lib/nodemask: inline next_node_in() and node_random() powerpc: drop dependency on <asm/machdep.h> in archrandom.h x86/olpc: fix 'logical not is only applied to the left hand side' lib/cpumask: move some one-line wrappers to header file headers/deps: mm: align MANITAINERS and Docs with new gfp.h structure headers/deps: mm: Split <linux/gfp_types.h> out of <linux/gfp.h> headers/deps: mm: Optimize <linux/gfp.h> header dependencies lib/cpumask: move trivial wrappers around find_bit to the header lib/cpumask: change return types to unsigned where appropriate cpumask: change return types to bool where appropriate lib/bitmap: change type of bitmap_weight to unsigned long lib/bitmap: change return types to bool where appropriate arm: align find_bit declarations with generic kernel iommu/vt-d: avoid invalid memory access via node_online(NUMA_NO_NODE) lib/test_bitmap: test the tail after bitmap_to_arr64() lib/bitmap: fix off-by-one in bitmap_to_arr64() lib: test_bitmap: add compile-time optimization/evaluations assertions bitmap: don't assume compiler evaluates small mem*() builtins calls net/ice: fix initializing the bitmap in the switch code bitops: let optimize out non-atomic bitops on compile-time constants ...
This commit is contained in:
commit
4e23eeebb2
38 changed files with 1077 additions and 790 deletions
|
|
@ -71,9 +71,9 @@ struct device;
|
|||
* bitmap_release_region(bitmap, pos, order) Free specified bit region
|
||||
* bitmap_allocate_region(bitmap, pos, order) Allocate specified bit region
|
||||
* bitmap_from_arr32(dst, buf, nbits) Copy nbits from u32[] buf to dst
|
||||
* bitmap_from_arr64(dst, buf, nbits) Copy nbits from u64[] buf to dst
|
||||
* bitmap_to_arr32(buf, src, nbits) Copy nbits from buf to u32[] dst
|
||||
* bitmap_to_arr64(buf, src, nbits) Copy nbits from buf to u64[] dst
|
||||
* bitmap_to_arr64(buf, src, nbits) Copy nbits from buf to u64[] dst
|
||||
* bitmap_get_value8(map, start) Get 8bit value from map at start
|
||||
* bitmap_set_value8(map, value, start) Set 8bit value to map at start
|
||||
*
|
||||
|
|
@ -148,13 +148,13 @@ void __bitmap_shift_left(unsigned long *dst, const unsigned long *src,
|
|||
unsigned int shift, unsigned int nbits);
|
||||
void bitmap_cut(unsigned long *dst, const unsigned long *src,
|
||||
unsigned int first, unsigned int cut, unsigned int nbits);
|
||||
int __bitmap_and(unsigned long *dst, const unsigned long *bitmap1,
|
||||
bool __bitmap_and(unsigned long *dst, const unsigned long *bitmap1,
|
||||
const unsigned long *bitmap2, unsigned int nbits);
|
||||
void __bitmap_or(unsigned long *dst, const unsigned long *bitmap1,
|
||||
const unsigned long *bitmap2, unsigned int nbits);
|
||||
void __bitmap_xor(unsigned long *dst, const unsigned long *bitmap1,
|
||||
const unsigned long *bitmap2, unsigned int nbits);
|
||||
int __bitmap_andnot(unsigned long *dst, const unsigned long *bitmap1,
|
||||
bool __bitmap_andnot(unsigned long *dst, const unsigned long *bitmap1,
|
||||
const unsigned long *bitmap2, unsigned int nbits);
|
||||
void __bitmap_replace(unsigned long *dst,
|
||||
const unsigned long *old, const unsigned long *new,
|
||||
|
|
@ -163,7 +163,7 @@ bool __bitmap_intersects(const unsigned long *bitmap1,
|
|||
const unsigned long *bitmap2, unsigned int nbits);
|
||||
bool __bitmap_subset(const unsigned long *bitmap1,
|
||||
const unsigned long *bitmap2, unsigned int nbits);
|
||||
int __bitmap_weight(const unsigned long *bitmap, unsigned int nbits);
|
||||
unsigned int __bitmap_weight(const unsigned long *bitmap, unsigned int nbits);
|
||||
void __bitmap_set(unsigned long *map, unsigned int start, int len);
|
||||
void __bitmap_clear(unsigned long *map, unsigned int start, int len);
|
||||
|
||||
|
|
@ -238,20 +238,32 @@ extern int bitmap_print_list_to_buf(char *buf, const unsigned long *maskp,
|
|||
static inline void bitmap_zero(unsigned long *dst, unsigned int nbits)
|
||||
{
|
||||
unsigned int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long);
|
||||
memset(dst, 0, len);
|
||||
|
||||
if (small_const_nbits(nbits))
|
||||
*dst = 0;
|
||||
else
|
||||
memset(dst, 0, len);
|
||||
}
|
||||
|
||||
static inline void bitmap_fill(unsigned long *dst, unsigned int nbits)
|
||||
{
|
||||
unsigned int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long);
|
||||
memset(dst, 0xff, len);
|
||||
|
||||
if (small_const_nbits(nbits))
|
||||
*dst = ~0UL;
|
||||
else
|
||||
memset(dst, 0xff, len);
|
||||
}
|
||||
|
||||
static inline void bitmap_copy(unsigned long *dst, const unsigned long *src,
|
||||
unsigned int nbits)
|
||||
{
|
||||
unsigned int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long);
|
||||
memcpy(dst, src, len);
|
||||
|
||||
if (small_const_nbits(nbits))
|
||||
*dst = *src;
|
||||
else
|
||||
memcpy(dst, src, len);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -303,7 +315,7 @@ void bitmap_to_arr64(u64 *buf, const unsigned long *bitmap, unsigned int nbits);
|
|||
bitmap_copy_clear_tail((unsigned long *)(buf), (const unsigned long *)(bitmap), (nbits))
|
||||
#endif
|
||||
|
||||
static inline int bitmap_and(unsigned long *dst, const unsigned long *src1,
|
||||
static inline bool bitmap_and(unsigned long *dst, const unsigned long *src1,
|
||||
const unsigned long *src2, unsigned int nbits)
|
||||
{
|
||||
if (small_const_nbits(nbits))
|
||||
|
|
@ -329,7 +341,7 @@ static inline void bitmap_xor(unsigned long *dst, const unsigned long *src1,
|
|||
__bitmap_xor(dst, src1, src2, nbits);
|
||||
}
|
||||
|
||||
static inline int bitmap_andnot(unsigned long *dst, const unsigned long *src1,
|
||||
static inline bool bitmap_andnot(unsigned long *dst, const unsigned long *src1,
|
||||
const unsigned long *src2, unsigned int nbits)
|
||||
{
|
||||
if (small_const_nbits(nbits))
|
||||
|
|
@ -419,7 +431,8 @@ static inline bool bitmap_full(const unsigned long *src, unsigned int nbits)
|
|||
return find_first_zero_bit(src, nbits) == nbits;
|
||||
}
|
||||
|
||||
static __always_inline int bitmap_weight(const unsigned long *src, unsigned int nbits)
|
||||
static __always_inline
|
||||
unsigned int bitmap_weight(const unsigned long *src, unsigned int nbits)
|
||||
{
|
||||
if (small_const_nbits(nbits))
|
||||
return hweight_long(*src & BITMAP_LAST_WORD_MASK(nbits));
|
||||
|
|
@ -431,6 +444,8 @@ static __always_inline void bitmap_set(unsigned long *map, unsigned int start,
|
|||
{
|
||||
if (__builtin_constant_p(nbits) && nbits == 1)
|
||||
__set_bit(start, map);
|
||||
else if (small_const_nbits(start + nbits))
|
||||
*map |= GENMASK(start + nbits - 1, start);
|
||||
else if (__builtin_constant_p(start & BITMAP_MEM_MASK) &&
|
||||
IS_ALIGNED(start, BITMAP_MEM_ALIGNMENT) &&
|
||||
__builtin_constant_p(nbits & BITMAP_MEM_MASK) &&
|
||||
|
|
@ -445,6 +460,8 @@ static __always_inline void bitmap_clear(unsigned long *map, unsigned int start,
|
|||
{
|
||||
if (__builtin_constant_p(nbits) && nbits == 1)
|
||||
__clear_bit(start, map);
|
||||
else if (small_const_nbits(start + nbits))
|
||||
*map &= ~GENMASK(start + nbits - 1, start);
|
||||
else if (__builtin_constant_p(start & BITMAP_MEM_MASK) &&
|
||||
IS_ALIGNED(start, BITMAP_MEM_ALIGNMENT) &&
|
||||
__builtin_constant_p(nbits & BITMAP_MEM_MASK) &&
|
||||
|
|
|
|||
|
|
@ -26,12 +26,62 @@ extern unsigned int __sw_hweight16(unsigned int w);
|
|||
extern unsigned int __sw_hweight32(unsigned int w);
|
||||
extern unsigned long __sw_hweight64(__u64 w);
|
||||
|
||||
/*
|
||||
* Defined here because those may be needed by architecture-specific static
|
||||
* inlines.
|
||||
*/
|
||||
|
||||
#include <asm-generic/bitops/generic-non-atomic.h>
|
||||
|
||||
/*
|
||||
* Many architecture-specific non-atomic bitops contain inline asm code and due
|
||||
* to that the compiler can't optimize them to compile-time expressions or
|
||||
* constants. In contrary, generic_*() helpers are defined in pure C and
|
||||
* compilers optimize them just well.
|
||||
* Therefore, to make `unsigned long foo = 0; __set_bit(BAR, &foo)` effectively
|
||||
* equal to `unsigned long foo = BIT(BAR)`, pick the generic C alternative when
|
||||
* the arguments can be resolved at compile time. That expression itself is a
|
||||
* constant and doesn't bring any functional changes to the rest of cases.
|
||||
* The casts to `uintptr_t` are needed to mitigate `-Waddress` warnings when
|
||||
* passing a bitmap from .bss or .data (-> `!!addr` is always true).
|
||||
*/
|
||||
#define bitop(op, nr, addr) \
|
||||
((__builtin_constant_p(nr) && \
|
||||
__builtin_constant_p((uintptr_t)(addr) != (uintptr_t)NULL) && \
|
||||
(uintptr_t)(addr) != (uintptr_t)NULL && \
|
||||
__builtin_constant_p(*(const unsigned long *)(addr))) ? \
|
||||
const##op(nr, addr) : op(nr, addr))
|
||||
|
||||
#define __set_bit(nr, addr) bitop(___set_bit, nr, addr)
|
||||
#define __clear_bit(nr, addr) bitop(___clear_bit, nr, addr)
|
||||
#define __change_bit(nr, addr) bitop(___change_bit, nr, addr)
|
||||
#define __test_and_set_bit(nr, addr) bitop(___test_and_set_bit, nr, addr)
|
||||
#define __test_and_clear_bit(nr, addr) bitop(___test_and_clear_bit, nr, addr)
|
||||
#define __test_and_change_bit(nr, addr) bitop(___test_and_change_bit, nr, addr)
|
||||
#define test_bit(nr, addr) bitop(_test_bit, nr, addr)
|
||||
|
||||
/*
|
||||
* Include this here because some architectures need generic_ffs/fls in
|
||||
* scope
|
||||
*/
|
||||
#include <asm/bitops.h>
|
||||
|
||||
/* Check that the bitops prototypes are sane */
|
||||
#define __check_bitop_pr(name) \
|
||||
static_assert(__same_type(arch_##name, generic_##name) && \
|
||||
__same_type(const_##name, generic_##name) && \
|
||||
__same_type(_##name, generic_##name))
|
||||
|
||||
__check_bitop_pr(__set_bit);
|
||||
__check_bitop_pr(__clear_bit);
|
||||
__check_bitop_pr(__change_bit);
|
||||
__check_bitop_pr(__test_and_set_bit);
|
||||
__check_bitop_pr(__test_and_clear_bit);
|
||||
__check_bitop_pr(__test_and_change_bit);
|
||||
__check_bitop_pr(test_bit);
|
||||
|
||||
#undef __check_bitop_pr
|
||||
|
||||
static inline int get_bitmask_order(unsigned int count)
|
||||
{
|
||||
int order;
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@
|
|||
#include <linux/bitmap.h>
|
||||
#include <linux/atomic.h>
|
||||
#include <linux/bug.h>
|
||||
#include <linux/gfp_types.h>
|
||||
#include <linux/numa.h>
|
||||
|
||||
/* Don't assign or return these: may not be this big! */
|
||||
typedef struct cpumask { DECLARE_BITMAP(bits, NR_CPUS); } cpumask_t;
|
||||
|
|
@ -162,7 +164,21 @@ static inline unsigned int cpumask_last(const struct cpumask *srcp)
|
|||
return find_last_bit(cpumask_bits(srcp), nr_cpumask_bits);
|
||||
}
|
||||
|
||||
unsigned int __pure cpumask_next(int n, const struct cpumask *srcp);
|
||||
/**
|
||||
* cpumask_next - get the next cpu in a cpumask
|
||||
* @n: the cpu prior to the place to search (ie. return will be > @n)
|
||||
* @srcp: the cpumask pointer
|
||||
*
|
||||
* Returns >= nr_cpu_ids if no further cpus set.
|
||||
*/
|
||||
static inline
|
||||
unsigned int cpumask_next(int n, const struct cpumask *srcp)
|
||||
{
|
||||
/* -1 is a legal arg here. */
|
||||
if (n != -1)
|
||||
cpumask_check(n);
|
||||
return find_next_bit(cpumask_bits(srcp), nr_cpumask_bits, n + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* cpumask_next_zero - get the next unset cpu in a cpumask
|
||||
|
|
@ -179,9 +195,6 @@ static inline unsigned int cpumask_next_zero(int n, const struct cpumask *srcp)
|
|||
return find_next_zero_bit(cpumask_bits(srcp), nr_cpumask_bits, n+1);
|
||||
}
|
||||
|
||||
int __pure cpumask_next_and(int n, const struct cpumask *, const struct cpumask *);
|
||||
int __pure cpumask_any_but(const struct cpumask *mask, unsigned int cpu);
|
||||
|
||||
#if NR_CPUS == 1
|
||||
/* Uniprocessor: there is only one valid CPU */
|
||||
static inline unsigned int cpumask_local_spread(unsigned int i, int node)
|
||||
|
|
@ -200,11 +213,30 @@ static inline int cpumask_any_distribute(const struct cpumask *srcp)
|
|||
}
|
||||
#else
|
||||
unsigned int cpumask_local_spread(unsigned int i, int node);
|
||||
int cpumask_any_and_distribute(const struct cpumask *src1p,
|
||||
unsigned int cpumask_any_and_distribute(const struct cpumask *src1p,
|
||||
const struct cpumask *src2p);
|
||||
int cpumask_any_distribute(const struct cpumask *srcp);
|
||||
unsigned int cpumask_any_distribute(const struct cpumask *srcp);
|
||||
#endif /* NR_CPUS */
|
||||
|
||||
/**
|
||||
* cpumask_next_and - get the next cpu in *src1p & *src2p
|
||||
* @n: the cpu prior to the place to search (ie. return will be > @n)
|
||||
* @src1p: the first cpumask pointer
|
||||
* @src2p: the second cpumask pointer
|
||||
*
|
||||
* Returns >= nr_cpu_ids if no further cpus set in both.
|
||||
*/
|
||||
static inline
|
||||
unsigned int cpumask_next_and(int n, const struct cpumask *src1p,
|
||||
const struct cpumask *src2p)
|
||||
{
|
||||
/* -1 is a legal arg here. */
|
||||
if (n != -1)
|
||||
cpumask_check(n);
|
||||
return find_next_and_bit(cpumask_bits(src1p), cpumask_bits(src2p),
|
||||
nr_cpumask_bits, n + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* for_each_cpu - iterate over every cpu in a mask
|
||||
* @cpu: the (optionally unsigned) integer iterator
|
||||
|
|
@ -229,7 +261,7 @@ int cpumask_any_distribute(const struct cpumask *srcp);
|
|||
(cpu) = cpumask_next_zero((cpu), (mask)), \
|
||||
(cpu) < nr_cpu_ids;)
|
||||
|
||||
int __pure cpumask_next_wrap(int n, const struct cpumask *mask, int start, bool wrap);
|
||||
unsigned int __pure cpumask_next_wrap(int n, const struct cpumask *mask, int start, bool wrap);
|
||||
|
||||
/**
|
||||
* for_each_cpu_wrap - iterate over every cpu in a mask, starting at a specified location
|
||||
|
|
@ -265,6 +297,26 @@ int __pure cpumask_next_wrap(int n, const struct cpumask *mask, int start, bool
|
|||
(cpu) = cpumask_next_and((cpu), (mask1), (mask2)), \
|
||||
(cpu) < nr_cpu_ids;)
|
||||
|
||||
/**
|
||||
* cpumask_any_but - return a "random" in a cpumask, but not this one.
|
||||
* @mask: the cpumask to search
|
||||
* @cpu: the cpu to ignore.
|
||||
*
|
||||
* Often used to find any cpu but smp_processor_id() in a mask.
|
||||
* Returns >= nr_cpu_ids if no cpus set.
|
||||
*/
|
||||
static inline
|
||||
unsigned int cpumask_any_but(const struct cpumask *mask, unsigned int cpu)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
cpumask_check(cpu);
|
||||
for_each_cpu(i, mask)
|
||||
if (i != cpu)
|
||||
break;
|
||||
return i;
|
||||
}
|
||||
|
||||
#define CPU_BITS_NONE \
|
||||
{ \
|
||||
[0 ... BITS_TO_LONGS(NR_CPUS)-1] = 0UL \
|
||||
|
|
@ -311,9 +363,9 @@ static __always_inline void __cpumask_clear_cpu(int cpu, struct cpumask *dstp)
|
|||
* @cpu: cpu number (< nr_cpu_ids)
|
||||
* @cpumask: the cpumask pointer
|
||||
*
|
||||
* Returns 1 if @cpu is set in @cpumask, else returns 0
|
||||
* Returns true if @cpu is set in @cpumask, else returns false
|
||||
*/
|
||||
static __always_inline int cpumask_test_cpu(int cpu, const struct cpumask *cpumask)
|
||||
static __always_inline bool cpumask_test_cpu(int cpu, const struct cpumask *cpumask)
|
||||
{
|
||||
return test_bit(cpumask_check(cpu), cpumask_bits((cpumask)));
|
||||
}
|
||||
|
|
@ -323,11 +375,11 @@ static __always_inline int cpumask_test_cpu(int cpu, const struct cpumask *cpuma
|
|||
* @cpu: cpu number (< nr_cpu_ids)
|
||||
* @cpumask: the cpumask pointer
|
||||
*
|
||||
* Returns 1 if @cpu is set in old bitmap of @cpumask, else returns 0
|
||||
* Returns true if @cpu is set in old bitmap of @cpumask, else returns false
|
||||
*
|
||||
* test_and_set_bit wrapper for cpumasks.
|
||||
*/
|
||||
static __always_inline int cpumask_test_and_set_cpu(int cpu, struct cpumask *cpumask)
|
||||
static __always_inline bool cpumask_test_and_set_cpu(int cpu, struct cpumask *cpumask)
|
||||
{
|
||||
return test_and_set_bit(cpumask_check(cpu), cpumask_bits(cpumask));
|
||||
}
|
||||
|
|
@ -337,11 +389,11 @@ static __always_inline int cpumask_test_and_set_cpu(int cpu, struct cpumask *cpu
|
|||
* @cpu: cpu number (< nr_cpu_ids)
|
||||
* @cpumask: the cpumask pointer
|
||||
*
|
||||
* Returns 1 if @cpu is set in old bitmap of @cpumask, else returns 0
|
||||
* Returns true if @cpu is set in old bitmap of @cpumask, else returns false
|
||||
*
|
||||
* test_and_clear_bit wrapper for cpumasks.
|
||||
*/
|
||||
static __always_inline int cpumask_test_and_clear_cpu(int cpu, struct cpumask *cpumask)
|
||||
static __always_inline bool cpumask_test_and_clear_cpu(int cpu, struct cpumask *cpumask)
|
||||
{
|
||||
return test_and_clear_bit(cpumask_check(cpu), cpumask_bits(cpumask));
|
||||
}
|
||||
|
|
@ -370,9 +422,9 @@ static inline void cpumask_clear(struct cpumask *dstp)
|
|||
* @src1p: the first input
|
||||
* @src2p: the second input
|
||||
*
|
||||
* If *@dstp is empty, returns 0, else returns 1
|
||||
* If *@dstp is empty, returns false, else returns true
|
||||
*/
|
||||
static inline int cpumask_and(struct cpumask *dstp,
|
||||
static inline bool cpumask_and(struct cpumask *dstp,
|
||||
const struct cpumask *src1p,
|
||||
const struct cpumask *src2p)
|
||||
{
|
||||
|
|
@ -413,9 +465,9 @@ static inline void cpumask_xor(struct cpumask *dstp,
|
|||
* @src1p: the first input
|
||||
* @src2p: the second input
|
||||
*
|
||||
* If *@dstp is empty, returns 0, else returns 1
|
||||
* If *@dstp is empty, returns false, else returns true
|
||||
*/
|
||||
static inline int cpumask_andnot(struct cpumask *dstp,
|
||||
static inline bool cpumask_andnot(struct cpumask *dstp,
|
||||
const struct cpumask *src1p,
|
||||
const struct cpumask *src2p)
|
||||
{
|
||||
|
|
@ -478,9 +530,9 @@ static inline bool cpumask_intersects(const struct cpumask *src1p,
|
|||
* @src1p: the first input
|
||||
* @src2p: the second input
|
||||
*
|
||||
* Returns 1 if *@src1p is a subset of *@src2p, else returns 0
|
||||
* Returns true if *@src1p is a subset of *@src2p, else returns false
|
||||
*/
|
||||
static inline int cpumask_subset(const struct cpumask *src1p,
|
||||
static inline bool cpumask_subset(const struct cpumask *src1p,
|
||||
const struct cpumask *src2p)
|
||||
{
|
||||
return bitmap_subset(cpumask_bits(src1p), cpumask_bits(src2p),
|
||||
|
|
@ -682,9 +734,35 @@ typedef struct cpumask *cpumask_var_t;
|
|||
#define __cpumask_var_read_mostly __read_mostly
|
||||
|
||||
bool alloc_cpumask_var_node(cpumask_var_t *mask, gfp_t flags, int node);
|
||||
bool alloc_cpumask_var(cpumask_var_t *mask, gfp_t flags);
|
||||
bool zalloc_cpumask_var_node(cpumask_var_t *mask, gfp_t flags, int node);
|
||||
bool zalloc_cpumask_var(cpumask_var_t *mask, gfp_t flags);
|
||||
|
||||
static inline
|
||||
bool zalloc_cpumask_var_node(cpumask_var_t *mask, gfp_t flags, int node)
|
||||
{
|
||||
return alloc_cpumask_var_node(mask, flags | __GFP_ZERO, node);
|
||||
}
|
||||
|
||||
/**
|
||||
* alloc_cpumask_var - allocate a struct cpumask
|
||||
* @mask: pointer to cpumask_var_t where the cpumask is returned
|
||||
* @flags: GFP_ flags
|
||||
*
|
||||
* Only defined when CONFIG_CPUMASK_OFFSTACK=y, otherwise is
|
||||
* a nop returning a constant 1 (in <linux/cpumask.h>).
|
||||
*
|
||||
* See alloc_cpumask_var_node.
|
||||
*/
|
||||
static inline
|
||||
bool alloc_cpumask_var(cpumask_var_t *mask, gfp_t flags)
|
||||
{
|
||||
return alloc_cpumask_var_node(mask, flags, NUMA_NO_NODE);
|
||||
}
|
||||
|
||||
static inline
|
||||
bool zalloc_cpumask_var(cpumask_var_t *mask, gfp_t flags)
|
||||
{
|
||||
return alloc_cpumask_var(mask, flags | __GFP_ZERO);
|
||||
}
|
||||
|
||||
void alloc_bootmem_cpumask_var(cpumask_var_t *mask);
|
||||
void free_cpumask_var(cpumask_var_t mask);
|
||||
void free_bootmem_cpumask_var(cpumask_var_t mask);
|
||||
|
|
|
|||
|
|
@ -2,357 +2,13 @@
|
|||
#ifndef __LINUX_GFP_H
|
||||
#define __LINUX_GFP_H
|
||||
|
||||
#include <linux/mmdebug.h>
|
||||
#include <linux/gfp_types.h>
|
||||
|
||||
#include <linux/mmzone.h>
|
||||
#include <linux/stddef.h>
|
||||
#include <linux/linkage.h>
|
||||
#include <linux/topology.h>
|
||||
|
||||
/* The typedef is in types.h but we want the documentation here */
|
||||
#if 0
|
||||
/**
|
||||
* typedef gfp_t - Memory allocation flags.
|
||||
*
|
||||
* GFP flags are commonly used throughout Linux to indicate how memory
|
||||
* should be allocated. The GFP acronym stands for get_free_pages(),
|
||||
* the underlying memory allocation function. Not every GFP flag is
|
||||
* supported by every function which may allocate memory. Most users
|
||||
* will want to use a plain ``GFP_KERNEL``.
|
||||
*/
|
||||
typedef unsigned int __bitwise gfp_t;
|
||||
#endif
|
||||
|
||||
struct vm_area_struct;
|
||||
|
||||
/*
|
||||
* In case of changes, please don't forget to update
|
||||
* include/trace/events/mmflags.h and tools/perf/builtin-kmem.c
|
||||
*/
|
||||
|
||||
/* Plain integer GFP bitmasks. Do not use this directly. */
|
||||
#define ___GFP_DMA 0x01u
|
||||
#define ___GFP_HIGHMEM 0x02u
|
||||
#define ___GFP_DMA32 0x04u
|
||||
#define ___GFP_MOVABLE 0x08u
|
||||
#define ___GFP_RECLAIMABLE 0x10u
|
||||
#define ___GFP_HIGH 0x20u
|
||||
#define ___GFP_IO 0x40u
|
||||
#define ___GFP_FS 0x80u
|
||||
#define ___GFP_ZERO 0x100u
|
||||
#define ___GFP_ATOMIC 0x200u
|
||||
#define ___GFP_DIRECT_RECLAIM 0x400u
|
||||
#define ___GFP_KSWAPD_RECLAIM 0x800u
|
||||
#define ___GFP_WRITE 0x1000u
|
||||
#define ___GFP_NOWARN 0x2000u
|
||||
#define ___GFP_RETRY_MAYFAIL 0x4000u
|
||||
#define ___GFP_NOFAIL 0x8000u
|
||||
#define ___GFP_NORETRY 0x10000u
|
||||
#define ___GFP_MEMALLOC 0x20000u
|
||||
#define ___GFP_COMP 0x40000u
|
||||
#define ___GFP_NOMEMALLOC 0x80000u
|
||||
#define ___GFP_HARDWALL 0x100000u
|
||||
#define ___GFP_THISNODE 0x200000u
|
||||
#define ___GFP_ACCOUNT 0x400000u
|
||||
#define ___GFP_ZEROTAGS 0x800000u
|
||||
#ifdef CONFIG_KASAN_HW_TAGS
|
||||
#define ___GFP_SKIP_ZERO 0x1000000u
|
||||
#define ___GFP_SKIP_KASAN_UNPOISON 0x2000000u
|
||||
#define ___GFP_SKIP_KASAN_POISON 0x4000000u
|
||||
#else
|
||||
#define ___GFP_SKIP_ZERO 0
|
||||
#define ___GFP_SKIP_KASAN_UNPOISON 0
|
||||
#define ___GFP_SKIP_KASAN_POISON 0
|
||||
#endif
|
||||
#ifdef CONFIG_LOCKDEP
|
||||
#define ___GFP_NOLOCKDEP 0x8000000u
|
||||
#else
|
||||
#define ___GFP_NOLOCKDEP 0
|
||||
#endif
|
||||
/* If the above are modified, __GFP_BITS_SHIFT may need updating */
|
||||
|
||||
/*
|
||||
* Physical address zone modifiers (see linux/mmzone.h - low four bits)
|
||||
*
|
||||
* Do not put any conditional on these. If necessary modify the definitions
|
||||
* without the underscores and use them consistently. The definitions here may
|
||||
* be used in bit comparisons.
|
||||
*/
|
||||
#define __GFP_DMA ((__force gfp_t)___GFP_DMA)
|
||||
#define __GFP_HIGHMEM ((__force gfp_t)___GFP_HIGHMEM)
|
||||
#define __GFP_DMA32 ((__force gfp_t)___GFP_DMA32)
|
||||
#define __GFP_MOVABLE ((__force gfp_t)___GFP_MOVABLE) /* ZONE_MOVABLE allowed */
|
||||
#define GFP_ZONEMASK (__GFP_DMA|__GFP_HIGHMEM|__GFP_DMA32|__GFP_MOVABLE)
|
||||
|
||||
/**
|
||||
* DOC: Page mobility and placement hints
|
||||
*
|
||||
* Page mobility and placement hints
|
||||
* ---------------------------------
|
||||
*
|
||||
* These flags provide hints about how mobile the page is. Pages with similar
|
||||
* mobility are placed within the same pageblocks to minimise problems due
|
||||
* to external fragmentation.
|
||||
*
|
||||
* %__GFP_MOVABLE (also a zone modifier) indicates that the page can be
|
||||
* moved by page migration during memory compaction or can be reclaimed.
|
||||
*
|
||||
* %__GFP_RECLAIMABLE is used for slab allocations that specify
|
||||
* SLAB_RECLAIM_ACCOUNT and whose pages can be freed via shrinkers.
|
||||
*
|
||||
* %__GFP_WRITE indicates the caller intends to dirty the page. Where possible,
|
||||
* these pages will be spread between local zones to avoid all the dirty
|
||||
* pages being in one zone (fair zone allocation policy).
|
||||
*
|
||||
* %__GFP_HARDWALL enforces the cpuset memory allocation policy.
|
||||
*
|
||||
* %__GFP_THISNODE forces the allocation to be satisfied from the requested
|
||||
* node with no fallbacks or placement policy enforcements.
|
||||
*
|
||||
* %__GFP_ACCOUNT causes the allocation to be accounted to kmemcg.
|
||||
*/
|
||||
#define __GFP_RECLAIMABLE ((__force gfp_t)___GFP_RECLAIMABLE)
|
||||
#define __GFP_WRITE ((__force gfp_t)___GFP_WRITE)
|
||||
#define __GFP_HARDWALL ((__force gfp_t)___GFP_HARDWALL)
|
||||
#define __GFP_THISNODE ((__force gfp_t)___GFP_THISNODE)
|
||||
#define __GFP_ACCOUNT ((__force gfp_t)___GFP_ACCOUNT)
|
||||
|
||||
/**
|
||||
* DOC: Watermark modifiers
|
||||
*
|
||||
* Watermark modifiers -- controls access to emergency reserves
|
||||
* ------------------------------------------------------------
|
||||
*
|
||||
* %__GFP_HIGH indicates that the caller is high-priority and that granting
|
||||
* the request is necessary before the system can make forward progress.
|
||||
* For example, creating an IO context to clean pages.
|
||||
*
|
||||
* %__GFP_ATOMIC indicates that the caller cannot reclaim or sleep and is
|
||||
* high priority. Users are typically interrupt handlers. This may be
|
||||
* used in conjunction with %__GFP_HIGH
|
||||
*
|
||||
* %__GFP_MEMALLOC allows access to all memory. This should only be used when
|
||||
* the caller guarantees the allocation will allow more memory to be freed
|
||||
* very shortly e.g. process exiting or swapping. Users either should
|
||||
* be the MM or co-ordinating closely with the VM (e.g. swap over NFS).
|
||||
* Users of this flag have to be extremely careful to not deplete the reserve
|
||||
* completely and implement a throttling mechanism which controls the
|
||||
* consumption of the reserve based on the amount of freed memory.
|
||||
* Usage of a pre-allocated pool (e.g. mempool) should be always considered
|
||||
* before using this flag.
|
||||
*
|
||||
* %__GFP_NOMEMALLOC is used to explicitly forbid access to emergency reserves.
|
||||
* This takes precedence over the %__GFP_MEMALLOC flag if both are set.
|
||||
*/
|
||||
#define __GFP_ATOMIC ((__force gfp_t)___GFP_ATOMIC)
|
||||
#define __GFP_HIGH ((__force gfp_t)___GFP_HIGH)
|
||||
#define __GFP_MEMALLOC ((__force gfp_t)___GFP_MEMALLOC)
|
||||
#define __GFP_NOMEMALLOC ((__force gfp_t)___GFP_NOMEMALLOC)
|
||||
|
||||
/**
|
||||
* DOC: Reclaim modifiers
|
||||
*
|
||||
* Reclaim modifiers
|
||||
* -----------------
|
||||
* Please note that all the following flags are only applicable to sleepable
|
||||
* allocations (e.g. %GFP_NOWAIT and %GFP_ATOMIC will ignore them).
|
||||
*
|
||||
* %__GFP_IO can start physical IO.
|
||||
*
|
||||
* %__GFP_FS can call down to the low-level FS. Clearing the flag avoids the
|
||||
* allocator recursing into the filesystem which might already be holding
|
||||
* locks.
|
||||
*
|
||||
* %__GFP_DIRECT_RECLAIM indicates that the caller may enter direct reclaim.
|
||||
* This flag can be cleared to avoid unnecessary delays when a fallback
|
||||
* option is available.
|
||||
*
|
||||
* %__GFP_KSWAPD_RECLAIM indicates that the caller wants to wake kswapd when
|
||||
* the low watermark is reached and have it reclaim pages until the high
|
||||
* watermark is reached. A caller may wish to clear this flag when fallback
|
||||
* options are available and the reclaim is likely to disrupt the system. The
|
||||
* canonical example is THP allocation where a fallback is cheap but
|
||||
* reclaim/compaction may cause indirect stalls.
|
||||
*
|
||||
* %__GFP_RECLAIM is shorthand to allow/forbid both direct and kswapd reclaim.
|
||||
*
|
||||
* The default allocator behavior depends on the request size. We have a concept
|
||||
* of so called costly allocations (with order > %PAGE_ALLOC_COSTLY_ORDER).
|
||||
* !costly allocations are too essential to fail so they are implicitly
|
||||
* non-failing by default (with some exceptions like OOM victims might fail so
|
||||
* the caller still has to check for failures) while costly requests try to be
|
||||
* not disruptive and back off even without invoking the OOM killer.
|
||||
* The following three modifiers might be used to override some of these
|
||||
* implicit rules
|
||||
*
|
||||
* %__GFP_NORETRY: The VM implementation will try only very lightweight
|
||||
* memory direct reclaim to get some memory under memory pressure (thus
|
||||
* it can sleep). It will avoid disruptive actions like OOM killer. The
|
||||
* caller must handle the failure which is quite likely to happen under
|
||||
* heavy memory pressure. The flag is suitable when failure can easily be
|
||||
* handled at small cost, such as reduced throughput
|
||||
*
|
||||
* %__GFP_RETRY_MAYFAIL: The VM implementation will retry memory reclaim
|
||||
* procedures that have previously failed if there is some indication
|
||||
* that progress has been made else where. It can wait for other
|
||||
* tasks to attempt high level approaches to freeing memory such as
|
||||
* compaction (which removes fragmentation) and page-out.
|
||||
* There is still a definite limit to the number of retries, but it is
|
||||
* a larger limit than with %__GFP_NORETRY.
|
||||
* Allocations with this flag may fail, but only when there is
|
||||
* genuinely little unused memory. While these allocations do not
|
||||
* directly trigger the OOM killer, their failure indicates that
|
||||
* the system is likely to need to use the OOM killer soon. The
|
||||
* caller must handle failure, but can reasonably do so by failing
|
||||
* a higher-level request, or completing it only in a much less
|
||||
* efficient manner.
|
||||
* If the allocation does fail, and the caller is in a position to
|
||||
* free some non-essential memory, doing so could benefit the system
|
||||
* as a whole.
|
||||
*
|
||||
* %__GFP_NOFAIL: The VM implementation _must_ retry infinitely: the caller
|
||||
* cannot handle allocation failures. The allocation could block
|
||||
* indefinitely but will never return with failure. Testing for
|
||||
* failure is pointless.
|
||||
* New users should be evaluated carefully (and the flag should be
|
||||
* used only when there is no reasonable failure policy) but it is
|
||||
* definitely preferable to use the flag rather than opencode endless
|
||||
* loop around allocator.
|
||||
* Using this flag for costly allocations is _highly_ discouraged.
|
||||
*/
|
||||
#define __GFP_IO ((__force gfp_t)___GFP_IO)
|
||||
#define __GFP_FS ((__force gfp_t)___GFP_FS)
|
||||
#define __GFP_DIRECT_RECLAIM ((__force gfp_t)___GFP_DIRECT_RECLAIM) /* Caller can reclaim */
|
||||
#define __GFP_KSWAPD_RECLAIM ((__force gfp_t)___GFP_KSWAPD_RECLAIM) /* kswapd can wake */
|
||||
#define __GFP_RECLAIM ((__force gfp_t)(___GFP_DIRECT_RECLAIM|___GFP_KSWAPD_RECLAIM))
|
||||
#define __GFP_RETRY_MAYFAIL ((__force gfp_t)___GFP_RETRY_MAYFAIL)
|
||||
#define __GFP_NOFAIL ((__force gfp_t)___GFP_NOFAIL)
|
||||
#define __GFP_NORETRY ((__force gfp_t)___GFP_NORETRY)
|
||||
|
||||
/**
|
||||
* DOC: Action modifiers
|
||||
*
|
||||
* Action modifiers
|
||||
* ----------------
|
||||
*
|
||||
* %__GFP_NOWARN suppresses allocation failure reports.
|
||||
*
|
||||
* %__GFP_COMP address compound page metadata.
|
||||
*
|
||||
* %__GFP_ZERO returns a zeroed page on success.
|
||||
*
|
||||
* %__GFP_ZEROTAGS zeroes memory tags at allocation time if the memory itself
|
||||
* is being zeroed (either via __GFP_ZERO or via init_on_alloc, provided that
|
||||
* __GFP_SKIP_ZERO is not set). This flag is intended for optimization: setting
|
||||
* memory tags at the same time as zeroing memory has minimal additional
|
||||
* performace impact.
|
||||
*
|
||||
* %__GFP_SKIP_KASAN_UNPOISON makes KASAN skip unpoisoning on page allocation.
|
||||
* Only effective in HW_TAGS mode.
|
||||
*
|
||||
* %__GFP_SKIP_KASAN_POISON makes KASAN skip poisoning on page deallocation.
|
||||
* Typically, used for userspace pages. Only effective in HW_TAGS mode.
|
||||
*/
|
||||
#define __GFP_NOWARN ((__force gfp_t)___GFP_NOWARN)
|
||||
#define __GFP_COMP ((__force gfp_t)___GFP_COMP)
|
||||
#define __GFP_ZERO ((__force gfp_t)___GFP_ZERO)
|
||||
#define __GFP_ZEROTAGS ((__force gfp_t)___GFP_ZEROTAGS)
|
||||
#define __GFP_SKIP_ZERO ((__force gfp_t)___GFP_SKIP_ZERO)
|
||||
#define __GFP_SKIP_KASAN_UNPOISON ((__force gfp_t)___GFP_SKIP_KASAN_UNPOISON)
|
||||
#define __GFP_SKIP_KASAN_POISON ((__force gfp_t)___GFP_SKIP_KASAN_POISON)
|
||||
|
||||
/* Disable lockdep for GFP context tracking */
|
||||
#define __GFP_NOLOCKDEP ((__force gfp_t)___GFP_NOLOCKDEP)
|
||||
|
||||
/* Room for N __GFP_FOO bits */
|
||||
#define __GFP_BITS_SHIFT (27 + IS_ENABLED(CONFIG_LOCKDEP))
|
||||
#define __GFP_BITS_MASK ((__force gfp_t)((1 << __GFP_BITS_SHIFT) - 1))
|
||||
|
||||
/**
|
||||
* DOC: Useful GFP flag combinations
|
||||
*
|
||||
* Useful GFP flag combinations
|
||||
* ----------------------------
|
||||
*
|
||||
* Useful GFP flag combinations that are commonly used. It is recommended
|
||||
* that subsystems start with one of these combinations and then set/clear
|
||||
* %__GFP_FOO flags as necessary.
|
||||
*
|
||||
* %GFP_ATOMIC users can not sleep and need the allocation to succeed. A lower
|
||||
* watermark is applied to allow access to "atomic reserves".
|
||||
* The current implementation doesn't support NMI and few other strict
|
||||
* non-preemptive contexts (e.g. raw_spin_lock). The same applies to %GFP_NOWAIT.
|
||||
*
|
||||
* %GFP_KERNEL is typical for kernel-internal allocations. The caller requires
|
||||
* %ZONE_NORMAL or a lower zone for direct access but can direct reclaim.
|
||||
*
|
||||
* %GFP_KERNEL_ACCOUNT is the same as GFP_KERNEL, except the allocation is
|
||||
* accounted to kmemcg.
|
||||
*
|
||||
* %GFP_NOWAIT is for kernel allocations that should not stall for direct
|
||||
* reclaim, start physical IO or use any filesystem callback.
|
||||
*
|
||||
* %GFP_NOIO will use direct reclaim to discard clean pages or slab pages
|
||||
* that do not require the starting of any physical IO.
|
||||
* Please try to avoid using this flag directly and instead use
|
||||
* memalloc_noio_{save,restore} to mark the whole scope which cannot
|
||||
* perform any IO with a short explanation why. All allocation requests
|
||||
* will inherit GFP_NOIO implicitly.
|
||||
*
|
||||
* %GFP_NOFS will use direct reclaim but will not use any filesystem interfaces.
|
||||
* Please try to avoid using this flag directly and instead use
|
||||
* memalloc_nofs_{save,restore} to mark the whole scope which cannot/shouldn't
|
||||
* recurse into the FS layer with a short explanation why. All allocation
|
||||
* requests will inherit GFP_NOFS implicitly.
|
||||
*
|
||||
* %GFP_USER is for userspace allocations that also need to be directly
|
||||
* accessibly by the kernel or hardware. It is typically used by hardware
|
||||
* for buffers that are mapped to userspace (e.g. graphics) that hardware
|
||||
* still must DMA to. cpuset limits are enforced for these allocations.
|
||||
*
|
||||
* %GFP_DMA exists for historical reasons and should be avoided where possible.
|
||||
* The flags indicates that the caller requires that the lowest zone be
|
||||
* used (%ZONE_DMA or 16M on x86-64). Ideally, this would be removed but
|
||||
* it would require careful auditing as some users really require it and
|
||||
* others use the flag to avoid lowmem reserves in %ZONE_DMA and treat the
|
||||
* lowest zone as a type of emergency reserve.
|
||||
*
|
||||
* %GFP_DMA32 is similar to %GFP_DMA except that the caller requires a 32-bit
|
||||
* address. Note that kmalloc(..., GFP_DMA32) does not return DMA32 memory
|
||||
* because the DMA32 kmalloc cache array is not implemented.
|
||||
* (Reason: there is no such user in kernel).
|
||||
*
|
||||
* %GFP_HIGHUSER is for userspace allocations that may be mapped to userspace,
|
||||
* do not need to be directly accessible by the kernel but that cannot
|
||||
* move once in use. An example may be a hardware allocation that maps
|
||||
* data directly into userspace but has no addressing limitations.
|
||||
*
|
||||
* %GFP_HIGHUSER_MOVABLE is for userspace allocations that the kernel does not
|
||||
* need direct access to but can use kmap() when access is required. They
|
||||
* are expected to be movable via page reclaim or page migration. Typically,
|
||||
* pages on the LRU would also be allocated with %GFP_HIGHUSER_MOVABLE.
|
||||
*
|
||||
* %GFP_TRANSHUGE and %GFP_TRANSHUGE_LIGHT are used for THP allocations. They
|
||||
* are compound allocations that will generally fail quickly if memory is not
|
||||
* available and will not wake kswapd/kcompactd on failure. The _LIGHT
|
||||
* version does not attempt reclaim/compaction at all and is by default used
|
||||
* in page fault path, while the non-light is used by khugepaged.
|
||||
*/
|
||||
#define GFP_ATOMIC (__GFP_HIGH|__GFP_ATOMIC|__GFP_KSWAPD_RECLAIM)
|
||||
#define GFP_KERNEL (__GFP_RECLAIM | __GFP_IO | __GFP_FS)
|
||||
#define GFP_KERNEL_ACCOUNT (GFP_KERNEL | __GFP_ACCOUNT)
|
||||
#define GFP_NOWAIT (__GFP_KSWAPD_RECLAIM)
|
||||
#define GFP_NOIO (__GFP_RECLAIM)
|
||||
#define GFP_NOFS (__GFP_RECLAIM | __GFP_IO)
|
||||
#define GFP_USER (__GFP_RECLAIM | __GFP_IO | __GFP_FS | __GFP_HARDWALL)
|
||||
#define GFP_DMA __GFP_DMA
|
||||
#define GFP_DMA32 __GFP_DMA32
|
||||
#define GFP_HIGHUSER (GFP_USER | __GFP_HIGHMEM)
|
||||
#define GFP_HIGHUSER_MOVABLE (GFP_HIGHUSER | __GFP_MOVABLE | \
|
||||
__GFP_SKIP_KASAN_POISON | __GFP_SKIP_KASAN_UNPOISON)
|
||||
#define GFP_TRANSHUGE_LIGHT ((GFP_HIGHUSER_MOVABLE | __GFP_COMP | \
|
||||
__GFP_NOMEMALLOC | __GFP_NOWARN) & ~__GFP_RECLAIM)
|
||||
#define GFP_TRANSHUGE (GFP_TRANSHUGE_LIGHT | __GFP_DIRECT_RECLAIM)
|
||||
|
||||
/* Convert GFP flags to their corresponding migrate type */
|
||||
#define GFP_MOVABLE_MASK (__GFP_RECLAIMABLE|__GFP_MOVABLE)
|
||||
#define GFP_MOVABLE_SHIFT 3
|
||||
|
|
|
|||
348
include/linux/gfp_types.h
Normal file
348
include/linux/gfp_types.h
Normal file
|
|
@ -0,0 +1,348 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __LINUX_GFP_TYPES_H
|
||||
#define __LINUX_GFP_TYPES_H
|
||||
|
||||
/* The typedef is in types.h but we want the documentation here */
|
||||
#if 0
|
||||
/**
|
||||
* typedef gfp_t - Memory allocation flags.
|
||||
*
|
||||
* GFP flags are commonly used throughout Linux to indicate how memory
|
||||
* should be allocated. The GFP acronym stands for get_free_pages(),
|
||||
* the underlying memory allocation function. Not every GFP flag is
|
||||
* supported by every function which may allocate memory. Most users
|
||||
* will want to use a plain ``GFP_KERNEL``.
|
||||
*/
|
||||
typedef unsigned int __bitwise gfp_t;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* In case of changes, please don't forget to update
|
||||
* include/trace/events/mmflags.h and tools/perf/builtin-kmem.c
|
||||
*/
|
||||
|
||||
/* Plain integer GFP bitmasks. Do not use this directly. */
|
||||
#define ___GFP_DMA 0x01u
|
||||
#define ___GFP_HIGHMEM 0x02u
|
||||
#define ___GFP_DMA32 0x04u
|
||||
#define ___GFP_MOVABLE 0x08u
|
||||
#define ___GFP_RECLAIMABLE 0x10u
|
||||
#define ___GFP_HIGH 0x20u
|
||||
#define ___GFP_IO 0x40u
|
||||
#define ___GFP_FS 0x80u
|
||||
#define ___GFP_ZERO 0x100u
|
||||
#define ___GFP_ATOMIC 0x200u
|
||||
#define ___GFP_DIRECT_RECLAIM 0x400u
|
||||
#define ___GFP_KSWAPD_RECLAIM 0x800u
|
||||
#define ___GFP_WRITE 0x1000u
|
||||
#define ___GFP_NOWARN 0x2000u
|
||||
#define ___GFP_RETRY_MAYFAIL 0x4000u
|
||||
#define ___GFP_NOFAIL 0x8000u
|
||||
#define ___GFP_NORETRY 0x10000u
|
||||
#define ___GFP_MEMALLOC 0x20000u
|
||||
#define ___GFP_COMP 0x40000u
|
||||
#define ___GFP_NOMEMALLOC 0x80000u
|
||||
#define ___GFP_HARDWALL 0x100000u
|
||||
#define ___GFP_THISNODE 0x200000u
|
||||
#define ___GFP_ACCOUNT 0x400000u
|
||||
#define ___GFP_ZEROTAGS 0x800000u
|
||||
#ifdef CONFIG_KASAN_HW_TAGS
|
||||
#define ___GFP_SKIP_ZERO 0x1000000u
|
||||
#define ___GFP_SKIP_KASAN_UNPOISON 0x2000000u
|
||||
#define ___GFP_SKIP_KASAN_POISON 0x4000000u
|
||||
#else
|
||||
#define ___GFP_SKIP_ZERO 0
|
||||
#define ___GFP_SKIP_KASAN_UNPOISON 0
|
||||
#define ___GFP_SKIP_KASAN_POISON 0
|
||||
#endif
|
||||
#ifdef CONFIG_LOCKDEP
|
||||
#define ___GFP_NOLOCKDEP 0x8000000u
|
||||
#else
|
||||
#define ___GFP_NOLOCKDEP 0
|
||||
#endif
|
||||
/* If the above are modified, __GFP_BITS_SHIFT may need updating */
|
||||
|
||||
/*
|
||||
* Physical address zone modifiers (see linux/mmzone.h - low four bits)
|
||||
*
|
||||
* Do not put any conditional on these. If necessary modify the definitions
|
||||
* without the underscores and use them consistently. The definitions here may
|
||||
* be used in bit comparisons.
|
||||
*/
|
||||
#define __GFP_DMA ((__force gfp_t)___GFP_DMA)
|
||||
#define __GFP_HIGHMEM ((__force gfp_t)___GFP_HIGHMEM)
|
||||
#define __GFP_DMA32 ((__force gfp_t)___GFP_DMA32)
|
||||
#define __GFP_MOVABLE ((__force gfp_t)___GFP_MOVABLE) /* ZONE_MOVABLE allowed */
|
||||
#define GFP_ZONEMASK (__GFP_DMA|__GFP_HIGHMEM|__GFP_DMA32|__GFP_MOVABLE)
|
||||
|
||||
/**
|
||||
* DOC: Page mobility and placement hints
|
||||
*
|
||||
* Page mobility and placement hints
|
||||
* ---------------------------------
|
||||
*
|
||||
* These flags provide hints about how mobile the page is. Pages with similar
|
||||
* mobility are placed within the same pageblocks to minimise problems due
|
||||
* to external fragmentation.
|
||||
*
|
||||
* %__GFP_MOVABLE (also a zone modifier) indicates that the page can be
|
||||
* moved by page migration during memory compaction or can be reclaimed.
|
||||
*
|
||||
* %__GFP_RECLAIMABLE is used for slab allocations that specify
|
||||
* SLAB_RECLAIM_ACCOUNT and whose pages can be freed via shrinkers.
|
||||
*
|
||||
* %__GFP_WRITE indicates the caller intends to dirty the page. Where possible,
|
||||
* these pages will be spread between local zones to avoid all the dirty
|
||||
* pages being in one zone (fair zone allocation policy).
|
||||
*
|
||||
* %__GFP_HARDWALL enforces the cpuset memory allocation policy.
|
||||
*
|
||||
* %__GFP_THISNODE forces the allocation to be satisfied from the requested
|
||||
* node with no fallbacks or placement policy enforcements.
|
||||
*
|
||||
* %__GFP_ACCOUNT causes the allocation to be accounted to kmemcg.
|
||||
*/
|
||||
#define __GFP_RECLAIMABLE ((__force gfp_t)___GFP_RECLAIMABLE)
|
||||
#define __GFP_WRITE ((__force gfp_t)___GFP_WRITE)
|
||||
#define __GFP_HARDWALL ((__force gfp_t)___GFP_HARDWALL)
|
||||
#define __GFP_THISNODE ((__force gfp_t)___GFP_THISNODE)
|
||||
#define __GFP_ACCOUNT ((__force gfp_t)___GFP_ACCOUNT)
|
||||
|
||||
/**
|
||||
* DOC: Watermark modifiers
|
||||
*
|
||||
* Watermark modifiers -- controls access to emergency reserves
|
||||
* ------------------------------------------------------------
|
||||
*
|
||||
* %__GFP_HIGH indicates that the caller is high-priority and that granting
|
||||
* the request is necessary before the system can make forward progress.
|
||||
* For example, creating an IO context to clean pages.
|
||||
*
|
||||
* %__GFP_ATOMIC indicates that the caller cannot reclaim or sleep and is
|
||||
* high priority. Users are typically interrupt handlers. This may be
|
||||
* used in conjunction with %__GFP_HIGH
|
||||
*
|
||||
* %__GFP_MEMALLOC allows access to all memory. This should only be used when
|
||||
* the caller guarantees the allocation will allow more memory to be freed
|
||||
* very shortly e.g. process exiting or swapping. Users either should
|
||||
* be the MM or co-ordinating closely with the VM (e.g. swap over NFS).
|
||||
* Users of this flag have to be extremely careful to not deplete the reserve
|
||||
* completely and implement a throttling mechanism which controls the
|
||||
* consumption of the reserve based on the amount of freed memory.
|
||||
* Usage of a pre-allocated pool (e.g. mempool) should be always considered
|
||||
* before using this flag.
|
||||
*
|
||||
* %__GFP_NOMEMALLOC is used to explicitly forbid access to emergency reserves.
|
||||
* This takes precedence over the %__GFP_MEMALLOC flag if both are set.
|
||||
*/
|
||||
#define __GFP_ATOMIC ((__force gfp_t)___GFP_ATOMIC)
|
||||
#define __GFP_HIGH ((__force gfp_t)___GFP_HIGH)
|
||||
#define __GFP_MEMALLOC ((__force gfp_t)___GFP_MEMALLOC)
|
||||
#define __GFP_NOMEMALLOC ((__force gfp_t)___GFP_NOMEMALLOC)
|
||||
|
||||
/**
|
||||
* DOC: Reclaim modifiers
|
||||
*
|
||||
* Reclaim modifiers
|
||||
* -----------------
|
||||
* Please note that all the following flags are only applicable to sleepable
|
||||
* allocations (e.g. %GFP_NOWAIT and %GFP_ATOMIC will ignore them).
|
||||
*
|
||||
* %__GFP_IO can start physical IO.
|
||||
*
|
||||
* %__GFP_FS can call down to the low-level FS. Clearing the flag avoids the
|
||||
* allocator recursing into the filesystem which might already be holding
|
||||
* locks.
|
||||
*
|
||||
* %__GFP_DIRECT_RECLAIM indicates that the caller may enter direct reclaim.
|
||||
* This flag can be cleared to avoid unnecessary delays when a fallback
|
||||
* option is available.
|
||||
*
|
||||
* %__GFP_KSWAPD_RECLAIM indicates that the caller wants to wake kswapd when
|
||||
* the low watermark is reached and have it reclaim pages until the high
|
||||
* watermark is reached. A caller may wish to clear this flag when fallback
|
||||
* options are available and the reclaim is likely to disrupt the system. The
|
||||
* canonical example is THP allocation where a fallback is cheap but
|
||||
* reclaim/compaction may cause indirect stalls.
|
||||
*
|
||||
* %__GFP_RECLAIM is shorthand to allow/forbid both direct and kswapd reclaim.
|
||||
*
|
||||
* The default allocator behavior depends on the request size. We have a concept
|
||||
* of so called costly allocations (with order > %PAGE_ALLOC_COSTLY_ORDER).
|
||||
* !costly allocations are too essential to fail so they are implicitly
|
||||
* non-failing by default (with some exceptions like OOM victims might fail so
|
||||
* the caller still has to check for failures) while costly requests try to be
|
||||
* not disruptive and back off even without invoking the OOM killer.
|
||||
* The following three modifiers might be used to override some of these
|
||||
* implicit rules
|
||||
*
|
||||
* %__GFP_NORETRY: The VM implementation will try only very lightweight
|
||||
* memory direct reclaim to get some memory under memory pressure (thus
|
||||
* it can sleep). It will avoid disruptive actions like OOM killer. The
|
||||
* caller must handle the failure which is quite likely to happen under
|
||||
* heavy memory pressure. The flag is suitable when failure can easily be
|
||||
* handled at small cost, such as reduced throughput
|
||||
*
|
||||
* %__GFP_RETRY_MAYFAIL: The VM implementation will retry memory reclaim
|
||||
* procedures that have previously failed if there is some indication
|
||||
* that progress has been made else where. It can wait for other
|
||||
* tasks to attempt high level approaches to freeing memory such as
|
||||
* compaction (which removes fragmentation) and page-out.
|
||||
* There is still a definite limit to the number of retries, but it is
|
||||
* a larger limit than with %__GFP_NORETRY.
|
||||
* Allocations with this flag may fail, but only when there is
|
||||
* genuinely little unused memory. While these allocations do not
|
||||
* directly trigger the OOM killer, their failure indicates that
|
||||
* the system is likely to need to use the OOM killer soon. The
|
||||
* caller must handle failure, but can reasonably do so by failing
|
||||
* a higher-level request, or completing it only in a much less
|
||||
* efficient manner.
|
||||
* If the allocation does fail, and the caller is in a position to
|
||||
* free some non-essential memory, doing so could benefit the system
|
||||
* as a whole.
|
||||
*
|
||||
* %__GFP_NOFAIL: The VM implementation _must_ retry infinitely: the caller
|
||||
* cannot handle allocation failures. The allocation could block
|
||||
* indefinitely but will never return with failure. Testing for
|
||||
* failure is pointless.
|
||||
* New users should be evaluated carefully (and the flag should be
|
||||
* used only when there is no reasonable failure policy) but it is
|
||||
* definitely preferable to use the flag rather than opencode endless
|
||||
* loop around allocator.
|
||||
* Using this flag for costly allocations is _highly_ discouraged.
|
||||
*/
|
||||
#define __GFP_IO ((__force gfp_t)___GFP_IO)
|
||||
#define __GFP_FS ((__force gfp_t)___GFP_FS)
|
||||
#define __GFP_DIRECT_RECLAIM ((__force gfp_t)___GFP_DIRECT_RECLAIM) /* Caller can reclaim */
|
||||
#define __GFP_KSWAPD_RECLAIM ((__force gfp_t)___GFP_KSWAPD_RECLAIM) /* kswapd can wake */
|
||||
#define __GFP_RECLAIM ((__force gfp_t)(___GFP_DIRECT_RECLAIM|___GFP_KSWAPD_RECLAIM))
|
||||
#define __GFP_RETRY_MAYFAIL ((__force gfp_t)___GFP_RETRY_MAYFAIL)
|
||||
#define __GFP_NOFAIL ((__force gfp_t)___GFP_NOFAIL)
|
||||
#define __GFP_NORETRY ((__force gfp_t)___GFP_NORETRY)
|
||||
|
||||
/**
|
||||
* DOC: Action modifiers
|
||||
*
|
||||
* Action modifiers
|
||||
* ----------------
|
||||
*
|
||||
* %__GFP_NOWARN suppresses allocation failure reports.
|
||||
*
|
||||
* %__GFP_COMP address compound page metadata.
|
||||
*
|
||||
* %__GFP_ZERO returns a zeroed page on success.
|
||||
*
|
||||
* %__GFP_ZEROTAGS zeroes memory tags at allocation time if the memory itself
|
||||
* is being zeroed (either via __GFP_ZERO or via init_on_alloc, provided that
|
||||
* __GFP_SKIP_ZERO is not set). This flag is intended for optimization: setting
|
||||
* memory tags at the same time as zeroing memory has minimal additional
|
||||
* performace impact.
|
||||
*
|
||||
* %__GFP_SKIP_KASAN_UNPOISON makes KASAN skip unpoisoning on page allocation.
|
||||
* Only effective in HW_TAGS mode.
|
||||
*
|
||||
* %__GFP_SKIP_KASAN_POISON makes KASAN skip poisoning on page deallocation.
|
||||
* Typically, used for userspace pages. Only effective in HW_TAGS mode.
|
||||
*/
|
||||
#define __GFP_NOWARN ((__force gfp_t)___GFP_NOWARN)
|
||||
#define __GFP_COMP ((__force gfp_t)___GFP_COMP)
|
||||
#define __GFP_ZERO ((__force gfp_t)___GFP_ZERO)
|
||||
#define __GFP_ZEROTAGS ((__force gfp_t)___GFP_ZEROTAGS)
|
||||
#define __GFP_SKIP_ZERO ((__force gfp_t)___GFP_SKIP_ZERO)
|
||||
#define __GFP_SKIP_KASAN_UNPOISON ((__force gfp_t)___GFP_SKIP_KASAN_UNPOISON)
|
||||
#define __GFP_SKIP_KASAN_POISON ((__force gfp_t)___GFP_SKIP_KASAN_POISON)
|
||||
|
||||
/* Disable lockdep for GFP context tracking */
|
||||
#define __GFP_NOLOCKDEP ((__force gfp_t)___GFP_NOLOCKDEP)
|
||||
|
||||
/* Room for N __GFP_FOO bits */
|
||||
#define __GFP_BITS_SHIFT (27 + IS_ENABLED(CONFIG_LOCKDEP))
|
||||
#define __GFP_BITS_MASK ((__force gfp_t)((1 << __GFP_BITS_SHIFT) - 1))
|
||||
|
||||
/**
|
||||
* DOC: Useful GFP flag combinations
|
||||
*
|
||||
* Useful GFP flag combinations
|
||||
* ----------------------------
|
||||
*
|
||||
* Useful GFP flag combinations that are commonly used. It is recommended
|
||||
* that subsystems start with one of these combinations and then set/clear
|
||||
* %__GFP_FOO flags as necessary.
|
||||
*
|
||||
* %GFP_ATOMIC users can not sleep and need the allocation to succeed. A lower
|
||||
* watermark is applied to allow access to "atomic reserves".
|
||||
* The current implementation doesn't support NMI and few other strict
|
||||
* non-preemptive contexts (e.g. raw_spin_lock). The same applies to %GFP_NOWAIT.
|
||||
*
|
||||
* %GFP_KERNEL is typical for kernel-internal allocations. The caller requires
|
||||
* %ZONE_NORMAL or a lower zone for direct access but can direct reclaim.
|
||||
*
|
||||
* %GFP_KERNEL_ACCOUNT is the same as GFP_KERNEL, except the allocation is
|
||||
* accounted to kmemcg.
|
||||
*
|
||||
* %GFP_NOWAIT is for kernel allocations that should not stall for direct
|
||||
* reclaim, start physical IO or use any filesystem callback.
|
||||
*
|
||||
* %GFP_NOIO will use direct reclaim to discard clean pages or slab pages
|
||||
* that do not require the starting of any physical IO.
|
||||
* Please try to avoid using this flag directly and instead use
|
||||
* memalloc_noio_{save,restore} to mark the whole scope which cannot
|
||||
* perform any IO with a short explanation why. All allocation requests
|
||||
* will inherit GFP_NOIO implicitly.
|
||||
*
|
||||
* %GFP_NOFS will use direct reclaim but will not use any filesystem interfaces.
|
||||
* Please try to avoid using this flag directly and instead use
|
||||
* memalloc_nofs_{save,restore} to mark the whole scope which cannot/shouldn't
|
||||
* recurse into the FS layer with a short explanation why. All allocation
|
||||
* requests will inherit GFP_NOFS implicitly.
|
||||
*
|
||||
* %GFP_USER is for userspace allocations that also need to be directly
|
||||
* accessibly by the kernel or hardware. It is typically used by hardware
|
||||
* for buffers that are mapped to userspace (e.g. graphics) that hardware
|
||||
* still must DMA to. cpuset limits are enforced for these allocations.
|
||||
*
|
||||
* %GFP_DMA exists for historical reasons and should be avoided where possible.
|
||||
* The flags indicates that the caller requires that the lowest zone be
|
||||
* used (%ZONE_DMA or 16M on x86-64). Ideally, this would be removed but
|
||||
* it would require careful auditing as some users really require it and
|
||||
* others use the flag to avoid lowmem reserves in %ZONE_DMA and treat the
|
||||
* lowest zone as a type of emergency reserve.
|
||||
*
|
||||
* %GFP_DMA32 is similar to %GFP_DMA except that the caller requires a 32-bit
|
||||
* address. Note that kmalloc(..., GFP_DMA32) does not return DMA32 memory
|
||||
* because the DMA32 kmalloc cache array is not implemented.
|
||||
* (Reason: there is no such user in kernel).
|
||||
*
|
||||
* %GFP_HIGHUSER is for userspace allocations that may be mapped to userspace,
|
||||
* do not need to be directly accessible by the kernel but that cannot
|
||||
* move once in use. An example may be a hardware allocation that maps
|
||||
* data directly into userspace but has no addressing limitations.
|
||||
*
|
||||
* %GFP_HIGHUSER_MOVABLE is for userspace allocations that the kernel does not
|
||||
* need direct access to but can use kmap() when access is required. They
|
||||
* are expected to be movable via page reclaim or page migration. Typically,
|
||||
* pages on the LRU would also be allocated with %GFP_HIGHUSER_MOVABLE.
|
||||
*
|
||||
* %GFP_TRANSHUGE and %GFP_TRANSHUGE_LIGHT are used for THP allocations. They
|
||||
* are compound allocations that will generally fail quickly if memory is not
|
||||
* available and will not wake kswapd/kcompactd on failure. The _LIGHT
|
||||
* version does not attempt reclaim/compaction at all and is by default used
|
||||
* in page fault path, while the non-light is used by khugepaged.
|
||||
*/
|
||||
#define GFP_ATOMIC (__GFP_HIGH|__GFP_ATOMIC|__GFP_KSWAPD_RECLAIM)
|
||||
#define GFP_KERNEL (__GFP_RECLAIM | __GFP_IO | __GFP_FS)
|
||||
#define GFP_KERNEL_ACCOUNT (GFP_KERNEL | __GFP_ACCOUNT)
|
||||
#define GFP_NOWAIT (__GFP_KSWAPD_RECLAIM)
|
||||
#define GFP_NOIO (__GFP_RECLAIM)
|
||||
#define GFP_NOFS (__GFP_RECLAIM | __GFP_IO)
|
||||
#define GFP_USER (__GFP_RECLAIM | __GFP_IO | __GFP_FS | __GFP_HARDWALL)
|
||||
#define GFP_DMA __GFP_DMA
|
||||
#define GFP_DMA32 __GFP_DMA32
|
||||
#define GFP_HIGHUSER (GFP_USER | __GFP_HIGHMEM)
|
||||
#define GFP_HIGHUSER_MOVABLE (GFP_HIGHUSER | __GFP_MOVABLE | \
|
||||
__GFP_SKIP_KASAN_POISON | __GFP_SKIP_KASAN_UNPOISON)
|
||||
#define GFP_TRANSHUGE_LIGHT ((GFP_HIGHUSER_MOVABLE | __GFP_COMP | \
|
||||
__GFP_NOMEMALLOC | __GFP_NOWARN) & ~__GFP_RECLAIM)
|
||||
#define GFP_TRANSHUGE (GFP_TRANSHUGE_LIGHT | __GFP_DIRECT_RECLAIM)
|
||||
|
||||
#endif /* __LINUX_GFP_TYPES_H */
|
||||
|
|
@ -94,6 +94,7 @@
|
|||
#include <linux/bitmap.h>
|
||||
#include <linux/minmax.h>
|
||||
#include <linux/numa.h>
|
||||
#include <linux/random.h>
|
||||
|
||||
typedef struct { DECLARE_BITMAP(bits, MAX_NUMNODES); } nodemask_t;
|
||||
extern nodemask_t _unused_nodemask_arg_;
|
||||
|
|
@ -276,7 +277,14 @@ static inline unsigned int __next_node(int n, const nodemask_t *srcp)
|
|||
* the first node in src if needed. Returns MAX_NUMNODES if src is empty.
|
||||
*/
|
||||
#define next_node_in(n, src) __next_node_in((n), &(src))
|
||||
unsigned int __next_node_in(int node, const nodemask_t *srcp);
|
||||
static inline unsigned int __next_node_in(int node, const nodemask_t *srcp)
|
||||
{
|
||||
unsigned int ret = __next_node(node, srcp);
|
||||
|
||||
if (ret == MAX_NUMNODES)
|
||||
ret = __first_node(srcp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline void init_nodemask_of_node(nodemask_t *mask, int node)
|
||||
{
|
||||
|
|
@ -493,14 +501,20 @@ static inline int num_node_state(enum node_states state)
|
|||
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_NUMA) && (MAX_NUMNODES > 1)
|
||||
extern int node_random(const nodemask_t *maskp);
|
||||
#else
|
||||
static inline int node_random(const nodemask_t *mask)
|
||||
static inline int node_random(const nodemask_t *maskp)
|
||||
{
|
||||
#if defined(CONFIG_NUMA) && (MAX_NUMNODES > 1)
|
||||
int w, bit = NUMA_NO_NODE;
|
||||
|
||||
w = nodes_weight(*maskp);
|
||||
if (w)
|
||||
bit = bitmap_ord_to_pos(maskp->bits,
|
||||
get_random_int() % w, MAX_NUMNODES);
|
||||
return bit;
|
||||
#else
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#define node_online_map node_states[N_ONLINE]
|
||||
#define node_possible_map node_states[N_POSSIBLE]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue