Commit a721aeac authored by Andrew Morton's avatar Andrew Morton

sync mm-stable with mm-hotfixes-stable to pick up depended-upon changes

parents d9d9bd97 1803d0c5
...@@ -429,6 +429,7 @@ Muna Sinada <quic_msinada@quicinc.com> <msinada@codeaurora.org> ...@@ -429,6 +429,7 @@ Muna Sinada <quic_msinada@quicinc.com> <msinada@codeaurora.org>
Murali Nalajala <quic_mnalajal@quicinc.com> <mnalajal@codeaurora.org> Murali Nalajala <quic_mnalajal@quicinc.com> <mnalajal@codeaurora.org>
Mythri P K <mythripk@ti.com> Mythri P K <mythripk@ti.com>
Nadia Yvette Chambers <nyc@holomorphy.com> William Lee Irwin III <wli@holomorphy.com> Nadia Yvette Chambers <nyc@holomorphy.com> William Lee Irwin III <wli@holomorphy.com>
Naoya Horiguchi <naoya.horiguchi@nec.com> <n-horiguchi@ah.jp.nec.com>
Nathan Chancellor <nathan@kernel.org> <natechancellor@gmail.com> Nathan Chancellor <nathan@kernel.org> <natechancellor@gmail.com>
Neeraj Upadhyay <quic_neeraju@quicinc.com> <neeraju@codeaurora.org> Neeraj Upadhyay <quic_neeraju@quicinc.com> <neeraju@codeaurora.org>
Neil Armstrong <neil.armstrong@linaro.org> <narmstrong@baylibre.com> Neil Armstrong <neil.armstrong@linaro.org> <narmstrong@baylibre.com>
......
...@@ -57,7 +57,7 @@ obj-$(CONFIG_MAGIC_SYSRQ) += sysrq.o ...@@ -57,7 +57,7 @@ obj-$(CONFIG_MAGIC_SYSRQ) += sysrq.o
obj-$(CONFIG_RELOCATABLE) += relocate.o obj-$(CONFIG_RELOCATABLE) += relocate.o
obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o obj-$(CONFIG_KEXEC_CORE) += machine_kexec.o relocate_kernel.o
obj-$(CONFIG_CRASH_DUMP) += crash_dump.o obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
obj-$(CONFIG_UNWINDER_GUESS) += unwind_guess.o obj-$(CONFIG_UNWINDER_GUESS) += unwind_guess.o
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
#ifndef _ASM_M68K_KEXEC_H #ifndef _ASM_M68K_KEXEC_H
#define _ASM_M68K_KEXEC_H #define _ASM_M68K_KEXEC_H
#ifdef CONFIG_KEXEC #ifdef CONFIG_KEXEC_CORE
/* Maximum physical address we can use pages from */ /* Maximum physical address we can use pages from */
#define KEXEC_SOURCE_MEMORY_LIMIT (-1UL) #define KEXEC_SOURCE_MEMORY_LIMIT (-1UL)
...@@ -25,6 +25,6 @@ static inline void crash_setup_regs(struct pt_regs *newregs, ...@@ -25,6 +25,6 @@ static inline void crash_setup_regs(struct pt_regs *newregs,
#endif /* __ASSEMBLY__ */ #endif /* __ASSEMBLY__ */
#endif /* CONFIG_KEXEC */ #endif /* CONFIG_KEXEC_CORE */
#endif /* _ASM_M68K_KEXEC_H */ #endif /* _ASM_M68K_KEXEC_H */
...@@ -25,7 +25,7 @@ obj-$(CONFIG_PCI) += pcibios.o ...@@ -25,7 +25,7 @@ obj-$(CONFIG_PCI) += pcibios.o
obj-$(CONFIG_M68K_NONCOHERENT_DMA) += dma.o obj-$(CONFIG_M68K_NONCOHERENT_DMA) += dma.o
obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o obj-$(CONFIG_KEXEC_CORE) += machine_kexec.o relocate_kernel.o
obj-$(CONFIG_BOOTINFO_PROC) += bootinfo_proc.o obj-$(CONFIG_BOOTINFO_PROC) += bootinfo_proc.o
obj-$(CONFIG_UBOOT) += uboot.o obj-$(CONFIG_UBOOT) += uboot.o
......
...@@ -422,7 +422,7 @@ static const struct plat_smp_ops octeon_smp_ops = { ...@@ -422,7 +422,7 @@ static const struct plat_smp_ops octeon_smp_ops = {
.cpu_disable = octeon_cpu_disable, .cpu_disable = octeon_cpu_disable,
.cpu_die = octeon_cpu_die, .cpu_die = octeon_cpu_die,
#endif #endif
#ifdef CONFIG_KEXEC #ifdef CONFIG_KEXEC_CORE
.kexec_nonboot_cpu = kexec_nonboot_cpu_jump, .kexec_nonboot_cpu = kexec_nonboot_cpu_jump,
#endif #endif
}; };
...@@ -502,7 +502,7 @@ static const struct plat_smp_ops octeon_78xx_smp_ops = { ...@@ -502,7 +502,7 @@ static const struct plat_smp_ops octeon_78xx_smp_ops = {
.cpu_disable = octeon_cpu_disable, .cpu_disable = octeon_cpu_disable,
.cpu_die = octeon_cpu_die, .cpu_die = octeon_cpu_die,
#endif #endif
#ifdef CONFIG_KEXEC #ifdef CONFIG_KEXEC_CORE
.kexec_nonboot_cpu = kexec_nonboot_cpu_jump, .kexec_nonboot_cpu = kexec_nonboot_cpu_jump,
#endif #endif
}; };
......
...@@ -31,7 +31,7 @@ static inline void crash_setup_regs(struct pt_regs *newregs, ...@@ -31,7 +31,7 @@ static inline void crash_setup_regs(struct pt_regs *newregs,
prepare_frametrace(newregs); prepare_frametrace(newregs);
} }
#ifdef CONFIG_KEXEC #ifdef CONFIG_KEXEC_CORE
struct kimage; struct kimage;
extern unsigned long kexec_args[4]; extern unsigned long kexec_args[4];
extern int (*_machine_kexec_prepare)(struct kimage *); extern int (*_machine_kexec_prepare)(struct kimage *);
......
...@@ -35,7 +35,7 @@ struct plat_smp_ops { ...@@ -35,7 +35,7 @@ struct plat_smp_ops {
void (*cpu_die)(unsigned int cpu); void (*cpu_die)(unsigned int cpu);
void (*cleanup_dead_cpu)(unsigned cpu); void (*cleanup_dead_cpu)(unsigned cpu);
#endif #endif
#ifdef CONFIG_KEXEC #ifdef CONFIG_KEXEC_CORE
void (*kexec_nonboot_cpu)(void); void (*kexec_nonboot_cpu)(void);
#endif #endif
}; };
......
...@@ -93,7 +93,7 @@ static inline void __cpu_die(unsigned int cpu) ...@@ -93,7 +93,7 @@ static inline void __cpu_die(unsigned int cpu)
extern void __noreturn play_dead(void); extern void __noreturn play_dead(void);
#endif #endif
#ifdef CONFIG_KEXEC #ifdef CONFIG_KEXEC_CORE
static inline void kexec_nonboot_cpu(void) static inline void kexec_nonboot_cpu(void)
{ {
extern const struct plat_smp_ops *mp_ops; /* private */ extern const struct plat_smp_ops *mp_ops; /* private */
......
...@@ -90,7 +90,7 @@ obj-$(CONFIG_GPIO_TXX9) += gpio_txx9.o ...@@ -90,7 +90,7 @@ obj-$(CONFIG_GPIO_TXX9) += gpio_txx9.o
obj-$(CONFIG_RELOCATABLE) += relocate.o obj-$(CONFIG_RELOCATABLE) += relocate.o
obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o crash.o obj-$(CONFIG_KEXEC_CORE) += machine_kexec.o relocate_kernel.o crash.o
obj-$(CONFIG_CRASH_DUMP) += crash_dump.o obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
obj-$(CONFIG_EARLY_PRINTK_8250) += early_printk_8250.o obj-$(CONFIG_EARLY_PRINTK_8250) += early_printk_8250.o
......
...@@ -434,7 +434,7 @@ const struct plat_smp_ops bmips43xx_smp_ops = { ...@@ -434,7 +434,7 @@ const struct plat_smp_ops bmips43xx_smp_ops = {
.cpu_disable = bmips_cpu_disable, .cpu_disable = bmips_cpu_disable,
.cpu_die = bmips_cpu_die, .cpu_die = bmips_cpu_die,
#endif #endif
#ifdef CONFIG_KEXEC #ifdef CONFIG_KEXEC_CORE
.kexec_nonboot_cpu = kexec_nonboot_cpu_jump, .kexec_nonboot_cpu = kexec_nonboot_cpu_jump,
#endif #endif
}; };
...@@ -451,7 +451,7 @@ const struct plat_smp_ops bmips5000_smp_ops = { ...@@ -451,7 +451,7 @@ const struct plat_smp_ops bmips5000_smp_ops = {
.cpu_disable = bmips_cpu_disable, .cpu_disable = bmips_cpu_disable,
.cpu_die = bmips_cpu_die, .cpu_die = bmips_cpu_die,
#endif #endif
#ifdef CONFIG_KEXEC #ifdef CONFIG_KEXEC_CORE
.kexec_nonboot_cpu = kexec_nonboot_cpu_jump, .kexec_nonboot_cpu = kexec_nonboot_cpu_jump,
#endif #endif
}; };
......
...@@ -392,7 +392,7 @@ static void cps_smp_finish(void) ...@@ -392,7 +392,7 @@ static void cps_smp_finish(void)
local_irq_enable(); local_irq_enable();
} }
#if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_KEXEC) #if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_KEXEC_CORE)
enum cpu_death { enum cpu_death {
CPU_DEATH_HALT, CPU_DEATH_HALT,
...@@ -429,7 +429,7 @@ static void cps_shutdown_this_cpu(enum cpu_death death) ...@@ -429,7 +429,7 @@ static void cps_shutdown_this_cpu(enum cpu_death death)
} }
} }
#ifdef CONFIG_KEXEC #ifdef CONFIG_KEXEC_CORE
static void cps_kexec_nonboot_cpu(void) static void cps_kexec_nonboot_cpu(void)
{ {
...@@ -439,9 +439,9 @@ static void cps_kexec_nonboot_cpu(void) ...@@ -439,9 +439,9 @@ static void cps_kexec_nonboot_cpu(void)
cps_shutdown_this_cpu(CPU_DEATH_POWER); cps_shutdown_this_cpu(CPU_DEATH_POWER);
} }
#endif /* CONFIG_KEXEC */ #endif /* CONFIG_KEXEC_CORE */
#endif /* CONFIG_HOTPLUG_CPU || CONFIG_KEXEC */ #endif /* CONFIG_HOTPLUG_CPU || CONFIG_KEXEC_CORE */
#ifdef CONFIG_HOTPLUG_CPU #ifdef CONFIG_HOTPLUG_CPU
...@@ -610,7 +610,7 @@ static const struct plat_smp_ops cps_smp_ops = { ...@@ -610,7 +610,7 @@ static const struct plat_smp_ops cps_smp_ops = {
.cpu_die = cps_cpu_die, .cpu_die = cps_cpu_die,
.cleanup_dead_cpu = cps_cleanup_dead_cpu, .cleanup_dead_cpu = cps_cleanup_dead_cpu,
#endif #endif
#ifdef CONFIG_KEXEC #ifdef CONFIG_KEXEC_CORE
.kexec_nonboot_cpu = cps_kexec_nonboot_cpu, .kexec_nonboot_cpu = cps_kexec_nonboot_cpu,
#endif #endif
}; };
......
...@@ -53,7 +53,7 @@ static void loongson_halt(void) ...@@ -53,7 +53,7 @@ static void loongson_halt(void)
} }
} }
#ifdef CONFIG_KEXEC #ifdef CONFIG_KEXEC_CORE
/* 0X80000000~0X80200000 is safe */ /* 0X80000000~0X80200000 is safe */
#define MAX_ARGS 64 #define MAX_ARGS 64
...@@ -158,7 +158,7 @@ static int __init mips_reboot_setup(void) ...@@ -158,7 +158,7 @@ static int __init mips_reboot_setup(void)
_machine_halt = loongson_halt; _machine_halt = loongson_halt;
pm_power_off = loongson_poweroff; pm_power_off = loongson_poweroff;
#ifdef CONFIG_KEXEC #ifdef CONFIG_KEXEC_CORE
kexec_argv = kmalloc(KEXEC_ARGV_SIZE, GFP_KERNEL); kexec_argv = kmalloc(KEXEC_ARGV_SIZE, GFP_KERNEL);
if (WARN_ON(!kexec_argv)) if (WARN_ON(!kexec_argv))
return -ENOMEM; return -ENOMEM;
......
...@@ -864,7 +864,7 @@ const struct plat_smp_ops loongson3_smp_ops = { ...@@ -864,7 +864,7 @@ const struct plat_smp_ops loongson3_smp_ops = {
.cpu_disable = loongson3_cpu_disable, .cpu_disable = loongson3_cpu_disable,
.cpu_die = loongson3_cpu_die, .cpu_die = loongson3_cpu_die,
#endif #endif
#ifdef CONFIG_KEXEC #ifdef CONFIG_KEXEC_CORE
.kexec_nonboot_cpu = kexec_nonboot_cpu_jump, .kexec_nonboot_cpu = kexec_nonboot_cpu_jump,
#endif #endif
}; };
...@@ -608,10 +608,10 @@ config ARCH_SUPPORTS_KEXEC ...@@ -608,10 +608,10 @@ config ARCH_SUPPORTS_KEXEC
def_bool PPC_BOOK3S || PPC_E500 || (44x && !SMP) def_bool PPC_BOOK3S || PPC_E500 || (44x && !SMP)
config ARCH_SUPPORTS_KEXEC_FILE config ARCH_SUPPORTS_KEXEC_FILE
def_bool PPC64 && CRYPTO=y && CRYPTO_SHA256=y def_bool PPC64
config ARCH_SUPPORTS_KEXEC_PURGATORY config ARCH_SUPPORTS_KEXEC_PURGATORY
def_bool KEXEC_FILE def_bool y
config ARCH_SELECTS_KEXEC_FILE config ARCH_SELECTS_KEXEC_FILE
def_bool y def_bool y
......
...@@ -685,7 +685,7 @@ config RISCV_BOOT_SPINWAIT ...@@ -685,7 +685,7 @@ config RISCV_BOOT_SPINWAIT
If unsure what to do here, say N. If unsure what to do here, say N.
config ARCH_SUPPORTS_KEXEC config ARCH_SUPPORTS_KEXEC
def_bool MMU def_bool y
config ARCH_SELECTS_KEXEC config ARCH_SELECTS_KEXEC
def_bool y def_bool y
...@@ -693,7 +693,7 @@ config ARCH_SELECTS_KEXEC ...@@ -693,7 +693,7 @@ config ARCH_SELECTS_KEXEC
select HOTPLUG_CPU if SMP select HOTPLUG_CPU if SMP
config ARCH_SUPPORTS_KEXEC_FILE config ARCH_SUPPORTS_KEXEC_FILE
def_bool 64BIT && MMU def_bool 64BIT
config ARCH_SELECTS_KEXEC_FILE config ARCH_SELECTS_KEXEC_FILE
def_bool y def_bool y
...@@ -702,9 +702,7 @@ config ARCH_SELECTS_KEXEC_FILE ...@@ -702,9 +702,7 @@ config ARCH_SELECTS_KEXEC_FILE
select KEXEC_ELF select KEXEC_ELF
config ARCH_SUPPORTS_KEXEC_PURGATORY config ARCH_SUPPORTS_KEXEC_PURGATORY
def_bool KEXEC_FILE def_bool ARCH_SUPPORTS_KEXEC_FILE
depends on CRYPTO=y
depends on CRYPTO_SHA256=y
config ARCH_SUPPORTS_CRASH_DUMP config ARCH_SUPPORTS_CRASH_DUMP
def_bool y def_bool y
......
...@@ -899,7 +899,7 @@ static inline pte_t pte_swp_clear_exclusive(pte_t pte) ...@@ -899,7 +899,7 @@ static inline pte_t pte_swp_clear_exclusive(pte_t pte)
#define PAGE_KERNEL __pgprot(0) #define PAGE_KERNEL __pgprot(0)
#define swapper_pg_dir NULL #define swapper_pg_dir NULL
#define TASK_SIZE 0xffffffffUL #define TASK_SIZE 0xffffffffUL
#define VMALLOC_START 0 #define VMALLOC_START _AC(0, UL)
#define VMALLOC_END TASK_SIZE #define VMALLOC_END TASK_SIZE
#endif /* !CONFIG_MMU */ #endif /* !CONFIG_MMU */
......
...@@ -5,17 +5,19 @@ ...@@ -5,17 +5,19 @@
void arch_crash_save_vmcoreinfo(void) void arch_crash_save_vmcoreinfo(void)
{ {
VMCOREINFO_NUMBER(VA_BITS);
VMCOREINFO_NUMBER(phys_ram_base); VMCOREINFO_NUMBER(phys_ram_base);
vmcoreinfo_append_str("NUMBER(PAGE_OFFSET)=0x%lx\n", PAGE_OFFSET); vmcoreinfo_append_str("NUMBER(PAGE_OFFSET)=0x%lx\n", PAGE_OFFSET);
vmcoreinfo_append_str("NUMBER(VMALLOC_START)=0x%lx\n", VMALLOC_START); vmcoreinfo_append_str("NUMBER(VMALLOC_START)=0x%lx\n", VMALLOC_START);
vmcoreinfo_append_str("NUMBER(VMALLOC_END)=0x%lx\n", VMALLOC_END); vmcoreinfo_append_str("NUMBER(VMALLOC_END)=0x%lx\n", VMALLOC_END);
#ifdef CONFIG_MMU
VMCOREINFO_NUMBER(VA_BITS);
vmcoreinfo_append_str("NUMBER(VMEMMAP_START)=0x%lx\n", VMEMMAP_START); vmcoreinfo_append_str("NUMBER(VMEMMAP_START)=0x%lx\n", VMEMMAP_START);
vmcoreinfo_append_str("NUMBER(VMEMMAP_END)=0x%lx\n", VMEMMAP_END); vmcoreinfo_append_str("NUMBER(VMEMMAP_END)=0x%lx\n", VMEMMAP_END);
#ifdef CONFIG_64BIT #ifdef CONFIG_64BIT
vmcoreinfo_append_str("NUMBER(MODULES_VADDR)=0x%lx\n", MODULES_VADDR); vmcoreinfo_append_str("NUMBER(MODULES_VADDR)=0x%lx\n", MODULES_VADDR);
vmcoreinfo_append_str("NUMBER(MODULES_END)=0x%lx\n", MODULES_END); vmcoreinfo_append_str("NUMBER(MODULES_END)=0x%lx\n", MODULES_END);
#endif
#endif #endif
vmcoreinfo_append_str("NUMBER(KERNEL_LINK_ADDR)=0x%lx\n", KERNEL_LINK_ADDR); vmcoreinfo_append_str("NUMBER(KERNEL_LINK_ADDR)=0x%lx\n", KERNEL_LINK_ADDR);
vmcoreinfo_append_str("NUMBER(va_kernel_pa_offset)=0x%lx\n", vmcoreinfo_append_str("NUMBER(va_kernel_pa_offset)=0x%lx\n",
......
...@@ -254,13 +254,13 @@ config ARCH_SUPPORTS_KEXEC ...@@ -254,13 +254,13 @@ config ARCH_SUPPORTS_KEXEC
def_bool y def_bool y
config ARCH_SUPPORTS_KEXEC_FILE config ARCH_SUPPORTS_KEXEC_FILE
def_bool CRYPTO && CRYPTO_SHA256 && CRYPTO_SHA256_S390 def_bool y
config ARCH_SUPPORTS_KEXEC_SIG config ARCH_SUPPORTS_KEXEC_SIG
def_bool MODULE_SIG_FORMAT def_bool MODULE_SIG_FORMAT
config ARCH_SUPPORTS_KEXEC_PURGATORY config ARCH_SUPPORTS_KEXEC_PURGATORY
def_bool KEXEC_FILE def_bool y
config ARCH_SUPPORTS_CRASH_DUMP config ARCH_SUPPORTS_CRASH_DUMP
def_bool y def_bool y
......
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
/* The native architecture */ /* The native architecture */
#define KEXEC_ARCH KEXEC_ARCH_SH #define KEXEC_ARCH KEXEC_ARCH_SH
#ifdef CONFIG_KEXEC #ifdef CONFIG_KEXEC_CORE
/* arch/sh/kernel/machine_kexec.c */ /* arch/sh/kernel/machine_kexec.c */
void reserve_crashkernel(void); void reserve_crashkernel(void);
...@@ -67,6 +67,6 @@ static inline void crash_setup_regs(struct pt_regs *newregs, ...@@ -67,6 +67,6 @@ static inline void crash_setup_regs(struct pt_regs *newregs,
} }
#else #else
static inline void reserve_crashkernel(void) { } static inline void reserve_crashkernel(void) { }
#endif /* CONFIG_KEXEC */ #endif /* CONFIG_KEXEC_CORE */
#endif /* __ASM_SH_KEXEC_H */ #endif /* __ASM_SH_KEXEC_H */
...@@ -33,7 +33,7 @@ obj-$(CONFIG_SMP) += smp.o ...@@ -33,7 +33,7 @@ obj-$(CONFIG_SMP) += smp.o
obj-$(CONFIG_SH_STANDARD_BIOS) += sh_bios.o obj-$(CONFIG_SH_STANDARD_BIOS) += sh_bios.o
obj-$(CONFIG_KGDB) += kgdb.o obj-$(CONFIG_KGDB) += kgdb.o
obj-$(CONFIG_MODULES) += sh_ksyms_32.o module.o obj-$(CONFIG_MODULES) += sh_ksyms_32.o module.o
obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o obj-$(CONFIG_KEXEC_CORE) += machine_kexec.o relocate_kernel.o
obj-$(CONFIG_CRASH_DUMP) += crash_dump.o obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
obj-$(CONFIG_STACKTRACE) += stacktrace.o obj-$(CONFIG_STACKTRACE) += stacktrace.o
obj-$(CONFIG_IO_TRAPPED) += io_trapped.o obj-$(CONFIG_IO_TRAPPED) += io_trapped.o
......
...@@ -63,7 +63,7 @@ struct machine_ops machine_ops = { ...@@ -63,7 +63,7 @@ struct machine_ops machine_ops = {
.shutdown = native_machine_shutdown, .shutdown = native_machine_shutdown,
.restart = native_machine_restart, .restart = native_machine_restart,
.halt = native_machine_halt, .halt = native_machine_halt,
#ifdef CONFIG_KEXEC #ifdef CONFIG_KEXEC_CORE
.crash_shutdown = native_machine_crash_shutdown, .crash_shutdown = native_machine_crash_shutdown,
#endif #endif
}; };
...@@ -88,7 +88,7 @@ void machine_halt(void) ...@@ -88,7 +88,7 @@ void machine_halt(void)
machine_ops.halt(); machine_ops.halt();
} }
#ifdef CONFIG_KEXEC #ifdef CONFIG_KEXEC_CORE
void machine_crash_shutdown(struct pt_regs *regs) void machine_crash_shutdown(struct pt_regs *regs)
{ {
machine_ops.crash_shutdown(regs); machine_ops.crash_shutdown(regs);
......
...@@ -220,7 +220,7 @@ void __init __add_active_range(unsigned int nid, unsigned long start_pfn, ...@@ -220,7 +220,7 @@ void __init __add_active_range(unsigned int nid, unsigned long start_pfn,
request_resource(res, &code_resource); request_resource(res, &code_resource);
request_resource(res, &data_resource); request_resource(res, &data_resource);
request_resource(res, &bss_resource); request_resource(res, &bss_resource);
#ifdef CONFIG_KEXEC #ifdef CONFIG_KEXEC_CORE
request_resource(res, &crashk_res); request_resource(res, &crashk_res);
#endif #endif
......
...@@ -2072,7 +2072,7 @@ config ARCH_SUPPORTS_KEXEC ...@@ -2072,7 +2072,7 @@ config ARCH_SUPPORTS_KEXEC
def_bool y def_bool y
config ARCH_SUPPORTS_KEXEC_FILE config ARCH_SUPPORTS_KEXEC_FILE
def_bool X86_64 && CRYPTO && CRYPTO_SHA256 def_bool X86_64
config ARCH_SELECTS_KEXEC_FILE config ARCH_SELECTS_KEXEC_FILE
def_bool y def_bool y
...@@ -2080,7 +2080,7 @@ config ARCH_SELECTS_KEXEC_FILE ...@@ -2080,7 +2080,7 @@ config ARCH_SELECTS_KEXEC_FILE
select HAVE_IMA_KEXEC if IMA select HAVE_IMA_KEXEC if IMA
config ARCH_SUPPORTS_KEXEC_PURGATORY config ARCH_SUPPORTS_KEXEC_PURGATORY
def_bool KEXEC_FILE def_bool y
config ARCH_SUPPORTS_KEXEC_SIG config ARCH_SUPPORTS_KEXEC_SIG
def_bool y def_bool y
......
...@@ -178,7 +178,7 @@ static unsigned long get_cmdline_acpi_rsdp(void) ...@@ -178,7 +178,7 @@ static unsigned long get_cmdline_acpi_rsdp(void)
{ {
unsigned long addr = 0; unsigned long addr = 0;
#ifdef CONFIG_KEXEC #ifdef CONFIG_KEXEC_CORE
char val[MAX_ADDR_LEN] = { }; char val[MAX_ADDR_LEN] = { };
int ret; int ret;
......
...@@ -579,6 +579,8 @@ struct damon_ctx { ...@@ -579,6 +579,8 @@ struct damon_ctx {
* update * update
*/ */
unsigned long next_ops_update_sis; unsigned long next_ops_update_sis;
/* for waiting until the execution of the kdamond_fn is started */
struct completion kdamond_started;
/* public: */ /* public: */
struct task_struct *kdamond; struct task_struct *kdamond;
......
...@@ -886,8 +886,8 @@ static inline bool vma_is_anonymous(struct vm_area_struct *vma) ...@@ -886,8 +886,8 @@ static inline bool vma_is_anonymous(struct vm_area_struct *vma)
*/ */
static inline bool vma_is_initial_heap(const struct vm_area_struct *vma) static inline bool vma_is_initial_heap(const struct vm_area_struct *vma)
{ {
return vma->vm_start <= vma->vm_mm->brk && return vma->vm_start < vma->vm_mm->brk &&
vma->vm_end >= vma->vm_mm->start_brk; vma->vm_end > vma->vm_mm->start_brk;
} }
/* /*
......
...@@ -232,22 +232,27 @@ static inline bool lru_gen_add_folio(struct lruvec *lruvec, struct folio *folio, ...@@ -232,22 +232,27 @@ static inline bool lru_gen_add_folio(struct lruvec *lruvec, struct folio *folio,
if (folio_test_unevictable(folio) || !lrugen->enabled) if (folio_test_unevictable(folio) || !lrugen->enabled)
return false; return false;
/* /*
* There are three common cases for this page: * There are four common cases for this page:
* 1. If it's hot, e.g., freshly faulted in or previously hot and * 1. If it's hot, i.e., freshly faulted in, add it to the youngest
* migrated, add it to the youngest generation. * generation, and it's protected over the rest below.
* 2. If it's cold but can't be evicted immediately, i.e., an anon page * 2. If it can't be evicted immediately, i.e., a dirty page pending
* not in swapcache or a dirty page pending writeback, add it to the * writeback, add it to the second youngest generation.
* second oldest generation. * 3. If it should be evicted first, e.g., cold and clean from
* 3. Everything else (clean, cold) is added to the oldest generation. * folio_rotate_reclaimable(), add it to the oldest generation.
* 4. Everything else falls between 2 & 3 above and is added to the
* second oldest generation if it's considered inactive, or the
* oldest generation otherwise. See lru_gen_is_active().
*/ */
if (folio_test_active(folio)) if (folio_test_active(folio))
seq = lrugen->max_seq; seq = lrugen->max_seq;
else if ((type == LRU_GEN_ANON && !folio_test_swapcache(folio)) || else if ((type == LRU_GEN_ANON && !folio_test_swapcache(folio)) ||
(folio_test_reclaim(folio) && (folio_test_reclaim(folio) &&
(folio_test_dirty(folio) || folio_test_writeback(folio)))) (folio_test_dirty(folio) || folio_test_writeback(folio))))
seq = lrugen->min_seq[type] + 1; seq = lrugen->max_seq - 1;
else else if (reclaiming || lrugen->min_seq[type] + MIN_NR_GENS >= lrugen->max_seq)
seq = lrugen->min_seq[type]; seq = lrugen->min_seq[type];
else
seq = lrugen->min_seq[type] + 1;
gen = lru_gen_from_seq(seq); gen = lru_gen_from_seq(seq);
flags = (gen + 1UL) << LRU_GEN_PGOFF; flags = (gen + 1UL) << LRU_GEN_PGOFF;
......
...@@ -510,33 +510,37 @@ void lru_gen_look_around(struct page_vma_mapped_walk *pvmw); ...@@ -510,33 +510,37 @@ void lru_gen_look_around(struct page_vma_mapped_walk *pvmw);
* the old generation, is incremented when all its bins become empty. * the old generation, is incremented when all its bins become empty.
* *
* There are four operations: * There are four operations:
* 1. MEMCG_LRU_HEAD, which moves an memcg to the head of a random bin in its * 1. MEMCG_LRU_HEAD, which moves a memcg to the head of a random bin in its
* current generation (old or young) and updates its "seg" to "head"; * current generation (old or young) and updates its "seg" to "head";
* 2. MEMCG_LRU_TAIL, which moves an memcg to the tail of a random bin in its * 2. MEMCG_LRU_TAIL, which moves a memcg to the tail of a random bin in its
* current generation (old or young) and updates its "seg" to "tail"; * current generation (old or young) and updates its "seg" to "tail";
* 3. MEMCG_LRU_OLD, which moves an memcg to the head of a random bin in the old * 3. MEMCG_LRU_OLD, which moves a memcg to the head of a random bin in the old
* generation, updates its "gen" to "old" and resets its "seg" to "default"; * generation, updates its "gen" to "old" and resets its "seg" to "default";
* 4. MEMCG_LRU_YOUNG, which moves an memcg to the tail of a random bin in the * 4. MEMCG_LRU_YOUNG, which moves a memcg to the tail of a random bin in the
* young generation, updates its "gen" to "young" and resets its "seg" to * young generation, updates its "gen" to "young" and resets its "seg" to
* "default". * "default".
* *
* The events that trigger the above operations are: * The events that trigger the above operations are:
* 1. Exceeding the soft limit, which triggers MEMCG_LRU_HEAD; * 1. Exceeding the soft limit, which triggers MEMCG_LRU_HEAD;
* 2. The first attempt to reclaim an memcg below low, which triggers * 2. The first attempt to reclaim a memcg below low, which triggers
* MEMCG_LRU_TAIL; * MEMCG_LRU_TAIL;
* 3. The first attempt to reclaim an memcg below reclaimable size threshold, * 3. The first attempt to reclaim a memcg offlined or below reclaimable size
* which triggers MEMCG_LRU_TAIL; * threshold, which triggers MEMCG_LRU_TAIL;
* 4. The second attempt to reclaim an memcg below reclaimable size threshold, * 4. The second attempt to reclaim a memcg offlined or below reclaimable size
* which triggers MEMCG_LRU_YOUNG; * threshold, which triggers MEMCG_LRU_YOUNG;
* 5. Attempting to reclaim an memcg below min, which triggers MEMCG_LRU_YOUNG; * 5. Attempting to reclaim a memcg below min, which triggers MEMCG_LRU_YOUNG;
* 6. Finishing the aging on the eviction path, which triggers MEMCG_LRU_YOUNG; * 6. Finishing the aging on the eviction path, which triggers MEMCG_LRU_YOUNG;
* 7. Offlining an memcg, which triggers MEMCG_LRU_OLD. * 7. Offlining a memcg, which triggers MEMCG_LRU_OLD.
* *
* Note that memcg LRU only applies to global reclaim, and the round-robin * Notes:
* incrementing of their max_seq counters ensures the eventual fairness to all * 1. Memcg LRU only applies to global reclaim, and the round-robin incrementing
* eligible memcgs. For memcg reclaim, it still relies on mem_cgroup_iter(). * of their max_seq counters ensures the eventual fairness to all eligible
*/ * memcgs. For memcg reclaim, it still relies on mem_cgroup_iter().
#define MEMCG_NR_GENS 2 * 2. There are only two valid generations: old (seq) and young (seq+1).
* MEMCG_NR_GENS is set to three so that when reading the generation counter
* locklessly, a stale value (seq-1) does not wraparound to young.
*/
#define MEMCG_NR_GENS 3
#define MEMCG_NR_BINS 8 #define MEMCG_NR_BINS 8
struct lru_gen_memcg { struct lru_gen_memcg {
......
...@@ -36,6 +36,8 @@ config KEXEC ...@@ -36,6 +36,8 @@ config KEXEC
config KEXEC_FILE config KEXEC_FILE
bool "Enable kexec file based system call" bool "Enable kexec file based system call"
depends on ARCH_SUPPORTS_KEXEC_FILE depends on ARCH_SUPPORTS_KEXEC_FILE
select CRYPTO
select CRYPTO_SHA256
select KEXEC_CORE select KEXEC_CORE
help help
This is new version of kexec system call. This system call is This is new version of kexec system call. This system call is
...@@ -94,7 +96,6 @@ config KEXEC_JUMP ...@@ -94,7 +96,6 @@ config KEXEC_JUMP
config CRASH_DUMP config CRASH_DUMP
bool "kernel crash dumps" bool "kernel crash dumps"
depends on ARCH_SUPPORTS_CRASH_DUMP depends on ARCH_SUPPORTS_CRASH_DUMP
depends on ARCH_SUPPORTS_KEXEC
select CRASH_CORE select CRASH_CORE
select KEXEC_CORE select KEXEC_CORE
help help
......
...@@ -440,7 +440,7 @@ void __init reserve_crashkernel_generic(char *cmdline, ...@@ -440,7 +440,7 @@ void __init reserve_crashkernel_generic(char *cmdline,
return; return;
} }
if ((crash_base > CRASH_ADDR_LOW_MAX) && if ((crash_base >= CRASH_ADDR_LOW_MAX) &&
crash_low_size && reserve_crashkernel_low(crash_low_size)) { crash_low_size && reserve_crashkernel_low(crash_low_size)) {
memblock_phys_free(crash_base, crash_size); memblock_phys_free(crash_base, crash_size);
return; return;
......
...@@ -5475,6 +5475,17 @@ int mas_preallocate(struct ma_state *mas, void *entry, gfp_t gfp) ...@@ -5475,6 +5475,17 @@ int mas_preallocate(struct ma_state *mas, void *entry, gfp_t gfp)
mas_wr_end_piv(&wr_mas); mas_wr_end_piv(&wr_mas);
node_size = mas_wr_new_end(&wr_mas); node_size = mas_wr_new_end(&wr_mas);
/* Slot store, does not require additional nodes */
if (node_size == wr_mas.node_end) {
/* reuse node */
if (!mt_in_rcu(mas->tree))
return 0;
/* shifting boundary */
if (wr_mas.offset_end - mas->offset == 1)
return 0;
}
if (node_size >= mt_slots[wr_mas.type]) { if (node_size >= mt_slots[wr_mas.type]) {
/* Split, worst case for now. */ /* Split, worst case for now. */
request = 1 + mas_mt_height(mas) * 2; request = 1 + mas_mt_height(mas) * 2;
......
...@@ -445,6 +445,8 @@ struct damon_ctx *damon_new_ctx(void) ...@@ -445,6 +445,8 @@ struct damon_ctx *damon_new_ctx(void)
if (!ctx) if (!ctx)
return NULL; return NULL;
init_completion(&ctx->kdamond_started);
ctx->attrs.sample_interval = 5 * 1000; ctx->attrs.sample_interval = 5 * 1000;
ctx->attrs.aggr_interval = 100 * 1000; ctx->attrs.aggr_interval = 100 * 1000;
ctx->attrs.ops_update_interval = 60 * 1000 * 1000; ctx->attrs.ops_update_interval = 60 * 1000 * 1000;
...@@ -668,11 +670,14 @@ static int __damon_start(struct damon_ctx *ctx) ...@@ -668,11 +670,14 @@ static int __damon_start(struct damon_ctx *ctx)
mutex_lock(&ctx->kdamond_lock); mutex_lock(&ctx->kdamond_lock);
if (!ctx->kdamond) { if (!ctx->kdamond) {
err = 0; err = 0;
reinit_completion(&ctx->kdamond_started);
ctx->kdamond = kthread_run(kdamond_fn, ctx, "kdamond.%d", ctx->kdamond = kthread_run(kdamond_fn, ctx, "kdamond.%d",
nr_running_ctxs); nr_running_ctxs);
if (IS_ERR(ctx->kdamond)) { if (IS_ERR(ctx->kdamond)) {
err = PTR_ERR(ctx->kdamond); err = PTR_ERR(ctx->kdamond);
ctx->kdamond = NULL; ctx->kdamond = NULL;
} else {
wait_for_completion(&ctx->kdamond_started);
} }
} }
mutex_unlock(&ctx->kdamond_lock); mutex_unlock(&ctx->kdamond_lock);
...@@ -1483,6 +1488,7 @@ static int kdamond_fn(void *data) ...@@ -1483,6 +1488,7 @@ static int kdamond_fn(void *data)
pr_debug("kdamond (%d) starts\n", current->pid); pr_debug("kdamond (%d) starts\n", current->pid);
complete(&ctx->kdamond_started);
kdamond_init_intervals_sis(ctx); kdamond_init_intervals_sis(ctx);
if (ctx->ops.init) if (ctx->ops.init)
......
...@@ -2607,6 +2607,15 @@ ssize_t filemap_read(struct kiocb *iocb, struct iov_iter *iter, ...@@ -2607,6 +2607,15 @@ ssize_t filemap_read(struct kiocb *iocb, struct iov_iter *iter,
goto put_folios; goto put_folios;
end_offset = min_t(loff_t, isize, iocb->ki_pos + iter->count); end_offset = min_t(loff_t, isize, iocb->ki_pos + iter->count);
/*
* Pairs with a barrier in
* block_write_end()->mark_buffer_dirty() or other page
* dirtying routines like iomap_write_end() to ensure
* changes to page contents are visible before we see
* increased inode size.
*/
smp_rmb();
/* /*
* Once we start copying data, we don't want to be touching any * Once we start copying data, we don't want to be touching any
* cachelines that might be contended: * cachelines that might be contended:
......
...@@ -493,14 +493,17 @@ static void kmalloc_oob_memset_2(struct kunit *test) ...@@ -493,14 +493,17 @@ static void kmalloc_oob_memset_2(struct kunit *test)
{ {
char *ptr; char *ptr;
size_t size = 128 - KASAN_GRANULE_SIZE; size_t size = 128 - KASAN_GRANULE_SIZE;
size_t memset_size = 2;
KASAN_TEST_NEEDS_CHECKED_MEMINTRINSICS(test); KASAN_TEST_NEEDS_CHECKED_MEMINTRINSICS(test);
ptr = kmalloc(size, GFP_KERNEL); ptr = kmalloc(size, GFP_KERNEL);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr);
OPTIMIZER_HIDE_VAR(ptr);
OPTIMIZER_HIDE_VAR(size); OPTIMIZER_HIDE_VAR(size);
KUNIT_EXPECT_KASAN_FAIL(test, memset(ptr + size - 1, 0, 2)); OPTIMIZER_HIDE_VAR(memset_size);
KUNIT_EXPECT_KASAN_FAIL(test, memset(ptr + size - 1, 0, memset_size));
kfree(ptr); kfree(ptr);
} }
...@@ -508,14 +511,17 @@ static void kmalloc_oob_memset_4(struct kunit *test) ...@@ -508,14 +511,17 @@ static void kmalloc_oob_memset_4(struct kunit *test)
{ {
char *ptr; char *ptr;
size_t size = 128 - KASAN_GRANULE_SIZE; size_t size = 128 - KASAN_GRANULE_SIZE;
size_t memset_size = 4;
KASAN_TEST_NEEDS_CHECKED_MEMINTRINSICS(test); KASAN_TEST_NEEDS_CHECKED_MEMINTRINSICS(test);
ptr = kmalloc(size, GFP_KERNEL); ptr = kmalloc(size, GFP_KERNEL);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr);
OPTIMIZER_HIDE_VAR(ptr);
OPTIMIZER_HIDE_VAR(size); OPTIMIZER_HIDE_VAR(size);
KUNIT_EXPECT_KASAN_FAIL(test, memset(ptr + size - 3, 0, 4)); OPTIMIZER_HIDE_VAR(memset_size);
KUNIT_EXPECT_KASAN_FAIL(test, memset(ptr + size - 3, 0, memset_size));
kfree(ptr); kfree(ptr);
} }
...@@ -523,14 +529,17 @@ static void kmalloc_oob_memset_8(struct kunit *test) ...@@ -523,14 +529,17 @@ static void kmalloc_oob_memset_8(struct kunit *test)
{ {
char *ptr; char *ptr;
size_t size = 128 - KASAN_GRANULE_SIZE; size_t size = 128 - KASAN_GRANULE_SIZE;
size_t memset_size = 8;
KASAN_TEST_NEEDS_CHECKED_MEMINTRINSICS(test); KASAN_TEST_NEEDS_CHECKED_MEMINTRINSICS(test);
ptr = kmalloc(size, GFP_KERNEL); ptr = kmalloc(size, GFP_KERNEL);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr);
OPTIMIZER_HIDE_VAR(ptr);
OPTIMIZER_HIDE_VAR(size); OPTIMIZER_HIDE_VAR(size);
KUNIT_EXPECT_KASAN_FAIL(test, memset(ptr + size - 7, 0, 8)); OPTIMIZER_HIDE_VAR(memset_size);
KUNIT_EXPECT_KASAN_FAIL(test, memset(ptr + size - 7, 0, memset_size));
kfree(ptr); kfree(ptr);
} }
...@@ -538,14 +547,17 @@ static void kmalloc_oob_memset_16(struct kunit *test) ...@@ -538,14 +547,17 @@ static void kmalloc_oob_memset_16(struct kunit *test)
{ {
char *ptr; char *ptr;
size_t size = 128 - KASAN_GRANULE_SIZE; size_t size = 128 - KASAN_GRANULE_SIZE;
size_t memset_size = 16;
KASAN_TEST_NEEDS_CHECKED_MEMINTRINSICS(test); KASAN_TEST_NEEDS_CHECKED_MEMINTRINSICS(test);
ptr = kmalloc(size, GFP_KERNEL); ptr = kmalloc(size, GFP_KERNEL);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr);
OPTIMIZER_HIDE_VAR(ptr);
OPTIMIZER_HIDE_VAR(size); OPTIMIZER_HIDE_VAR(size);
KUNIT_EXPECT_KASAN_FAIL(test, memset(ptr + size - 15, 0, 16)); OPTIMIZER_HIDE_VAR(memset_size);
KUNIT_EXPECT_KASAN_FAIL(test, memset(ptr + size - 15, 0, memset_size));
kfree(ptr); kfree(ptr);
} }
......
...@@ -595,10 +595,9 @@ struct task_struct *task_early_kill(struct task_struct *tsk, int force_early) ...@@ -595,10 +595,9 @@ struct task_struct *task_early_kill(struct task_struct *tsk, int force_early)
/* /*
* Collect processes when the error hit an anonymous page. * Collect processes when the error hit an anonymous page.
*/ */
static void collect_procs_anon(struct page *page, struct list_head *to_kill, static void collect_procs_anon(struct folio *folio, struct page *page,
int force_early) struct list_head *to_kill, int force_early)
{ {
struct folio *folio = page_folio(page);
struct vm_area_struct *vma; struct vm_area_struct *vma;
struct task_struct *tsk; struct task_struct *tsk;
struct anon_vma *av; struct anon_vma *av;
...@@ -633,12 +632,12 @@ static void collect_procs_anon(struct page *page, struct list_head *to_kill, ...@@ -633,12 +632,12 @@ static void collect_procs_anon(struct page *page, struct list_head *to_kill,
/* /*
* Collect processes when the error hit a file mapped page. * Collect processes when the error hit a file mapped page.
*/ */
static void collect_procs_file(struct page *page, struct list_head *to_kill, static void collect_procs_file(struct folio *folio, struct page *page,
int force_early) struct list_head *to_kill, int force_early)
{ {
struct vm_area_struct *vma; struct vm_area_struct *vma;
struct task_struct *tsk; struct task_struct *tsk;
struct address_space *mapping = page->mapping; struct address_space *mapping = folio->mapping;
pgoff_t pgoff; pgoff_t pgoff;
i_mmap_lock_read(mapping); i_mmap_lock_read(mapping);
...@@ -704,17 +703,17 @@ static void collect_procs_fsdax(struct page *page, ...@@ -704,17 +703,17 @@ static void collect_procs_fsdax(struct page *page,
/* /*
* Collect the processes who have the corrupted page mapped to kill. * Collect the processes who have the corrupted page mapped to kill.
*/ */
static void collect_procs(struct page *page, struct list_head *tokill, static void collect_procs(struct folio *folio, struct page *page,
int force_early) struct list_head *tokill, int force_early)
{ {
if (!page->mapping) if (!folio->mapping)
return; return;
if (unlikely(PageKsm(page))) if (unlikely(PageKsm(page)))
collect_procs_ksm(page, tokill, force_early); collect_procs_ksm(page, tokill, force_early);
else if (PageAnon(page)) else if (PageAnon(page))
collect_procs_anon(page, tokill, force_early); collect_procs_anon(folio, page, tokill, force_early);
else else
collect_procs_file(page, tokill, force_early); collect_procs_file(folio, page, tokill, force_early);
} }
struct hwpoison_walk { struct hwpoison_walk {
...@@ -1570,7 +1569,7 @@ static bool hwpoison_user_mappings(struct page *p, unsigned long pfn, ...@@ -1570,7 +1569,7 @@ static bool hwpoison_user_mappings(struct page *p, unsigned long pfn,
* This check implies we don't kill processes if their pages * This check implies we don't kill processes if their pages
* are in the swap cache early. Those are always late kills. * are in the swap cache early. Those are always late kills.
*/ */
if (!page_mapped(hpage)) if (!page_mapped(p))
return true; return true;
if (PageSwapCache(p)) { if (PageSwapCache(p)) {
...@@ -1601,7 +1600,7 @@ static bool hwpoison_user_mappings(struct page *p, unsigned long pfn, ...@@ -1601,7 +1600,7 @@ static bool hwpoison_user_mappings(struct page *p, unsigned long pfn,
* mapped in dirty form. This has to be done before try_to_unmap, * mapped in dirty form. This has to be done before try_to_unmap,
* because ttu takes the rmap data structures down. * because ttu takes the rmap data structures down.
*/ */
collect_procs(hpage, &tokill, flags & MF_ACTION_REQUIRED); collect_procs(folio, p, &tokill, flags & MF_ACTION_REQUIRED);
if (PageHuge(hpage) && !PageAnon(hpage)) { if (PageHuge(hpage) && !PageAnon(hpage)) {
/* /*
...@@ -1621,10 +1620,10 @@ static bool hwpoison_user_mappings(struct page *p, unsigned long pfn, ...@@ -1621,10 +1620,10 @@ static bool hwpoison_user_mappings(struct page *p, unsigned long pfn,
try_to_unmap(folio, ttu); try_to_unmap(folio, ttu);
} }
unmap_success = !page_mapped(hpage); unmap_success = !page_mapped(p);
if (!unmap_success) if (!unmap_success)
pr_err("%#lx: failed to unmap page (mapcount=%d)\n", pr_err("%#lx: failed to unmap page (mapcount=%d)\n",
pfn, page_mapcount(hpage)); pfn, page_mapcount(p));
/* /*
* try_to_unmap() might put mlocked page in lru cache, so call * try_to_unmap() might put mlocked page in lru cache, so call
...@@ -1704,7 +1703,7 @@ static void unmap_and_kill(struct list_head *to_kill, unsigned long pfn, ...@@ -1704,7 +1703,7 @@ static void unmap_and_kill(struct list_head *to_kill, unsigned long pfn,
* mapping being torn down is communicated in siginfo, see * mapping being torn down is communicated in siginfo, see
* kill_proc() * kill_proc()
*/ */
loff_t start = (index << PAGE_SHIFT) & ~(size - 1); loff_t start = ((loff_t)index << PAGE_SHIFT) & ~(size - 1);
unmap_mapping_range(mapping, start, size, 0); unmap_mapping_range(mapping, start, size, 0);
} }
...@@ -1771,7 +1770,7 @@ static int mf_generic_kill_procs(unsigned long long pfn, int flags, ...@@ -1771,7 +1770,7 @@ static int mf_generic_kill_procs(unsigned long long pfn, int flags,
* SIGBUS (i.e. MF_MUST_KILL) * SIGBUS (i.e. MF_MUST_KILL)
*/ */
flags |= MF_ACTION_REQUIRED | MF_MUST_KILL; flags |= MF_ACTION_REQUIRED | MF_MUST_KILL;
collect_procs(&folio->page, &to_kill, true); collect_procs(folio, &folio->page, &to_kill, true);
unmap_and_kill(&to_kill, pfn, folio->mapping, folio->index, flags); unmap_and_kill(&to_kill, pfn, folio->mapping, folio->index, flags);
unlock: unlock:
......
...@@ -405,6 +405,7 @@ int folio_migrate_mapping(struct address_space *mapping, ...@@ -405,6 +405,7 @@ int folio_migrate_mapping(struct address_space *mapping,
int dirty; int dirty;
int expected_count = folio_expected_refs(mapping, folio) + extra_count; int expected_count = folio_expected_refs(mapping, folio) + extra_count;
long nr = folio_nr_pages(folio); long nr = folio_nr_pages(folio);
long entries, i;
if (!mapping) { if (!mapping) {
/* Anonymous page without mapping */ /* Anonymous page without mapping */
...@@ -442,8 +443,10 @@ int folio_migrate_mapping(struct address_space *mapping, ...@@ -442,8 +443,10 @@ int folio_migrate_mapping(struct address_space *mapping,
folio_set_swapcache(newfolio); folio_set_swapcache(newfolio);
newfolio->private = folio_get_private(folio); newfolio->private = folio_get_private(folio);
} }
entries = nr;
} else { } else {
VM_BUG_ON_FOLIO(folio_test_swapcache(folio), folio); VM_BUG_ON_FOLIO(folio_test_swapcache(folio), folio);
entries = 1;
} }
/* Move dirty while page refs frozen and newpage not yet exposed */ /* Move dirty while page refs frozen and newpage not yet exposed */
...@@ -453,7 +456,11 @@ int folio_migrate_mapping(struct address_space *mapping, ...@@ -453,7 +456,11 @@ int folio_migrate_mapping(struct address_space *mapping,
folio_set_dirty(newfolio); folio_set_dirty(newfolio);
} }
/* Swap cache still stores N entries instead of a high-order entry */
for (i = 0; i < entries; i++) {
xas_store(&xas, newfolio); xas_store(&xas, newfolio);
xas_next(&xas);
}
/* /*
* Drop cache reference from old page by unfreezing * Drop cache reference from old page by unfreezing
......
...@@ -1080,7 +1080,24 @@ static void shmem_undo_range(struct inode *inode, loff_t lstart, loff_t lend, ...@@ -1080,7 +1080,24 @@ static void shmem_undo_range(struct inode *inode, loff_t lstart, loff_t lend,
} }
VM_BUG_ON_FOLIO(folio_test_writeback(folio), VM_BUG_ON_FOLIO(folio_test_writeback(folio),
folio); folio);
if (!folio_test_large(folio)) {
truncate_inode_folio(mapping, folio); truncate_inode_folio(mapping, folio);
} else if (truncate_inode_partial_folio(folio, lstart, lend)) {
/*
* If we split a page, reset the loop so
* that we pick up the new sub pages.
* Otherwise the THP was entirely
* dropped or the target range was
* zeroed, so just continue the loop as
* is.
*/
if (!folio_test_large(folio)) {
folio_unlock(folio);
index = start;
break;
}
}
} }
folio_unlock(folio); folio_unlock(folio);
} }
......
...@@ -4093,6 +4093,9 @@ static void lru_gen_rotate_memcg(struct lruvec *lruvec, int op) ...@@ -4093,6 +4093,9 @@ static void lru_gen_rotate_memcg(struct lruvec *lruvec, int op)
else else
VM_WARN_ON_ONCE(true); VM_WARN_ON_ONCE(true);
WRITE_ONCE(lruvec->lrugen.seg, seg);
WRITE_ONCE(lruvec->lrugen.gen, new);
hlist_nulls_del_rcu(&lruvec->lrugen.list); hlist_nulls_del_rcu(&lruvec->lrugen.list);
if (op == MEMCG_LRU_HEAD || op == MEMCG_LRU_OLD) if (op == MEMCG_LRU_HEAD || op == MEMCG_LRU_OLD)
...@@ -4103,9 +4106,6 @@ static void lru_gen_rotate_memcg(struct lruvec *lruvec, int op) ...@@ -4103,9 +4106,6 @@ static void lru_gen_rotate_memcg(struct lruvec *lruvec, int op)
pgdat->memcg_lru.nr_memcgs[old]--; pgdat->memcg_lru.nr_memcgs[old]--;
pgdat->memcg_lru.nr_memcgs[new]++; pgdat->memcg_lru.nr_memcgs[new]++;
lruvec->lrugen.gen = new;
WRITE_ONCE(lruvec->lrugen.seg, seg);
if (!pgdat->memcg_lru.nr_memcgs[old] && old == get_memcg_gen(pgdat->memcg_lru.seq)) if (!pgdat->memcg_lru.nr_memcgs[old] && old == get_memcg_gen(pgdat->memcg_lru.seq))
WRITE_ONCE(pgdat->memcg_lru.seq, pgdat->memcg_lru.seq + 1); WRITE_ONCE(pgdat->memcg_lru.seq, pgdat->memcg_lru.seq + 1);
...@@ -4128,11 +4128,11 @@ void lru_gen_online_memcg(struct mem_cgroup *memcg) ...@@ -4128,11 +4128,11 @@ void lru_gen_online_memcg(struct mem_cgroup *memcg)
gen = get_memcg_gen(pgdat->memcg_lru.seq); gen = get_memcg_gen(pgdat->memcg_lru.seq);
lruvec->lrugen.gen = gen;
hlist_nulls_add_tail_rcu(&lruvec->lrugen.list, &pgdat->memcg_lru.fifo[gen][bin]); hlist_nulls_add_tail_rcu(&lruvec->lrugen.list, &pgdat->memcg_lru.fifo[gen][bin]);
pgdat->memcg_lru.nr_memcgs[gen]++; pgdat->memcg_lru.nr_memcgs[gen]++;
lruvec->lrugen.gen = gen;
spin_unlock_irq(&pgdat->memcg_lru.lock); spin_unlock_irq(&pgdat->memcg_lru.lock);
} }
} }
...@@ -4236,7 +4236,7 @@ static bool sort_folio(struct lruvec *lruvec, struct folio *folio, struct scan_c ...@@ -4236,7 +4236,7 @@ static bool sort_folio(struct lruvec *lruvec, struct folio *folio, struct scan_c
} }
/* protected */ /* protected */
if (tier > tier_idx) { if (tier > tier_idx || refs == BIT(LRU_REFS_WIDTH)) {
int hist = lru_hist_from_seq(lrugen->min_seq[type]); int hist = lru_hist_from_seq(lrugen->min_seq[type]);
gen = folio_inc_gen(lruvec, folio, false); gen = folio_inc_gen(lruvec, folio, false);
...@@ -4602,7 +4602,12 @@ static bool should_run_aging(struct lruvec *lruvec, unsigned long max_seq, ...@@ -4602,7 +4602,12 @@ static bool should_run_aging(struct lruvec *lruvec, unsigned long max_seq,
} }
/* try to scrape all its memory if this memcg was deleted */ /* try to scrape all its memory if this memcg was deleted */
*nr_to_scan = mem_cgroup_online(memcg) ? (total >> sc->priority) : total; if (!mem_cgroup_online(memcg)) {
*nr_to_scan = total;
return false;
}
*nr_to_scan = total >> sc->priority;
/* /*
* The aging tries to be lazy to reduce the overhead, while the eviction * The aging tries to be lazy to reduce the overhead, while the eviction
...@@ -4639,7 +4644,7 @@ static long get_nr_to_scan(struct lruvec *lruvec, struct scan_control *sc, bool ...@@ -4639,7 +4644,7 @@ static long get_nr_to_scan(struct lruvec *lruvec, struct scan_control *sc, bool
DEFINE_MAX_SEQ(lruvec); DEFINE_MAX_SEQ(lruvec);
if (mem_cgroup_below_min(sc->target_mem_cgroup, memcg)) if (mem_cgroup_below_min(sc->target_mem_cgroup, memcg))
return 0; return -1;
if (!should_run_aging(lruvec, max_seq, sc, can_swap, &nr_to_scan)) if (!should_run_aging(lruvec, max_seq, sc, can_swap, &nr_to_scan))
return nr_to_scan; return nr_to_scan;
...@@ -4652,20 +4657,41 @@ static long get_nr_to_scan(struct lruvec *lruvec, struct scan_control *sc, bool ...@@ -4652,20 +4657,41 @@ static long get_nr_to_scan(struct lruvec *lruvec, struct scan_control *sc, bool
return try_to_inc_max_seq(lruvec, max_seq, sc, can_swap, false) ? -1 : 0; return try_to_inc_max_seq(lruvec, max_seq, sc, can_swap, false) ? -1 : 0;
} }
static unsigned long get_nr_to_reclaim(struct scan_control *sc) static bool should_abort_scan(struct lruvec *lruvec, struct scan_control *sc)
{ {
int i;
enum zone_watermarks mark;
/* don't abort memcg reclaim to ensure fairness */ /* don't abort memcg reclaim to ensure fairness */
if (!root_reclaim(sc)) if (!root_reclaim(sc))
return -1; return false;
if (sc->nr_reclaimed >= max(sc->nr_to_reclaim, compact_gap(sc->order)))
return true;
/* check the order to exclude compaction-induced reclaim */
if (!current_is_kswapd() || sc->order)
return false;
return max(sc->nr_to_reclaim, compact_gap(sc->order)); mark = sysctl_numa_balancing_mode & NUMA_BALANCING_MEMORY_TIERING ?
WMARK_PROMO : WMARK_HIGH;
for (i = 0; i <= sc->reclaim_idx; i++) {
struct zone *zone = lruvec_pgdat(lruvec)->node_zones + i;
unsigned long size = wmark_pages(zone, mark) + MIN_LRU_BATCH;
if (managed_zone(zone) && !zone_watermark_ok(zone, 0, size, sc->reclaim_idx, 0))
return false;
}
/* kswapd should abort if all eligible zones are safe */
return true;
} }
static bool try_to_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc) static bool try_to_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc)
{ {
long nr_to_scan; long nr_to_scan;
unsigned long scanned = 0; unsigned long scanned = 0;
unsigned long nr_to_reclaim = get_nr_to_reclaim(sc);
int swappiness = get_swappiness(lruvec, sc); int swappiness = get_swappiness(lruvec, sc);
/* clean file folios are more likely to exist */ /* clean file folios are more likely to exist */
...@@ -4687,13 +4713,13 @@ static bool try_to_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc) ...@@ -4687,13 +4713,13 @@ static bool try_to_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc)
if (scanned >= nr_to_scan) if (scanned >= nr_to_scan)
break; break;
if (sc->nr_reclaimed >= nr_to_reclaim) if (should_abort_scan(lruvec, sc))
break; break;
cond_resched(); cond_resched();
} }
/* whether try_to_inc_max_seq() was successful */ /* whether this lruvec should be rotated */
return nr_to_scan < 0; return nr_to_scan < 0;
} }
...@@ -4702,14 +4728,9 @@ static int shrink_one(struct lruvec *lruvec, struct scan_control *sc) ...@@ -4702,14 +4728,9 @@ static int shrink_one(struct lruvec *lruvec, struct scan_control *sc)
bool success; bool success;
unsigned long scanned = sc->nr_scanned; unsigned long scanned = sc->nr_scanned;
unsigned long reclaimed = sc->nr_reclaimed; unsigned long reclaimed = sc->nr_reclaimed;
int seg = lru_gen_memcg_seg(lruvec);
struct mem_cgroup *memcg = lruvec_memcg(lruvec); struct mem_cgroup *memcg = lruvec_memcg(lruvec);
struct pglist_data *pgdat = lruvec_pgdat(lruvec); struct pglist_data *pgdat = lruvec_pgdat(lruvec);
/* see the comment on MEMCG_NR_GENS */
if (!lruvec_is_sizable(lruvec, sc))
return seg != MEMCG_LRU_TAIL ? MEMCG_LRU_TAIL : MEMCG_LRU_YOUNG;
mem_cgroup_calculate_protection(NULL, memcg); mem_cgroup_calculate_protection(NULL, memcg);
if (mem_cgroup_below_min(NULL, memcg)) if (mem_cgroup_below_min(NULL, memcg))
...@@ -4717,7 +4738,7 @@ static int shrink_one(struct lruvec *lruvec, struct scan_control *sc) ...@@ -4717,7 +4738,7 @@ static int shrink_one(struct lruvec *lruvec, struct scan_control *sc)
if (mem_cgroup_below_low(NULL, memcg)) { if (mem_cgroup_below_low(NULL, memcg)) {
/* see the comment on MEMCG_NR_GENS */ /* see the comment on MEMCG_NR_GENS */
if (seg != MEMCG_LRU_TAIL) if (lru_gen_memcg_seg(lruvec) != MEMCG_LRU_TAIL)
return MEMCG_LRU_TAIL; return MEMCG_LRU_TAIL;
memcg_memory_event(memcg, MEMCG_LOW); memcg_memory_event(memcg, MEMCG_LOW);
...@@ -4733,7 +4754,15 @@ static int shrink_one(struct lruvec *lruvec, struct scan_control *sc) ...@@ -4733,7 +4754,15 @@ static int shrink_one(struct lruvec *lruvec, struct scan_control *sc)
flush_reclaim_state(sc); flush_reclaim_state(sc);
return success ? MEMCG_LRU_YOUNG : 0; if (success && mem_cgroup_online(memcg))
return MEMCG_LRU_YOUNG;
if (!success && lruvec_is_sizable(lruvec, sc))
return 0;
/* one retry if offlined or too small */
return lru_gen_memcg_seg(lruvec) != MEMCG_LRU_TAIL ?
MEMCG_LRU_TAIL : MEMCG_LRU_YOUNG;
} }
#ifdef CONFIG_MEMCG #ifdef CONFIG_MEMCG
...@@ -4747,14 +4776,13 @@ static void shrink_many(struct pglist_data *pgdat, struct scan_control *sc) ...@@ -4747,14 +4776,13 @@ static void shrink_many(struct pglist_data *pgdat, struct scan_control *sc)
struct lruvec *lruvec; struct lruvec *lruvec;
struct lru_gen_folio *lrugen; struct lru_gen_folio *lrugen;
struct mem_cgroup *memcg; struct mem_cgroup *memcg;
const struct hlist_nulls_node *pos; struct hlist_nulls_node *pos;
unsigned long nr_to_reclaim = get_nr_to_reclaim(sc);
gen = get_memcg_gen(READ_ONCE(pgdat->memcg_lru.seq));
bin = first_bin = get_random_u32_below(MEMCG_NR_BINS); bin = first_bin = get_random_u32_below(MEMCG_NR_BINS);
restart: restart:
op = 0; op = 0;
memcg = NULL; memcg = NULL;
gen = get_memcg_gen(READ_ONCE(pgdat->memcg_lru.seq));
rcu_read_lock(); rcu_read_lock();
...@@ -4765,6 +4793,10 @@ static void shrink_many(struct pglist_data *pgdat, struct scan_control *sc) ...@@ -4765,6 +4793,10 @@ static void shrink_many(struct pglist_data *pgdat, struct scan_control *sc)
} }
mem_cgroup_put(memcg); mem_cgroup_put(memcg);
memcg = NULL;
if (gen != READ_ONCE(lrugen->gen))
continue;
lruvec = container_of(lrugen, struct lruvec, lrugen); lruvec = container_of(lrugen, struct lruvec, lrugen);
memcg = lruvec_memcg(lruvec); memcg = lruvec_memcg(lruvec);
...@@ -4781,7 +4813,7 @@ static void shrink_many(struct pglist_data *pgdat, struct scan_control *sc) ...@@ -4781,7 +4813,7 @@ static void shrink_many(struct pglist_data *pgdat, struct scan_control *sc)
rcu_read_lock(); rcu_read_lock();
if (sc->nr_reclaimed >= nr_to_reclaim) if (should_abort_scan(lruvec, sc))
break; break;
} }
...@@ -4792,7 +4824,7 @@ static void shrink_many(struct pglist_data *pgdat, struct scan_control *sc) ...@@ -4792,7 +4824,7 @@ static void shrink_many(struct pglist_data *pgdat, struct scan_control *sc)
mem_cgroup_put(memcg); mem_cgroup_put(memcg);
if (sc->nr_reclaimed >= nr_to_reclaim) if (!is_a_nulls(pos))
return; return;
/* restart if raced with lru_gen_rotate_memcg() */ /* restart if raced with lru_gen_rotate_memcg() */
...@@ -4849,16 +4881,14 @@ static void set_initial_priority(struct pglist_data *pgdat, struct scan_control ...@@ -4849,16 +4881,14 @@ static void set_initial_priority(struct pglist_data *pgdat, struct scan_control
if (sc->priority != DEF_PRIORITY || sc->nr_to_reclaim < MIN_LRU_BATCH) if (sc->priority != DEF_PRIORITY || sc->nr_to_reclaim < MIN_LRU_BATCH)
return; return;
/* /*
* Determine the initial priority based on ((total / MEMCG_NR_GENS) >> * Determine the initial priority based on
* priority) * reclaimed_to_scanned_ratio = nr_to_reclaim, where the * (total >> priority) * reclaimed_to_scanned_ratio = nr_to_reclaim,
* estimated reclaimed_to_scanned_ratio = inactive / total. * where reclaimed_to_scanned_ratio = inactive / total.
*/ */
reclaimable = node_page_state(pgdat, NR_INACTIVE_FILE); reclaimable = node_page_state(pgdat, NR_INACTIVE_FILE);
if (get_swappiness(lruvec, sc)) if (get_swappiness(lruvec, sc))
reclaimable += node_page_state(pgdat, NR_INACTIVE_ANON); reclaimable += node_page_state(pgdat, NR_INACTIVE_ANON);
reclaimable /= MEMCG_NR_GENS;
/* round down reclaimable and round up sc->nr_to_reclaim */ /* round down reclaimable and round up sc->nr_to_reclaim */
priority = fls_long(reclaimable) - 1 - fls_long(sc->nr_to_reclaim - 1); priority = fls_long(reclaimable) - 1 - fls_long(sc->nr_to_reclaim - 1);
......
...@@ -313,10 +313,10 @@ static void lru_gen_refault(struct folio *folio, void *shadow) ...@@ -313,10 +313,10 @@ static void lru_gen_refault(struct folio *folio, void *shadow)
* 1. For pages accessed through page tables, hotter pages pushed out * 1. For pages accessed through page tables, hotter pages pushed out
* hot pages which refaulted immediately. * hot pages which refaulted immediately.
* 2. For pages accessed multiple times through file descriptors, * 2. For pages accessed multiple times through file descriptors,
* numbers of accesses might have been out of the range. * they would have been protected by sort_folio().
*/ */
if (lru_gen_in_fault() || refs == BIT(LRU_REFS_WIDTH)) { if (lru_gen_in_fault() || refs >= BIT(LRU_REFS_WIDTH) - 1) {
folio_set_workingset(folio); set_mask_bits(&folio->flags, 0, LRU_REFS_MASK | BIT(PG_workingset));
mod_lruvec_state(lruvec, WORKINGSET_RESTORE_BASE + type, delta); mod_lruvec_state(lruvec, WORKINGSET_RESTORE_BASE + type, delta);
} }
unlock: unlock:
......
...@@ -35545,7 +35545,7 @@ static noinline void __init check_prealloc(struct maple_tree *mt) ...@@ -35545,7 +35545,7 @@ static noinline void __init check_prealloc(struct maple_tree *mt)
MT_BUG_ON(mt, mas_preallocate(&mas, ptr, GFP_KERNEL) != 0); MT_BUG_ON(mt, mas_preallocate(&mas, ptr, GFP_KERNEL) != 0);
allocated = mas_allocated(&mas); allocated = mas_allocated(&mas);
height = mas_mt_height(&mas); height = mas_mt_height(&mas);
MT_BUG_ON(mt, allocated != 1); MT_BUG_ON(mt, allocated != 0);
mas_store_prealloc(&mas, ptr); mas_store_prealloc(&mas, ptr);
MT_BUG_ON(mt, mas_allocated(&mas) != 0); MT_BUG_ON(mt, mas_allocated(&mas) != 0);
...@@ -155,12 +155,10 @@ ifneq ($(KBUILD_OUTPUT),) ...@@ -155,12 +155,10 @@ ifneq ($(KBUILD_OUTPUT),)
abs_objtree := $(realpath $(abs_objtree)) abs_objtree := $(realpath $(abs_objtree))
BUILD := $(abs_objtree)/kselftest BUILD := $(abs_objtree)/kselftest
KHDR_INCLUDES := -isystem ${abs_objtree}/usr/include KHDR_INCLUDES := -isystem ${abs_objtree}/usr/include
KHDR_DIR := ${abs_objtree}/usr/include
else else
BUILD := $(CURDIR) BUILD := $(CURDIR)
abs_srctree := $(shell cd $(top_srcdir) && pwd) abs_srctree := $(shell cd $(top_srcdir) && pwd)
KHDR_INCLUDES := -isystem ${abs_srctree}/usr/include KHDR_INCLUDES := -isystem ${abs_srctree}/usr/include
KHDR_DIR := ${abs_srctree}/usr/include
DEFAULT_INSTALL_HDR_PATH := 1 DEFAULT_INSTALL_HDR_PATH := 1
endif endif
...@@ -174,7 +172,7 @@ export KHDR_INCLUDES ...@@ -174,7 +172,7 @@ export KHDR_INCLUDES
# all isn't the first target in the file. # all isn't the first target in the file.
.DEFAULT_GOAL := all .DEFAULT_GOAL := all
all: kernel_header_files all:
@ret=1; \ @ret=1; \
for TARGET in $(TARGETS); do \ for TARGET in $(TARGETS); do \
BUILD_TARGET=$$BUILD/$$TARGET; \ BUILD_TARGET=$$BUILD/$$TARGET; \
...@@ -185,23 +183,6 @@ all: kernel_header_files ...@@ -185,23 +183,6 @@ all: kernel_header_files
ret=$$((ret * $$?)); \ ret=$$((ret * $$?)); \
done; exit $$ret; done; exit $$ret;
kernel_header_files:
@ls $(KHDR_DIR)/linux/*.h >/dev/null 2>/dev/null; \
if [ $$? -ne 0 ]; then \
RED='\033[1;31m'; \
NOCOLOR='\033[0m'; \
echo; \
echo -e "$${RED}error$${NOCOLOR}: missing kernel header files."; \
echo "Please run this and try again:"; \
echo; \
echo " cd $(top_srcdir)"; \
echo " make headers"; \
echo; \
exit 1; \
fi
.PHONY: kernel_header_files
run_tests: all run_tests: all
@for TARGET in $(TARGETS); do \ @for TARGET in $(TARGETS); do \
BUILD_TARGET=$$BUILD/$$TARGET; \ BUILD_TARGET=$$BUILD/$$TARGET; \
......
...@@ -44,26 +44,10 @@ endif ...@@ -44,26 +44,10 @@ endif
selfdir = $(realpath $(dir $(filter %/lib.mk,$(MAKEFILE_LIST)))) selfdir = $(realpath $(dir $(filter %/lib.mk,$(MAKEFILE_LIST))))
top_srcdir = $(selfdir)/../../.. top_srcdir = $(selfdir)/../../..
ifeq ("$(origin O)", "command line") ifeq ($(KHDR_INCLUDES),)
KBUILD_OUTPUT := $(O) KHDR_INCLUDES := -isystem $(top_srcdir)/usr/include
endif endif
ifneq ($(KBUILD_OUTPUT),)
# Make's built-in functions such as $(abspath ...), $(realpath ...) cannot
# expand a shell special character '~'. We use a somewhat tedious way here.
abs_objtree := $(shell cd $(top_srcdir) && mkdir -p $(KBUILD_OUTPUT) && cd $(KBUILD_OUTPUT) && pwd)
$(if $(abs_objtree),, \
$(error failed to create output directory "$(KBUILD_OUTPUT)"))
# $(realpath ...) resolves symlinks
abs_objtree := $(realpath $(abs_objtree))
KHDR_DIR := ${abs_objtree}/usr/include
else
abs_srctree := $(shell cd $(top_srcdir) && pwd)
KHDR_DIR := ${abs_srctree}/usr/include
endif
KHDR_INCLUDES := -isystem $(KHDR_DIR)
# The following are built by lib.mk common compile rules. # The following are built by lib.mk common compile rules.
# TEST_CUSTOM_PROGS should be used by tests that require # TEST_CUSTOM_PROGS should be used by tests that require
# custom build rule and prevent common build rule use. # custom build rule and prevent common build rule use.
...@@ -74,25 +58,7 @@ TEST_GEN_PROGS := $(patsubst %,$(OUTPUT)/%,$(TEST_GEN_PROGS)) ...@@ -74,25 +58,7 @@ TEST_GEN_PROGS := $(patsubst %,$(OUTPUT)/%,$(TEST_GEN_PROGS))
TEST_GEN_PROGS_EXTENDED := $(patsubst %,$(OUTPUT)/%,$(TEST_GEN_PROGS_EXTENDED)) TEST_GEN_PROGS_EXTENDED := $(patsubst %,$(OUTPUT)/%,$(TEST_GEN_PROGS_EXTENDED))
TEST_GEN_FILES := $(patsubst %,$(OUTPUT)/%,$(TEST_GEN_FILES)) TEST_GEN_FILES := $(patsubst %,$(OUTPUT)/%,$(TEST_GEN_FILES))
all: kernel_header_files $(TEST_GEN_PROGS) $(TEST_GEN_PROGS_EXTENDED) \ all: $(TEST_GEN_PROGS) $(TEST_GEN_PROGS_EXTENDED) $(TEST_GEN_FILES)
$(TEST_GEN_FILES)
kernel_header_files:
@ls $(KHDR_DIR)/linux/*.h >/dev/null 2>/dev/null; \
if [ $$? -ne 0 ]; then \
RED='\033[1;31m'; \
NOCOLOR='\033[0m'; \
echo; \
echo -e "$${RED}error$${NOCOLOR}: missing kernel header files."; \
echo "Please run this and try again:"; \
echo; \
echo " cd $(top_srcdir)"; \
echo " make headers"; \
echo; \
exit 1; \
fi
.PHONY: kernel_header_files
define RUN_TESTS define RUN_TESTS
BASE_DIR="$(selfdir)"; \ BASE_DIR="$(selfdir)"; \
......
...@@ -1680,6 +1680,8 @@ int main(int argc, char **argv) ...@@ -1680,6 +1680,8 @@ int main(int argc, char **argv)
{ {
int err; int err;
ksft_print_header();
pagesize = getpagesize(); pagesize = getpagesize();
thpsize = read_pmd_pagesize(); thpsize = read_pmd_pagesize();
if (thpsize) if (thpsize)
...@@ -1689,7 +1691,6 @@ int main(int argc, char **argv) ...@@ -1689,7 +1691,6 @@ int main(int argc, char **argv)
ARRAY_SIZE(hugetlbsizes)); ARRAY_SIZE(hugetlbsizes));
detect_huge_zeropage(); detect_huge_zeropage();
ksft_print_header();
ksft_set_plan(ARRAY_SIZE(anon_test_cases) * tests_per_anon_test_case() + ksft_set_plan(ARRAY_SIZE(anon_test_cases) * tests_per_anon_test_case() +
ARRAY_SIZE(anon_thp_test_cases) * tests_per_anon_thp_test_case() + ARRAY_SIZE(anon_thp_test_cases) * tests_per_anon_thp_test_case() +
ARRAY_SIZE(non_anon_test_cases) * tests_per_non_anon_test_case()); ARRAY_SIZE(non_anon_test_cases) * tests_per_non_anon_test_case());
......
...@@ -62,6 +62,9 @@ static void test_mlock_limit(int fd) ...@@ -62,6 +62,9 @@ static void test_mlock_limit(int fd)
char *mem; char *mem;
len = mlock_limit_cur; len = mlock_limit_cur;
if (len % page_size != 0)
len = (len/page_size) * page_size;
mem = mmap(NULL, len, prot, mode, fd, 0); mem = mmap(NULL, len, prot, mode, fd, 0);
if (mem == MAP_FAILED) { if (mem == MAP_FAILED) {
fail("unable to mmap secret memory\n"); fail("unable to mmap secret memory\n");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment