Merge branch 'akpm' (patches from Andrew)
Merge second patch-bomb from Andrew Morton: - a couple of hotfixes - the rest of MM - a new timer slack control in procfs - a couple of procfs fixes - a few misc things - some printk tweaks - lib/ updates, notably to radix-tree. - add my and Nick Piggin's old userspace radix-tree test harness to tools/testing/radix-tree/. Matthew said it was a godsend during the radix-tree work he did. - a few code-size improvements, switching to __always_inline where gcc screwed up. - partially implement character sets in sscanf * emailed patches from Andrew Morton <akpm@linux-foundation.org>: (118 commits) sscanf: implement basic character sets lib/bug.c: use common WARN helper param: convert some "on"/"off" users to strtobool lib: add "on"/"off" support to kstrtobool lib: update single-char callers of strtobool() lib: move strtobool() to kstrtobool() include/linux/unaligned: force inlining of byteswap operations include/uapi/linux/byteorder, swab: force inlining of some byteswap operations include/asm-generic/atomic-long.h: force inlining of some atomic_long operations usb: common: convert to use match_string() helper ide: hpt366: convert to use match_string() helper ata: hpt366: convert to use match_string() helper power: ab8500: convert to use match_string() helper power: charger_manager: convert to use match_string() helper drm/edid: convert to use match_string() helper pinctrl: convert to use match_string() helper device property: convert to use match_string() helper lib/string: introduce match_string() helper radix-tree tests: add test for radix_tree_iter_next radix-tree tests: add regression3 test ...
This commit is contained in:
commit
814a2bf957
225 changed files with 5048 additions and 1915 deletions
|
|
@ -82,15 +82,15 @@ struct buffer_head {
|
|||
* and buffer_foo() functions.
|
||||
*/
|
||||
#define BUFFER_FNS(bit, name) \
|
||||
static inline void set_buffer_##name(struct buffer_head *bh) \
|
||||
static __always_inline void set_buffer_##name(struct buffer_head *bh) \
|
||||
{ \
|
||||
set_bit(BH_##bit, &(bh)->b_state); \
|
||||
} \
|
||||
static inline void clear_buffer_##name(struct buffer_head *bh) \
|
||||
static __always_inline void clear_buffer_##name(struct buffer_head *bh) \
|
||||
{ \
|
||||
clear_bit(BH_##bit, &(bh)->b_state); \
|
||||
} \
|
||||
static inline int buffer_##name(const struct buffer_head *bh) \
|
||||
static __always_inline int buffer_##name(const struct buffer_head *bh) \
|
||||
{ \
|
||||
return test_bit(BH_##bit, &(bh)->b_state); \
|
||||
}
|
||||
|
|
@ -99,11 +99,11 @@ static inline int buffer_##name(const struct buffer_head *bh) \
|
|||
* test_set_buffer_foo() and test_clear_buffer_foo()
|
||||
*/
|
||||
#define TAS_BUFFER_FNS(bit, name) \
|
||||
static inline int test_set_buffer_##name(struct buffer_head *bh) \
|
||||
static __always_inline int test_set_buffer_##name(struct buffer_head *bh) \
|
||||
{ \
|
||||
return test_and_set_bit(BH_##bit, &(bh)->b_state); \
|
||||
} \
|
||||
static inline int test_clear_buffer_##name(struct buffer_head *bh) \
|
||||
static __always_inline int test_clear_buffer_##name(struct buffer_head *bh) \
|
||||
{ \
|
||||
return test_and_clear_bit(BH_##bit, &(bh)->b_state); \
|
||||
} \
|
||||
|
|
|
|||
|
|
@ -52,6 +52,10 @@ extern void compaction_defer_reset(struct zone *zone, int order,
|
|||
bool alloc_success);
|
||||
extern bool compaction_restarting(struct zone *zone, int order);
|
||||
|
||||
extern int kcompactd_run(int nid);
|
||||
extern void kcompactd_stop(int nid);
|
||||
extern void wakeup_kcompactd(pg_data_t *pgdat, int order, int classzone_idx);
|
||||
|
||||
#else
|
||||
static inline unsigned long try_to_compact_pages(gfp_t gfp_mask,
|
||||
unsigned int order, int alloc_flags,
|
||||
|
|
@ -84,6 +88,18 @@ static inline bool compaction_deferred(struct zone *zone, int order)
|
|||
return true;
|
||||
}
|
||||
|
||||
static inline int kcompactd_run(int nid)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline void kcompactd_stop(int nid)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void wakeup_kcompactd(pg_data_t *pgdat, int order, int classzone_idx)
|
||||
{
|
||||
}
|
||||
|
||||
#endif /* CONFIG_COMPACTION */
|
||||
|
||||
#if defined(CONFIG_COMPACTION) && defined(CONFIG_SYSFS) && defined(CONFIG_NUMA)
|
||||
|
|
|
|||
|
|
@ -231,7 +231,7 @@ static inline long freezable_schedule_timeout_killable_unsafe(long timeout)
|
|||
* call this with locks held.
|
||||
*/
|
||||
static inline int freezable_schedule_hrtimeout_range(ktime_t *expires,
|
||||
unsigned long delta, const enum hrtimer_mode mode)
|
||||
u64 delta, const enum hrtimer_mode mode)
|
||||
{
|
||||
int __retval;
|
||||
freezer_do_not_count();
|
||||
|
|
|
|||
|
|
@ -105,8 +105,6 @@ struct vm_area_struct;
|
|||
*
|
||||
* __GFP_NOMEMALLOC is used to explicitly forbid access to emergency reserves.
|
||||
* This takes precedence over the __GFP_MEMALLOC flag if both are set.
|
||||
*
|
||||
* __GFP_NOACCOUNT ignores the accounting for kmemcg limit enforcement.
|
||||
*/
|
||||
#define __GFP_ATOMIC ((__force gfp_t)___GFP_ATOMIC)
|
||||
#define __GFP_HIGH ((__force gfp_t)___GFP_HIGH)
|
||||
|
|
@ -259,7 +257,7 @@ struct vm_area_struct;
|
|||
#define GFP_HIGHUSER_MOVABLE (GFP_HIGHUSER | __GFP_MOVABLE)
|
||||
#define GFP_TRANSHUGE ((GFP_HIGHUSER_MOVABLE | __GFP_COMP | \
|
||||
__GFP_NOMEMALLOC | __GFP_NORETRY | __GFP_NOWARN) & \
|
||||
~__GFP_KSWAPD_RECLAIM)
|
||||
~__GFP_RECLAIM)
|
||||
|
||||
/* Convert GFP flags to their corresponding migrate type */
|
||||
#define GFP_MOVABLE_MASK (__GFP_RECLAIMABLE|__GFP_MOVABLE)
|
||||
|
|
@ -333,22 +331,29 @@ static inline bool gfpflags_allow_blocking(const gfp_t gfp_flags)
|
|||
* 0xe => BAD (MOVABLE+DMA32+HIGHMEM)
|
||||
* 0xf => BAD (MOVABLE+DMA32+HIGHMEM+DMA)
|
||||
*
|
||||
* ZONES_SHIFT must be <= 2 on 32 bit platforms.
|
||||
* GFP_ZONES_SHIFT must be <= 2 on 32 bit platforms.
|
||||
*/
|
||||
|
||||
#if 16 * ZONES_SHIFT > BITS_PER_LONG
|
||||
#error ZONES_SHIFT too large to create GFP_ZONE_TABLE integer
|
||||
#if defined(CONFIG_ZONE_DEVICE) && (MAX_NR_ZONES-1) <= 4
|
||||
/* ZONE_DEVICE is not a valid GFP zone specifier */
|
||||
#define GFP_ZONES_SHIFT 2
|
||||
#else
|
||||
#define GFP_ZONES_SHIFT ZONES_SHIFT
|
||||
#endif
|
||||
|
||||
#if 16 * GFP_ZONES_SHIFT > BITS_PER_LONG
|
||||
#error GFP_ZONES_SHIFT too large to create GFP_ZONE_TABLE integer
|
||||
#endif
|
||||
|
||||
#define GFP_ZONE_TABLE ( \
|
||||
(ZONE_NORMAL << 0 * ZONES_SHIFT) \
|
||||
| (OPT_ZONE_DMA << ___GFP_DMA * ZONES_SHIFT) \
|
||||
| (OPT_ZONE_HIGHMEM << ___GFP_HIGHMEM * ZONES_SHIFT) \
|
||||
| (OPT_ZONE_DMA32 << ___GFP_DMA32 * ZONES_SHIFT) \
|
||||
| (ZONE_NORMAL << ___GFP_MOVABLE * ZONES_SHIFT) \
|
||||
| (OPT_ZONE_DMA << (___GFP_MOVABLE | ___GFP_DMA) * ZONES_SHIFT) \
|
||||
| (ZONE_MOVABLE << (___GFP_MOVABLE | ___GFP_HIGHMEM) * ZONES_SHIFT) \
|
||||
| (OPT_ZONE_DMA32 << (___GFP_MOVABLE | ___GFP_DMA32) * ZONES_SHIFT) \
|
||||
(ZONE_NORMAL << 0 * GFP_ZONES_SHIFT) \
|
||||
| (OPT_ZONE_DMA << ___GFP_DMA * GFP_ZONES_SHIFT) \
|
||||
| (OPT_ZONE_HIGHMEM << ___GFP_HIGHMEM * GFP_ZONES_SHIFT) \
|
||||
| (OPT_ZONE_DMA32 << ___GFP_DMA32 * GFP_ZONES_SHIFT) \
|
||||
| (ZONE_NORMAL << ___GFP_MOVABLE * GFP_ZONES_SHIFT) \
|
||||
| (OPT_ZONE_DMA << (___GFP_MOVABLE | ___GFP_DMA) * GFP_ZONES_SHIFT) \
|
||||
| (ZONE_MOVABLE << (___GFP_MOVABLE | ___GFP_HIGHMEM) * GFP_ZONES_SHIFT)\
|
||||
| (OPT_ZONE_DMA32 << (___GFP_MOVABLE | ___GFP_DMA32) * GFP_ZONES_SHIFT)\
|
||||
)
|
||||
|
||||
/*
|
||||
|
|
@ -373,8 +378,8 @@ static inline enum zone_type gfp_zone(gfp_t flags)
|
|||
enum zone_type z;
|
||||
int bit = (__force int) (flags & GFP_ZONEMASK);
|
||||
|
||||
z = (GFP_ZONE_TABLE >> (bit * ZONES_SHIFT)) &
|
||||
((1 << ZONES_SHIFT) - 1);
|
||||
z = (GFP_ZONE_TABLE >> (bit * GFP_ZONES_SHIFT)) &
|
||||
((1 << GFP_ZONES_SHIFT) - 1);
|
||||
VM_BUG_ON((GFP_ZONE_BAD >> bit) & 1);
|
||||
return z;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -220,7 +220,7 @@ static inline void hrtimer_set_expires_range(struct hrtimer *timer, ktime_t time
|
|||
timer->node.expires = ktime_add_safe(time, delta);
|
||||
}
|
||||
|
||||
static inline void hrtimer_set_expires_range_ns(struct hrtimer *timer, ktime_t time, unsigned long delta)
|
||||
static inline void hrtimer_set_expires_range_ns(struct hrtimer *timer, ktime_t time, u64 delta)
|
||||
{
|
||||
timer->_softexpires = time;
|
||||
timer->node.expires = ktime_add_safe(time, ns_to_ktime(delta));
|
||||
|
|
@ -378,7 +378,7 @@ static inline void destroy_hrtimer_on_stack(struct hrtimer *timer) { }
|
|||
|
||||
/* Basic timer operations: */
|
||||
extern void hrtimer_start_range_ns(struct hrtimer *timer, ktime_t tim,
|
||||
unsigned long range_ns, const enum hrtimer_mode mode);
|
||||
u64 range_ns, const enum hrtimer_mode mode);
|
||||
|
||||
/**
|
||||
* hrtimer_start - (re)start an hrtimer on the current CPU
|
||||
|
|
@ -399,7 +399,7 @@ extern int hrtimer_try_to_cancel(struct hrtimer *timer);
|
|||
static inline void hrtimer_start_expires(struct hrtimer *timer,
|
||||
enum hrtimer_mode mode)
|
||||
{
|
||||
unsigned long delta;
|
||||
u64 delta;
|
||||
ktime_t soft, hard;
|
||||
soft = hrtimer_get_softexpires(timer);
|
||||
hard = hrtimer_get_expires(timer);
|
||||
|
|
@ -477,10 +477,12 @@ extern long hrtimer_nanosleep_restart(struct restart_block *restart_block);
|
|||
extern void hrtimer_init_sleeper(struct hrtimer_sleeper *sl,
|
||||
struct task_struct *tsk);
|
||||
|
||||
extern int schedule_hrtimeout_range(ktime_t *expires, unsigned long delta,
|
||||
extern int schedule_hrtimeout_range(ktime_t *expires, u64 delta,
|
||||
const enum hrtimer_mode mode);
|
||||
extern int schedule_hrtimeout_range_clock(ktime_t *expires,
|
||||
unsigned long delta, const enum hrtimer_mode mode, int clock);
|
||||
u64 delta,
|
||||
const enum hrtimer_mode mode,
|
||||
int clock);
|
||||
extern int schedule_hrtimeout(ktime_t *expires, const enum hrtimer_mode mode);
|
||||
|
||||
/* Soft interrupt function to run the hrtimer queues: */
|
||||
|
|
|
|||
|
|
@ -41,7 +41,8 @@ int vmf_insert_pfn_pmd(struct vm_area_struct *, unsigned long addr, pmd_t *,
|
|||
enum transparent_hugepage_flag {
|
||||
TRANSPARENT_HUGEPAGE_FLAG,
|
||||
TRANSPARENT_HUGEPAGE_REQ_MADV_FLAG,
|
||||
TRANSPARENT_HUGEPAGE_DEFRAG_FLAG,
|
||||
TRANSPARENT_HUGEPAGE_DEFRAG_DIRECT_FLAG,
|
||||
TRANSPARENT_HUGEPAGE_DEFRAG_KSWAPD_FLAG,
|
||||
TRANSPARENT_HUGEPAGE_DEFRAG_REQ_MADV_FLAG,
|
||||
TRANSPARENT_HUGEPAGE_DEFRAG_KHUGEPAGED_FLAG,
|
||||
TRANSPARENT_HUGEPAGE_USE_ZERO_PAGE_FLAG,
|
||||
|
|
@ -71,12 +72,6 @@ extern bool is_vma_temporary_stack(struct vm_area_struct *vma);
|
|||
((__vma)->vm_flags & VM_HUGEPAGE))) && \
|
||||
!((__vma)->vm_flags & VM_NOHUGEPAGE) && \
|
||||
!is_vma_temporary_stack(__vma))
|
||||
#define transparent_hugepage_defrag(__vma) \
|
||||
((transparent_hugepage_flags & \
|
||||
(1<<TRANSPARENT_HUGEPAGE_DEFRAG_FLAG)) || \
|
||||
(transparent_hugepage_flags & \
|
||||
(1<<TRANSPARENT_HUGEPAGE_DEFRAG_REQ_MADV_FLAG) && \
|
||||
(__vma)->vm_flags & VM_HUGEPAGE))
|
||||
#define transparent_hugepage_use_zero_page() \
|
||||
(transparent_hugepage_flags & \
|
||||
(1<<TRANSPARENT_HUGEPAGE_USE_ZERO_PAGE_FLAG))
|
||||
|
|
@ -101,16 +96,21 @@ static inline int split_huge_page(struct page *page)
|
|||
void deferred_split_huge_page(struct page *page);
|
||||
|
||||
void __split_huge_pmd(struct vm_area_struct *vma, pmd_t *pmd,
|
||||
unsigned long address);
|
||||
unsigned long address, bool freeze);
|
||||
|
||||
#define split_huge_pmd(__vma, __pmd, __address) \
|
||||
do { \
|
||||
pmd_t *____pmd = (__pmd); \
|
||||
if (pmd_trans_huge(*____pmd) \
|
||||
|| pmd_devmap(*____pmd)) \
|
||||
__split_huge_pmd(__vma, __pmd, __address); \
|
||||
__split_huge_pmd(__vma, __pmd, __address, \
|
||||
false); \
|
||||
} while (0)
|
||||
|
||||
|
||||
void split_huge_pmd_address(struct vm_area_struct *vma, unsigned long address,
|
||||
bool freeze, struct page *page);
|
||||
|
||||
#if HPAGE_PMD_ORDER >= MAX_ORDER
|
||||
#error "hugepages can't be allocated by the buddy allocator"
|
||||
#endif
|
||||
|
|
@ -178,6 +178,10 @@ static inline int split_huge_page(struct page *page)
|
|||
static inline void deferred_split_huge_page(struct page *page) {}
|
||||
#define split_huge_pmd(__vma, __pmd, __address) \
|
||||
do { } while (0)
|
||||
|
||||
static inline void split_huge_pmd_address(struct vm_area_struct *vma,
|
||||
unsigned long address, bool freeze, struct page *page) {}
|
||||
|
||||
static inline int hugepage_madvise(struct vm_area_struct *vma,
|
||||
unsigned long *vm_flags, int advice)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -357,6 +357,7 @@ int __must_check kstrtou16(const char *s, unsigned int base, u16 *res);
|
|||
int __must_check kstrtos16(const char *s, unsigned int base, s16 *res);
|
||||
int __must_check kstrtou8(const char *s, unsigned int base, u8 *res);
|
||||
int __must_check kstrtos8(const char *s, unsigned int base, s8 *res);
|
||||
int __must_check kstrtobool(const char *s, bool *res);
|
||||
|
||||
int __must_check kstrtoull_from_user(const char __user *s, size_t count, unsigned int base, unsigned long long *res);
|
||||
int __must_check kstrtoll_from_user(const char __user *s, size_t count, unsigned int base, long long *res);
|
||||
|
|
@ -368,6 +369,7 @@ int __must_check kstrtou16_from_user(const char __user *s, size_t count, unsigne
|
|||
int __must_check kstrtos16_from_user(const char __user *s, size_t count, unsigned int base, s16 *res);
|
||||
int __must_check kstrtou8_from_user(const char __user *s, size_t count, unsigned int base, u8 *res);
|
||||
int __must_check kstrtos8_from_user(const char __user *s, size_t count, unsigned int base, s8 *res);
|
||||
int __must_check kstrtobool_from_user(const char __user *s, size_t count, bool *res);
|
||||
|
||||
static inline int __must_check kstrtou64_from_user(const char __user *s, size_t count, unsigned int base, u64 *res)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ static inline void INIT_HLIST_BL_NODE(struct hlist_bl_node *h)
|
|||
|
||||
#define hlist_bl_entry(ptr, type, member) container_of(ptr,type,member)
|
||||
|
||||
static inline int hlist_bl_unhashed(const struct hlist_bl_node *h)
|
||||
static inline bool hlist_bl_unhashed(const struct hlist_bl_node *h)
|
||||
{
|
||||
return !h->pprev;
|
||||
}
|
||||
|
|
@ -68,7 +68,7 @@ static inline void hlist_bl_set_first(struct hlist_bl_head *h,
|
|||
h->first = (struct hlist_bl_node *)((unsigned long)n | LIST_BL_LOCKMASK);
|
||||
}
|
||||
|
||||
static inline int hlist_bl_empty(const struct hlist_bl_head *h)
|
||||
static inline bool hlist_bl_empty(const struct hlist_bl_head *h)
|
||||
{
|
||||
return !((unsigned long)READ_ONCE(h->first) & ~LIST_BL_LOCKMASK);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,7 +52,10 @@ enum mem_cgroup_stat_index {
|
|||
MEM_CGROUP_STAT_SWAP, /* # of pages, swapped out */
|
||||
MEM_CGROUP_STAT_NSTATS,
|
||||
/* default hierarchy stats */
|
||||
MEMCG_SOCK = MEM_CGROUP_STAT_NSTATS,
|
||||
MEMCG_KERNEL_STACK = MEM_CGROUP_STAT_NSTATS,
|
||||
MEMCG_SLAB_RECLAIMABLE,
|
||||
MEMCG_SLAB_UNRECLAIMABLE,
|
||||
MEMCG_SOCK,
|
||||
MEMCG_NR_STAT,
|
||||
};
|
||||
|
||||
|
|
@ -400,6 +403,9 @@ int mem_cgroup_select_victim_node(struct mem_cgroup *memcg);
|
|||
void mem_cgroup_update_lru_size(struct lruvec *lruvec, enum lru_list lru,
|
||||
int nr_pages);
|
||||
|
||||
unsigned long mem_cgroup_node_nr_lru_pages(struct mem_cgroup *memcg,
|
||||
int nid, unsigned int lru_mask);
|
||||
|
||||
static inline
|
||||
unsigned long mem_cgroup_get_lru_size(struct lruvec *lruvec, enum lru_list lru)
|
||||
{
|
||||
|
|
@ -658,6 +664,13 @@ mem_cgroup_update_lru_size(struct lruvec *lruvec, enum lru_list lru,
|
|||
{
|
||||
}
|
||||
|
||||
static inline unsigned long
|
||||
mem_cgroup_node_nr_lru_pages(struct mem_cgroup *memcg,
|
||||
int nid, unsigned int lru_mask)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void
|
||||
mem_cgroup_print_oom_info(struct mem_cgroup *memcg, struct task_struct *p)
|
||||
{
|
||||
|
|
@ -792,11 +805,6 @@ static inline bool memcg_kmem_enabled(void)
|
|||
return static_branch_unlikely(&memcg_kmem_enabled_key);
|
||||
}
|
||||
|
||||
static inline bool memcg_kmem_online(struct mem_cgroup *memcg)
|
||||
{
|
||||
return memcg->kmem_state == KMEM_ONLINE;
|
||||
}
|
||||
|
||||
/*
|
||||
* In general, we'll do everything in our power to not incur in any overhead
|
||||
* for non-memcg users for the kmem functions. Not even a function call, if we
|
||||
|
|
@ -883,6 +891,20 @@ static __always_inline void memcg_kmem_put_cache(struct kmem_cache *cachep)
|
|||
if (memcg_kmem_enabled())
|
||||
__memcg_kmem_put_cache(cachep);
|
||||
}
|
||||
|
||||
/**
|
||||
* memcg_kmem_update_page_stat - update kmem page state statistics
|
||||
* @page: the page
|
||||
* @idx: page state item to account
|
||||
* @val: number of pages (positive or negative)
|
||||
*/
|
||||
static inline void memcg_kmem_update_page_stat(struct page *page,
|
||||
enum mem_cgroup_stat_index idx, int val)
|
||||
{
|
||||
if (memcg_kmem_enabled() && page->mem_cgroup)
|
||||
this_cpu_add(page->mem_cgroup->stat->count[idx], val);
|
||||
}
|
||||
|
||||
#else
|
||||
#define for_each_memcg_cache_index(_idx) \
|
||||
for (; NULL; )
|
||||
|
|
@ -892,11 +914,6 @@ static inline bool memcg_kmem_enabled(void)
|
|||
return false;
|
||||
}
|
||||
|
||||
static inline bool memcg_kmem_online(struct mem_cgroup *memcg)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline int memcg_kmem_charge(struct page *page, gfp_t gfp, int order)
|
||||
{
|
||||
return 0;
|
||||
|
|
@ -928,6 +945,11 @@ memcg_kmem_get_cache(struct kmem_cache *cachep, gfp_t gfp)
|
|||
static inline void memcg_kmem_put_cache(struct kmem_cache *cachep)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void memcg_kmem_update_page_stat(struct page *page,
|
||||
enum mem_cgroup_stat_index idx, int val)
|
||||
{
|
||||
}
|
||||
#endif /* CONFIG_MEMCG && !CONFIG_SLOB */
|
||||
|
||||
#endif /* _LINUX_MEMCONTROL_H */
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
#include <linux/resource.h>
|
||||
#include <linux/page_ext.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/page_ref.h>
|
||||
|
||||
struct mempolicy;
|
||||
struct anon_vma;
|
||||
|
|
@ -82,6 +83,27 @@ extern int mmap_rnd_compat_bits __read_mostly;
|
|||
#define mm_forbids_zeropage(X) (0)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Default maximum number of active map areas, this limits the number of vmas
|
||||
* per mm struct. Users can overwrite this number by sysctl but there is a
|
||||
* problem.
|
||||
*
|
||||
* When a program's coredump is generated as ELF format, a section is created
|
||||
* per a vma. In ELF, the number of sections is represented in unsigned short.
|
||||
* This means the number of sections should be smaller than 65535 at coredump.
|
||||
* Because the kernel adds some informative sections to a image of program at
|
||||
* generating coredump, we need some margin. The number of extra sections is
|
||||
* 1-3 now and depends on arch. We use "5" as safe margin, here.
|
||||
*
|
||||
* ELF extended numbering allows more than 65535 sections, so 16-bit bound is
|
||||
* not a hard limit any more. Although some userspace tools can be surprised by
|
||||
* that.
|
||||
*/
|
||||
#define MAPCOUNT_ELF_CORE_MARGIN (5)
|
||||
#define DEFAULT_MAX_MAP_COUNT (USHRT_MAX - MAPCOUNT_ELF_CORE_MARGIN)
|
||||
|
||||
extern int sysctl_max_map_count;
|
||||
|
||||
extern unsigned long sysctl_user_reserve_kbytes;
|
||||
extern unsigned long sysctl_admin_reserve_kbytes;
|
||||
|
||||
|
|
@ -122,6 +144,7 @@ extern unsigned int kobjsize(const void *objp);
|
|||
|
||||
/*
|
||||
* vm_flags in vm_area_struct, see mm_types.h.
|
||||
* When changing, update also include/trace/events/mmflags.h
|
||||
*/
|
||||
#define VM_NONE 0x00000000
|
||||
|
||||
|
|
@ -364,8 +387,8 @@ static inline int pmd_devmap(pmd_t pmd)
|
|||
*/
|
||||
static inline int put_page_testzero(struct page *page)
|
||||
{
|
||||
VM_BUG_ON_PAGE(atomic_read(&page->_count) == 0, page);
|
||||
return atomic_dec_and_test(&page->_count);
|
||||
VM_BUG_ON_PAGE(page_ref_count(page) == 0, page);
|
||||
return page_ref_dec_and_test(page);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -376,7 +399,7 @@ static inline int put_page_testzero(struct page *page)
|
|||
*/
|
||||
static inline int get_page_unless_zero(struct page *page)
|
||||
{
|
||||
return atomic_inc_not_zero(&page->_count);
|
||||
return page_ref_add_unless(page, 1, 0);
|
||||
}
|
||||
|
||||
extern int page_is_ram(unsigned long pfn);
|
||||
|
|
@ -464,11 +487,6 @@ static inline int total_mapcount(struct page *page)
|
|||
}
|
||||
#endif
|
||||
|
||||
static inline int page_count(struct page *page)
|
||||
{
|
||||
return atomic_read(&compound_head(page)->_count);
|
||||
}
|
||||
|
||||
static inline struct page *virt_to_head_page(const void *x)
|
||||
{
|
||||
struct page *page = virt_to_page(x);
|
||||
|
|
@ -476,15 +494,6 @@ static inline struct page *virt_to_head_page(const void *x)
|
|||
return compound_head(page);
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup the page count before being freed into the page allocator for
|
||||
* the first time (boot or memory hotplug)
|
||||
*/
|
||||
static inline void init_page_count(struct page *page)
|
||||
{
|
||||
atomic_set(&page->_count, 1);
|
||||
}
|
||||
|
||||
void __put_page(struct page *page);
|
||||
|
||||
void put_pages_list(struct list_head *pages);
|
||||
|
|
@ -694,8 +703,8 @@ static inline void get_page(struct page *page)
|
|||
* Getting a normal page or the head of a compound page
|
||||
* requires to already have an elevated page->_count.
|
||||
*/
|
||||
VM_BUG_ON_PAGE(atomic_read(&page->_count) <= 0, page);
|
||||
atomic_inc(&page->_count);
|
||||
VM_BUG_ON_PAGE(page_ref_count(page) <= 0, page);
|
||||
page_ref_inc(page);
|
||||
|
||||
if (unlikely(is_zone_device_page(page)))
|
||||
get_zone_device_page(page);
|
||||
|
|
@ -1043,8 +1052,6 @@ static inline void clear_page_pfmemalloc(struct page *page)
|
|||
* just gets major/minor fault counters bumped up.
|
||||
*/
|
||||
|
||||
#define VM_FAULT_MINOR 0 /* For backwards compat. Remove me quickly. */
|
||||
|
||||
#define VM_FAULT_OOM 0x0001
|
||||
#define VM_FAULT_SIGBUS 0x0002
|
||||
#define VM_FAULT_MAJOR 0x0004
|
||||
|
|
@ -1523,8 +1530,7 @@ static inline void mm_dec_nr_pmds(struct mm_struct *mm)
|
|||
}
|
||||
#endif
|
||||
|
||||
int __pte_alloc(struct mm_struct *mm, struct vm_area_struct *vma,
|
||||
pmd_t *pmd, unsigned long address);
|
||||
int __pte_alloc(struct mm_struct *mm, pmd_t *pmd, unsigned long address);
|
||||
int __pte_alloc_kernel(pmd_t *pmd, unsigned long address);
|
||||
|
||||
/*
|
||||
|
|
@ -1650,15 +1656,15 @@ static inline void pgtable_page_dtor(struct page *page)
|
|||
pte_unmap(pte); \
|
||||
} while (0)
|
||||
|
||||
#define pte_alloc_map(mm, vma, pmd, address) \
|
||||
((unlikely(pmd_none(*(pmd))) && __pte_alloc(mm, vma, \
|
||||
pmd, address))? \
|
||||
NULL: pte_offset_map(pmd, address))
|
||||
#define pte_alloc(mm, pmd, address) \
|
||||
(unlikely(pmd_none(*(pmd))) && __pte_alloc(mm, pmd, address))
|
||||
|
||||
#define pte_alloc_map(mm, pmd, address) \
|
||||
(pte_alloc(mm, pmd, address) ? NULL : pte_offset_map(pmd, address))
|
||||
|
||||
#define pte_alloc_map_lock(mm, pmd, address, ptlp) \
|
||||
((unlikely(pmd_none(*(pmd))) && __pte_alloc(mm, NULL, \
|
||||
pmd, address))? \
|
||||
NULL: pte_offset_map_lock(mm, pmd, address, ptlp))
|
||||
(pte_alloc(mm, pmd, address) ? \
|
||||
NULL : pte_offset_map_lock(mm, pmd, address, ptlp))
|
||||
|
||||
#define pte_alloc_kernel(pmd, address) \
|
||||
((unlikely(pmd_none(*(pmd))) && __pte_alloc_kernel(pmd, address))? \
|
||||
|
|
@ -1853,6 +1859,7 @@ extern int __meminit init_per_zone_wmark_min(void);
|
|||
extern void mem_init(void);
|
||||
extern void __init mmap_init(void);
|
||||
extern void show_mem(unsigned int flags);
|
||||
extern long si_mem_available(void);
|
||||
extern void si_meminfo(struct sysinfo * val);
|
||||
extern void si_meminfo_node(struct sysinfo *val, int nid);
|
||||
|
||||
|
|
@ -1867,6 +1874,7 @@ extern void zone_pcp_reset(struct zone *zone);
|
|||
|
||||
/* page_alloc.c */
|
||||
extern int min_free_kbytes;
|
||||
extern int watermark_scale_factor;
|
||||
|
||||
/* nommu.c */
|
||||
extern atomic_long_t mmap_pages_allocated;
|
||||
|
|
|
|||
|
|
@ -668,6 +668,12 @@ typedef struct pglist_data {
|
|||
mem_hotplug_begin/end() */
|
||||
int kswapd_max_order;
|
||||
enum zone_type classzone_idx;
|
||||
#ifdef CONFIG_COMPACTION
|
||||
int kcompactd_max_order;
|
||||
enum zone_type kcompactd_classzone_idx;
|
||||
wait_queue_head_t kcompactd_wait;
|
||||
struct task_struct *kcompactd;
|
||||
#endif
|
||||
#ifdef CONFIG_NUMA_BALANCING
|
||||
/* Lock serializing the migrate rate limiting window */
|
||||
spinlock_t numabalancing_migrate_lock;
|
||||
|
|
@ -835,6 +841,8 @@ static inline int is_highmem(struct zone *zone)
|
|||
struct ctl_table;
|
||||
int min_free_kbytes_sysctl_handler(struct ctl_table *, int,
|
||||
void __user *, size_t *, loff_t *);
|
||||
int watermark_scale_factor_sysctl_handler(struct ctl_table *, int,
|
||||
void __user *, size_t *, loff_t *);
|
||||
extern int sysctl_lowmem_reserve_ratio[MAX_NR_ZONES-1];
|
||||
int lowmem_reserve_ratio_sysctl_handler(struct ctl_table *, int,
|
||||
void __user *, size_t *, loff_t *);
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@
|
|||
#define ZONES_SHIFT 1
|
||||
#elif MAX_NR_ZONES <= 4
|
||||
#define ZONES_SHIFT 2
|
||||
#elif MAX_NR_ZONES <= 8
|
||||
#define ZONES_SHIFT 3
|
||||
#else
|
||||
#error ZONES_SHIFT -- too many zones configured adjust calculation
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -144,12 +144,12 @@ static inline struct page *compound_head(struct page *page)
|
|||
return page;
|
||||
}
|
||||
|
||||
static inline int PageTail(struct page *page)
|
||||
static __always_inline int PageTail(struct page *page)
|
||||
{
|
||||
return READ_ONCE(page->compound_head) & 1;
|
||||
}
|
||||
|
||||
static inline int PageCompound(struct page *page)
|
||||
static __always_inline int PageCompound(struct page *page)
|
||||
{
|
||||
return test_bit(PG_head, &page->flags) || PageTail(page);
|
||||
}
|
||||
|
|
@ -184,31 +184,31 @@ static inline int PageCompound(struct page *page)
|
|||
* Macros to create function definitions for page flags
|
||||
*/
|
||||
#define TESTPAGEFLAG(uname, lname, policy) \
|
||||
static inline int Page##uname(struct page *page) \
|
||||
static __always_inline int Page##uname(struct page *page) \
|
||||
{ return test_bit(PG_##lname, &policy(page, 0)->flags); }
|
||||
|
||||
#define SETPAGEFLAG(uname, lname, policy) \
|
||||
static inline void SetPage##uname(struct page *page) \
|
||||
static __always_inline void SetPage##uname(struct page *page) \
|
||||
{ set_bit(PG_##lname, &policy(page, 1)->flags); }
|
||||
|
||||
#define CLEARPAGEFLAG(uname, lname, policy) \
|
||||
static inline void ClearPage##uname(struct page *page) \
|
||||
static __always_inline void ClearPage##uname(struct page *page) \
|
||||
{ clear_bit(PG_##lname, &policy(page, 1)->flags); }
|
||||
|
||||
#define __SETPAGEFLAG(uname, lname, policy) \
|
||||
static inline void __SetPage##uname(struct page *page) \
|
||||
static __always_inline void __SetPage##uname(struct page *page) \
|
||||
{ __set_bit(PG_##lname, &policy(page, 1)->flags); }
|
||||
|
||||
#define __CLEARPAGEFLAG(uname, lname, policy) \
|
||||
static inline void __ClearPage##uname(struct page *page) \
|
||||
static __always_inline void __ClearPage##uname(struct page *page) \
|
||||
{ __clear_bit(PG_##lname, &policy(page, 1)->flags); }
|
||||
|
||||
#define TESTSETFLAG(uname, lname, policy) \
|
||||
static inline int TestSetPage##uname(struct page *page) \
|
||||
static __always_inline int TestSetPage##uname(struct page *page) \
|
||||
{ return test_and_set_bit(PG_##lname, &policy(page, 1)->flags); }
|
||||
|
||||
#define TESTCLEARFLAG(uname, lname, policy) \
|
||||
static inline int TestClearPage##uname(struct page *page) \
|
||||
static __always_inline int TestClearPage##uname(struct page *page) \
|
||||
{ return test_and_clear_bit(PG_##lname, &policy(page, 1)->flags); }
|
||||
|
||||
#define PAGEFLAG(uname, lname, policy) \
|
||||
|
|
@ -371,7 +371,7 @@ PAGEFLAG(Idle, idle, PF_ANY)
|
|||
#define PAGE_MAPPING_KSM 2
|
||||
#define PAGE_MAPPING_FLAGS (PAGE_MAPPING_ANON | PAGE_MAPPING_KSM)
|
||||
|
||||
static inline int PageAnon(struct page *page)
|
||||
static __always_inline int PageAnon(struct page *page)
|
||||
{
|
||||
page = compound_head(page);
|
||||
return ((unsigned long)page->mapping & PAGE_MAPPING_ANON) != 0;
|
||||
|
|
@ -384,7 +384,7 @@ static inline int PageAnon(struct page *page)
|
|||
* is found in VM_MERGEABLE vmas. It's a PageAnon page, pointing not to any
|
||||
* anon_vma, but to that page's node of the stable tree.
|
||||
*/
|
||||
static inline int PageKsm(struct page *page)
|
||||
static __always_inline int PageKsm(struct page *page)
|
||||
{
|
||||
page = compound_head(page);
|
||||
return ((unsigned long)page->mapping & PAGE_MAPPING_FLAGS) ==
|
||||
|
|
@ -415,14 +415,14 @@ static inline int PageUptodate(struct page *page)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static inline void __SetPageUptodate(struct page *page)
|
||||
static __always_inline void __SetPageUptodate(struct page *page)
|
||||
{
|
||||
VM_BUG_ON_PAGE(PageTail(page), page);
|
||||
smp_wmb();
|
||||
__set_bit(PG_uptodate, &page->flags);
|
||||
}
|
||||
|
||||
static inline void SetPageUptodate(struct page *page)
|
||||
static __always_inline void SetPageUptodate(struct page *page)
|
||||
{
|
||||
VM_BUG_ON_PAGE(PageTail(page), page);
|
||||
/*
|
||||
|
|
@ -456,12 +456,12 @@ static inline void set_page_writeback_keepwrite(struct page *page)
|
|||
|
||||
__PAGEFLAG(Head, head, PF_ANY) CLEARPAGEFLAG(Head, head, PF_ANY)
|
||||
|
||||
static inline void set_compound_head(struct page *page, struct page *head)
|
||||
static __always_inline void set_compound_head(struct page *page, struct page *head)
|
||||
{
|
||||
WRITE_ONCE(page->compound_head, (unsigned long)head + 1);
|
||||
}
|
||||
|
||||
static inline void clear_compound_head(struct page *page)
|
||||
static __always_inline void clear_compound_head(struct page *page)
|
||||
{
|
||||
WRITE_ONCE(page->compound_head, 0);
|
||||
}
|
||||
|
|
@ -593,6 +593,8 @@ static inline void __ClearPageBuddy(struct page *page)
|
|||
atomic_set(&page->_mapcount, -1);
|
||||
}
|
||||
|
||||
extern bool is_free_buddy_page(struct page *page);
|
||||
|
||||
#define PAGE_BALLOON_MAPCOUNT_VALUE (-256)
|
||||
|
||||
static inline int PageBalloon(struct page *page)
|
||||
|
|
|
|||
173
include/linux/page_ref.h
Normal file
173
include/linux/page_ref.h
Normal file
|
|
@ -0,0 +1,173 @@
|
|||
#ifndef _LINUX_PAGE_REF_H
|
||||
#define _LINUX_PAGE_REF_H
|
||||
|
||||
#include <linux/atomic.h>
|
||||
#include <linux/mm_types.h>
|
||||
#include <linux/page-flags.h>
|
||||
#include <linux/tracepoint-defs.h>
|
||||
|
||||
extern struct tracepoint __tracepoint_page_ref_set;
|
||||
extern struct tracepoint __tracepoint_page_ref_mod;
|
||||
extern struct tracepoint __tracepoint_page_ref_mod_and_test;
|
||||
extern struct tracepoint __tracepoint_page_ref_mod_and_return;
|
||||
extern struct tracepoint __tracepoint_page_ref_mod_unless;
|
||||
extern struct tracepoint __tracepoint_page_ref_freeze;
|
||||
extern struct tracepoint __tracepoint_page_ref_unfreeze;
|
||||
|
||||
#ifdef CONFIG_DEBUG_PAGE_REF
|
||||
|
||||
/*
|
||||
* Ideally we would want to use the trace_<tracepoint>_enabled() helper
|
||||
* functions. But due to include header file issues, that is not
|
||||
* feasible. Instead we have to open code the static key functions.
|
||||
*
|
||||
* See trace_##name##_enabled(void) in include/linux/tracepoint.h
|
||||
*/
|
||||
#define page_ref_tracepoint_active(t) static_key_false(&(t).key)
|
||||
|
||||
extern void __page_ref_set(struct page *page, int v);
|
||||
extern void __page_ref_mod(struct page *page, int v);
|
||||
extern void __page_ref_mod_and_test(struct page *page, int v, int ret);
|
||||
extern void __page_ref_mod_and_return(struct page *page, int v, int ret);
|
||||
extern void __page_ref_mod_unless(struct page *page, int v, int u);
|
||||
extern void __page_ref_freeze(struct page *page, int v, int ret);
|
||||
extern void __page_ref_unfreeze(struct page *page, int v);
|
||||
|
||||
#else
|
||||
|
||||
#define page_ref_tracepoint_active(t) false
|
||||
|
||||
static inline void __page_ref_set(struct page *page, int v)
|
||||
{
|
||||
}
|
||||
static inline void __page_ref_mod(struct page *page, int v)
|
||||
{
|
||||
}
|
||||
static inline void __page_ref_mod_and_test(struct page *page, int v, int ret)
|
||||
{
|
||||
}
|
||||
static inline void __page_ref_mod_and_return(struct page *page, int v, int ret)
|
||||
{
|
||||
}
|
||||
static inline void __page_ref_mod_unless(struct page *page, int v, int u)
|
||||
{
|
||||
}
|
||||
static inline void __page_ref_freeze(struct page *page, int v, int ret)
|
||||
{
|
||||
}
|
||||
static inline void __page_ref_unfreeze(struct page *page, int v)
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static inline int page_ref_count(struct page *page)
|
||||
{
|
||||
return atomic_read(&page->_count);
|
||||
}
|
||||
|
||||
static inline int page_count(struct page *page)
|
||||
{
|
||||
return atomic_read(&compound_head(page)->_count);
|
||||
}
|
||||
|
||||
static inline void set_page_count(struct page *page, int v)
|
||||
{
|
||||
atomic_set(&page->_count, v);
|
||||
if (page_ref_tracepoint_active(__tracepoint_page_ref_set))
|
||||
__page_ref_set(page, v);
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup the page count before being freed into the page allocator for
|
||||
* the first time (boot or memory hotplug)
|
||||
*/
|
||||
static inline void init_page_count(struct page *page)
|
||||
{
|
||||
set_page_count(page, 1);
|
||||
}
|
||||
|
||||
static inline void page_ref_add(struct page *page, int nr)
|
||||
{
|
||||
atomic_add(nr, &page->_count);
|
||||
if (page_ref_tracepoint_active(__tracepoint_page_ref_mod))
|
||||
__page_ref_mod(page, nr);
|
||||
}
|
||||
|
||||
static inline void page_ref_sub(struct page *page, int nr)
|
||||
{
|
||||
atomic_sub(nr, &page->_count);
|
||||
if (page_ref_tracepoint_active(__tracepoint_page_ref_mod))
|
||||
__page_ref_mod(page, -nr);
|
||||
}
|
||||
|
||||
static inline void page_ref_inc(struct page *page)
|
||||
{
|
||||
atomic_inc(&page->_count);
|
||||
if (page_ref_tracepoint_active(__tracepoint_page_ref_mod))
|
||||
__page_ref_mod(page, 1);
|
||||
}
|
||||
|
||||
static inline void page_ref_dec(struct page *page)
|
||||
{
|
||||
atomic_dec(&page->_count);
|
||||
if (page_ref_tracepoint_active(__tracepoint_page_ref_mod))
|
||||
__page_ref_mod(page, -1);
|
||||
}
|
||||
|
||||
static inline int page_ref_sub_and_test(struct page *page, int nr)
|
||||
{
|
||||
int ret = atomic_sub_and_test(nr, &page->_count);
|
||||
|
||||
if (page_ref_tracepoint_active(__tracepoint_page_ref_mod_and_test))
|
||||
__page_ref_mod_and_test(page, -nr, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline int page_ref_dec_and_test(struct page *page)
|
||||
{
|
||||
int ret = atomic_dec_and_test(&page->_count);
|
||||
|
||||
if (page_ref_tracepoint_active(__tracepoint_page_ref_mod_and_test))
|
||||
__page_ref_mod_and_test(page, -1, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline int page_ref_dec_return(struct page *page)
|
||||
{
|
||||
int ret = atomic_dec_return(&page->_count);
|
||||
|
||||
if (page_ref_tracepoint_active(__tracepoint_page_ref_mod_and_return))
|
||||
__page_ref_mod_and_return(page, -1, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline int page_ref_add_unless(struct page *page, int nr, int u)
|
||||
{
|
||||
int ret = atomic_add_unless(&page->_count, nr, u);
|
||||
|
||||
if (page_ref_tracepoint_active(__tracepoint_page_ref_mod_unless))
|
||||
__page_ref_mod_unless(page, nr, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline int page_ref_freeze(struct page *page, int count)
|
||||
{
|
||||
int ret = likely(atomic_cmpxchg(&page->_count, count, 0) == count);
|
||||
|
||||
if (page_ref_tracepoint_active(__tracepoint_page_ref_freeze))
|
||||
__page_ref_freeze(page, count, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline void page_ref_unfreeze(struct page *page, int count)
|
||||
{
|
||||
VM_BUG_ON_PAGE(page_count(page) != 0, page);
|
||||
VM_BUG_ON(count == 0);
|
||||
|
||||
atomic_set(&page->_count, count);
|
||||
if (page_ref_tracepoint_active(__tracepoint_page_ref_unfreeze))
|
||||
__page_ref_unfreeze(page, count);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -165,7 +165,7 @@ static inline int page_cache_get_speculative(struct page *page)
|
|||
* SMP requires.
|
||||
*/
|
||||
VM_BUG_ON_PAGE(page_count(page) == 0, page);
|
||||
atomic_inc(&page->_count);
|
||||
page_ref_inc(page);
|
||||
|
||||
#else
|
||||
if (unlikely(!get_page_unless_zero(page))) {
|
||||
|
|
@ -194,10 +194,10 @@ static inline int page_cache_add_speculative(struct page *page, int count)
|
|||
VM_BUG_ON(!in_atomic());
|
||||
# endif
|
||||
VM_BUG_ON_PAGE(page_count(page) == 0, page);
|
||||
atomic_add(count, &page->_count);
|
||||
page_ref_add(page, count);
|
||||
|
||||
#else
|
||||
if (unlikely(!atomic_add_unless(&page->_count, count, 0)))
|
||||
if (unlikely(!page_ref_add_unless(page, count, 0)))
|
||||
return 0;
|
||||
#endif
|
||||
VM_BUG_ON_PAGE(PageCompound(page) && page != compound_head(page), page);
|
||||
|
|
@ -205,19 +205,6 @@ static inline int page_cache_add_speculative(struct page *page, int count)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static inline int page_freeze_refs(struct page *page, int count)
|
||||
{
|
||||
return likely(atomic_cmpxchg(&page->_count, count, 0) == count);
|
||||
}
|
||||
|
||||
static inline void page_unfreeze_refs(struct page *page, int count)
|
||||
{
|
||||
VM_BUG_ON_PAGE(page_count(page) != 0, page);
|
||||
VM_BUG_ON(count == 0);
|
||||
|
||||
atomic_set(&page->_count, count);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NUMA
|
||||
extern struct page *__page_cache_alloc(gfp_t gfp);
|
||||
#else
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@ extern void poll_initwait(struct poll_wqueues *pwq);
|
|||
extern void poll_freewait(struct poll_wqueues *pwq);
|
||||
extern int poll_schedule_timeout(struct poll_wqueues *pwq, int state,
|
||||
ktime_t *expires, unsigned long slack);
|
||||
extern long select_estimate_accuracy(struct timespec *tv);
|
||||
extern u64 select_estimate_accuracy(struct timespec *tv);
|
||||
|
||||
|
||||
static inline int poll_schedule(struct poll_wqueues *pwq, int state)
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
* as needed after allocation when they are freed. Per cpu lists of pages
|
||||
* are kept that only contain node local pages.
|
||||
*
|
||||
* (C) 2007, SGI. Christoph Lameter <clameter@sgi.com>
|
||||
* (C) 2007, SGI. Christoph Lameter <cl@linux.com>
|
||||
*/
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/gfp.h>
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
#ifndef _LINUX_RADIX_TREE_H
|
||||
#define _LINUX_RADIX_TREE_H
|
||||
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/preempt.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/bug.h>
|
||||
|
|
@ -270,8 +271,15 @@ static inline void radix_tree_replace_slot(void **pslot, void *item)
|
|||
}
|
||||
|
||||
int __radix_tree_create(struct radix_tree_root *root, unsigned long index,
|
||||
struct radix_tree_node **nodep, void ***slotp);
|
||||
int radix_tree_insert(struct radix_tree_root *, unsigned long, void *);
|
||||
unsigned order, struct radix_tree_node **nodep,
|
||||
void ***slotp);
|
||||
int __radix_tree_insert(struct radix_tree_root *, unsigned long index,
|
||||
unsigned order, void *);
|
||||
static inline int radix_tree_insert(struct radix_tree_root *root,
|
||||
unsigned long index, void *entry)
|
||||
{
|
||||
return __radix_tree_insert(root, index, 0, entry);
|
||||
}
|
||||
void *__radix_tree_lookup(struct radix_tree_root *root, unsigned long index,
|
||||
struct radix_tree_node **nodep, void ***slotp);
|
||||
void *radix_tree_lookup(struct radix_tree_root *, unsigned long);
|
||||
|
|
@ -394,6 +402,22 @@ void **radix_tree_iter_retry(struct radix_tree_iter *iter)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* radix_tree_iter_next - resume iterating when the chunk may be invalid
|
||||
* @iter: iterator state
|
||||
*
|
||||
* If the iterator needs to release then reacquire a lock, the chunk may
|
||||
* have been invalidated by an insertion or deletion. Call this function
|
||||
* to continue the iteration from the next index.
|
||||
*/
|
||||
static inline __must_check
|
||||
void **radix_tree_iter_next(struct radix_tree_iter *iter)
|
||||
{
|
||||
iter->next_index = iter->index + 1;
|
||||
iter->tags = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* radix_tree_chunk_size - get current chunk size
|
||||
*
|
||||
|
|
|
|||
|
|
@ -86,6 +86,7 @@ enum ttu_flags {
|
|||
TTU_MIGRATION = 2, /* migration mode */
|
||||
TTU_MUNLOCK = 4, /* munlock mode */
|
||||
TTU_LZFREE = 8, /* lazy free mode */
|
||||
TTU_SPLIT_HUGE_PMD = 16, /* split huge PMD if any */
|
||||
|
||||
TTU_IGNORE_MLOCK = (1 << 8), /* ignore mlock */
|
||||
TTU_IGNORE_ACCESS = (1 << 9), /* don't age */
|
||||
|
|
@ -93,6 +94,8 @@ enum ttu_flags {
|
|||
TTU_BATCH_FLUSH = (1 << 11), /* Batch TLB flushes where possible
|
||||
* and caller guarantees they will
|
||||
* do a final flush if necessary */
|
||||
TTU_RMAP_LOCKED = (1 << 12) /* do not grab rmap lock:
|
||||
* caller holds it */
|
||||
};
|
||||
|
||||
#ifdef CONFIG_MMU
|
||||
|
|
@ -240,6 +243,8 @@ int page_mkclean(struct page *);
|
|||
*/
|
||||
int try_to_munlock(struct page *);
|
||||
|
||||
void remove_migration_ptes(struct page *old, struct page *new, bool locked);
|
||||
|
||||
/*
|
||||
* Called by memory-failure.c to kill processes.
|
||||
*/
|
||||
|
|
@ -266,6 +271,7 @@ struct rmap_walk_control {
|
|||
};
|
||||
|
||||
int rmap_walk(struct page *page, struct rmap_walk_control *rwc);
|
||||
int rmap_walk_locked(struct page *page, struct rmap_walk_control *rwc);
|
||||
|
||||
#else /* !CONFIG_MMU */
|
||||
|
||||
|
|
|
|||
|
|
@ -1791,8 +1791,8 @@ struct task_struct {
|
|||
* time slack values; these are used to round up poll() and
|
||||
* select() etc timeout values. These are in nanoseconds.
|
||||
*/
|
||||
unsigned long timer_slack_ns;
|
||||
unsigned long default_timer_slack_ns;
|
||||
u64 timer_slack_ns;
|
||||
u64 default_timer_slack_ns;
|
||||
|
||||
#ifdef CONFIG_KASAN
|
||||
unsigned int kasan_depth;
|
||||
|
|
|
|||
|
|
@ -14,27 +14,6 @@ extern int proc_dohung_task_timeout_secs(struct ctl_table *table, int write,
|
|||
enum { sysctl_hung_task_timeout_secs = 0 };
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Default maximum number of active map areas, this limits the number of vmas
|
||||
* per mm struct. Users can overwrite this number by sysctl but there is a
|
||||
* problem.
|
||||
*
|
||||
* When a program's coredump is generated as ELF format, a section is created
|
||||
* per a vma. In ELF, the number of sections is represented in unsigned short.
|
||||
* This means the number of sections should be smaller than 65535 at coredump.
|
||||
* Because the kernel adds some informative sections to a image of program at
|
||||
* generating coredump, we need some margin. The number of extra sections is
|
||||
* 1-3 now and depends on arch. We use "5" as safe margin, here.
|
||||
*
|
||||
* ELF extended numbering allows more than 65535 sections, so 16-bit bound is
|
||||
* not a hard limit any more. Although some userspace tools can be surprised by
|
||||
* that.
|
||||
*/
|
||||
#define MAPCOUNT_ELF_CORE_MARGIN (5)
|
||||
#define DEFAULT_MAX_MAP_COUNT (USHRT_MAX - MAPCOUNT_ELF_CORE_MARGIN)
|
||||
|
||||
extern int sysctl_max_map_count;
|
||||
|
||||
extern unsigned int sysctl_sched_latency;
|
||||
extern unsigned int sysctl_sched_min_granularity;
|
||||
extern unsigned int sysctl_sched_wakeup_granularity;
|
||||
|
|
|
|||
|
|
@ -128,7 +128,13 @@ extern char **argv_split(gfp_t gfp, const char *str, int *argcp);
|
|||
extern void argv_free(char **argv);
|
||||
|
||||
extern bool sysfs_streq(const char *s1, const char *s2);
|
||||
extern int strtobool(const char *s, bool *res);
|
||||
extern int kstrtobool(const char *s, bool *res);
|
||||
static inline int strtobool(const char *s, bool *res)
|
||||
{
|
||||
return kstrtobool(s, res);
|
||||
}
|
||||
|
||||
int match_string(const char * const *array, size_t n, const char *string);
|
||||
|
||||
#ifdef CONFIG_BINARY_PRINTF
|
||||
int vbin_printf(u32 *bin_buf, size_t size, const char *fmt, va_list args);
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@ enum tick_dep_bits {
|
|||
#define TICK_DEP_MASK_CLOCK_UNSTABLE (1 << TICK_DEP_BIT_CLOCK_UNSTABLE)
|
||||
|
||||
#ifdef CONFIG_NO_HZ_COMMON
|
||||
extern int tick_nohz_enabled;
|
||||
extern bool tick_nohz_enabled;
|
||||
extern int tick_nohz_tick_stopped(void);
|
||||
extern void tick_nohz_idle_enter(void);
|
||||
extern void tick_nohz_idle_exit(void);
|
||||
|
|
|
|||
|
|
@ -4,62 +4,62 @@
|
|||
#include <linux/kernel.h>
|
||||
#include <asm/byteorder.h>
|
||||
|
||||
static inline u16 get_unaligned_le16(const void *p)
|
||||
static __always_inline u16 get_unaligned_le16(const void *p)
|
||||
{
|
||||
return le16_to_cpup((__le16 *)p);
|
||||
}
|
||||
|
||||
static inline u32 get_unaligned_le32(const void *p)
|
||||
static __always_inline u32 get_unaligned_le32(const void *p)
|
||||
{
|
||||
return le32_to_cpup((__le32 *)p);
|
||||
}
|
||||
|
||||
static inline u64 get_unaligned_le64(const void *p)
|
||||
static __always_inline u64 get_unaligned_le64(const void *p)
|
||||
{
|
||||
return le64_to_cpup((__le64 *)p);
|
||||
}
|
||||
|
||||
static inline u16 get_unaligned_be16(const void *p)
|
||||
static __always_inline u16 get_unaligned_be16(const void *p)
|
||||
{
|
||||
return be16_to_cpup((__be16 *)p);
|
||||
}
|
||||
|
||||
static inline u32 get_unaligned_be32(const void *p)
|
||||
static __always_inline u32 get_unaligned_be32(const void *p)
|
||||
{
|
||||
return be32_to_cpup((__be32 *)p);
|
||||
}
|
||||
|
||||
static inline u64 get_unaligned_be64(const void *p)
|
||||
static __always_inline u64 get_unaligned_be64(const void *p)
|
||||
{
|
||||
return be64_to_cpup((__be64 *)p);
|
||||
}
|
||||
|
||||
static inline void put_unaligned_le16(u16 val, void *p)
|
||||
static __always_inline void put_unaligned_le16(u16 val, void *p)
|
||||
{
|
||||
*((__le16 *)p) = cpu_to_le16(val);
|
||||
}
|
||||
|
||||
static inline void put_unaligned_le32(u32 val, void *p)
|
||||
static __always_inline void put_unaligned_le32(u32 val, void *p)
|
||||
{
|
||||
*((__le32 *)p) = cpu_to_le32(val);
|
||||
}
|
||||
|
||||
static inline void put_unaligned_le64(u64 val, void *p)
|
||||
static __always_inline void put_unaligned_le64(u64 val, void *p)
|
||||
{
|
||||
*((__le64 *)p) = cpu_to_le64(val);
|
||||
}
|
||||
|
||||
static inline void put_unaligned_be16(u16 val, void *p)
|
||||
static __always_inline void put_unaligned_be16(u16 val, void *p)
|
||||
{
|
||||
*((__be16 *)p) = cpu_to_be16(val);
|
||||
}
|
||||
|
||||
static inline void put_unaligned_be32(u32 val, void *p)
|
||||
static __always_inline void put_unaligned_be32(u32 val, void *p)
|
||||
{
|
||||
*((__be32 *)p) = cpu_to_be32(val);
|
||||
}
|
||||
|
||||
static inline void put_unaligned_be64(u64 val, void *p)
|
||||
static __always_inline void put_unaligned_be64(u64 val, void *p)
|
||||
{
|
||||
*((__be64 *)p) = cpu_to_be64(val);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@ enum vm_event_item { PGPGIN, PGPGOUT, PSWPIN, PSWPOUT,
|
|||
COMPACTMIGRATE_SCANNED, COMPACTFREE_SCANNED,
|
||||
COMPACTISOLATED,
|
||||
COMPACTSTALL, COMPACTFAIL, COMPACTSUCCESS,
|
||||
KCOMPACTD_WAKE,
|
||||
#endif
|
||||
#ifdef CONFIG_HUGETLB_PAGE
|
||||
HTLB_BUDDY_PGALLOC, HTLB_BUDDY_PGALLOC_FAIL,
|
||||
|
|
@ -71,6 +72,7 @@ enum vm_event_item { PGPGIN, PGPGOUT, PSWPIN, PSWPOUT,
|
|||
THP_COLLAPSE_ALLOC_FAILED,
|
||||
THP_SPLIT_PAGE,
|
||||
THP_SPLIT_PAGE_FAILED,
|
||||
THP_DEFERRED_SPLIT_PAGE,
|
||||
THP_SPLIT_PMD,
|
||||
THP_ZERO_PAGE_ALLOC,
|
||||
THP_ZERO_PAGE_ALLOC_FAILED,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue