diff options
author | Anthony G. Basile <blueness@gentoo.org> | 2014-11-23 07:09:35 -0500 |
---|---|---|
committer | Anthony G. Basile <blueness@gentoo.org> | 2014-11-23 07:09:35 -0500 |
commit | 201a50d3b65cc7eff1a8782ae970262895e774cc (patch) | |
tree | 66d1b3da5f7db9c12457bd93d77af0c0dff097bf /1024_linux-3.14.25.patch | |
parent | Linux patch 3.14.25 (diff) | |
download | linux-patches-201a50d3b65cc7eff1a8782ae970262895e774cc.tar.gz linux-patches-201a50d3b65cc7eff1a8782ae970262895e774cc.tar.bz2 linux-patches-201a50d3b65cc7eff1a8782ae970262895e774cc.zip |
Properly name Linux patch 3.14.25
Diffstat (limited to '1024_linux-3.14.25.patch')
-rw-r--r-- | 1024_linux-3.14.25.patch | 7549 |
1 files changed, 7549 insertions, 0 deletions
diff --git a/1024_linux-3.14.25.patch b/1024_linux-3.14.25.patch new file mode 100644 index 00000000..03df3d2b --- /dev/null +++ b/1024_linux-3.14.25.patch @@ -0,0 +1,7549 @@ +diff --git a/Documentation/devicetree/bindings/ata/sata_rcar.txt b/Documentation/devicetree/bindings/ata/sata_rcar.txt +index 1e6111333fa8..7dd32d321a34 100644 +--- a/Documentation/devicetree/bindings/ata/sata_rcar.txt ++++ b/Documentation/devicetree/bindings/ata/sata_rcar.txt +@@ -3,7 +3,8 @@ + Required properties: + - compatible : should contain one of the following: + - "renesas,sata-r8a7779" for R-Car H1 +- - "renesas,sata-r8a7790" for R-Car H2 ++ - "renesas,sata-r8a7790-es1" for R-Car H2 ES1 ++ - "renesas,sata-r8a7790" for R-Car H2 other than ES1 + - "renesas,sata-r8a7791" for R-Car M2 + - reg : address and length of the SATA registers; + - interrupts : must consist of one interrupt specifier. +diff --git a/Makefile b/Makefile +index 8fd06101c482..eb96e40238f7 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 3 + PATCHLEVEL = 14 +-SUBLEVEL = 24 ++SUBLEVEL = 25 + EXTRAVERSION = + NAME = Remembering Coco + +diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S +index 066b03480b63..8017cde13648 100644 +--- a/arch/arm/boot/compressed/head.S ++++ b/arch/arm/boot/compressed/head.S +@@ -400,8 +400,7 @@ dtb_check_done: + add sp, sp, r6 + #endif + +- tst r4, #1 +- bleq cache_clean_flush ++ bl cache_clean_flush + + adr r0, BSYM(restart) + add r0, r0, r6 +@@ -1050,6 +1049,8 @@ cache_clean_flush: + b call_cache_fn + + __armv4_mpu_cache_flush: ++ tst r4, #1 ++ movne pc, lr + mov r2, #1 + mov r3, #0 + mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache +@@ -1067,6 +1068,8 @@ __armv4_mpu_cache_flush: + mov pc, lr + + __fa526_cache_flush: ++ tst r4, #1 ++ movne pc, lr + mov r1, #0 + mcr p15, 0, r1, c7, c14, 0 @ clean and invalidate D cache + mcr p15, 0, r1, c7, c5, 0 @ flush I cache +@@ -1075,13 +1078,16 @@ __fa526_cache_flush: + + __armv6_mmu_cache_flush: + mov r1, #0 +- mcr p15, 0, r1, c7, c14, 0 @ clean+invalidate D ++ tst r4, #1 ++ mcreq p15, 0, r1, c7, c14, 0 @ clean+invalidate D + mcr p15, 0, r1, c7, c5, 0 @ invalidate I+BTB +- mcr p15, 0, r1, c7, c15, 0 @ clean+invalidate unified ++ mcreq p15, 0, r1, c7, c15, 0 @ clean+invalidate unified + mcr p15, 0, r1, c7, c10, 4 @ drain WB + mov pc, lr + + __armv7_mmu_cache_flush: ++ tst r4, #1 ++ bne iflush + mrc p15, 0, r10, c0, c1, 5 @ read ID_MMFR1 + tst r10, #0xf << 16 @ hierarchical cache (ARMv7) + mov r10, #0 +@@ -1142,6 +1148,8 @@ iflush: + mov pc, lr + + __armv5tej_mmu_cache_flush: ++ tst r4, #1 ++ movne pc, lr + 1: mrc p15, 0, r15, c7, c14, 3 @ test,clean,invalidate D cache + bne 1b + mcr p15, 0, r0, c7, c5, 0 @ flush I cache +@@ -1149,6 +1157,8 @@ __armv5tej_mmu_cache_flush: + mov pc, lr + + __armv4_mmu_cache_flush: ++ tst r4, #1 ++ movne pc, lr + mov r2, #64*1024 @ default: 32K dcache size (*2) + mov r11, #32 @ default: 32 byte line size + mrc p15, 0, r3, c0, c0, 1 @ read cache type +@@ -1182,6 +1192,8 @@ no_cache_id: + + __armv3_mmu_cache_flush: + __armv3_mpu_cache_flush: ++ tst r4, #1 ++ movne pc, lr + mov r1, #0 + mcr p15, 0, r1, c7, c0, 0 @ invalidate whole cache v3 + mov pc, lr +diff --git a/arch/arm/kernel/kprobes-common.c b/arch/arm/kernel/kprobes-common.c +index 18a76282970e..380c20fb9c85 100644 +--- a/arch/arm/kernel/kprobes-common.c ++++ b/arch/arm/kernel/kprobes-common.c +@@ -14,6 +14,7 @@ + #include <linux/kernel.h> + #include <linux/kprobes.h> + #include <asm/system_info.h> ++#include <asm/opcodes.h> + + #include "kprobes.h" + +@@ -305,7 +306,8 @@ kprobe_decode_ldmstm(kprobe_opcode_t insn, struct arch_specific_insn *asi) + + if (handler) { + /* We can emulate the instruction in (possibly) modified form */ +- asi->insn[0] = (insn & 0xfff00000) | (rn << 16) | reglist; ++ asi->insn[0] = __opcode_to_mem_arm((insn & 0xfff00000) | ++ (rn << 16) | reglist); + asi->insn_handler = handler; + return INSN_GOOD; + } +@@ -334,13 +336,14 @@ prepare_emulated_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi, + #ifdef CONFIG_THUMB2_KERNEL + if (thumb) { + u16 *thumb_insn = (u16 *)asi->insn; +- thumb_insn[1] = 0x4770; /* Thumb bx lr */ +- thumb_insn[2] = 0x4770; /* Thumb bx lr */ ++ /* Thumb bx lr */ ++ thumb_insn[1] = __opcode_to_mem_thumb16(0x4770); ++ thumb_insn[2] = __opcode_to_mem_thumb16(0x4770); + return insn; + } +- asi->insn[1] = 0xe12fff1e; /* ARM bx lr */ ++ asi->insn[1] = __opcode_to_mem_arm(0xe12fff1e); /* ARM bx lr */ + #else +- asi->insn[1] = 0xe1a0f00e; /* mov pc, lr */ ++ asi->insn[1] = __opcode_to_mem_arm(0xe1a0f00e); /* mov pc, lr */ + #endif + /* Make an ARM instruction unconditional */ + if (insn < 0xe0000000) +@@ -360,12 +363,12 @@ set_emulated_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi, + if (thumb) { + u16 *ip = (u16 *)asi->insn; + if (is_wide_instruction(insn)) +- *ip++ = insn >> 16; +- *ip++ = insn; ++ *ip++ = __opcode_to_mem_thumb16(insn >> 16); ++ *ip++ = __opcode_to_mem_thumb16(insn); + return; + } + #endif +- asi->insn[0] = insn; ++ asi->insn[0] = __opcode_to_mem_arm(insn); + } + + /* +diff --git a/arch/arm/kernel/kprobes-thumb.c b/arch/arm/kernel/kprobes-thumb.c +index 6123daf397a7..241222c66a13 100644 +--- a/arch/arm/kernel/kprobes-thumb.c ++++ b/arch/arm/kernel/kprobes-thumb.c +@@ -11,6 +11,7 @@ + #include <linux/kernel.h> + #include <linux/kprobes.h> + #include <linux/module.h> ++#include <asm/opcodes.h> + + #include "kprobes.h" + +@@ -163,9 +164,9 @@ t32_decode_ldmstm(kprobe_opcode_t insn, struct arch_specific_insn *asi) + enum kprobe_insn ret = kprobe_decode_ldmstm(insn, asi); + + /* Fixup modified instruction to have halfwords in correct order...*/ +- insn = asi->insn[0]; +- ((u16 *)asi->insn)[0] = insn >> 16; +- ((u16 *)asi->insn)[1] = insn & 0xffff; ++ insn = __mem_to_opcode_arm(asi->insn[0]); ++ ((u16 *)asi->insn)[0] = __opcode_to_mem_thumb16(insn >> 16); ++ ((u16 *)asi->insn)[1] = __opcode_to_mem_thumb16(insn & 0xffff); + + return ret; + } +@@ -1153,7 +1154,7 @@ t16_decode_hiregs(kprobe_opcode_t insn, struct arch_specific_insn *asi) + { + insn &= ~0x00ff; + insn |= 0x001; /* Set Rdn = R1 and Rm = R0 */ +- ((u16 *)asi->insn)[0] = insn; ++ ((u16 *)asi->insn)[0] = __opcode_to_mem_thumb16(insn); + asi->insn_handler = t16_emulate_hiregs; + return INSN_GOOD; + } +@@ -1182,8 +1183,10 @@ t16_decode_push(kprobe_opcode_t insn, struct arch_specific_insn *asi) + * and call it with R9=SP and LR in the register list represented + * by R8. + */ +- ((u16 *)asi->insn)[0] = 0xe929; /* 1st half STMDB R9!,{} */ +- ((u16 *)asi->insn)[1] = insn & 0x1ff; /* 2nd half (register list) */ ++ /* 1st half STMDB R9!,{} */ ++ ((u16 *)asi->insn)[0] = __opcode_to_mem_thumb16(0xe929); ++ /* 2nd half (register list) */ ++ ((u16 *)asi->insn)[1] = __opcode_to_mem_thumb16(insn & 0x1ff); + asi->insn_handler = t16_emulate_push; + return INSN_GOOD; + } +@@ -1232,8 +1235,10 @@ t16_decode_pop(kprobe_opcode_t insn, struct arch_specific_insn *asi) + * and call it with R9=SP and PC in the register list represented + * by R8. + */ +- ((u16 *)asi->insn)[0] = 0xe8b9; /* 1st half LDMIA R9!,{} */ +- ((u16 *)asi->insn)[1] = insn & 0x1ff; /* 2nd half (register list) */ ++ /* 1st half LDMIA R9!,{} */ ++ ((u16 *)asi->insn)[0] = __opcode_to_mem_thumb16(0xe8b9); ++ /* 2nd half (register list) */ ++ ((u16 *)asi->insn)[1] = __opcode_to_mem_thumb16(insn & 0x1ff); + asi->insn_handler = insn & 0x100 ? t16_emulate_pop_pc + : t16_emulate_pop_nopc; + return INSN_GOOD; +diff --git a/arch/arm/kernel/kprobes.c b/arch/arm/kernel/kprobes.c +index a7b621ece23d..49a87b6d0bf3 100644 +--- a/arch/arm/kernel/kprobes.c ++++ b/arch/arm/kernel/kprobes.c +@@ -26,6 +26,7 @@ + #include <linux/stop_machine.h> + #include <linux/stringify.h> + #include <asm/traps.h> ++#include <asm/opcodes.h> + #include <asm/cacheflush.h> + + #include "kprobes.h" +@@ -62,10 +63,10 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p) + #ifdef CONFIG_THUMB2_KERNEL + thumb = true; + addr &= ~1; /* Bit 0 would normally be set to indicate Thumb code */ +- insn = ((u16 *)addr)[0]; ++ insn = __mem_to_opcode_thumb16(((u16 *)addr)[0]); + if (is_wide_instruction(insn)) { +- insn <<= 16; +- insn |= ((u16 *)addr)[1]; ++ u16 inst2 = __mem_to_opcode_thumb16(((u16 *)addr)[1]); ++ insn = __opcode_thumb32_compose(insn, inst2); + decode_insn = thumb32_kprobe_decode_insn; + } else + decode_insn = thumb16_kprobe_decode_insn; +@@ -73,7 +74,7 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p) + thumb = false; + if (addr & 0x3) + return -EINVAL; +- insn = *p->addr; ++ insn = __mem_to_opcode_arm(*p->addr); + decode_insn = arm_kprobe_decode_insn; + #endif + +diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig +index ca8ecdee47d8..e9c290c21744 100644 +--- a/arch/arm/mm/Kconfig ++++ b/arch/arm/mm/Kconfig +@@ -798,6 +798,7 @@ config NEED_KUSER_HELPERS + + config KUSER_HELPERS + bool "Enable kuser helpers in vector page" if !NEED_KUSER_HELPERS ++ depends on MMU + default y + help + Warning: disabling this option may break user programs. +diff --git a/arch/arm64/kernel/insn.c b/arch/arm64/kernel/insn.c +index 92f36835486b..565e26f23f31 100644 +--- a/arch/arm64/kernel/insn.c ++++ b/arch/arm64/kernel/insn.c +@@ -156,9 +156,10 @@ static int __kprobes aarch64_insn_patch_text_cb(void *arg) + * which ends with "dsb; isb" pair guaranteeing global + * visibility. + */ +- atomic_set(&pp->cpu_count, -1); ++ /* Notify other processors with an additional increment. */ ++ atomic_inc(&pp->cpu_count); + } else { +- while (atomic_read(&pp->cpu_count) != -1) ++ while (atomic_read(&pp->cpu_count) <= num_online_cpus()) + cpu_relax(); + isb(); + } +diff --git a/arch/arm64/lib/clear_user.S b/arch/arm64/lib/clear_user.S +index 6e0ed93d51fe..c17967fdf5f6 100644 +--- a/arch/arm64/lib/clear_user.S ++++ b/arch/arm64/lib/clear_user.S +@@ -46,7 +46,7 @@ USER(9f, strh wzr, [x0], #2 ) + sub x1, x1, #2 + 4: adds x1, x1, #1 + b.mi 5f +- strb wzr, [x0] ++USER(9f, strb wzr, [x0] ) + 5: mov x0, #0 + ret + ENDPROC(__clear_user) +diff --git a/arch/parisc/include/uapi/asm/shmbuf.h b/arch/parisc/include/uapi/asm/shmbuf.h +index 0a3eada1863b..f395cde7b593 100644 +--- a/arch/parisc/include/uapi/asm/shmbuf.h ++++ b/arch/parisc/include/uapi/asm/shmbuf.h +@@ -36,23 +36,16 @@ struct shmid64_ds { + unsigned int __unused2; + }; + +-#ifdef CONFIG_64BIT +-/* The 'unsigned int' (formerly 'unsigned long') data types below will +- * ensure that a 32-bit app calling shmctl(*,IPC_INFO,*) will work on +- * a wide kernel, but if some of these values are meant to contain pointers +- * they may need to be 'long long' instead. -PB XXX FIXME +- */ +-#endif + struct shminfo64 { +- unsigned int shmmax; +- unsigned int shmmin; +- unsigned int shmmni; +- unsigned int shmseg; +- unsigned int shmall; +- unsigned int __unused1; +- unsigned int __unused2; +- unsigned int __unused3; +- unsigned int __unused4; ++ unsigned long shmmax; ++ unsigned long shmmin; ++ unsigned long shmmni; ++ unsigned long shmseg; ++ unsigned long shmall; ++ unsigned long __unused1; ++ unsigned long __unused2; ++ unsigned long __unused3; ++ unsigned long __unused4; + }; + + #endif /* _PARISC_SHMBUF_H */ +diff --git a/arch/parisc/kernel/syscall_table.S b/arch/parisc/kernel/syscall_table.S +index 7dd8a3b22147..fc77d53e2ca5 100644 +--- a/arch/parisc/kernel/syscall_table.S ++++ b/arch/parisc/kernel/syscall_table.S +@@ -286,11 +286,11 @@ + ENTRY_COMP(msgsnd) + ENTRY_COMP(msgrcv) + ENTRY_SAME(msgget) /* 190 */ +- ENTRY_SAME(msgctl) +- ENTRY_SAME(shmat) ++ ENTRY_COMP(msgctl) ++ ENTRY_COMP(shmat) + ENTRY_SAME(shmdt) + ENTRY_SAME(shmget) +- ENTRY_SAME(shmctl) /* 195 */ ++ ENTRY_COMP(shmctl) /* 195 */ + ENTRY_SAME(ni_syscall) /* streams1 */ + ENTRY_SAME(ni_syscall) /* streams2 */ + ENTRY_SAME(lstat64) +@@ -323,7 +323,7 @@ + ENTRY_SAME(epoll_ctl) /* 225 */ + ENTRY_SAME(epoll_wait) + ENTRY_SAME(remap_file_pages) +- ENTRY_SAME(semtimedop) ++ ENTRY_COMP(semtimedop) + ENTRY_COMP(mq_open) + ENTRY_SAME(mq_unlink) /* 230 */ + ENTRY_COMP(mq_timedsend) +diff --git a/arch/sparc/include/asm/atomic_32.h b/arch/sparc/include/asm/atomic_32.h +index 905832aa9e9e..a0ed182ae73c 100644 +--- a/arch/sparc/include/asm/atomic_32.h ++++ b/arch/sparc/include/asm/atomic_32.h +@@ -21,7 +21,7 @@ + + extern int __atomic_add_return(int, atomic_t *); + extern int atomic_cmpxchg(atomic_t *, int, int); +-#define atomic_xchg(v, new) (xchg(&((v)->counter), new)) ++extern int atomic_xchg(atomic_t *, int); + extern int __atomic_add_unless(atomic_t *, int, int); + extern void atomic_set(atomic_t *, int); + +diff --git a/arch/sparc/include/asm/cmpxchg_32.h b/arch/sparc/include/asm/cmpxchg_32.h +index 1fae1a02e3c2..ae0f9a7a314d 100644 +--- a/arch/sparc/include/asm/cmpxchg_32.h ++++ b/arch/sparc/include/asm/cmpxchg_32.h +@@ -11,22 +11,14 @@ + #ifndef __ARCH_SPARC_CMPXCHG__ + #define __ARCH_SPARC_CMPXCHG__ + +-static inline unsigned long xchg_u32(__volatile__ unsigned long *m, unsigned long val) +-{ +- __asm__ __volatile__("swap [%2], %0" +- : "=&r" (val) +- : "0" (val), "r" (m) +- : "memory"); +- return val; +-} +- ++extern unsigned long __xchg_u32(volatile u32 *m, u32 new); + extern void __xchg_called_with_bad_pointer(void); + + static inline unsigned long __xchg(unsigned long x, __volatile__ void * ptr, int size) + { + switch (size) { + case 4: +- return xchg_u32(ptr, x); ++ return __xchg_u32(ptr, x); + } + __xchg_called_with_bad_pointer(); + return x; +diff --git a/arch/sparc/include/asm/vio.h b/arch/sparc/include/asm/vio.h +index 432afa838861..55841c184e6d 100644 +--- a/arch/sparc/include/asm/vio.h ++++ b/arch/sparc/include/asm/vio.h +@@ -118,12 +118,18 @@ struct vio_disk_attr_info { + u8 vdisk_type; + #define VD_DISK_TYPE_SLICE 0x01 /* Slice in block device */ + #define VD_DISK_TYPE_DISK 0x02 /* Entire block device */ +- u16 resv1; ++ u8 vdisk_mtype; /* v1.1 */ ++#define VD_MEDIA_TYPE_FIXED 0x01 /* Fixed device */ ++#define VD_MEDIA_TYPE_CD 0x02 /* CD Device */ ++#define VD_MEDIA_TYPE_DVD 0x03 /* DVD Device */ ++ u8 resv1; + u32 vdisk_block_size; + u64 operations; +- u64 vdisk_size; ++ u64 vdisk_size; /* v1.1 */ + u64 max_xfer_size; +- u64 resv2[2]; ++ u32 phys_block_size; /* v1.2 */ ++ u32 resv2; ++ u64 resv3[1]; + }; + + struct vio_disk_desc { +@@ -259,7 +265,7 @@ static inline u32 vio_dring_avail(struct vio_dring_state *dr, + unsigned int ring_size) + { + return (dr->pending - +- ((dr->prod - dr->cons) & (ring_size - 1))); ++ ((dr->prod - dr->cons) & (ring_size - 1)) - 1); + } + + #define VIO_MAX_TYPE_LEN 32 +diff --git a/arch/sparc/kernel/pci_schizo.c b/arch/sparc/kernel/pci_schizo.c +index 8f76f23dac38..f9c6813c132d 100644 +--- a/arch/sparc/kernel/pci_schizo.c ++++ b/arch/sparc/kernel/pci_schizo.c +@@ -581,7 +581,7 @@ static irqreturn_t schizo_pcierr_intr_other(struct pci_pbm_info *pbm) + { + unsigned long csr_reg, csr, csr_error_bits; + irqreturn_t ret = IRQ_NONE; +- u16 stat; ++ u32 stat; + + csr_reg = pbm->pbm_regs + SCHIZO_PCI_CTRL; + csr = upa_readq(csr_reg); +@@ -617,7 +617,7 @@ static irqreturn_t schizo_pcierr_intr_other(struct pci_pbm_info *pbm) + pbm->name); + ret = IRQ_HANDLED; + } +- pci_read_config_word(pbm->pci_bus->self, PCI_STATUS, &stat); ++ pbm->pci_ops->read(pbm->pci_bus, 0, PCI_STATUS, 2, &stat); + if (stat & (PCI_STATUS_PARITY | + PCI_STATUS_SIG_TARGET_ABORT | + PCI_STATUS_REC_TARGET_ABORT | +@@ -625,7 +625,7 @@ static irqreturn_t schizo_pcierr_intr_other(struct pci_pbm_info *pbm) + PCI_STATUS_SIG_SYSTEM_ERROR)) { + printk("%s: PCI bus error, PCI_STATUS[%04x]\n", + pbm->name, stat); +- pci_write_config_word(pbm->pci_bus->self, PCI_STATUS, 0xffff); ++ pbm->pci_ops->write(pbm->pci_bus, 0, PCI_STATUS, 2, 0xffff); + ret = IRQ_HANDLED; + } + return ret; +diff --git a/arch/sparc/kernel/smp_64.c b/arch/sparc/kernel/smp_64.c +index 50c3dd03be31..9af0a5dbb36d 100644 +--- a/arch/sparc/kernel/smp_64.c ++++ b/arch/sparc/kernel/smp_64.c +@@ -823,13 +823,17 @@ void arch_send_call_function_single_ipi(int cpu) + void __irq_entry smp_call_function_client(int irq, struct pt_regs *regs) + { + clear_softint(1 << irq); ++ irq_enter(); + generic_smp_call_function_interrupt(); ++ irq_exit(); + } + + void __irq_entry smp_call_function_single_client(int irq, struct pt_regs *regs) + { + clear_softint(1 << irq); ++ irq_enter(); + generic_smp_call_function_single_interrupt(); ++ irq_exit(); + } + + static void tsb_sync(void *info) +diff --git a/arch/sparc/lib/atomic32.c b/arch/sparc/lib/atomic32.c +index 1d32b54089aa..8f2f94d53434 100644 +--- a/arch/sparc/lib/atomic32.c ++++ b/arch/sparc/lib/atomic32.c +@@ -40,6 +40,19 @@ int __atomic_add_return(int i, atomic_t *v) + } + EXPORT_SYMBOL(__atomic_add_return); + ++int atomic_xchg(atomic_t *v, int new) ++{ ++ int ret; ++ unsigned long flags; ++ ++ spin_lock_irqsave(ATOMIC_HASH(v), flags); ++ ret = v->counter; ++ v->counter = new; ++ spin_unlock_irqrestore(ATOMIC_HASH(v), flags); ++ return ret; ++} ++EXPORT_SYMBOL(atomic_xchg); ++ + int atomic_cmpxchg(atomic_t *v, int old, int new) + { + int ret; +@@ -132,3 +145,17 @@ unsigned long __cmpxchg_u32(volatile u32 *ptr, u32 old, u32 new) + return (unsigned long)prev; + } + EXPORT_SYMBOL(__cmpxchg_u32); ++ ++unsigned long __xchg_u32(volatile u32 *ptr, u32 new) ++{ ++ unsigned long flags; ++ u32 prev; ++ ++ spin_lock_irqsave(ATOMIC_HASH(ptr), flags); ++ prev = *ptr; ++ *ptr = new; ++ spin_unlock_irqrestore(ATOMIC_HASH(ptr), flags); ++ ++ return (unsigned long)prev; ++} ++EXPORT_SYMBOL(__xchg_u32); +diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile +index 0fcd9133790c..14fe7cba21d1 100644 +--- a/arch/x86/boot/compressed/Makefile ++++ b/arch/x86/boot/compressed/Makefile +@@ -75,8 +75,10 @@ suffix-$(CONFIG_KERNEL_XZ) := xz + suffix-$(CONFIG_KERNEL_LZO) := lzo + suffix-$(CONFIG_KERNEL_LZ4) := lz4 + ++RUN_SIZE = $(shell objdump -h vmlinux | \ ++ perl $(srctree)/arch/x86/tools/calc_run_size.pl) + quiet_cmd_mkpiggy = MKPIGGY $@ +- cmd_mkpiggy = $(obj)/mkpiggy $< > $@ || ( rm -f $@ ; false ) ++ cmd_mkpiggy = $(obj)/mkpiggy $< $(RUN_SIZE) > $@ || ( rm -f $@ ; false ) + + targets += piggy.S + $(obj)/piggy.S: $(obj)/vmlinux.bin.$(suffix-y) $(obj)/mkpiggy FORCE +diff --git a/arch/x86/boot/compressed/head_32.S b/arch/x86/boot/compressed/head_32.S +index f45ab7a36fb6..c5b56ed10aff 100644 +--- a/arch/x86/boot/compressed/head_32.S ++++ b/arch/x86/boot/compressed/head_32.S +@@ -186,7 +186,8 @@ relocated: + * Do the decompression, and jump to the new kernel.. + */ + /* push arguments for decompress_kernel: */ +- pushl $z_output_len /* decompressed length */ ++ pushl $z_run_size /* size of kernel with .bss and .brk */ ++ pushl $z_output_len /* decompressed length, end of relocs */ + leal z_extract_offset_negative(%ebx), %ebp + pushl %ebp /* output address */ + pushl $z_input_len /* input_len */ +@@ -196,7 +197,7 @@ relocated: + pushl %eax /* heap area */ + pushl %esi /* real mode pointer */ + call decompress_kernel /* returns kernel location in %eax */ +- addl $24, %esp ++ addl $28, %esp + + /* + * Jump to the decompressed kernel. +diff --git a/arch/x86/boot/compressed/head_64.S b/arch/x86/boot/compressed/head_64.S +index b10fa66a2540..34bbc0911b7c 100644 +--- a/arch/x86/boot/compressed/head_64.S ++++ b/arch/x86/boot/compressed/head_64.S +@@ -334,13 +334,16 @@ relocated: + * Do the decompression, and jump to the new kernel.. + */ + pushq %rsi /* Save the real mode argument */ ++ movq $z_run_size, %r9 /* size of kernel with .bss and .brk */ ++ pushq %r9 + movq %rsi, %rdi /* real mode address */ + leaq boot_heap(%rip), %rsi /* malloc area for uncompression */ + leaq input_data(%rip), %rdx /* input_data */ + movl $z_input_len, %ecx /* input_len */ + movq %rbp, %r8 /* output target address */ +- movq $z_output_len, %r9 /* decompressed length */ ++ movq $z_output_len, %r9 /* decompressed length, end of relocs */ + call decompress_kernel /* returns kernel location in %rax */ ++ popq %r9 + popq %rsi + + /* +diff --git a/arch/x86/boot/compressed/misc.c b/arch/x86/boot/compressed/misc.c +index 196eaf373a06..eb25ca1eb6da 100644 +--- a/arch/x86/boot/compressed/misc.c ++++ b/arch/x86/boot/compressed/misc.c +@@ -393,7 +393,8 @@ asmlinkage void *decompress_kernel(void *rmode, memptr heap, + unsigned char *input_data, + unsigned long input_len, + unsigned char *output, +- unsigned long output_len) ++ unsigned long output_len, ++ unsigned long run_size) + { + real_mode = rmode; + +@@ -416,8 +417,14 @@ asmlinkage void *decompress_kernel(void *rmode, memptr heap, + free_mem_ptr = heap; /* Heap */ + free_mem_end_ptr = heap + BOOT_HEAP_SIZE; + +- output = choose_kernel_location(input_data, input_len, +- output, output_len); ++ /* ++ * The memory hole needed for the kernel is the larger of either ++ * the entire decompressed kernel plus relocation table, or the ++ * entire decompressed kernel plus .bss and .brk sections. ++ */ ++ output = choose_kernel_location(input_data, input_len, output, ++ output_len > run_size ? output_len ++ : run_size); + + /* Validate memory location choices. */ + if ((unsigned long)output & (MIN_KERNEL_ALIGN - 1)) +diff --git a/arch/x86/boot/compressed/mkpiggy.c b/arch/x86/boot/compressed/mkpiggy.c +index b669ab65bf6c..d8222f213182 100644 +--- a/arch/x86/boot/compressed/mkpiggy.c ++++ b/arch/x86/boot/compressed/mkpiggy.c +@@ -36,11 +36,13 @@ int main(int argc, char *argv[]) + uint32_t olen; + long ilen; + unsigned long offs; ++ unsigned long run_size; + FILE *f = NULL; + int retval = 1; + +- if (argc < 2) { +- fprintf(stderr, "Usage: %s compressed_file\n", argv[0]); ++ if (argc < 3) { ++ fprintf(stderr, "Usage: %s compressed_file run_size\n", ++ argv[0]); + goto bail; + } + +@@ -74,6 +76,7 @@ int main(int argc, char *argv[]) + offs += olen >> 12; /* Add 8 bytes for each 32K block */ + offs += 64*1024 + 128; /* Add 64K + 128 bytes slack */ + offs = (offs+4095) & ~4095; /* Round to a 4K boundary */ ++ run_size = atoi(argv[2]); + + printf(".section \".rodata..compressed\",\"a\",@progbits\n"); + printf(".globl z_input_len\n"); +@@ -85,6 +88,8 @@ int main(int argc, char *argv[]) + /* z_extract_offset_negative allows simplification of head_32.S */ + printf(".globl z_extract_offset_negative\n"); + printf("z_extract_offset_negative = -0x%lx\n", offs); ++ printf(".globl z_run_size\n"); ++ printf("z_run_size = %lu\n", run_size); + + printf(".globl input_data, input_data_end\n"); + printf("input_data:\n"); +diff --git a/arch/x86/kernel/cpu/microcode/amd_early.c b/arch/x86/kernel/cpu/microcode/amd_early.c +index 617a9e284245..b63773ba1646 100644 +--- a/arch/x86/kernel/cpu/microcode/amd_early.c ++++ b/arch/x86/kernel/cpu/microcode/amd_early.c +@@ -108,12 +108,13 @@ static size_t compute_container_size(u8 *data, u32 total_size) + * load_microcode_amd() to save equivalent cpu table and microcode patches in + * kernel heap memory. + */ +-static void apply_ucode_in_initrd(void *ucode, size_t size) ++static void apply_ucode_in_initrd(void *ucode, size_t size, bool save_patch) + { + struct equiv_cpu_entry *eq; + size_t *cont_sz; + u32 *header; + u8 *data, **cont; ++ u8 (*patch)[PATCH_MAX_SIZE]; + u16 eq_id = 0; + int offset, left; + u32 rev, eax, ebx, ecx, edx; +@@ -123,10 +124,12 @@ static void apply_ucode_in_initrd(void *ucode, size_t size) + new_rev = (u32 *)__pa_nodebug(&ucode_new_rev); + cont_sz = (size_t *)__pa_nodebug(&container_size); + cont = (u8 **)__pa_nodebug(&container); ++ patch = (u8 (*)[PATCH_MAX_SIZE])__pa_nodebug(&amd_ucode_patch); + #else + new_rev = &ucode_new_rev; + cont_sz = &container_size; + cont = &container; ++ patch = &amd_ucode_patch; + #endif + + data = ucode; +@@ -213,9 +216,9 @@ static void apply_ucode_in_initrd(void *ucode, size_t size) + rev = mc->hdr.patch_id; + *new_rev = rev; + +- /* save ucode patch */ +- memcpy(amd_ucode_patch, mc, +- min_t(u32, header[1], PATCH_MAX_SIZE)); ++ if (save_patch) ++ memcpy(patch, mc, ++ min_t(u32, header[1], PATCH_MAX_SIZE)); + } + } + +@@ -246,7 +249,7 @@ void __init load_ucode_amd_bsp(void) + *data = cp.data; + *size = cp.size; + +- apply_ucode_in_initrd(cp.data, cp.size); ++ apply_ucode_in_initrd(cp.data, cp.size, true); + } + + #ifdef CONFIG_X86_32 +@@ -263,7 +266,7 @@ void load_ucode_amd_ap(void) + size_t *usize; + void **ucode; + +- mc = (struct microcode_amd *)__pa(amd_ucode_patch); ++ mc = (struct microcode_amd *)__pa_nodebug(amd_ucode_patch); + if (mc->hdr.patch_id && mc->hdr.processor_rev_id) { + __apply_microcode_amd(mc); + return; +@@ -275,7 +278,7 @@ void load_ucode_amd_ap(void) + if (!*ucode || !*usize) + return; + +- apply_ucode_in_initrd(*ucode, *usize); ++ apply_ucode_in_initrd(*ucode, *usize, false); + } + + static void __init collect_cpu_sig_on_bsp(void *arg) +@@ -339,7 +342,7 @@ void load_ucode_amd_ap(void) + * AP has a different equivalence ID than BSP, looks like + * mixed-steppings silicon so go through the ucode blob anew. + */ +- apply_ucode_in_initrd(ucode_cpio.data, ucode_cpio.size); ++ apply_ucode_in_initrd(ucode_cpio.data, ucode_cpio.size, false); + } + } + #endif +@@ -347,7 +350,9 @@ void load_ucode_amd_ap(void) + int __init save_microcode_in_initrd_amd(void) + { + unsigned long cont; ++ int retval = 0; + enum ucode_state ret; ++ u8 *cont_va; + u32 eax; + + if (!container) +@@ -355,13 +360,15 @@ int __init save_microcode_in_initrd_amd(void) + + #ifdef CONFIG_X86_32 + get_bsp_sig(); +- cont = (unsigned long)container; ++ cont = (unsigned long)container; ++ cont_va = __va(container); + #else + /* + * We need the physical address of the container for both bitness since + * boot_params.hdr.ramdisk_image is a physical address. + */ +- cont = __pa(container); ++ cont = __pa(container); ++ cont_va = container; + #endif + + /* +@@ -372,6 +379,8 @@ int __init save_microcode_in_initrd_amd(void) + if (relocated_ramdisk) + container = (u8 *)(__va(relocated_ramdisk) + + (cont - boot_params.hdr.ramdisk_image)); ++ else ++ container = cont_va; + + if (ucode_new_rev) + pr_info("microcode: updated early to new patch_level=0x%08x\n", +@@ -382,7 +391,7 @@ int __init save_microcode_in_initrd_amd(void) + + ret = load_microcode_amd(eax, container, container_size); + if (ret != UCODE_OK) +- return -EINVAL; ++ retval = -EINVAL; + + /* + * This will be freed any msec now, stash patches for the current +@@ -391,5 +400,5 @@ int __init save_microcode_in_initrd_amd(void) + container = NULL; + container_size = 0; + +- return 0; ++ return retval; + } +diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c +index 1340ebfcb467..5ee8064bd1d2 100644 +--- a/arch/x86/kernel/cpu/perf_event_intel.c ++++ b/arch/x86/kernel/cpu/perf_event_intel.c +@@ -2475,6 +2475,9 @@ __init int intel_pmu_init(void) + case 62: /* IvyBridge EP */ + memcpy(hw_cache_event_ids, snb_hw_cache_event_ids, + sizeof(hw_cache_event_ids)); ++ /* dTLB-load-misses on IVB is different than SNB */ ++ hw_cache_event_ids[C(DTLB)][C(OP_READ)][C(RESULT_MISS)] = 0x8108; /* DTLB_LOAD_MISSES.DEMAND_LD_MISS_CAUSES_A_WALK */ ++ + memcpy(hw_cache_extra_regs, snb_hw_cache_extra_regs, + sizeof(hw_cache_extra_regs)); + +diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c +index 7461f50d5bb1..0686fe313b3b 100644 +--- a/arch/x86/kernel/ptrace.c ++++ b/arch/x86/kernel/ptrace.c +@@ -1441,15 +1441,6 @@ void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, + force_sig_info(SIGTRAP, &info, tsk); + } + +- +-#ifdef CONFIG_X86_32 +-# define IS_IA32 1 +-#elif defined CONFIG_IA32_EMULATION +-# define IS_IA32 is_compat_task() +-#else +-# define IS_IA32 0 +-#endif +- + /* + * We must return the syscall number to actually look up in the table. + * This can be -1L to skip running any syscall at all. +@@ -1487,7 +1478,7 @@ long syscall_trace_enter(struct pt_regs *regs) + if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT))) + trace_sys_enter(regs, regs->orig_ax); + +- if (IS_IA32) ++ if (is_ia32_task()) + audit_syscall_entry(AUDIT_ARCH_I386, + regs->orig_ax, + regs->bx, regs->cx, +diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c +index 51c2851ca243..fab97ade0fc8 100644 +--- a/arch/x86/kvm/x86.c ++++ b/arch/x86/kvm/x86.c +@@ -4911,7 +4911,7 @@ static int handle_emulation_failure(struct kvm_vcpu *vcpu) + + ++vcpu->stat.insn_emulation_fail; + trace_kvm_emulate_insn_failed(vcpu); +- if (!is_guest_mode(vcpu)) { ++ if (!is_guest_mode(vcpu) && kvm_x86_ops->get_cpl(vcpu) == 0) { + vcpu->run->exit_reason = KVM_EXIT_INTERNAL_ERROR; + vcpu->run->internal.suberror = KVM_INTERNAL_ERROR_EMULATION; + vcpu->run->internal.ndata = 0; +diff --git a/arch/x86/mm/pgtable.c b/arch/x86/mm/pgtable.c +index c96314abd144..0004ac72dbdd 100644 +--- a/arch/x86/mm/pgtable.c ++++ b/arch/x86/mm/pgtable.c +@@ -399,13 +399,20 @@ int pmdp_test_and_clear_young(struct vm_area_struct *vma, + int ptep_clear_flush_young(struct vm_area_struct *vma, + unsigned long address, pte_t *ptep) + { +- int young; +- +- young = ptep_test_and_clear_young(vma, address, ptep); +- if (young) +- flush_tlb_page(vma, address); +- +- return young; ++ /* ++ * On x86 CPUs, clearing the accessed bit without a TLB flush ++ * doesn't cause data corruption. [ It could cause incorrect ++ * page aging and the (mistaken) reclaim of hot pages, but the ++ * chance of that should be relatively low. ] ++ * ++ * So as a performance optimization don't flush the TLB when ++ * clearing the accessed bit, it will eventually be flushed by ++ * a context switch or a VM operation anyway. [ In the rare ++ * event of it not getting flushed for a long time the delay ++ * shouldn't really matter because there's no real memory ++ * pressure for swapout to react to. ] ++ */ ++ return ptep_test_and_clear_young(vma, address, ptep); + } + + #ifdef CONFIG_TRANSPARENT_HUGEPAGE +diff --git a/arch/x86/tools/calc_run_size.pl b/arch/x86/tools/calc_run_size.pl +new file mode 100644 +index 000000000000..0b0b124d3ece +--- /dev/null ++++ b/arch/x86/tools/calc_run_size.pl +@@ -0,0 +1,30 @@ ++#!/usr/bin/perl ++# ++# Calculate the amount of space needed to run the kernel, including room for ++# the .bss and .brk sections. ++# ++# Usage: ++# objdump -h a.out | perl calc_run_size.pl ++use strict; ++ ++my $mem_size = 0; ++my $file_offset = 0; ++ ++my $sections=" *[0-9]+ \.(?:bss|brk) +"; ++while (<>) { ++ if (/^$sections([0-9a-f]+) +(?:[0-9a-f]+ +){2}([0-9a-f]+)/) { ++ my $size = hex($1); ++ my $offset = hex($2); ++ $mem_size += $size; ++ if ($file_offset == 0) { ++ $file_offset = $offset; ++ } elsif ($file_offset != $offset) { ++ die ".bss and .brk lack common file offset\n"; ++ } ++ } ++} ++ ++if ($file_offset == 0) { ++ die "Never found .bss or .brk file offset\n"; ++} ++printf("%d\n", $mem_size + $file_offset); +diff --git a/arch/xtensa/include/uapi/asm/unistd.h b/arch/xtensa/include/uapi/asm/unistd.h +index b9395529f02d..50084f7c01c8 100644 +--- a/arch/xtensa/include/uapi/asm/unistd.h ++++ b/arch/xtensa/include/uapi/asm/unistd.h +@@ -384,7 +384,8 @@ __SYSCALL(174, sys_chroot, 1) + #define __NR_pivot_root 175 + __SYSCALL(175, sys_pivot_root, 2) + #define __NR_umount 176 +-__SYSCALL(176, sys_umount, 2) ++__SYSCALL(176, sys_oldumount, 1) ++#define __ARCH_WANT_SYS_OLDUMOUNT + #define __NR_swapoff 177 + __SYSCALL(177, sys_swapoff, 1) + #define __NR_sync 178 +diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c +index 00663d60f6d4..e662f147d436 100644 +--- a/drivers/ata/ahci.c ++++ b/drivers/ata/ahci.c +@@ -61,6 +61,7 @@ enum board_ids { + /* board IDs by feature in alphabetical order */ + board_ahci, + board_ahci_ign_iferr, ++ board_ahci_nomsi, + board_ahci_noncq, + board_ahci_nosntf, + board_ahci_yes_fbs, +@@ -122,6 +123,13 @@ static const struct ata_port_info ahci_port_info[] = { + .udma_mask = ATA_UDMA6, + .port_ops = &ahci_ops, + }, ++ [board_ahci_nomsi] = { ++ AHCI_HFLAGS (AHCI_HFLAG_NO_MSI), ++ .flags = AHCI_FLAG_COMMON, ++ .pio_mask = ATA_PIO4, ++ .udma_mask = ATA_UDMA6, ++ .port_ops = &ahci_ops, ++ }, + [board_ahci_noncq] = { + AHCI_HFLAGS (AHCI_HFLAG_NO_NCQ), + .flags = AHCI_FLAG_COMMON, +@@ -314,6 +322,11 @@ static const struct pci_device_id ahci_pci_tbl[] = { + { PCI_VDEVICE(INTEL, 0x8c87), board_ahci }, /* 9 Series RAID */ + { PCI_VDEVICE(INTEL, 0x8c8e), board_ahci }, /* 9 Series RAID */ + { PCI_VDEVICE(INTEL, 0x8c8f), board_ahci }, /* 9 Series RAID */ ++ { PCI_VDEVICE(INTEL, 0xa103), board_ahci }, /* Sunrise Point-H AHCI */ ++ { PCI_VDEVICE(INTEL, 0xa103), board_ahci }, /* Sunrise Point-H RAID */ ++ { PCI_VDEVICE(INTEL, 0xa105), board_ahci }, /* Sunrise Point-H RAID */ ++ { PCI_VDEVICE(INTEL, 0xa107), board_ahci }, /* Sunrise Point-H RAID */ ++ { PCI_VDEVICE(INTEL, 0xa10f), board_ahci }, /* Sunrise Point-H RAID */ + + /* JMicron 360/1/3/5/6, match class to avoid IDE function */ + { PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, +@@ -476,10 +489,10 @@ static const struct pci_device_id ahci_pci_tbl[] = { + { PCI_VDEVICE(ASMEDIA, 0x0612), board_ahci }, /* ASM1062 */ + + /* +- * Samsung SSDs found on some macbooks. NCQ times out. +- * https://bugzilla.kernel.org/show_bug.cgi?id=60731 ++ * Samsung SSDs found on some macbooks. NCQ times out if MSI is ++ * enabled. https://bugzilla.kernel.org/show_bug.cgi?id=60731 + */ +- { PCI_VDEVICE(SAMSUNG, 0x1600), board_ahci_noncq }, ++ { PCI_VDEVICE(SAMSUNG, 0x1600), board_ahci_nomsi }, + + /* Enmotus */ + { PCI_DEVICE(0x1c44, 0x8000), board_ahci }, +diff --git a/drivers/ata/sata_rcar.c b/drivers/ata/sata_rcar.c +index 2b25bd83fc9d..c1ea780fca07 100644 +--- a/drivers/ata/sata_rcar.c ++++ b/drivers/ata/sata_rcar.c +@@ -146,6 +146,7 @@ + enum sata_rcar_type { + RCAR_GEN1_SATA, + RCAR_GEN2_SATA, ++ RCAR_R8A7790_ES1_SATA, + }; + + struct sata_rcar_priv { +@@ -763,6 +764,9 @@ static void sata_rcar_setup_port(struct ata_host *host) + ap->udma_mask = ATA_UDMA6; + ap->flags |= ATA_FLAG_SATA; + ++ if (priv->type == RCAR_R8A7790_ES1_SATA) ++ ap->flags |= ATA_FLAG_NO_DIPM; ++ + ioaddr->cmd_addr = base + SDATA_REG; + ioaddr->ctl_addr = base + SSDEVCON_REG; + ioaddr->scr_addr = base + SCRSSTS_REG; +@@ -792,6 +796,7 @@ static void sata_rcar_init_controller(struct ata_host *host) + sata_rcar_gen1_phy_init(priv); + break; + case RCAR_GEN2_SATA: ++ case RCAR_R8A7790_ES1_SATA: + sata_rcar_gen2_phy_init(priv); + break; + default: +@@ -838,6 +843,10 @@ static struct of_device_id sata_rcar_match[] = { + .data = (void *)RCAR_GEN2_SATA + }, + { ++ .compatible = "renesas,sata-r8a7790-es1", ++ .data = (void *)RCAR_R8A7790_ES1_SATA ++ }, ++ { + .compatible = "renesas,sata-r8a7791", + .data = (void *)RCAR_GEN2_SATA + }, +@@ -849,6 +858,7 @@ static const struct platform_device_id sata_rcar_id_table[] = { + { "sata_rcar", RCAR_GEN1_SATA }, /* Deprecated by "sata-r8a7779" */ + { "sata-r8a7779", RCAR_GEN1_SATA }, + { "sata-r8a7790", RCAR_GEN2_SATA }, ++ { "sata-r8a7790-es1", RCAR_R8A7790_ES1_SATA }, + { "sata-r8a7791", RCAR_GEN2_SATA }, + { }, + }; +diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c +index f6cff3be0ed7..2f9a3d8ecbbf 100644 +--- a/drivers/base/regmap/regmap.c ++++ b/drivers/base/regmap/regmap.c +@@ -1557,8 +1557,10 @@ int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val, + } else { + void *wval; + +- if (!val_count) +- return -EINVAL; ++ if (!val_count) { ++ ret = -EINVAL; ++ goto out; ++ } + + wval = kmemdup(val, val_count * val_bytes, GFP_KERNEL); + if (!wval) { +diff --git a/drivers/block/sunvdc.c b/drivers/block/sunvdc.c +index 5814deb6963d..0ebadf93b6c5 100644 +--- a/drivers/block/sunvdc.c ++++ b/drivers/block/sunvdc.c +@@ -9,6 +9,7 @@ + #include <linux/blkdev.h> + #include <linux/hdreg.h> + #include <linux/genhd.h> ++#include <linux/cdrom.h> + #include <linux/slab.h> + #include <linux/spinlock.h> + #include <linux/completion.h> +@@ -22,8 +23,8 @@ + + #define DRV_MODULE_NAME "sunvdc" + #define PFX DRV_MODULE_NAME ": " +-#define DRV_MODULE_VERSION "1.0" +-#define DRV_MODULE_RELDATE "June 25, 2007" ++#define DRV_MODULE_VERSION "1.1" ++#define DRV_MODULE_RELDATE "February 13, 2013" + + static char version[] = + DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; +@@ -32,7 +33,7 @@ MODULE_DESCRIPTION("Sun LDOM virtual disk client driver"); + MODULE_LICENSE("GPL"); + MODULE_VERSION(DRV_MODULE_VERSION); + +-#define VDC_TX_RING_SIZE 256 ++#define VDC_TX_RING_SIZE 512 + + #define WAITING_FOR_LINK_UP 0x01 + #define WAITING_FOR_TX_SPACE 0x02 +@@ -65,11 +66,9 @@ struct vdc_port { + u64 operations; + u32 vdisk_size; + u8 vdisk_type; ++ u8 vdisk_mtype; + + char disk_name[32]; +- +- struct vio_disk_geom geom; +- struct vio_disk_vtoc label; + }; + + static inline struct vdc_port *to_vdc_port(struct vio_driver_state *vio) +@@ -79,9 +78,16 @@ static inline struct vdc_port *to_vdc_port(struct vio_driver_state *vio) + + /* Ordered from largest major to lowest */ + static struct vio_version vdc_versions[] = { ++ { .major = 1, .minor = 1 }, + { .major = 1, .minor = 0 }, + }; + ++static inline int vdc_version_supported(struct vdc_port *port, ++ u16 major, u16 minor) ++{ ++ return port->vio.ver.major == major && port->vio.ver.minor >= minor; ++} ++ + #define VDCBLK_NAME "vdisk" + static int vdc_major; + #define PARTITION_SHIFT 3 +@@ -94,18 +100,54 @@ static inline u32 vdc_tx_dring_avail(struct vio_dring_state *dr) + static int vdc_getgeo(struct block_device *bdev, struct hd_geometry *geo) + { + struct gendisk *disk = bdev->bd_disk; +- struct vdc_port *port = disk->private_data; ++ sector_t nsect = get_capacity(disk); ++ sector_t cylinders = nsect; + +- geo->heads = (u8) port->geom.num_hd; +- geo->sectors = (u8) port->geom.num_sec; +- geo->cylinders = port->geom.num_cyl; ++ geo->heads = 0xff; ++ geo->sectors = 0x3f; ++ sector_div(cylinders, geo->heads * geo->sectors); ++ geo->cylinders = cylinders; ++ if ((sector_t)(geo->cylinders + 1) * geo->heads * geo->sectors < nsect) ++ geo->cylinders = 0xffff; + + return 0; + } + ++/* Add ioctl/CDROM_GET_CAPABILITY to support cdrom_id in udev ++ * when vdisk_mtype is VD_MEDIA_TYPE_CD or VD_MEDIA_TYPE_DVD. ++ * Needed to be able to install inside an ldom from an iso image. ++ */ ++static int vdc_ioctl(struct block_device *bdev, fmode_t mode, ++ unsigned command, unsigned long argument) ++{ ++ int i; ++ struct gendisk *disk; ++ ++ switch (command) { ++ case CDROMMULTISESSION: ++ pr_debug(PFX "Multisession CDs not supported\n"); ++ for (i = 0; i < sizeof(struct cdrom_multisession); i++) ++ if (put_user(0, (char __user *)(argument + i))) ++ return -EFAULT; ++ return 0; ++ ++ case CDROM_GET_CAPABILITY: ++ disk = bdev->bd_disk; ++ ++ if (bdev->bd_disk && (disk->flags & GENHD_FL_CD)) ++ return 0; ++ return -EINVAL; ++ ++ default: ++ pr_debug(PFX "ioctl %08x not supported\n", command); ++ return -EINVAL; ++ } ++} ++ + static const struct block_device_operations vdc_fops = { + .owner = THIS_MODULE, + .getgeo = vdc_getgeo, ++ .ioctl = vdc_ioctl, + }; + + static void vdc_finish(struct vio_driver_state *vio, int err, int waiting_for) +@@ -165,9 +207,9 @@ static int vdc_handle_attr(struct vio_driver_state *vio, void *arg) + struct vio_disk_attr_info *pkt = arg; + + viodbg(HS, "GOT ATTR stype[0x%x] ops[%llx] disk_size[%llu] disk_type[%x] " +- "xfer_mode[0x%x] blksz[%u] max_xfer[%llu]\n", ++ "mtype[0x%x] xfer_mode[0x%x] blksz[%u] max_xfer[%llu]\n", + pkt->tag.stype, pkt->operations, +- pkt->vdisk_size, pkt->vdisk_type, ++ pkt->vdisk_size, pkt->vdisk_type, pkt->vdisk_mtype, + pkt->xfer_mode, pkt->vdisk_block_size, + pkt->max_xfer_size); + +@@ -192,8 +234,11 @@ static int vdc_handle_attr(struct vio_driver_state *vio, void *arg) + } + + port->operations = pkt->operations; +- port->vdisk_size = pkt->vdisk_size; + port->vdisk_type = pkt->vdisk_type; ++ if (vdc_version_supported(port, 1, 1)) { ++ port->vdisk_size = pkt->vdisk_size; ++ port->vdisk_mtype = pkt->vdisk_mtype; ++ } + if (pkt->max_xfer_size < port->max_xfer_size) + port->max_xfer_size = pkt->max_xfer_size; + port->vdisk_block_size = pkt->vdisk_block_size; +@@ -236,7 +281,9 @@ static void vdc_end_one(struct vdc_port *port, struct vio_dring_state *dr, + + __blk_end_request(req, (desc->status ? -EIO : 0), desc->size); + +- if (blk_queue_stopped(port->disk->queue)) ++ /* restart blk queue when ring is half emptied */ ++ if (blk_queue_stopped(port->disk->queue) && ++ vdc_tx_dring_avail(dr) * 100 / VDC_TX_RING_SIZE >= 50) + blk_start_queue(port->disk->queue); + } + +@@ -388,12 +435,6 @@ static int __send_request(struct request *req) + for (i = 0; i < nsg; i++) + len += sg[i].length; + +- if (unlikely(vdc_tx_dring_avail(dr) < 1)) { +- blk_stop_queue(port->disk->queue); +- err = -ENOMEM; +- goto out; +- } +- + desc = vio_dring_cur(dr); + + err = ldc_map_sg(port->vio.lp, sg, nsg, +@@ -433,21 +474,32 @@ static int __send_request(struct request *req) + port->req_id++; + dr->prod = (dr->prod + 1) & (VDC_TX_RING_SIZE - 1); + } +-out: + + return err; + } + +-static void do_vdc_request(struct request_queue *q) ++static void do_vdc_request(struct request_queue *rq) + { +- while (1) { +- struct request *req = blk_fetch_request(q); ++ struct request *req; + +- if (!req) +- break; ++ while ((req = blk_peek_request(rq)) != NULL) { ++ struct vdc_port *port; ++ struct vio_dring_state *dr; + +- if (__send_request(req) < 0) +- __blk_end_request_all(req, -EIO); ++ port = req->rq_disk->private_data; ++ dr = &port->vio.drings[VIO_DRIVER_TX_RING]; ++ if (unlikely(vdc_tx_dring_avail(dr) < 1)) ++ goto wait; ++ ++ blk_start_request(req); ++ ++ if (__send_request(req) < 0) { ++ blk_requeue_request(rq, req); ++wait: ++ /* Avoid pointless unplugs. */ ++ blk_stop_queue(rq); ++ break; ++ } + } + } + +@@ -656,25 +708,27 @@ static int probe_disk(struct vdc_port *port) + if (comp.err) + return comp.err; + +- err = generic_request(port, VD_OP_GET_VTOC, +- &port->label, sizeof(port->label)); +- if (err < 0) { +- printk(KERN_ERR PFX "VD_OP_GET_VTOC returns error %d\n", err); +- return err; +- } +- +- err = generic_request(port, VD_OP_GET_DISKGEOM, +- &port->geom, sizeof(port->geom)); +- if (err < 0) { +- printk(KERN_ERR PFX "VD_OP_GET_DISKGEOM returns " +- "error %d\n", err); +- return err; ++ if (vdc_version_supported(port, 1, 1)) { ++ /* vdisk_size should be set during the handshake, if it wasn't ++ * then the underlying disk is reserved by another system ++ */ ++ if (port->vdisk_size == -1) ++ return -ENODEV; ++ } else { ++ struct vio_disk_geom geom; ++ ++ err = generic_request(port, VD_OP_GET_DISKGEOM, ++ &geom, sizeof(geom)); ++ if (err < 0) { ++ printk(KERN_ERR PFX "VD_OP_GET_DISKGEOM returns " ++ "error %d\n", err); ++ return err; ++ } ++ port->vdisk_size = ((u64)geom.num_cyl * ++ (u64)geom.num_hd * ++ (u64)geom.num_sec); + } + +- port->vdisk_size = ((u64)port->geom.num_cyl * +- (u64)port->geom.num_hd * +- (u64)port->geom.num_sec); +- + q = blk_init_queue(do_vdc_request, &port->vio.lock); + if (!q) { + printk(KERN_ERR PFX "%s: Could not allocate queue.\n", +@@ -691,6 +745,10 @@ static int probe_disk(struct vdc_port *port) + + port->disk = g; + ++ /* Each segment in a request is up to an aligned page in size. */ ++ blk_queue_segment_boundary(q, PAGE_SIZE - 1); ++ blk_queue_max_segment_size(q, PAGE_SIZE); ++ + blk_queue_max_segments(q, port->ring_cookies); + blk_queue_max_hw_sectors(q, port->max_xfer_size); + g->major = vdc_major; +@@ -704,9 +762,32 @@ static int probe_disk(struct vdc_port *port) + + set_capacity(g, port->vdisk_size); + +- printk(KERN_INFO PFX "%s: %u sectors (%u MB)\n", ++ if (vdc_version_supported(port, 1, 1)) { ++ switch (port->vdisk_mtype) { ++ case VD_MEDIA_TYPE_CD: ++ pr_info(PFX "Virtual CDROM %s\n", port->disk_name); ++ g->flags |= GENHD_FL_CD; ++ g->flags |= GENHD_FL_REMOVABLE; ++ set_disk_ro(g, 1); ++ break; ++ ++ case VD_MEDIA_TYPE_DVD: ++ pr_info(PFX "Virtual DVD %s\n", port->disk_name); ++ g->flags |= GENHD_FL_CD; ++ g->flags |= GENHD_FL_REMOVABLE; ++ set_disk_ro(g, 1); ++ break; ++ ++ case VD_MEDIA_TYPE_FIXED: ++ pr_info(PFX "Virtual Hard disk %s\n", port->disk_name); ++ break; ++ } ++ } ++ ++ pr_info(PFX "%s: %u sectors (%u MB) protocol %d.%d\n", + g->disk_name, +- port->vdisk_size, (port->vdisk_size >> (20 - 9))); ++ port->vdisk_size, (port->vdisk_size >> (20 - 9)), ++ port->vio.ver.major, port->vio.ver.minor); + + add_disk(g); + +@@ -765,6 +846,7 @@ static int vdc_port_probe(struct vio_dev *vdev, const struct vio_device_id *id) + else + snprintf(port->disk_name, sizeof(port->disk_name), + VDCBLK_NAME "%c", 'a' + ((int)vdev->dev_no % 26)); ++ port->vdisk_size = -1; + + err = vio_driver_init(&port->vio, vdev, VDEV_DISK, + vdc_versions, ARRAY_SIZE(vdc_versions), +diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c +index 51c557cfd92b..d8ddb8e2adc1 100644 +--- a/drivers/block/zram/zram_drv.c ++++ b/drivers/block/zram/zram_drv.c +@@ -447,7 +447,8 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index, + } + + if (page_zero_filled(uncmem)) { +- kunmap_atomic(user_mem); ++ if (user_mem) ++ kunmap_atomic(user_mem); + /* Free memory associated with this sector now. */ + write_lock(&zram->meta->tb_lock); + zram_free_page(zram, index); +diff --git a/drivers/char/hw_random/pseries-rng.c b/drivers/char/hw_random/pseries-rng.c +index ab7ffdec0ec3..f38f2c13e79c 100644 +--- a/drivers/char/hw_random/pseries-rng.c ++++ b/drivers/char/hw_random/pseries-rng.c +@@ -25,18 +25,21 @@ + #include <asm/vio.h> + + +-static int pseries_rng_data_read(struct hwrng *rng, u32 *data) ++static int pseries_rng_read(struct hwrng *rng, void *data, size_t max, bool wait) + { ++ u64 buffer[PLPAR_HCALL_BUFSIZE]; ++ size_t size = max < 8 ? max : 8; + int rc; + +- rc = plpar_hcall(H_RANDOM, (unsigned long *)data); ++ rc = plpar_hcall(H_RANDOM, (unsigned long *)buffer); + if (rc != H_SUCCESS) { + pr_err_ratelimited("H_RANDOM call failed %d\n", rc); + return -EIO; + } ++ memcpy(data, buffer, size); + + /* The hypervisor interface returns 64 bits */ +- return 8; ++ return size; + } + + /** +@@ -55,7 +58,7 @@ static unsigned long pseries_rng_get_desired_dma(struct vio_dev *vdev) + + static struct hwrng pseries_rng = { + .name = KBUILD_MODNAME, +- .data_read = pseries_rng_data_read, ++ .read = pseries_rng_read, + }; + + static int __init pseries_rng_probe(struct vio_dev *dev, +diff --git a/drivers/crypto/caam/caamhash.c b/drivers/crypto/caam/caamhash.c +index a4127453baae..d97a03dbf42c 100644 +--- a/drivers/crypto/caam/caamhash.c ++++ b/drivers/crypto/caam/caamhash.c +@@ -835,8 +835,9 @@ static int ahash_update_ctx(struct ahash_request *req) + edesc->sec4_sg + sec4_sg_src_index, + chained); + if (*next_buflen) { +- sg_copy_part(next_buf, req->src, to_hash - +- *buflen, req->nbytes); ++ scatterwalk_map_and_copy(next_buf, req->src, ++ to_hash - *buflen, ++ *next_buflen, 0); + state->current_buf = !state->current_buf; + } + } else { +@@ -869,7 +870,8 @@ static int ahash_update_ctx(struct ahash_request *req) + kfree(edesc); + } + } else if (*next_buflen) { +- sg_copy(buf + *buflen, req->src, req->nbytes); ++ scatterwalk_map_and_copy(buf + *buflen, req->src, 0, ++ req->nbytes, 0); + *buflen = *next_buflen; + *next_buflen = last_buflen; + } +@@ -1216,8 +1218,9 @@ static int ahash_update_no_ctx(struct ahash_request *req) + src_map_to_sec4_sg(jrdev, req->src, src_nents, + edesc->sec4_sg + 1, chained); + if (*next_buflen) { +- sg_copy_part(next_buf, req->src, to_hash - *buflen, +- req->nbytes); ++ scatterwalk_map_and_copy(next_buf, req->src, ++ to_hash - *buflen, ++ *next_buflen, 0); + state->current_buf = !state->current_buf; + } + +@@ -1248,7 +1251,8 @@ static int ahash_update_no_ctx(struct ahash_request *req) + kfree(edesc); + } + } else if (*next_buflen) { +- sg_copy(buf + *buflen, req->src, req->nbytes); ++ scatterwalk_map_and_copy(buf + *buflen, req->src, 0, ++ req->nbytes, 0); + *buflen = *next_buflen; + *next_buflen = 0; + } +@@ -1405,7 +1409,8 @@ static int ahash_update_first(struct ahash_request *req) + } + + if (*next_buflen) +- sg_copy_part(next_buf, req->src, to_hash, req->nbytes); ++ scatterwalk_map_and_copy(next_buf, req->src, to_hash, ++ *next_buflen, 0); + + sh_len = desc_len(sh_desc); + desc = edesc->hw_desc; +@@ -1438,7 +1443,8 @@ static int ahash_update_first(struct ahash_request *req) + state->update = ahash_update_no_ctx; + state->finup = ahash_finup_no_ctx; + state->final = ahash_final_no_ctx; +- sg_copy(next_buf, req->src, req->nbytes); ++ scatterwalk_map_and_copy(next_buf, req->src, 0, ++ req->nbytes, 0); + } + #ifdef DEBUG + print_hex_dump(KERN_ERR, "next buf@"__stringify(__LINE__)": ", +diff --git a/drivers/crypto/caam/key_gen.c b/drivers/crypto/caam/key_gen.c +index ea2e406610eb..b872eed2957b 100644 +--- a/drivers/crypto/caam/key_gen.c ++++ b/drivers/crypto/caam/key_gen.c +@@ -51,23 +51,29 @@ int gen_split_key(struct device *jrdev, u8 *key_out, int split_key_len, + u32 *desc; + struct split_key_result result; + dma_addr_t dma_addr_in, dma_addr_out; +- int ret = 0; ++ int ret = -ENOMEM; + + desc = kmalloc(CAAM_CMD_SZ * 6 + CAAM_PTR_SZ * 2, GFP_KERNEL | GFP_DMA); + if (!desc) { + dev_err(jrdev, "unable to allocate key input memory\n"); +- return -ENOMEM; ++ return ret; + } + +- init_job_desc(desc, 0); +- + dma_addr_in = dma_map_single(jrdev, (void *)key_in, keylen, + DMA_TO_DEVICE); + if (dma_mapping_error(jrdev, dma_addr_in)) { + dev_err(jrdev, "unable to map key input memory\n"); +- kfree(desc); +- return -ENOMEM; ++ goto out_free; + } ++ ++ dma_addr_out = dma_map_single(jrdev, key_out, split_key_pad_len, ++ DMA_FROM_DEVICE); ++ if (dma_mapping_error(jrdev, dma_addr_out)) { ++ dev_err(jrdev, "unable to map key output memory\n"); ++ goto out_unmap_in; ++ } ++ ++ init_job_desc(desc, 0); + append_key(desc, dma_addr_in, keylen, CLASS_2 | KEY_DEST_CLASS_REG); + + /* Sets MDHA up into an HMAC-INIT */ +@@ -84,13 +90,6 @@ int gen_split_key(struct device *jrdev, u8 *key_out, int split_key_len, + * FIFO_STORE with the explicit split-key content store + * (0x26 output type) + */ +- dma_addr_out = dma_map_single(jrdev, key_out, split_key_pad_len, +- DMA_FROM_DEVICE); +- if (dma_mapping_error(jrdev, dma_addr_out)) { +- dev_err(jrdev, "unable to map key output memory\n"); +- kfree(desc); +- return -ENOMEM; +- } + append_fifo_store(desc, dma_addr_out, split_key_len, + LDST_CLASS_2_CCB | FIFOST_TYPE_SPLIT_KEK); + +@@ -118,10 +117,10 @@ int gen_split_key(struct device *jrdev, u8 *key_out, int split_key_len, + + dma_unmap_single(jrdev, dma_addr_out, split_key_pad_len, + DMA_FROM_DEVICE); ++out_unmap_in: + dma_unmap_single(jrdev, dma_addr_in, keylen, DMA_TO_DEVICE); +- ++out_free: + kfree(desc); +- + return ret; + } + EXPORT_SYMBOL(gen_split_key); +diff --git a/drivers/crypto/caam/sg_sw_sec4.h b/drivers/crypto/caam/sg_sw_sec4.h +index b12ff85f4241..ce28a563effc 100644 +--- a/drivers/crypto/caam/sg_sw_sec4.h ++++ b/drivers/crypto/caam/sg_sw_sec4.h +@@ -116,57 +116,3 @@ static int dma_unmap_sg_chained(struct device *dev, struct scatterlist *sg, + } + return nents; + } +- +-/* Map SG page in kernel virtual address space and copy */ +-static inline void sg_map_copy(u8 *dest, struct scatterlist *sg, +- int len, int offset) +-{ +- u8 *mapped_addr; +- +- /* +- * Page here can be user-space pinned using get_user_pages +- * Same must be kmapped before use and kunmapped subsequently +- */ +- mapped_addr = kmap_atomic(sg_page(sg)); +- memcpy(dest, mapped_addr + offset, len); +- kunmap_atomic(mapped_addr); +-} +- +-/* Copy from len bytes of sg to dest, starting from beginning */ +-static inline void sg_copy(u8 *dest, struct scatterlist *sg, unsigned int len) +-{ +- struct scatterlist *current_sg = sg; +- int cpy_index = 0, next_cpy_index = current_sg->length; +- +- while (next_cpy_index < len) { +- sg_map_copy(dest + cpy_index, current_sg, current_sg->length, +- current_sg->offset); +- current_sg = scatterwalk_sg_next(current_sg); +- cpy_index = next_cpy_index; +- next_cpy_index += current_sg->length; +- } +- if (cpy_index < len) +- sg_map_copy(dest + cpy_index, current_sg, len-cpy_index, +- current_sg->offset); +-} +- +-/* Copy sg data, from to_skip to end, to dest */ +-static inline void sg_copy_part(u8 *dest, struct scatterlist *sg, +- int to_skip, unsigned int end) +-{ +- struct scatterlist *current_sg = sg; +- int sg_index, cpy_index, offset; +- +- sg_index = current_sg->length; +- while (sg_index <= to_skip) { +- current_sg = scatterwalk_sg_next(current_sg); +- sg_index += current_sg->length; +- } +- cpy_index = sg_index - to_skip; +- offset = current_sg->offset + current_sg->length - cpy_index; +- sg_map_copy(dest, current_sg, cpy_index, offset); +- if (end - sg_index) { +- current_sg = scatterwalk_sg_next(current_sg); +- sg_copy(dest + cpy_index, current_sg, end - sg_index); +- } +-} +diff --git a/drivers/firewire/core-cdev.c b/drivers/firewire/core-cdev.c +index d7d5c8af92b9..6d4456898007 100644 +--- a/drivers/firewire/core-cdev.c ++++ b/drivers/firewire/core-cdev.c +@@ -1637,8 +1637,7 @@ static int dispatch_ioctl(struct client *client, + _IOC_SIZE(cmd) > sizeof(buffer)) + return -ENOTTY; + +- if (_IOC_DIR(cmd) == _IOC_READ) +- memset(&buffer, 0, _IOC_SIZE(cmd)); ++ memset(&buffer, 0, sizeof(buffer)); + + if (_IOC_DIR(cmd) & _IOC_WRITE) + if (copy_from_user(&buffer, arg, _IOC_SIZE(cmd))) +diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c +index ab5c26575622..ddf70d6c0270 100644 +--- a/drivers/gpu/drm/radeon/cik.c ++++ b/drivers/gpu/drm/radeon/cik.c +@@ -3936,8 +3936,8 @@ static int cik_cp_gfx_start(struct radeon_device *rdev) + /* init the CE partitions. CE only used for gfx on CIK */ + radeon_ring_write(ring, PACKET3(PACKET3_SET_BASE, 2)); + radeon_ring_write(ring, PACKET3_BASE_INDEX(CE_PARTITION_BASE)); +- radeon_ring_write(ring, 0xc000); +- radeon_ring_write(ring, 0xc000); ++ radeon_ring_write(ring, 0x8000); ++ radeon_ring_write(ring, 0x8000); + + /* setup clear context state */ + radeon_ring_write(ring, PACKET3(PACKET3_PREAMBLE_CNTL, 0)); +@@ -8893,6 +8893,9 @@ void dce8_bandwidth_update(struct radeon_device *rdev) + u32 num_heads = 0, lb_size; + int i; + ++ if (!rdev->mode_info.mode_config_initialized) ++ return; ++ + radeon_update_display_priority(rdev); + + for (i = 0; i < rdev->num_crtc; i++) { +diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c +index 4b3c5f7ae63b..7138f3e31b7c 100644 +--- a/drivers/gpu/drm/radeon/evergreen.c ++++ b/drivers/gpu/drm/radeon/evergreen.c +@@ -2362,6 +2362,9 @@ void evergreen_bandwidth_update(struct radeon_device *rdev) + u32 num_heads = 0, lb_size; + int i; + ++ if (!rdev->mode_info.mode_config_initialized) ++ return; ++ + radeon_update_display_priority(rdev); + + for (i = 0; i < rdev->num_crtc; i++) { +@@ -2570,6 +2573,7 @@ void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *sav + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 1); + tmp |= EVERGREEN_CRTC_BLANK_DATA_EN; + WREG32(EVERGREEN_CRTC_BLANK_CONTROL + crtc_offsets[i], tmp); ++ WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 0); + } + } else { + tmp = RREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i]); +diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c +index 3cc78bb66042..07620e198a6d 100644 +--- a/drivers/gpu/drm/radeon/r100.c ++++ b/drivers/gpu/drm/radeon/r100.c +@@ -3219,6 +3219,9 @@ void r100_bandwidth_update(struct radeon_device *rdev) + uint32_t pixel_bytes1 = 0; + uint32_t pixel_bytes2 = 0; + ++ if (!rdev->mode_info.mode_config_initialized) ++ return; ++ + radeon_update_display_priority(rdev); + + if (rdev->mode_info.crtcs[0]->base.enabled) { +diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c +index 95b693c11640..e5619d5e2a30 100644 +--- a/drivers/gpu/drm/radeon/rs600.c ++++ b/drivers/gpu/drm/radeon/rs600.c +@@ -890,6 +890,9 @@ void rs600_bandwidth_update(struct radeon_device *rdev) + u32 d1mode_priority_a_cnt, d2mode_priority_a_cnt; + /* FIXME: implement full support */ + ++ if (!rdev->mode_info.mode_config_initialized) ++ return; ++ + radeon_update_display_priority(rdev); + + if (rdev->mode_info.crtcs[0]->base.enabled) +diff --git a/drivers/gpu/drm/radeon/rs690.c b/drivers/gpu/drm/radeon/rs690.c +index 3462b64369bf..0a2d36e81108 100644 +--- a/drivers/gpu/drm/radeon/rs690.c ++++ b/drivers/gpu/drm/radeon/rs690.c +@@ -579,6 +579,9 @@ void rs690_bandwidth_update(struct radeon_device *rdev) + u32 d1mode_priority_a_cnt, d1mode_priority_b_cnt; + u32 d2mode_priority_a_cnt, d2mode_priority_b_cnt; + ++ if (!rdev->mode_info.mode_config_initialized) ++ return; ++ + radeon_update_display_priority(rdev); + + if (rdev->mode_info.crtcs[0]->base.enabled) +diff --git a/drivers/gpu/drm/radeon/rv515.c b/drivers/gpu/drm/radeon/rv515.c +index 237dd29d9f1c..b49965a21a2d 100644 +--- a/drivers/gpu/drm/radeon/rv515.c ++++ b/drivers/gpu/drm/radeon/rv515.c +@@ -1276,6 +1276,9 @@ void rv515_bandwidth_update(struct radeon_device *rdev) + struct drm_display_mode *mode0 = NULL; + struct drm_display_mode *mode1 = NULL; + ++ if (!rdev->mode_info.mode_config_initialized) ++ return; ++ + radeon_update_display_priority(rdev); + + if (rdev->mode_info.crtcs[0]->base.enabled) +diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c +index 559564c1dc97..52b64ad285d6 100644 +--- a/drivers/gpu/drm/radeon/si.c ++++ b/drivers/gpu/drm/radeon/si.c +@@ -2227,6 +2227,9 @@ void dce6_bandwidth_update(struct radeon_device *rdev) + u32 num_heads = 0, lb_size; + int i; + ++ if (!rdev->mode_info.mode_config_initialized) ++ return; ++ + radeon_update_display_priority(rdev); + + for (i = 0; i < rdev->num_crtc; i++) { +diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c +index ea6203ee7bcc..23467a2abd62 100644 +--- a/drivers/infiniband/core/uverbs_cmd.c ++++ b/drivers/infiniband/core/uverbs_cmd.c +@@ -2425,6 +2425,8 @@ ssize_t ib_uverbs_create_ah(struct ib_uverbs_file *file, + attr.grh.sgid_index = cmd.attr.grh.sgid_index; + attr.grh.hop_limit = cmd.attr.grh.hop_limit; + attr.grh.traffic_class = cmd.attr.grh.traffic_class; ++ attr.vlan_id = 0; ++ memset(&attr.dmac, 0, sizeof(attr.dmac)); + memcpy(attr.grh.dgid.raw, cmd.attr.grh.dgid, 16); + + ah = ib_create_ah(pd, &attr); +diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c +index fb15c64ffb95..4979b00fbf04 100644 +--- a/drivers/input/mouse/alps.c ++++ b/drivers/input/mouse/alps.c +@@ -1047,7 +1047,13 @@ static psmouse_ret_t alps_process_byte(struct psmouse *psmouse) + { + struct alps_data *priv = psmouse->private; + +- if ((psmouse->packet[0] & 0xc8) == 0x08) { /* PS/2 packet */ ++ /* ++ * Check if we are dealing with a bare PS/2 packet, presumably from ++ * a device connected to the external PS/2 port. Because bare PS/2 ++ * protocol does not have enough constant bits to self-synchronize ++ * properly we only do this if the device is fully synchronized. ++ */ ++ if (!psmouse->out_of_sync_cnt && (psmouse->packet[0] & 0xc8) == 0x08) { + if (psmouse->pktcnt == 3) { + alps_report_bare_ps2_packet(psmouse, psmouse->packet, + true); +@@ -1071,12 +1077,27 @@ static psmouse_ret_t alps_process_byte(struct psmouse *psmouse) + } + + /* Bytes 2 - pktsize should have 0 in the highest bit */ +- if ((priv->proto_version < ALPS_PROTO_V5) && ++ if (priv->proto_version < ALPS_PROTO_V5 && + psmouse->pktcnt >= 2 && psmouse->pktcnt <= psmouse->pktsize && + (psmouse->packet[psmouse->pktcnt - 1] & 0x80)) { + psmouse_dbg(psmouse, "refusing packet[%i] = %x\n", + psmouse->pktcnt - 1, + psmouse->packet[psmouse->pktcnt - 1]); ++ ++ if (priv->proto_version == ALPS_PROTO_V3 && ++ psmouse->pktcnt == psmouse->pktsize) { ++ /* ++ * Some Dell boxes, such as Latitude E6440 or E7440 ++ * with closed lid, quite often smash last byte of ++ * otherwise valid packet with 0xff. Given that the ++ * next packet is very likely to be valid let's ++ * report PSMOUSE_FULL_PACKET but not process data, ++ * rather than reporting PSMOUSE_BAD_DATA and ++ * filling the logs. ++ */ ++ return PSMOUSE_FULL_PACKET; ++ } ++ + return PSMOUSE_BAD_DATA; + } + +@@ -2148,6 +2169,9 @@ int alps_init(struct psmouse *psmouse) + /* We are having trouble resyncing ALPS touchpads so disable it for now */ + psmouse->resync_time = 0; + ++ /* Allow 2 invalid packets without resetting device */ ++ psmouse->resetafter = psmouse->pktsize * 2; ++ + return 0; + + init_fail: +diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c +index a50a2a7a43f7..1e76eb8f06c7 100644 +--- a/drivers/input/mouse/synaptics.c ++++ b/drivers/input/mouse/synaptics.c +@@ -132,8 +132,8 @@ static const struct min_max_quirk min_max_pnpid_table[] = { + 1232, 5710, 1156, 4696 + }, + { +- (const char * const []){"LEN0034", "LEN0036", "LEN2002", +- "LEN2004", NULL}, ++ (const char * const []){"LEN0034", "LEN0036", "LEN0039", ++ "LEN2002", "LEN2004", NULL}, + 1024, 5112, 2024, 4832 + }, + { +@@ -160,6 +160,7 @@ static const char * const topbuttonpad_pnp_ids[] = { + "LEN0036", /* T440 */ + "LEN0037", + "LEN0038", ++ "LEN0039", /* T440s */ + "LEN0041", + "LEN0042", /* Yoga */ + "LEN0045", +diff --git a/drivers/md/dm-bufio.c b/drivers/md/dm-bufio.c +index ca1621b49453..a1cebf745b22 100644 +--- a/drivers/md/dm-bufio.c ++++ b/drivers/md/dm-bufio.c +@@ -1448,9 +1448,9 @@ static void drop_buffers(struct dm_bufio_client *c) + + /* + * Test if the buffer is unused and too old, and commit it. +- * At if noio is set, we must not do any I/O because we hold +- * dm_bufio_clients_lock and we would risk deadlock if the I/O gets rerouted to +- * different bufio client. ++ * And if GFP_NOFS is used, we must not do any I/O because we hold ++ * dm_bufio_clients_lock and we would risk deadlock if the I/O gets ++ * rerouted to different bufio client. + */ + static int __cleanup_old_buffer(struct dm_buffer *b, gfp_t gfp, + unsigned long max_jiffies) +@@ -1458,7 +1458,7 @@ static int __cleanup_old_buffer(struct dm_buffer *b, gfp_t gfp, + if (jiffies - b->last_accessed < max_jiffies) + return 0; + +- if (!(gfp & __GFP_IO)) { ++ if (!(gfp & __GFP_FS)) { + if (test_bit(B_READING, &b->state) || + test_bit(B_WRITING, &b->state) || + test_bit(B_DIRTY, &b->state)) +@@ -1500,7 +1500,7 @@ dm_bufio_shrink_scan(struct shrinker *shrink, struct shrink_control *sc) + unsigned long freed; + + c = container_of(shrink, struct dm_bufio_client, shrinker); +- if (sc->gfp_mask & __GFP_IO) ++ if (sc->gfp_mask & __GFP_FS) + dm_bufio_lock(c); + else if (!dm_bufio_trylock(c)) + return SHRINK_STOP; +@@ -1517,7 +1517,7 @@ dm_bufio_shrink_count(struct shrinker *shrink, struct shrink_control *sc) + unsigned long count; + + c = container_of(shrink, struct dm_bufio_client, shrinker); +- if (sc->gfp_mask & __GFP_IO) ++ if (sc->gfp_mask & __GFP_FS) + dm_bufio_lock(c); + else if (!dm_bufio_trylock(c)) + return 0; +diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c +index 4880b69e2e9e..59715389b3cf 100644 +--- a/drivers/md/dm-raid.c ++++ b/drivers/md/dm-raid.c +@@ -785,8 +785,7 @@ struct dm_raid_superblock { + __le32 layout; + __le32 stripe_sectors; + +- __u8 pad[452]; /* Round struct to 512 bytes. */ +- /* Always set to 0 when writing. */ ++ /* Remainder of a logical block is zero-filled when writing (see super_sync()). */ + } __packed; + + static int read_disk_sb(struct md_rdev *rdev, int size) +@@ -823,7 +822,7 @@ static void super_sync(struct mddev *mddev, struct md_rdev *rdev) + test_bit(Faulty, &(rs->dev[i].rdev.flags))) + failed_devices |= (1ULL << i); + +- memset(sb, 0, sizeof(*sb)); ++ memset(sb + 1, 0, rdev->sb_size - sizeof(*sb)); + + sb->magic = cpu_to_le32(DM_RAID_MAGIC); + sb->features = cpu_to_le32(0); /* No features yet */ +@@ -858,7 +857,11 @@ static int super_load(struct md_rdev *rdev, struct md_rdev *refdev) + uint64_t events_sb, events_refsb; + + rdev->sb_start = 0; +- rdev->sb_size = sizeof(*sb); ++ rdev->sb_size = bdev_logical_block_size(rdev->meta_bdev); ++ if (rdev->sb_size < sizeof(*sb) || rdev->sb_size > PAGE_SIZE) { ++ DMERR("superblock size of a logical block is no longer valid"); ++ return -EINVAL; ++ } + + ret = read_disk_sb(rdev, rdev->sb_size); + if (ret) +diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c +index 359af3a519b5..37f2648c112b 100644 +--- a/drivers/md/dm-thin.c ++++ b/drivers/md/dm-thin.c +@@ -1704,6 +1704,14 @@ static int thin_bio_map(struct dm_target *ti, struct bio *bio) + return DM_MAPIO_SUBMITTED; + } + ++ /* ++ * We must hold the virtual cell before doing the lookup, otherwise ++ * there's a race with discard. ++ */ ++ build_virtual_key(tc->td, block, &key); ++ if (dm_bio_detain(tc->pool->prison, &key, bio, &cell1, &cell_result)) ++ return DM_MAPIO_SUBMITTED; ++ + r = dm_thin_find_block(td, block, 0, &result); + + /* +@@ -1727,13 +1735,10 @@ static int thin_bio_map(struct dm_target *ti, struct bio *bio) + * shared flag will be set in their case. + */ + thin_defer_bio(tc, bio); ++ cell_defer_no_holder_no_free(tc, &cell1); + return DM_MAPIO_SUBMITTED; + } + +- build_virtual_key(tc->td, block, &key); +- if (dm_bio_detain(tc->pool->prison, &key, bio, &cell1, &cell_result)) +- return DM_MAPIO_SUBMITTED; +- + build_data_key(tc->td, result.block, &key); + if (dm_bio_detain(tc->pool->prison, &key, bio, &cell2, &cell_result)) { + cell_defer_no_holder_no_free(tc, &cell1); +@@ -1754,6 +1759,7 @@ static int thin_bio_map(struct dm_target *ti, struct bio *bio) + * of doing so. + */ + handle_unserviceable_bio(tc->pool, bio); ++ cell_defer_no_holder_no_free(tc, &cell1); + return DM_MAPIO_SUBMITTED; + } + /* fall through */ +@@ -1764,6 +1770,7 @@ static int thin_bio_map(struct dm_target *ti, struct bio *bio) + * provide the hint to load the metadata into cache. + */ + thin_defer_bio(tc, bio); ++ cell_defer_no_holder_no_free(tc, &cell1); + return DM_MAPIO_SUBMITTED; + + default: +@@ -1773,6 +1780,7 @@ static int thin_bio_map(struct dm_target *ti, struct bio *bio) + * pool is switched to fail-io mode. + */ + bio_io_error(bio); ++ cell_defer_no_holder_no_free(tc, &cell1); + return DM_MAPIO_SUBMITTED; + } + } +diff --git a/drivers/md/md.c b/drivers/md/md.c +index 73aedcb639c0..40959ee73583 100644 +--- a/drivers/md/md.c ++++ b/drivers/md/md.c +@@ -5333,6 +5333,7 @@ static int md_set_readonly(struct mddev *mddev, struct block_device *bdev) + printk("md: %s still in use.\n",mdname(mddev)); + if (did_freeze) { + clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery); ++ set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); + md_wakeup_thread(mddev->thread); + } + err = -EBUSY; +@@ -5347,6 +5348,8 @@ static int md_set_readonly(struct mddev *mddev, struct block_device *bdev) + mddev->ro = 1; + set_disk_ro(mddev->gendisk, 1); + clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery); ++ set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); ++ md_wakeup_thread(mddev->thread); + sysfs_notify_dirent_safe(mddev->sysfs_state); + err = 0; + } +@@ -5390,6 +5393,7 @@ static int do_md_stop(struct mddev * mddev, int mode, + mutex_unlock(&mddev->open_mutex); + if (did_freeze) { + clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery); ++ set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); + md_wakeup_thread(mddev->thread); + } + return -EBUSY; +diff --git a/drivers/md/persistent-data/dm-btree-internal.h b/drivers/md/persistent-data/dm-btree-internal.h +index 37d367bb9aa8..bf2b80d5c470 100644 +--- a/drivers/md/persistent-data/dm-btree-internal.h ++++ b/drivers/md/persistent-data/dm-btree-internal.h +@@ -42,6 +42,12 @@ struct btree_node { + } __packed; + + ++/* ++ * Locks a block using the btree node validator. ++ */ ++int bn_read_lock(struct dm_btree_info *info, dm_block_t b, ++ struct dm_block **result); ++ + void inc_children(struct dm_transaction_manager *tm, struct btree_node *n, + struct dm_btree_value_type *vt); + +diff --git a/drivers/md/persistent-data/dm-btree-spine.c b/drivers/md/persistent-data/dm-btree-spine.c +index cf9fd676ae44..1b5e13ec7f96 100644 +--- a/drivers/md/persistent-data/dm-btree-spine.c ++++ b/drivers/md/persistent-data/dm-btree-spine.c +@@ -92,7 +92,7 @@ struct dm_block_validator btree_node_validator = { + + /*----------------------------------------------------------------*/ + +-static int bn_read_lock(struct dm_btree_info *info, dm_block_t b, ++int bn_read_lock(struct dm_btree_info *info, dm_block_t b, + struct dm_block **result) + { + return dm_tm_read_lock(info->tm, b, &btree_node_validator, result); +diff --git a/drivers/md/persistent-data/dm-btree.c b/drivers/md/persistent-data/dm-btree.c +index 416060c25709..200ac12a1d40 100644 +--- a/drivers/md/persistent-data/dm-btree.c ++++ b/drivers/md/persistent-data/dm-btree.c +@@ -847,22 +847,26 @@ EXPORT_SYMBOL_GPL(dm_btree_find_lowest_key); + * FIXME: We shouldn't use a recursive algorithm when we have limited stack + * space. Also this only works for single level trees. + */ +-static int walk_node(struct ro_spine *s, dm_block_t block, ++static int walk_node(struct dm_btree_info *info, dm_block_t block, + int (*fn)(void *context, uint64_t *keys, void *leaf), + void *context) + { + int r; + unsigned i, nr; ++ struct dm_block *node; + struct btree_node *n; + uint64_t keys; + +- r = ro_step(s, block); +- n = ro_node(s); ++ r = bn_read_lock(info, block, &node); ++ if (r) ++ return r; ++ ++ n = dm_block_data(node); + + nr = le32_to_cpu(n->header.nr_entries); + for (i = 0; i < nr; i++) { + if (le32_to_cpu(n->header.flags) & INTERNAL_NODE) { +- r = walk_node(s, value64(n, i), fn, context); ++ r = walk_node(info, value64(n, i), fn, context); + if (r) + goto out; + } else { +@@ -874,7 +878,7 @@ static int walk_node(struct ro_spine *s, dm_block_t block, + } + + out: +- ro_pop(s); ++ dm_tm_unlock(info->tm, node); + return r; + } + +@@ -882,15 +886,7 @@ int dm_btree_walk(struct dm_btree_info *info, dm_block_t root, + int (*fn)(void *context, uint64_t *keys, void *leaf), + void *context) + { +- int r; +- struct ro_spine spine; +- + BUG_ON(info->levels > 1); +- +- init_ro_spine(&spine, info); +- r = walk_node(&spine, root, fn, context); +- exit_ro_spine(&spine); +- +- return r; ++ return walk_node(info, root, fn, context); + } + EXPORT_SYMBOL_GPL(dm_btree_walk); +diff --git a/drivers/media/usb/ttusb-dec/ttusbdecfe.c b/drivers/media/usb/ttusb-dec/ttusbdecfe.c +index 5c45c9d0712d..9c29552aedec 100644 +--- a/drivers/media/usb/ttusb-dec/ttusbdecfe.c ++++ b/drivers/media/usb/ttusb-dec/ttusbdecfe.c +@@ -156,6 +156,9 @@ static int ttusbdecfe_dvbs_diseqc_send_master_cmd(struct dvb_frontend* fe, struc + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00 }; + ++ if (cmd->msg_len > sizeof(b) - 4) ++ return -EINVAL; ++ + memcpy(&b[4], cmd->msg, cmd->msg_len); + + state->config->send_command(fe, 0x72, +diff --git a/drivers/net/ethernet/smsc/smsc911x.c b/drivers/net/ethernet/smsc/smsc911x.c +index 6382b7c416f4..e10f5ed26181 100644 +--- a/drivers/net/ethernet/smsc/smsc911x.c ++++ b/drivers/net/ethernet/smsc/smsc911x.c +@@ -1341,6 +1341,42 @@ static void smsc911x_rx_multicast_update_workaround(struct smsc911x_data *pdata) + spin_unlock(&pdata->mac_lock); + } + ++static int smsc911x_phy_general_power_up(struct smsc911x_data *pdata) ++{ ++ int rc = 0; ++ ++ if (!pdata->phy_dev) ++ return rc; ++ ++ /* If the internal PHY is in General Power-Down mode, all, except the ++ * management interface, is powered-down and stays in that condition as ++ * long as Phy register bit 0.11 is HIGH. ++ * ++ * In that case, clear the bit 0.11, so the PHY powers up and we can ++ * access to the phy registers. ++ */ ++ rc = phy_read(pdata->phy_dev, MII_BMCR); ++ if (rc < 0) { ++ SMSC_WARN(pdata, drv, "Failed reading PHY control reg"); ++ return rc; ++ } ++ ++ /* If the PHY general power-down bit is not set is not necessary to ++ * disable the general power down-mode. ++ */ ++ if (rc & BMCR_PDOWN) { ++ rc = phy_write(pdata->phy_dev, MII_BMCR, rc & ~BMCR_PDOWN); ++ if (rc < 0) { ++ SMSC_WARN(pdata, drv, "Failed writing PHY control reg"); ++ return rc; ++ } ++ ++ usleep_range(1000, 1500); ++ } ++ ++ return 0; ++} ++ + static int smsc911x_phy_disable_energy_detect(struct smsc911x_data *pdata) + { + int rc = 0; +@@ -1414,6 +1450,16 @@ static int smsc911x_soft_reset(struct smsc911x_data *pdata) + int ret; + + /* ++ * Make sure to power-up the PHY chip before doing a reset, otherwise ++ * the reset fails. ++ */ ++ ret = smsc911x_phy_general_power_up(pdata); ++ if (ret) { ++ SMSC_WARN(pdata, drv, "Failed to power-up the PHY chip"); ++ return ret; ++ } ++ ++ /* + * LAN9210/LAN9211/LAN9220/LAN9221 chips have an internal PHY that + * are initialized in a Energy Detect Power-Down mode that prevents + * the MAC chip to be software reseted. So we have to wakeup the PHY +diff --git a/drivers/net/ethernet/sun/sunvnet.c b/drivers/net/ethernet/sun/sunvnet.c +index fd411d6e19a2..03ae9def0e0c 100644 +--- a/drivers/net/ethernet/sun/sunvnet.c ++++ b/drivers/net/ethernet/sun/sunvnet.c +@@ -656,7 +656,7 @@ static int vnet_start_xmit(struct sk_buff *skb, struct net_device *dev) + spin_lock_irqsave(&port->vio.lock, flags); + + dr = &port->vio.drings[VIO_DRIVER_TX_RING]; +- if (unlikely(vnet_tx_dring_avail(dr) < 2)) { ++ if (unlikely(vnet_tx_dring_avail(dr) < 1)) { + if (!netif_queue_stopped(dev)) { + netif_stop_queue(dev); + +@@ -704,7 +704,7 @@ static int vnet_start_xmit(struct sk_buff *skb, struct net_device *dev) + dev->stats.tx_bytes += skb->len; + + dr->prod = (dr->prod + 1) & (VNET_TX_RING_SIZE - 1); +- if (unlikely(vnet_tx_dring_avail(dr) < 2)) { ++ if (unlikely(vnet_tx_dring_avail(dr) < 1)) { + netif_stop_queue(dev); + if (vnet_tx_dring_avail(dr) > VNET_TX_WAKEUP_THRESH(dr)) + netif_wake_queue(dev); +diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c +index f30ceb17d5fc..07c942b6ae01 100644 +--- a/drivers/net/macvtap.c ++++ b/drivers/net/macvtap.c +@@ -66,7 +66,7 @@ static struct cdev macvtap_cdev; + static const struct proto_ops macvtap_socket_ops; + + #define TUN_OFFLOADS (NETIF_F_HW_CSUM | NETIF_F_TSO_ECN | NETIF_F_TSO | \ +- NETIF_F_TSO6) ++ NETIF_F_TSO6 | NETIF_F_UFO) + #define RX_OFFLOADS (NETIF_F_GRO | NETIF_F_LRO) + #define TAP_FEATURES (NETIF_F_GSO | NETIF_F_SG) + +@@ -570,8 +570,6 @@ static int macvtap_skb_from_vnet_hdr(struct sk_buff *skb, + gso_type = SKB_GSO_TCPV6; + break; + case VIRTIO_NET_HDR_GSO_UDP: +- pr_warn_once("macvtap: %s: using disabled UFO feature; please fix this program\n", +- current->comm); + gso_type = SKB_GSO_UDP; + if (skb->protocol == htons(ETH_P_IPV6)) + ipv6_proxy_select_ident(skb); +@@ -619,6 +617,8 @@ static void macvtap_skb_to_vnet_hdr(const struct sk_buff *skb, + vnet_hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV4; + else if (sinfo->gso_type & SKB_GSO_TCPV6) + vnet_hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV6; ++ else if (sinfo->gso_type & SKB_GSO_UDP) ++ vnet_hdr->gso_type = VIRTIO_NET_HDR_GSO_UDP; + else + BUG(); + if (sinfo->gso_type & SKB_GSO_TCP_ECN) +@@ -629,6 +629,8 @@ static void macvtap_skb_to_vnet_hdr(const struct sk_buff *skb, + if (skb->ip_summed == CHECKSUM_PARTIAL) { + vnet_hdr->flags = VIRTIO_NET_HDR_F_NEEDS_CSUM; + vnet_hdr->csum_start = skb_checksum_start_offset(skb); ++ if (vlan_tx_tag_present(skb)) ++ vnet_hdr->csum_start += VLAN_HLEN; + vnet_hdr->csum_offset = skb->csum_offset; + } else if (skb->ip_summed == CHECKSUM_UNNECESSARY) { + vnet_hdr->flags = VIRTIO_NET_HDR_F_DATA_VALID; +@@ -953,6 +955,9 @@ static int set_offload(struct macvtap_queue *q, unsigned long arg) + if (arg & TUN_F_TSO6) + feature_mask |= NETIF_F_TSO6; + } ++ ++ if (arg & TUN_F_UFO) ++ feature_mask |= NETIF_F_UFO; + } + + /* tun/tap driver inverts the usage for TSO offloads, where +@@ -963,7 +968,7 @@ static int set_offload(struct macvtap_queue *q, unsigned long arg) + * When user space turns off TSO, we turn off GSO/LRO so that + * user-space will not receive TSO frames. + */ +- if (feature_mask & (NETIF_F_TSO | NETIF_F_TSO6)) ++ if (feature_mask & (NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_UFO)) + features |= RX_OFFLOADS; + else + features &= ~RX_OFFLOADS; +@@ -1064,7 +1069,7 @@ static long macvtap_ioctl(struct file *file, unsigned int cmd, + case TUNSETOFFLOAD: + /* let the user check for future flags */ + if (arg & ~(TUN_F_CSUM | TUN_F_TSO4 | TUN_F_TSO6 | +- TUN_F_TSO_ECN)) ++ TUN_F_TSO_ECN | TUN_F_UFO)) + return -EINVAL; + + rtnl_lock(); +diff --git a/drivers/net/tun.c b/drivers/net/tun.c +index 2c8b1c21c452..ec63314d6480 100644 +--- a/drivers/net/tun.c ++++ b/drivers/net/tun.c +@@ -175,7 +175,7 @@ struct tun_struct { + struct net_device *dev; + netdev_features_t set_features; + #define TUN_USER_FEATURES (NETIF_F_HW_CSUM|NETIF_F_TSO_ECN|NETIF_F_TSO| \ +- NETIF_F_TSO6) ++ NETIF_F_TSO6|NETIF_F_UFO) + + int vnet_hdr_sz; + int sndbuf; +@@ -1153,20 +1153,10 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile, + skb_shinfo(skb)->gso_type = SKB_GSO_TCPV6; + break; + case VIRTIO_NET_HDR_GSO_UDP: +- { +- static bool warned; +- +- if (!warned) { +- warned = true; +- netdev_warn(tun->dev, +- "%s: using disabled UFO feature; please fix this program\n", +- current->comm); +- } + skb_shinfo(skb)->gso_type = SKB_GSO_UDP; + if (skb->protocol == htons(ETH_P_IPV6)) + ipv6_proxy_select_ident(skb); + break; +- } + default: + tun->dev->stats.rx_frame_errors++; + kfree_skb(skb); +@@ -1236,6 +1226,10 @@ static ssize_t tun_put_user(struct tun_struct *tun, + struct tun_pi pi = { 0, skb->protocol }; + ssize_t total = 0; + int vlan_offset = 0, copied; ++ int vlan_hlen = 0; ++ ++ if (vlan_tx_tag_present(skb)) ++ vlan_hlen = VLAN_HLEN; + + if (!(tun->flags & TUN_NO_PI)) { + if ((len -= sizeof(pi)) < 0) +@@ -1266,6 +1260,8 @@ static ssize_t tun_put_user(struct tun_struct *tun, + gso.gso_type = VIRTIO_NET_HDR_GSO_TCPV4; + else if (sinfo->gso_type & SKB_GSO_TCPV6) + gso.gso_type = VIRTIO_NET_HDR_GSO_TCPV6; ++ else if (sinfo->gso_type & SKB_GSO_UDP) ++ gso.gso_type = VIRTIO_NET_HDR_GSO_UDP; + else { + pr_err("unexpected GSO type: " + "0x%x, gso_size %d, hdr_len %d\n", +@@ -1285,7 +1281,8 @@ static ssize_t tun_put_user(struct tun_struct *tun, + + if (skb->ip_summed == CHECKSUM_PARTIAL) { + gso.flags = VIRTIO_NET_HDR_F_NEEDS_CSUM; +- gso.csum_start = skb_checksum_start_offset(skb); ++ gso.csum_start = skb_checksum_start_offset(skb) + ++ vlan_hlen; + gso.csum_offset = skb->csum_offset; + } else if (skb->ip_summed == CHECKSUM_UNNECESSARY) { + gso.flags = VIRTIO_NET_HDR_F_DATA_VALID; +@@ -1298,10 +1295,9 @@ static ssize_t tun_put_user(struct tun_struct *tun, + } + + copied = total; +- total += skb->len; +- if (!vlan_tx_tag_present(skb)) { +- len = min_t(int, skb->len, len); +- } else { ++ len = min_t(int, skb->len + vlan_hlen, len); ++ total += skb->len + vlan_hlen; ++ if (vlan_hlen) { + int copy, ret; + struct { + __be16 h_vlan_proto; +@@ -1312,8 +1308,6 @@ static ssize_t tun_put_user(struct tun_struct *tun, + veth.h_vlan_TCI = htons(vlan_tx_tag_get(skb)); + + vlan_offset = offsetof(struct vlan_ethhdr, h_vlan_proto); +- len = min_t(int, skb->len + VLAN_HLEN, len); +- total += VLAN_HLEN; + + copy = min_t(int, vlan_offset, len); + ret = skb_copy_datagram_const_iovec(skb, 0, iv, copied, copy); +@@ -1795,6 +1789,11 @@ static int set_offload(struct tun_struct *tun, unsigned long arg) + features |= NETIF_F_TSO6; + arg &= ~(TUN_F_TSO4|TUN_F_TSO6); + } ++ ++ if (arg & TUN_F_UFO) { ++ features |= NETIF_F_UFO; ++ arg &= ~TUN_F_UFO; ++ } + } + + /* This gives the user a way to test for new features in future by +diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c +index 07a3255fd3cc..841b60831df1 100644 +--- a/drivers/net/virtio_net.c ++++ b/drivers/net/virtio_net.c +@@ -496,17 +496,8 @@ static void receive_buf(struct receive_queue *rq, void *buf, unsigned int len) + skb_shinfo(skb)->gso_type = SKB_GSO_TCPV4; + break; + case VIRTIO_NET_HDR_GSO_UDP: +- { +- static bool warned; +- +- if (!warned) { +- warned = true; +- netdev_warn(dev, +- "host using disabled UFO feature; please fix it\n"); +- } + skb_shinfo(skb)->gso_type = SKB_GSO_UDP; + break; +- } + case VIRTIO_NET_HDR_GSO_TCPV6: + skb_shinfo(skb)->gso_type = SKB_GSO_TCPV6; + break; +@@ -845,6 +836,8 @@ static int xmit_skb(struct send_queue *sq, struct sk_buff *skb) + hdr->hdr.gso_type = VIRTIO_NET_HDR_GSO_TCPV4; + else if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6) + hdr->hdr.gso_type = VIRTIO_NET_HDR_GSO_TCPV6; ++ else if (skb_shinfo(skb)->gso_type & SKB_GSO_UDP) ++ hdr->hdr.gso_type = VIRTIO_NET_HDR_GSO_UDP; + else + BUG(); + if (skb_shinfo(skb)->gso_type & SKB_GSO_TCP_ECN) +@@ -1664,7 +1657,7 @@ static int virtnet_probe(struct virtio_device *vdev) + dev->features |= NETIF_F_HW_CSUM|NETIF_F_SG|NETIF_F_FRAGLIST; + + if (virtio_has_feature(vdev, VIRTIO_NET_F_GSO)) { +- dev->hw_features |= NETIF_F_TSO ++ dev->hw_features |= NETIF_F_TSO | NETIF_F_UFO + | NETIF_F_TSO_ECN | NETIF_F_TSO6; + } + /* Individual feature bits: what can host handle? */ +@@ -1674,9 +1667,11 @@ static int virtnet_probe(struct virtio_device *vdev) + dev->hw_features |= NETIF_F_TSO6; + if (virtio_has_feature(vdev, VIRTIO_NET_F_HOST_ECN)) + dev->hw_features |= NETIF_F_TSO_ECN; ++ if (virtio_has_feature(vdev, VIRTIO_NET_F_HOST_UFO)) ++ dev->hw_features |= NETIF_F_UFO; + + if (gso) +- dev->features |= dev->hw_features & NETIF_F_ALL_TSO; ++ dev->features |= dev->hw_features & (NETIF_F_ALL_TSO|NETIF_F_UFO); + /* (!csum && gso) case will be fixed by register_netdev() */ + } + if (virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_CSUM)) +@@ -1716,7 +1711,8 @@ static int virtnet_probe(struct virtio_device *vdev) + /* If we can receive ANY GSO packets, we must allocate large ones. */ + if (virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_TSO4) || + virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_TSO6) || +- virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_ECN)) ++ virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_ECN) || ++ virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_UFO)) + vi->big_packets = true; + + if (virtio_has_feature(vdev, VIRTIO_NET_F_MRG_RXBUF)) +@@ -1907,9 +1903,9 @@ static struct virtio_device_id id_table[] = { + static unsigned int features[] = { + VIRTIO_NET_F_CSUM, VIRTIO_NET_F_GUEST_CSUM, + VIRTIO_NET_F_GSO, VIRTIO_NET_F_MAC, +- VIRTIO_NET_F_HOST_TSO4, VIRTIO_NET_F_HOST_TSO6, ++ VIRTIO_NET_F_HOST_TSO4, VIRTIO_NET_F_HOST_UFO, VIRTIO_NET_F_HOST_TSO6, + VIRTIO_NET_F_HOST_ECN, VIRTIO_NET_F_GUEST_TSO4, VIRTIO_NET_F_GUEST_TSO6, +- VIRTIO_NET_F_GUEST_ECN, ++ VIRTIO_NET_F_GUEST_ECN, VIRTIO_NET_F_GUEST_UFO, + VIRTIO_NET_F_MRG_RXBUF, VIRTIO_NET_F_STATUS, VIRTIO_NET_F_CTRL_VQ, + VIRTIO_NET_F_CTRL_RX, VIRTIO_NET_F_CTRL_VLAN, + VIRTIO_NET_F_GUEST_ANNOUNCE, VIRTIO_NET_F_MQ, +diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c +index 0704a0402897..5441b49ef89d 100644 +--- a/drivers/net/vxlan.c ++++ b/drivers/net/vxlan.c +@@ -279,13 +279,15 @@ static inline struct vxlan_rdst *first_remote_rtnl(struct vxlan_fdb *fdb) + return list_first_entry(&fdb->remotes, struct vxlan_rdst, list); + } + +-/* Find VXLAN socket based on network namespace and UDP port */ +-static struct vxlan_sock *vxlan_find_sock(struct net *net, __be16 port) ++/* Find VXLAN socket based on network namespace, address family and UDP port */ ++static struct vxlan_sock *vxlan_find_sock(struct net *net, ++ sa_family_t family, __be16 port) + { + struct vxlan_sock *vs; + + hlist_for_each_entry_rcu(vs, vs_head(net, port), hlist) { +- if (inet_sk(vs->sock->sk)->inet_sport == port) ++ if (inet_sk(vs->sock->sk)->inet_sport == port && ++ inet_sk(vs->sock->sk)->sk.sk_family == family) + return vs; + } + return NULL; +@@ -304,11 +306,12 @@ static struct vxlan_dev *vxlan_vs_find_vni(struct vxlan_sock *vs, u32 id) + } + + /* Look up VNI in a per net namespace table */ +-static struct vxlan_dev *vxlan_find_vni(struct net *net, u32 id, __be16 port) ++static struct vxlan_dev *vxlan_find_vni(struct net *net, u32 id, ++ sa_family_t family, __be16 port) + { + struct vxlan_sock *vs; + +- vs = vxlan_find_sock(net, port); ++ vs = vxlan_find_sock(net, family, port); + if (!vs) + return NULL; + +@@ -1872,7 +1875,8 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev, + struct vxlan_dev *dst_vxlan; + + ip_rt_put(rt); +- dst_vxlan = vxlan_find_vni(dev_net(dev), vni, dst_port); ++ dst_vxlan = vxlan_find_vni(dev_net(dev), vni, ++ dst->sa.sa_family, dst_port); + if (!dst_vxlan) + goto tx_error; + vxlan_encap_bypass(skb, vxlan, dst_vxlan); +@@ -1925,7 +1929,8 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev, + struct vxlan_dev *dst_vxlan; + + dst_release(ndst); +- dst_vxlan = vxlan_find_vni(dev_net(dev), vni, dst_port); ++ dst_vxlan = vxlan_find_vni(dev_net(dev), vni, ++ dst->sa.sa_family, dst_port); + if (!dst_vxlan) + goto tx_error; + vxlan_encap_bypass(skb, vxlan, dst_vxlan); +@@ -2083,6 +2088,7 @@ static int vxlan_init(struct net_device *dev) + { + struct vxlan_dev *vxlan = netdev_priv(dev); + struct vxlan_net *vn = net_generic(dev_net(dev), vxlan_net_id); ++ bool ipv6 = vxlan->flags & VXLAN_F_IPV6; + struct vxlan_sock *vs; + int i; + +@@ -2098,7 +2104,8 @@ static int vxlan_init(struct net_device *dev) + + + spin_lock(&vn->sock_lock); +- vs = vxlan_find_sock(dev_net(dev), vxlan->dst_port); ++ vs = vxlan_find_sock(dev_net(dev), ipv6 ? AF_INET6 : AF_INET, ++ vxlan->dst_port); + if (vs) { + /* If we have a socket with same port already, reuse it */ + atomic_inc(&vs->refcnt); +@@ -2566,7 +2573,7 @@ struct vxlan_sock *vxlan_sock_add(struct net *net, __be16 port, + return vs; + + spin_lock(&vn->sock_lock); +- vs = vxlan_find_sock(net, port); ++ vs = vxlan_find_sock(net, ipv6 ? AF_INET6 : AF_INET, port); + if (vs) { + if (vs->rcv == rcv) + atomic_inc(&vs->refcnt); +@@ -2712,7 +2719,8 @@ static int vxlan_newlink(struct net *net, struct net_device *dev, + if (data[IFLA_VXLAN_PORT]) + vxlan->dst_port = nla_get_be16(data[IFLA_VXLAN_PORT]); + +- if (vxlan_find_vni(net, vni, vxlan->dst_port)) { ++ if (vxlan_find_vni(net, vni, use_ipv6 ? AF_INET6 : AF_INET, ++ vxlan->dst_port)) { + pr_info("duplicate VNI %u\n", vni); + return -EEXIST; + } +diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h +index 1f065cf4a4ba..d090ed79ada0 100644 +--- a/drivers/net/wireless/iwlwifi/iwl-trans.h ++++ b/drivers/net/wireless/iwlwifi/iwl-trans.h +@@ -514,6 +514,7 @@ enum iwl_trans_state { + * Set during transport allocation. + * @hw_id_str: a string with info about HW ID. Set during transport allocation. + * @pm_support: set to true in start_hw if link pm is supported ++ * @ltr_enabled: set to true if the LTR is enabled + * @dev_cmd_pool: pool for Tx cmd allocation - for internal use only. + * The user should use iwl_trans_{alloc,free}_tx_cmd. + * @dev_cmd_headroom: room needed for the transport's private use before the +@@ -539,6 +540,7 @@ struct iwl_trans { + u8 rx_mpdu_cmd, rx_mpdu_cmd_hdr_size; + + bool pm_support; ++ bool ltr_enabled; + + /* The following fields are internal only */ + struct kmem_cache *dev_cmd_pool; +diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h +index 884c08725308..fa66471283d9 100644 +--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h ++++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h +@@ -66,13 +66,46 @@ + + /* Power Management Commands, Responses, Notifications */ + ++/** ++ * enum iwl_ltr_config_flags - masks for LTR config command flags ++ * @LTR_CFG_FLAG_FEATURE_ENABLE: Feature operational status ++ * @LTR_CFG_FLAG_HW_DIS_ON_SHADOW_REG_ACCESS: allow LTR change on shadow ++ * memory access ++ * @LTR_CFG_FLAG_HW_EN_SHRT_WR_THROUGH: allow LTR msg send on ANY LTR ++ * reg change ++ * @LTR_CFG_FLAG_HW_DIS_ON_D0_2_D3: allow LTR msg send on transition from ++ * D0 to D3 ++ * @LTR_CFG_FLAG_SW_SET_SHORT: fixed static short LTR register ++ * @LTR_CFG_FLAG_SW_SET_LONG: fixed static short LONG register ++ * @LTR_CFG_FLAG_DENIE_C10_ON_PD: allow going into C10 on PD ++ */ ++enum iwl_ltr_config_flags { ++ LTR_CFG_FLAG_FEATURE_ENABLE = BIT(0), ++ LTR_CFG_FLAG_HW_DIS_ON_SHADOW_REG_ACCESS = BIT(1), ++ LTR_CFG_FLAG_HW_EN_SHRT_WR_THROUGH = BIT(2), ++ LTR_CFG_FLAG_HW_DIS_ON_D0_2_D3 = BIT(3), ++ LTR_CFG_FLAG_SW_SET_SHORT = BIT(4), ++ LTR_CFG_FLAG_SW_SET_LONG = BIT(5), ++ LTR_CFG_FLAG_DENIE_C10_ON_PD = BIT(6), ++}; ++ ++/** ++ * struct iwl_ltr_config_cmd - configures the LTR ++ * @flags: See %enum iwl_ltr_config_flags ++ */ ++struct iwl_ltr_config_cmd { ++ __le32 flags; ++ __le32 static_long; ++ __le32 static_short; ++} __packed; ++ + /* Radio LP RX Energy Threshold measured in dBm */ + #define POWER_LPRX_RSSI_THRESHOLD 75 + #define POWER_LPRX_RSSI_THRESHOLD_MAX 94 + #define POWER_LPRX_RSSI_THRESHOLD_MIN 30 + + /** +- * enum iwl_scan_flags - masks for power table command flags ++ * enum iwl_power_flags - masks for power table command flags + * @POWER_FLAGS_POWER_SAVE_ENA_MSK: '1' Allow to save power by turning off + * receiver and transmitter. '0' - does not allow. + * @POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK: '0' Driver disables power management, +diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api.h b/drivers/net/wireless/iwlwifi/mvm/fw-api.h +index d0a04779d734..d8948aa9c2d2 100644 +--- a/drivers/net/wireless/iwlwifi/mvm/fw-api.h ++++ b/drivers/net/wireless/iwlwifi/mvm/fw-api.h +@@ -142,6 +142,7 @@ enum { + /* Power - legacy power table command */ + POWER_TABLE_CMD = 0x77, + PSM_UAPSD_AP_MISBEHAVING_NOTIFICATION = 0x78, ++ LTR_CONFIG = 0xee, + + /* Thermal Throttling*/ + REPLY_THERMAL_MNG_BACKOFF = 0x7e, +diff --git a/drivers/net/wireless/iwlwifi/mvm/fw.c b/drivers/net/wireless/iwlwifi/mvm/fw.c +index c03d39541f9e..2ef344fc0acb 100644 +--- a/drivers/net/wireless/iwlwifi/mvm/fw.c ++++ b/drivers/net/wireless/iwlwifi/mvm/fw.c +@@ -439,6 +439,15 @@ int iwl_mvm_up(struct iwl_mvm *mvm) + goto error; + } + ++ if (mvm->trans->ltr_enabled) { ++ struct iwl_ltr_config_cmd cmd = { ++ .flags = cpu_to_le32(LTR_CFG_FLAG_FEATURE_ENABLE), ++ }; ++ ++ WARN_ON(iwl_mvm_send_cmd_pdu(mvm, LTR_CONFIG, 0, ++ sizeof(cmd), &cmd)); ++ } ++ + ret = iwl_mvm_power_update_device_mode(mvm); + if (ret) + goto error; +diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c +index a3d43de342d7..dbff7f0bc6a8 100644 +--- a/drivers/net/wireless/iwlwifi/mvm/ops.c ++++ b/drivers/net/wireless/iwlwifi/mvm/ops.c +@@ -313,6 +313,7 @@ static const char *iwl_mvm_cmd_strings[REPLY_MAX] = { + CMD(REPLY_BEACON_FILTERING_CMD), + CMD(REPLY_THERMAL_MNG_BACKOFF), + CMD(MAC_PM_POWER_TABLE), ++ CMD(LTR_CONFIG), + CMD(BT_COEX_CI), + CMD(PSM_UAPSD_AP_MISBEHAVING_NOTIFICATION), + }; +diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c +index 16be0c07c64a..fb62927ca44d 100644 +--- a/drivers/net/wireless/iwlwifi/pcie/trans.c ++++ b/drivers/net/wireless/iwlwifi/pcie/trans.c +@@ -94,6 +94,7 @@ static void iwl_pcie_apm_config(struct iwl_trans *trans) + { + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); + u16 lctl; ++ u16 cap; + + /* + * HW bug W/A for instability in PCIe bus L0S->L1 transition. +@@ -104,16 +105,17 @@ static void iwl_pcie_apm_config(struct iwl_trans *trans) + * power savings, even without L1. + */ + pcie_capability_read_word(trans_pcie->pci_dev, PCI_EXP_LNKCTL, &lctl); +- if (lctl & PCI_EXP_LNKCTL_ASPM_L1) { +- /* L1-ASPM enabled; disable(!) L0S */ ++ if (lctl & PCI_EXP_LNKCTL_ASPM_L1) + iwl_set_bit(trans, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED); +- dev_info(trans->dev, "L1 Enabled; Disabling L0S\n"); +- } else { +- /* L1-ASPM disabled; enable(!) L0S */ ++ else + iwl_clear_bit(trans, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED); +- dev_info(trans->dev, "L1 Disabled; Enabling L0S\n"); +- } + trans->pm_support = !(lctl & PCI_EXP_LNKCTL_ASPM_L0S); ++ ++ pcie_capability_read_word(trans_pcie->pci_dev, PCI_EXP_DEVCTL2, &cap); ++ trans->ltr_enabled = cap & PCI_EXP_DEVCTL2_LTR_EN; ++ dev_info(trans->dev, "L1 %sabled - LTR %sabled\n", ++ (lctl & PCI_EXP_LNKCTL_ASPM_L1) ? "En" : "Dis", ++ trans->ltr_enabled ? "En" : "Dis"); + } + + /* +diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c +index 69d4c3179d04..505ff601d9f4 100644 +--- a/drivers/net/wireless/mac80211_hwsim.c ++++ b/drivers/net/wireless/mac80211_hwsim.c +@@ -1974,7 +1974,7 @@ static int mac80211_hwsim_create_radio(int channels, const char *reg_alpha2, + if (err != 0) { + printk(KERN_DEBUG "mac80211_hwsim: device_bind_driver failed (%d)\n", + err); +- goto failed_hw; ++ goto failed_bind; + } + + skb_queue_head_init(&data->pending); +@@ -2157,6 +2157,8 @@ static int mac80211_hwsim_create_radio(int channels, const char *reg_alpha2, + return idx; + + failed_hw: ++ device_release_driver(data->dev); ++failed_bind: + device_unregister(data->dev); + failed_drvdata: + ieee80211_free_hw(hw); +diff --git a/drivers/platform/x86/dell-wmi.c b/drivers/platform/x86/dell-wmi.c +index 390e8e33d5e3..25721bf20092 100644 +--- a/drivers/platform/x86/dell-wmi.c ++++ b/drivers/platform/x86/dell-wmi.c +@@ -163,18 +163,24 @@ static void dell_wmi_notify(u32 value, void *context) + const struct key_entry *key; + int reported_key; + u16 *buffer_entry = (u16 *)obj->buffer.pointer; ++ int buffer_size = obj->buffer.length/2; + +- if (dell_new_hk_type && (buffer_entry[1] != 0x10)) { ++ if (buffer_size >= 2 && dell_new_hk_type && buffer_entry[1] != 0x10) { + pr_info("Received unknown WMI event (0x%x)\n", + buffer_entry[1]); + kfree(obj); + return; + } + +- if (dell_new_hk_type || buffer_entry[1] == 0x0) ++ if (buffer_size >= 3 && (dell_new_hk_type || buffer_entry[1] == 0x0)) + reported_key = (int)buffer_entry[2]; +- else ++ else if (buffer_size >= 2) + reported_key = (int)buffer_entry[1] & 0xffff; ++ else { ++ pr_info("Received unknown WMI event\n"); ++ kfree(obj); ++ return; ++ } + + key = sparse_keymap_entry_from_scancode(dell_wmi_input_dev, + reported_key); +diff --git a/drivers/power/bq2415x_charger.c b/drivers/power/bq2415x_charger.c +index e384844a1ae1..1f49986fc605 100644 +--- a/drivers/power/bq2415x_charger.c ++++ b/drivers/power/bq2415x_charger.c +@@ -1579,8 +1579,15 @@ static int bq2415x_probe(struct i2c_client *client, + if (np) { + bq->notify_psy = power_supply_get_by_phandle(np, "ti,usb-charger-detection"); + +- if (!bq->notify_psy) +- return -EPROBE_DEFER; ++ if (IS_ERR(bq->notify_psy)) { ++ dev_info(&client->dev, ++ "no 'ti,usb-charger-detection' property (err=%ld)\n", ++ PTR_ERR(bq->notify_psy)); ++ bq->notify_psy = NULL; ++ } else if (!bq->notify_psy) { ++ ret = -EPROBE_DEFER; ++ goto error_2; ++ } + } + else if (pdata->notify_device) + bq->notify_psy = power_supply_get_by_name(pdata->notify_device); +@@ -1602,27 +1609,27 @@ static int bq2415x_probe(struct i2c_client *client, + ret = of_property_read_u32(np, "ti,current-limit", + &bq->init_data.current_limit); + if (ret) +- return ret; ++ goto error_2; + ret = of_property_read_u32(np, "ti,weak-battery-voltage", + &bq->init_data.weak_battery_voltage); + if (ret) +- return ret; ++ goto error_2; + ret = of_property_read_u32(np, "ti,battery-regulation-voltage", + &bq->init_data.battery_regulation_voltage); + if (ret) +- return ret; ++ goto error_2; + ret = of_property_read_u32(np, "ti,charge-current", + &bq->init_data.charge_current); + if (ret) +- return ret; ++ goto error_2; + ret = of_property_read_u32(np, "ti,termination-current", + &bq->init_data.termination_current); + if (ret) +- return ret; ++ goto error_2; + ret = of_property_read_u32(np, "ti,resistor-sense", + &bq->init_data.resistor_sense); + if (ret) +- return ret; ++ goto error_2; + } else { + memcpy(&bq->init_data, pdata, sizeof(bq->init_data)); + } +diff --git a/drivers/power/charger-manager.c b/drivers/power/charger-manager.c +index ef1f4c928431..03bfac3655ef 100644 +--- a/drivers/power/charger-manager.c ++++ b/drivers/power/charger-manager.c +@@ -97,6 +97,7 @@ static struct charger_global_desc *g_desc; /* init with setup_charger_manager */ + static bool is_batt_present(struct charger_manager *cm) + { + union power_supply_propval val; ++ struct power_supply *psy; + bool present = false; + int i, ret; + +@@ -107,16 +108,27 @@ static bool is_batt_present(struct charger_manager *cm) + case CM_NO_BATTERY: + break; + case CM_FUEL_GAUGE: +- ret = cm->fuel_gauge->get_property(cm->fuel_gauge, ++ psy = power_supply_get_by_name(cm->desc->psy_fuel_gauge); ++ if (!psy) ++ break; ++ ++ ret = psy->get_property(psy, + POWER_SUPPLY_PROP_PRESENT, &val); + if (ret == 0 && val.intval) + present = true; + break; + case CM_CHARGER_STAT: +- for (i = 0; cm->charger_stat[i]; i++) { +- ret = cm->charger_stat[i]->get_property( +- cm->charger_stat[i], +- POWER_SUPPLY_PROP_PRESENT, &val); ++ for (i = 0; cm->desc->psy_charger_stat[i]; i++) { ++ psy = power_supply_get_by_name( ++ cm->desc->psy_charger_stat[i]); ++ if (!psy) { ++ dev_err(cm->dev, "Cannot find power supply \"%s\"\n", ++ cm->desc->psy_charger_stat[i]); ++ continue; ++ } ++ ++ ret = psy->get_property(psy, POWER_SUPPLY_PROP_PRESENT, ++ &val); + if (ret == 0 && val.intval) { + present = true; + break; +@@ -139,14 +151,20 @@ static bool is_batt_present(struct charger_manager *cm) + static bool is_ext_pwr_online(struct charger_manager *cm) + { + union power_supply_propval val; ++ struct power_supply *psy; + bool online = false; + int i, ret; + + /* If at least one of them has one, it's yes. */ +- for (i = 0; cm->charger_stat[i]; i++) { +- ret = cm->charger_stat[i]->get_property( +- cm->charger_stat[i], +- POWER_SUPPLY_PROP_ONLINE, &val); ++ for (i = 0; cm->desc->psy_charger_stat[i]; i++) { ++ psy = power_supply_get_by_name(cm->desc->psy_charger_stat[i]); ++ if (!psy) { ++ dev_err(cm->dev, "Cannot find power supply \"%s\"\n", ++ cm->desc->psy_charger_stat[i]); ++ continue; ++ } ++ ++ ret = psy->get_property(psy, POWER_SUPPLY_PROP_ONLINE, &val); + if (ret == 0 && val.intval) { + online = true; + break; +@@ -167,12 +185,14 @@ static bool is_ext_pwr_online(struct charger_manager *cm) + static int get_batt_uV(struct charger_manager *cm, int *uV) + { + union power_supply_propval val; ++ struct power_supply *fuel_gauge; + int ret; + +- if (!cm->fuel_gauge) ++ fuel_gauge = power_supply_get_by_name(cm->desc->psy_fuel_gauge); ++ if (!fuel_gauge) + return -ENODEV; + +- ret = cm->fuel_gauge->get_property(cm->fuel_gauge, ++ ret = fuel_gauge->get_property(fuel_gauge, + POWER_SUPPLY_PROP_VOLTAGE_NOW, &val); + if (ret) + return ret; +@@ -189,6 +209,7 @@ static bool is_charging(struct charger_manager *cm) + { + int i, ret; + bool charging = false; ++ struct power_supply *psy; + union power_supply_propval val; + + /* If there is no battery, it cannot be charged */ +@@ -196,17 +217,22 @@ static bool is_charging(struct charger_manager *cm) + return false; + + /* If at least one of the charger is charging, return yes */ +- for (i = 0; cm->charger_stat[i]; i++) { ++ for (i = 0; cm->desc->psy_charger_stat[i]; i++) { + /* 1. The charger sholuld not be DISABLED */ + if (cm->emergency_stop) + continue; + if (!cm->charger_enabled) + continue; + ++ psy = power_supply_get_by_name(cm->desc->psy_charger_stat[i]); ++ if (!psy) { ++ dev_err(cm->dev, "Cannot find power supply \"%s\"\n", ++ cm->desc->psy_charger_stat[i]); ++ continue; ++ } ++ + /* 2. The charger should be online (ext-power) */ +- ret = cm->charger_stat[i]->get_property( +- cm->charger_stat[i], +- POWER_SUPPLY_PROP_ONLINE, &val); ++ ret = psy->get_property(psy, POWER_SUPPLY_PROP_ONLINE, &val); + if (ret) { + dev_warn(cm->dev, "Cannot read ONLINE value from %s\n", + cm->desc->psy_charger_stat[i]); +@@ -219,9 +245,7 @@ static bool is_charging(struct charger_manager *cm) + * 3. The charger should not be FULL, DISCHARGING, + * or NOT_CHARGING. + */ +- ret = cm->charger_stat[i]->get_property( +- cm->charger_stat[i], +- POWER_SUPPLY_PROP_STATUS, &val); ++ ret = psy->get_property(psy, POWER_SUPPLY_PROP_STATUS, &val); + if (ret) { + dev_warn(cm->dev, "Cannot read STATUS value from %s\n", + cm->desc->psy_charger_stat[i]); +@@ -248,6 +272,7 @@ static bool is_full_charged(struct charger_manager *cm) + { + struct charger_desc *desc = cm->desc; + union power_supply_propval val; ++ struct power_supply *fuel_gauge; + int ret = 0; + int uV; + +@@ -255,11 +280,15 @@ static bool is_full_charged(struct charger_manager *cm) + if (!is_batt_present(cm)) + return false; + +- if (cm->fuel_gauge && desc->fullbatt_full_capacity > 0) { ++ fuel_gauge = power_supply_get_by_name(cm->desc->psy_fuel_gauge); ++ if (!fuel_gauge) ++ return false; ++ ++ if (desc->fullbatt_full_capacity > 0) { + val.intval = 0; + + /* Not full if capacity of fuel gauge isn't full */ +- ret = cm->fuel_gauge->get_property(cm->fuel_gauge, ++ ret = fuel_gauge->get_property(fuel_gauge, + POWER_SUPPLY_PROP_CHARGE_FULL, &val); + if (!ret && val.intval > desc->fullbatt_full_capacity) + return true; +@@ -273,10 +302,10 @@ static bool is_full_charged(struct charger_manager *cm) + } + + /* Full, if the capacity is more than fullbatt_soc */ +- if (cm->fuel_gauge && desc->fullbatt_soc > 0) { ++ if (desc->fullbatt_soc > 0) { + val.intval = 0; + +- ret = cm->fuel_gauge->get_property(cm->fuel_gauge, ++ ret = fuel_gauge->get_property(fuel_gauge, + POWER_SUPPLY_PROP_CAPACITY, &val); + if (!ret && val.intval >= desc->fullbatt_soc) + return true; +@@ -551,6 +580,20 @@ static int check_charging_duration(struct charger_manager *cm) + return ret; + } + ++static int cm_get_battery_temperature_by_psy(struct charger_manager *cm, ++ int *temp) ++{ ++ struct power_supply *fuel_gauge; ++ ++ fuel_gauge = power_supply_get_by_name(cm->desc->psy_fuel_gauge); ++ if (!fuel_gauge) ++ return -ENODEV; ++ ++ return fuel_gauge->get_property(fuel_gauge, ++ POWER_SUPPLY_PROP_TEMP, ++ (union power_supply_propval *)temp); ++} ++ + static int cm_get_battery_temperature(struct charger_manager *cm, + int *temp) + { +@@ -560,15 +603,18 @@ static int cm_get_battery_temperature(struct charger_manager *cm, + return -ENODEV; + + #ifdef CONFIG_THERMAL +- ret = thermal_zone_get_temp(cm->tzd_batt, (unsigned long *)temp); +- if (!ret) +- /* Calibrate temperature unit */ +- *temp /= 100; +-#else +- ret = cm->fuel_gauge->get_property(cm->fuel_gauge, +- POWER_SUPPLY_PROP_TEMP, +- (union power_supply_propval *)temp); ++ if (cm->tzd_batt) { ++ ret = thermal_zone_get_temp(cm->tzd_batt, (unsigned long *)temp); ++ if (!ret) ++ /* Calibrate temperature unit */ ++ *temp /= 100; ++ } else + #endif ++ { ++ /* if-else continued from CONFIG_THERMAL */ ++ ret = cm_get_battery_temperature_by_psy(cm, temp); ++ } ++ + return ret; + } + +@@ -827,6 +873,7 @@ static int charger_get_property(struct power_supply *psy, + struct charger_manager *cm = container_of(psy, + struct charger_manager, charger_psy); + struct charger_desc *desc = cm->desc; ++ struct power_supply *fuel_gauge; + int ret = 0; + int uV; + +@@ -857,14 +904,20 @@ static int charger_get_property(struct power_supply *psy, + ret = get_batt_uV(cm, &val->intval); + break; + case POWER_SUPPLY_PROP_CURRENT_NOW: +- ret = cm->fuel_gauge->get_property(cm->fuel_gauge, ++ fuel_gauge = power_supply_get_by_name(cm->desc->psy_fuel_gauge); ++ if (!fuel_gauge) { ++ ret = -ENODEV; ++ break; ++ } ++ ret = fuel_gauge->get_property(fuel_gauge, + POWER_SUPPLY_PROP_CURRENT_NOW, val); + break; + case POWER_SUPPLY_PROP_TEMP: + case POWER_SUPPLY_PROP_TEMP_AMBIENT: + return cm_get_battery_temperature(cm, &val->intval); + case POWER_SUPPLY_PROP_CAPACITY: +- if (!cm->fuel_gauge) { ++ fuel_gauge = power_supply_get_by_name(cm->desc->psy_fuel_gauge); ++ if (!fuel_gauge) { + ret = -ENODEV; + break; + } +@@ -875,7 +928,7 @@ static int charger_get_property(struct power_supply *psy, + break; + } + +- ret = cm->fuel_gauge->get_property(cm->fuel_gauge, ++ ret = fuel_gauge->get_property(fuel_gauge, + POWER_SUPPLY_PROP_CAPACITY, val); + if (ret) + break; +@@ -924,7 +977,14 @@ static int charger_get_property(struct power_supply *psy, + break; + case POWER_SUPPLY_PROP_CHARGE_NOW: + if (is_charging(cm)) { +- ret = cm->fuel_gauge->get_property(cm->fuel_gauge, ++ fuel_gauge = power_supply_get_by_name( ++ cm->desc->psy_fuel_gauge); ++ if (!fuel_gauge) { ++ ret = -ENODEV; ++ break; ++ } ++ ++ ret = fuel_gauge->get_property(fuel_gauge, + POWER_SUPPLY_PROP_CHARGE_NOW, + val); + if (ret) { +@@ -1485,14 +1545,15 @@ err: + return ret; + } + +-static int cm_init_thermal_data(struct charger_manager *cm) ++static int cm_init_thermal_data(struct charger_manager *cm, ++ struct power_supply *fuel_gauge) + { + struct charger_desc *desc = cm->desc; + union power_supply_propval val; + int ret; + + /* Verify whether fuel gauge provides battery temperature */ +- ret = cm->fuel_gauge->get_property(cm->fuel_gauge, ++ ret = fuel_gauge->get_property(fuel_gauge, + POWER_SUPPLY_PROP_TEMP, &val); + + if (!ret) { +@@ -1502,8 +1563,6 @@ static int cm_init_thermal_data(struct charger_manager *cm) + cm->desc->measure_battery_temp = true; + } + #ifdef CONFIG_THERMAL +- cm->tzd_batt = cm->fuel_gauge->tzd; +- + if (ret && desc->thermal_zone) { + cm->tzd_batt = + thermal_zone_get_zone_by_name(desc->thermal_zone); +@@ -1666,6 +1725,7 @@ static int charger_manager_probe(struct platform_device *pdev) + int ret = 0, i = 0; + int j = 0; + union power_supply_propval val; ++ struct power_supply *fuel_gauge; + + if (g_desc && !rtc_dev && g_desc->rtc_name) { + rtc_dev = rtc_class_open(g_desc->rtc_name); +@@ -1729,23 +1789,20 @@ static int charger_manager_probe(struct platform_device *pdev) + while (desc->psy_charger_stat[i]) + i++; + +- cm->charger_stat = devm_kzalloc(&pdev->dev, +- sizeof(struct power_supply *) * i, GFP_KERNEL); +- if (!cm->charger_stat) +- return -ENOMEM; +- ++ /* Check if charger's supplies are present at probe */ + for (i = 0; desc->psy_charger_stat[i]; i++) { +- cm->charger_stat[i] = power_supply_get_by_name( +- desc->psy_charger_stat[i]); +- if (!cm->charger_stat[i]) { ++ struct power_supply *psy; ++ ++ psy = power_supply_get_by_name(desc->psy_charger_stat[i]); ++ if (!psy) { + dev_err(&pdev->dev, "Cannot find power supply \"%s\"\n", + desc->psy_charger_stat[i]); + return -ENODEV; + } + } + +- cm->fuel_gauge = power_supply_get_by_name(desc->psy_fuel_gauge); +- if (!cm->fuel_gauge) { ++ fuel_gauge = power_supply_get_by_name(desc->psy_fuel_gauge); ++ if (!fuel_gauge) { + dev_err(&pdev->dev, "Cannot find power supply \"%s\"\n", + desc->psy_fuel_gauge); + return -ENODEV; +@@ -1788,13 +1845,13 @@ static int charger_manager_probe(struct platform_device *pdev) + cm->charger_psy.num_properties = psy_default.num_properties; + + /* Find which optional psy-properties are available */ +- if (!cm->fuel_gauge->get_property(cm->fuel_gauge, ++ if (!fuel_gauge->get_property(fuel_gauge, + POWER_SUPPLY_PROP_CHARGE_NOW, &val)) { + cm->charger_psy.properties[cm->charger_psy.num_properties] = + POWER_SUPPLY_PROP_CHARGE_NOW; + cm->charger_psy.num_properties++; + } +- if (!cm->fuel_gauge->get_property(cm->fuel_gauge, ++ if (!fuel_gauge->get_property(fuel_gauge, + POWER_SUPPLY_PROP_CURRENT_NOW, + &val)) { + cm->charger_psy.properties[cm->charger_psy.num_properties] = +@@ -1802,7 +1859,7 @@ static int charger_manager_probe(struct platform_device *pdev) + cm->charger_psy.num_properties++; + } + +- ret = cm_init_thermal_data(cm); ++ ret = cm_init_thermal_data(cm, fuel_gauge); + if (ret) { + dev_err(&pdev->dev, "Failed to initialize thermal data\n"); + cm->desc->measure_battery_temp = false; +@@ -2059,8 +2116,8 @@ static bool find_power_supply(struct charger_manager *cm, + int i; + bool found = false; + +- for (i = 0; cm->charger_stat[i]; i++) { +- if (psy == cm->charger_stat[i]) { ++ for (i = 0; cm->desc->psy_charger_stat[i]; i++) { ++ if (!strcmp(psy->name, cm->desc->psy_charger_stat[i])) { + found = true; + break; + } +diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c +index edb4d46fa874..96b6664bb1cf 100644 +--- a/drivers/scsi/scsi_error.c ++++ b/drivers/scsi/scsi_error.c +@@ -1984,8 +1984,10 @@ static void scsi_restart_operations(struct Scsi_Host *shost) + * is no point trying to lock the door of an off-line device. + */ + shost_for_each_device(sdev, shost) { +- if (scsi_device_online(sdev) && sdev->locked) ++ if (scsi_device_online(sdev) && sdev->was_reset && sdev->locked) { + scsi_eh_lock_door(sdev); ++ sdev->was_reset = 0; ++ } + } + + /* +diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c +index b01fb6c527e3..d43c544d3b68 100644 +--- a/fs/btrfs/compression.c ++++ b/fs/btrfs/compression.c +@@ -472,7 +472,7 @@ static noinline int add_ra_bio_pages(struct inode *inode, + rcu_read_lock(); + page = radix_tree_lookup(&mapping->page_tree, pg_index); + rcu_read_unlock(); +- if (page) { ++ if (page && !radix_tree_exceptional_entry(page)) { + misses++; + if (misses > 4) + break; +diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c +index a9a881ed8cbe..f6d00df99a8c 100644 +--- a/fs/btrfs/file.c ++++ b/fs/btrfs/file.c +@@ -425,13 +425,8 @@ static noinline int btrfs_copy_from_user(loff_t pos, int num_pages, + struct page *page = prepared_pages[pg]; + /* + * Copy data from userspace to the current page +- * +- * Disable pagefault to avoid recursive lock since +- * the pages are already locked + */ +- pagefault_disable(); + copied = iov_iter_copy_from_user_atomic(page, i, offset, count); +- pagefault_enable(); + + /* Flush processor's dcache for this page */ + flush_dcache_page(page); +diff --git a/fs/cramfs/inode.c b/fs/cramfs/inode.c +index 06610cf94d57..a1f801c14fbc 100644 +--- a/fs/cramfs/inode.c ++++ b/fs/cramfs/inode.c +@@ -195,8 +195,7 @@ static void *cramfs_read(struct super_block *sb, unsigned int offset, unsigned i + struct page *page = NULL; + + if (blocknr + i < devsize) { +- page = read_mapping_page_async(mapping, blocknr + i, +- NULL); ++ page = read_mapping_page(mapping, blocknr + i, NULL); + /* synchronous error? */ + if (IS_ERR(page)) + page = NULL; +diff --git a/fs/fuse/file.c b/fs/fuse/file.c +index 77bcc303c3ae..a91d3b4d32f3 100644 +--- a/fs/fuse/file.c ++++ b/fs/fuse/file.c +@@ -1003,9 +1003,7 @@ static ssize_t fuse_fill_write_pages(struct fuse_req *req, + if (mapping_writably_mapped(mapping)) + flush_dcache_page(page); + +- pagefault_disable(); + tmp = iov_iter_copy_from_user_atomic(page, ii, offset, bytes); +- pagefault_enable(); + flush_dcache_page(page); + + mark_page_accessed(page); +diff --git a/fs/gfs2/meta_io.c b/fs/gfs2/meta_io.c +index c7f24690ed05..b82a9c99e18b 100644 +--- a/fs/gfs2/meta_io.c ++++ b/fs/gfs2/meta_io.c +@@ -97,6 +97,11 @@ const struct address_space_operations gfs2_meta_aops = { + .releasepage = gfs2_releasepage, + }; + ++const struct address_space_operations gfs2_rgrp_aops = { ++ .writepage = gfs2_aspace_writepage, ++ .releasepage = gfs2_releasepage, ++}; ++ + /** + * gfs2_getbuf - Get a buffer with a given address space + * @gl: the glock +diff --git a/fs/gfs2/meta_io.h b/fs/gfs2/meta_io.h +index 4823b934208a..ac5d8027d335 100644 +--- a/fs/gfs2/meta_io.h ++++ b/fs/gfs2/meta_io.h +@@ -38,12 +38,15 @@ static inline void gfs2_buffer_copy_tail(struct buffer_head *to_bh, + } + + extern const struct address_space_operations gfs2_meta_aops; ++extern const struct address_space_operations gfs2_rgrp_aops; + + static inline struct gfs2_sbd *gfs2_mapping2sbd(struct address_space *mapping) + { + struct inode *inode = mapping->host; + if (mapping->a_ops == &gfs2_meta_aops) + return (((struct gfs2_glock *)mapping) - 1)->gl_sbd; ++ else if (mapping->a_ops == &gfs2_rgrp_aops) ++ return container_of(mapping, struct gfs2_sbd, sd_aspace); + else + return inode->i_sb->s_fs_info; + } +diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c +index c6872d09561a..f6c9d83aa39b 100644 +--- a/fs/gfs2/ops_fstype.c ++++ b/fs/gfs2/ops_fstype.c +@@ -104,7 +104,7 @@ static struct gfs2_sbd *init_sbd(struct super_block *sb) + mapping = &sdp->sd_aspace; + + address_space_init_once(mapping); +- mapping->a_ops = &gfs2_meta_aops; ++ mapping->a_ops = &gfs2_rgrp_aops; + mapping->host = sb->s_bdev->bd_inode; + mapping->flags = 0; + mapping_set_gfp_mask(mapping, GFP_NOFS); +diff --git a/fs/ioprio.c b/fs/ioprio.c +index e50170ca7c33..31666c92b46a 100644 +--- a/fs/ioprio.c ++++ b/fs/ioprio.c +@@ -157,14 +157,16 @@ out: + + int ioprio_best(unsigned short aprio, unsigned short bprio) + { +- unsigned short aclass = IOPRIO_PRIO_CLASS(aprio); +- unsigned short bclass = IOPRIO_PRIO_CLASS(bprio); ++ unsigned short aclass; ++ unsigned short bclass; + +- if (aclass == IOPRIO_CLASS_NONE) +- aclass = IOPRIO_CLASS_BE; +- if (bclass == IOPRIO_CLASS_NONE) +- bclass = IOPRIO_CLASS_BE; ++ if (!ioprio_valid(aprio)) ++ aprio = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, IOPRIO_NORM); ++ if (!ioprio_valid(bprio)) ++ bprio = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, IOPRIO_NORM); + ++ aclass = IOPRIO_PRIO_CLASS(aprio); ++ bclass = IOPRIO_PRIO_CLASS(bprio); + if (aclass == bclass) + return min(aprio, bprio); + if (aclass > bclass) +diff --git a/fs/jffs2/fs.c b/fs/jffs2/fs.c +index a69e426435dd..5b234db85854 100644 +--- a/fs/jffs2/fs.c ++++ b/fs/jffs2/fs.c +@@ -687,7 +687,7 @@ unsigned char *jffs2_gc_fetch_page(struct jffs2_sb_info *c, + struct inode *inode = OFNI_EDONI_2SFFJ(f); + struct page *pg; + +- pg = read_cache_page_async(inode->i_mapping, offset >> PAGE_CACHE_SHIFT, ++ pg = read_cache_page(inode->i_mapping, offset >> PAGE_CACHE_SHIFT, + (void *)jffs2_do_readpage_unlock, inode); + if (IS_ERR(pg)) + return (void *)pg; +diff --git a/fs/nfs/blocklayout/blocklayout.c b/fs/nfs/blocklayout/blocklayout.c +index 56ff823ca82e..65d849bdf77a 100644 +--- a/fs/nfs/blocklayout/blocklayout.c ++++ b/fs/nfs/blocklayout/blocklayout.c +@@ -1213,7 +1213,7 @@ static u64 pnfs_num_cont_bytes(struct inode *inode, pgoff_t idx) + end = DIV_ROUND_UP(i_size_read(inode), PAGE_CACHE_SIZE); + if (end != NFS_I(inode)->npages) { + rcu_read_lock(); +- end = radix_tree_next_hole(&mapping->page_tree, idx + 1, ULONG_MAX); ++ end = page_cache_next_hole(mapping, idx + 1, ULONG_MAX); + rcu_read_unlock(); + } + +diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c +index 5d8ccecf5f5c..3ed1be9aade3 100644 +--- a/fs/nfs/delegation.c ++++ b/fs/nfs/delegation.c +@@ -109,6 +109,8 @@ again: + continue; + if (!test_bit(NFS_DELEGATED_STATE, &state->flags)) + continue; ++ if (!nfs4_valid_open_stateid(state)) ++ continue; + if (!nfs4_stateid_match(&state->stateid, stateid)) + continue; + get_nfs_open_context(ctx); +@@ -177,7 +179,11 @@ static int nfs_do_return_delegation(struct inode *inode, struct nfs_delegation * + { + int res = 0; + +- res = nfs4_proc_delegreturn(inode, delegation->cred, &delegation->stateid, issync); ++ if (!test_bit(NFS_DELEGATION_REVOKED, &delegation->flags)) ++ res = nfs4_proc_delegreturn(inode, ++ delegation->cred, ++ &delegation->stateid, ++ issync); + nfs_free_delegation(delegation); + return res; + } +@@ -364,11 +370,13 @@ static int nfs_end_delegation_return(struct inode *inode, struct nfs_delegation + { + struct nfs_client *clp = NFS_SERVER(inode)->nfs_client; + struct nfs_inode *nfsi = NFS_I(inode); +- int err; ++ int err = 0; + + if (delegation == NULL) + return 0; + do { ++ if (test_bit(NFS_DELEGATION_REVOKED, &delegation->flags)) ++ break; + err = nfs_delegation_claim_opens(inode, &delegation->stateid); + if (!issync || err != -EAGAIN) + break; +@@ -589,10 +597,23 @@ static void nfs_client_mark_return_unused_delegation_types(struct nfs_client *cl + rcu_read_unlock(); + } + ++static void nfs_revoke_delegation(struct inode *inode) ++{ ++ struct nfs_delegation *delegation; ++ rcu_read_lock(); ++ delegation = rcu_dereference(NFS_I(inode)->delegation); ++ if (delegation != NULL) { ++ set_bit(NFS_DELEGATION_REVOKED, &delegation->flags); ++ nfs_mark_return_delegation(NFS_SERVER(inode), delegation); ++ } ++ rcu_read_unlock(); ++} ++ + void nfs_remove_bad_delegation(struct inode *inode) + { + struct nfs_delegation *delegation; + ++ nfs_revoke_delegation(inode); + delegation = nfs_inode_detach_delegation(inode); + if (delegation) { + nfs_inode_find_state_and_recover(inode, &delegation->stateid); +diff --git a/fs/nfs/delegation.h b/fs/nfs/delegation.h +index 9a79c7a99d6d..e02b090ab9da 100644 +--- a/fs/nfs/delegation.h ++++ b/fs/nfs/delegation.h +@@ -31,6 +31,7 @@ enum { + NFS_DELEGATION_RETURN_IF_CLOSED, + NFS_DELEGATION_REFERENCED, + NFS_DELEGATION_RETURNING, ++ NFS_DELEGATION_REVOKED, + }; + + int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct nfs_openres *res); +diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c +index b8797ae6831f..de2543d3c283 100644 +--- a/fs/nfs/direct.c ++++ b/fs/nfs/direct.c +@@ -178,6 +178,7 @@ static void nfs_direct_req_free(struct kref *kref) + { + struct nfs_direct_req *dreq = container_of(kref, struct nfs_direct_req, kref); + ++ nfs_free_pnfs_ds_cinfo(&dreq->ds_cinfo); + if (dreq->l_ctx != NULL) + nfs_put_lock_context(dreq->l_ctx); + if (dreq->ctx != NULL) +diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c +index 15f9d98627a4..6659ce545f15 100644 +--- a/fs/nfs/inode.c ++++ b/fs/nfs/inode.c +@@ -592,7 +592,7 @@ int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) + { + struct inode *inode = dentry->d_inode; + int need_atime = NFS_I(inode)->cache_validity & NFS_INO_INVALID_ATIME; +- int err; ++ int err = 0; + + trace_nfs_getattr_enter(inode); + /* Flush out writes to the server in order to update c/mtime. */ +diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c +index da657b7804a5..bd01803d0656 100644 +--- a/fs/nfs/nfs4proc.c ++++ b/fs/nfs/nfs4proc.c +@@ -1587,7 +1587,7 @@ static int nfs4_handle_delegation_recall_error(struct nfs_server *server, struct + nfs_inode_find_state_and_recover(state->inode, + stateid); + nfs4_schedule_stateid_recovery(server, state); +- return 0; ++ return -EAGAIN; + case -NFS4ERR_DELAY: + case -NFS4ERR_GRACE: + set_bit(NFS_DELEGATED_STATE, &state->flags); +@@ -2034,46 +2034,60 @@ static int nfs4_open_expired(struct nfs4_state_owner *sp, struct nfs4_state *sta + return ret; + } + ++static void nfs_finish_clear_delegation_stateid(struct nfs4_state *state) ++{ ++ nfs_remove_bad_delegation(state->inode); ++ write_seqlock(&state->seqlock); ++ nfs4_stateid_copy(&state->stateid, &state->open_stateid); ++ write_sequnlock(&state->seqlock); ++ clear_bit(NFS_DELEGATED_STATE, &state->flags); ++} ++ ++static void nfs40_clear_delegation_stateid(struct nfs4_state *state) ++{ ++ if (rcu_access_pointer(NFS_I(state->inode)->delegation) != NULL) ++ nfs_finish_clear_delegation_stateid(state); ++} ++ ++static int nfs40_open_expired(struct nfs4_state_owner *sp, struct nfs4_state *state) ++{ ++ /* NFSv4.0 doesn't allow for delegation recovery on open expire */ ++ nfs40_clear_delegation_stateid(state); ++ return nfs4_open_expired(sp, state); ++} ++ + #if defined(CONFIG_NFS_V4_1) +-static void nfs41_clear_delegation_stateid(struct nfs4_state *state) ++static void nfs41_check_delegation_stateid(struct nfs4_state *state) + { + struct nfs_server *server = NFS_SERVER(state->inode); +- nfs4_stateid *stateid = &state->stateid; ++ nfs4_stateid stateid; + struct nfs_delegation *delegation; +- struct rpc_cred *cred = NULL; +- int status = -NFS4ERR_BAD_STATEID; +- +- /* If a state reset has been done, test_stateid is unneeded */ +- if (test_bit(NFS_DELEGATED_STATE, &state->flags) == 0) +- return; ++ struct rpc_cred *cred; ++ int status; + + /* Get the delegation credential for use by test/free_stateid */ + rcu_read_lock(); + delegation = rcu_dereference(NFS_I(state->inode)->delegation); +- if (delegation != NULL && +- nfs4_stateid_match(&delegation->stateid, stateid)) { +- cred = get_rpccred(delegation->cred); +- rcu_read_unlock(); +- status = nfs41_test_stateid(server, stateid, cred); +- trace_nfs4_test_delegation_stateid(state, NULL, status); +- } else ++ if (delegation == NULL) { + rcu_read_unlock(); ++ return; ++ } ++ ++ nfs4_stateid_copy(&stateid, &delegation->stateid); ++ cred = get_rpccred(delegation->cred); ++ rcu_read_unlock(); ++ status = nfs41_test_stateid(server, &stateid, cred); ++ trace_nfs4_test_delegation_stateid(state, NULL, status); + + if (status != NFS_OK) { + /* Free the stateid unless the server explicitly + * informs us the stateid is unrecognized. */ + if (status != -NFS4ERR_BAD_STATEID) +- nfs41_free_stateid(server, stateid, cred); +- nfs_remove_bad_delegation(state->inode); +- +- write_seqlock(&state->seqlock); +- nfs4_stateid_copy(&state->stateid, &state->open_stateid); +- write_sequnlock(&state->seqlock); +- clear_bit(NFS_DELEGATED_STATE, &state->flags); ++ nfs41_free_stateid(server, &stateid, cred); ++ nfs_finish_clear_delegation_stateid(state); + } + +- if (cred != NULL) +- put_rpccred(cred); ++ put_rpccred(cred); + } + + /** +@@ -2117,7 +2131,7 @@ static int nfs41_open_expired(struct nfs4_state_owner *sp, struct nfs4_state *st + { + int status; + +- nfs41_clear_delegation_stateid(state); ++ nfs41_check_delegation_stateid(state); + status = nfs41_check_open_stateid(state); + if (status != NFS_OK) + status = nfs4_open_expired(sp, state); +@@ -8255,7 +8269,7 @@ static const struct nfs4_state_recovery_ops nfs41_reboot_recovery_ops = { + static const struct nfs4_state_recovery_ops nfs40_nograce_recovery_ops = { + .owner_flag_bit = NFS_OWNER_RECLAIM_NOGRACE, + .state_flag_bit = NFS_STATE_RECLAIM_NOGRACE, +- .recover_open = nfs4_open_expired, ++ .recover_open = nfs40_open_expired, + .recover_lock = nfs4_lock_expired, + .establish_clid = nfs4_init_clientid, + }; +diff --git a/fs/super.c b/fs/super.c +index 88a6bc6e3cc9..440ef51cd696 100644 +--- a/fs/super.c ++++ b/fs/super.c +@@ -114,9 +114,14 @@ static unsigned long super_cache_count(struct shrinker *shrink, + + sb = container_of(shrink, struct super_block, s_shrink); + +- if (!grab_super_passive(sb)) +- return 0; +- ++ /* ++ * Don't call grab_super_passive as it is a potential ++ * scalability bottleneck. The counts could get updated ++ * between super_cache_count and super_cache_scan anyway. ++ * Call to super_cache_count with shrinker_rwsem held ++ * ensures the safety of call to list_lru_count_node() and ++ * s_op->nr_cached_objects(). ++ */ + if (sb->s_op && sb->s_op->nr_cached_objects) + total_objects = sb->s_op->nr_cached_objects(sb, + sc->nid); +@@ -127,7 +132,6 @@ static unsigned long super_cache_count(struct shrinker *shrink, + sc->nid); + + total_objects = vfs_pressure_ratio(total_objects); +- drop_super(sb); + return total_objects; + } + +@@ -278,10 +282,8 @@ void deactivate_locked_super(struct super_block *s) + struct file_system_type *fs = s->s_type; + if (atomic_dec_and_test(&s->s_active)) { + cleancache_invalidate_fs(s); +- fs->kill_sb(s); +- +- /* caches are now gone, we can safely kill the shrinker now */ + unregister_shrinker(&s->s_shrink); ++ fs->kill_sb(s); + + put_filesystem(fs); + put_super(s); +diff --git a/include/dt-bindings/pinctrl/dra.h b/include/dt-bindings/pinctrl/dra.h +index 3d33794e4f3e..7448edff4723 100644 +--- a/include/dt-bindings/pinctrl/dra.h ++++ b/include/dt-bindings/pinctrl/dra.h +@@ -40,8 +40,8 @@ + + /* Active pin states */ + #define PIN_OUTPUT (0 | PULL_DIS) +-#define PIN_OUTPUT_PULLUP (PIN_OUTPUT | PULL_ENA | PULL_UP) +-#define PIN_OUTPUT_PULLDOWN (PIN_OUTPUT | PULL_ENA) ++#define PIN_OUTPUT_PULLUP (PULL_UP) ++#define PIN_OUTPUT_PULLDOWN (0) + #define PIN_INPUT (INPUT_EN | PULL_DIS) + #define PIN_INPUT_SLEW (INPUT_EN | SLEWCONTROL) + #define PIN_INPUT_PULLUP (PULL_ENA | INPUT_EN | PULL_UP) +diff --git a/include/linux/clocksource.h b/include/linux/clocksource.h +index 67301a405712..879065d8d208 100644 +--- a/include/linux/clocksource.h ++++ b/include/linux/clocksource.h +@@ -289,7 +289,7 @@ extern struct clocksource* clocksource_get_next(void); + extern void clocksource_change_rating(struct clocksource *cs, int rating); + extern void clocksource_suspend(void); + extern void clocksource_resume(void); +-extern struct clocksource * __init __weak clocksource_default_clock(void); ++extern struct clocksource * __init clocksource_default_clock(void); + extern void clocksource_mark_unstable(struct clocksource *cs); + + extern u64 +diff --git a/include/linux/compaction.h b/include/linux/compaction.h +index 7e1c76e3cd68..01e3132820da 100644 +--- a/include/linux/compaction.h ++++ b/include/linux/compaction.h +@@ -22,7 +22,7 @@ extern int sysctl_extfrag_handler(struct ctl_table *table, int write, + extern int fragmentation_index(struct zone *zone, unsigned int order); + extern unsigned long try_to_compact_pages(struct zonelist *zonelist, + int order, gfp_t gfp_mask, nodemask_t *mask, +- bool sync, bool *contended); ++ enum migrate_mode mode, bool *contended); + extern void compact_pgdat(pg_data_t *pgdat, int order); + extern void reset_isolation_suitable(pg_data_t *pgdat); + extern unsigned long compaction_suitable(struct zone *zone, int order); +@@ -91,7 +91,7 @@ static inline bool compaction_restarting(struct zone *zone, int order) + #else + static inline unsigned long try_to_compact_pages(struct zonelist *zonelist, + int order, gfp_t gfp_mask, nodemask_t *nodemask, +- bool sync, bool *contended) ++ enum migrate_mode mode, bool *contended) + { + return COMPACT_CONTINUE; + } +diff --git a/include/linux/crash_dump.h b/include/linux/crash_dump.h +index 7032518f8542..60023e5d3169 100644 +--- a/include/linux/crash_dump.h ++++ b/include/linux/crash_dump.h +@@ -14,14 +14,13 @@ + extern unsigned long long elfcorehdr_addr; + extern unsigned long long elfcorehdr_size; + +-extern int __weak elfcorehdr_alloc(unsigned long long *addr, +- unsigned long long *size); +-extern void __weak elfcorehdr_free(unsigned long long addr); +-extern ssize_t __weak elfcorehdr_read(char *buf, size_t count, u64 *ppos); +-extern ssize_t __weak elfcorehdr_read_notes(char *buf, size_t count, u64 *ppos); +-extern int __weak remap_oldmem_pfn_range(struct vm_area_struct *vma, +- unsigned long from, unsigned long pfn, +- unsigned long size, pgprot_t prot); ++extern int elfcorehdr_alloc(unsigned long long *addr, unsigned long long *size); ++extern void elfcorehdr_free(unsigned long long addr); ++extern ssize_t elfcorehdr_read(char *buf, size_t count, u64 *ppos); ++extern ssize_t elfcorehdr_read_notes(char *buf, size_t count, u64 *ppos); ++extern int remap_oldmem_pfn_range(struct vm_area_struct *vma, ++ unsigned long from, unsigned long pfn, ++ unsigned long size, pgprot_t prot); + + extern ssize_t copy_oldmem_page(unsigned long, char *, size_t, + unsigned long, int); +diff --git a/include/linux/kgdb.h b/include/linux/kgdb.h +index 6b06d378f3df..e465bb15912d 100644 +--- a/include/linux/kgdb.h ++++ b/include/linux/kgdb.h +@@ -283,7 +283,7 @@ struct kgdb_io { + + extern struct kgdb_arch arch_kgdb_ops; + +-extern unsigned long __weak kgdb_arch_pc(int exception, struct pt_regs *regs); ++extern unsigned long kgdb_arch_pc(int exception, struct pt_regs *regs); + + #ifdef CONFIG_SERIAL_KGDB_NMI + extern int kgdb_register_nmi_console(void); +diff --git a/include/linux/memory.h b/include/linux/memory.h +index bb7384e3c3d8..8b8d8d12348e 100644 +--- a/include/linux/memory.h ++++ b/include/linux/memory.h +@@ -35,7 +35,7 @@ struct memory_block { + }; + + int arch_get_memory_phys_device(unsigned long start_pfn); +-unsigned long __weak memory_block_size_bytes(void); ++unsigned long memory_block_size_bytes(void); + + /* These states are exposed to userspace as text strings in sysfs */ + #define MEM_ONLINE (1<<0) /* exposed to userspace */ +diff --git a/include/linux/migrate.h b/include/linux/migrate.h +index 84a31ad0b791..a2901c414664 100644 +--- a/include/linux/migrate.h ++++ b/include/linux/migrate.h +@@ -5,7 +5,9 @@ + #include <linux/mempolicy.h> + #include <linux/migrate_mode.h> + +-typedef struct page *new_page_t(struct page *, unsigned long private, int **); ++typedef struct page *new_page_t(struct page *page, unsigned long private, ++ int **reason); ++typedef void free_page_t(struct page *page, unsigned long private); + + /* + * Return values from addresss_space_operations.migratepage(): +@@ -38,7 +40,7 @@ enum migrate_reason { + extern void putback_movable_pages(struct list_head *l); + extern int migrate_page(struct address_space *, + struct page *, struct page *, enum migrate_mode); +-extern int migrate_pages(struct list_head *l, new_page_t x, ++extern int migrate_pages(struct list_head *l, new_page_t new, free_page_t free, + unsigned long private, enum migrate_mode mode, int reason); + + extern int migrate_prep(void); +@@ -56,8 +58,9 @@ extern int migrate_page_move_mapping(struct address_space *mapping, + #else + + static inline void putback_movable_pages(struct list_head *l) {} +-static inline int migrate_pages(struct list_head *l, new_page_t x, +- unsigned long private, enum migrate_mode mode, int reason) ++static inline int migrate_pages(struct list_head *l, new_page_t new, ++ free_page_t free, unsigned long private, enum migrate_mode mode, ++ int reason) + { return -ENOSYS; } + + static inline int migrate_prep(void) { return -ENOSYS; } +diff --git a/include/linux/mm.h b/include/linux/mm.h +index 0a0b024ec7e8..d5039daf1e1c 100644 +--- a/include/linux/mm.h ++++ b/include/linux/mm.h +@@ -1041,6 +1041,14 @@ extern void show_free_areas(unsigned int flags); + extern bool skip_free_areas_node(unsigned int flags, int nid); + + int shmem_zero_setup(struct vm_area_struct *); ++#ifdef CONFIG_SHMEM ++bool shmem_mapping(struct address_space *mapping); ++#else ++static inline bool shmem_mapping(struct address_space *mapping) ++{ ++ return false; ++} ++#endif + + extern int can_do_mlock(void); + extern int user_shm_lock(size_t, struct user_struct *); +@@ -1848,9 +1856,6 @@ void page_cache_async_readahead(struct address_space *mapping, + unsigned long size); + + unsigned long max_sane_readahead(unsigned long nr); +-unsigned long ra_submit(struct file_ra_state *ra, +- struct address_space *mapping, +- struct file *filp); + + /* Generic expand stack which grows the stack according to GROWS{UP,DOWN} */ + extern int expand_stack(struct vm_area_struct *vma, unsigned long address); +diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h +index e6800f0c0d7b..18843532a0c9 100644 +--- a/include/linux/mmzone.h ++++ b/include/linux/mmzone.h +@@ -361,9 +361,10 @@ struct zone { + /* Set to true when the PG_migrate_skip bits should be cleared */ + bool compact_blockskip_flush; + +- /* pfns where compaction scanners should start */ ++ /* pfn where compaction free scanner should start */ + unsigned long compact_cached_free_pfn; +- unsigned long compact_cached_migrate_pfn; ++ /* pfn where async and sync compaction migration scanner should start */ ++ unsigned long compact_cached_migrate_pfn[2]; + #endif + #ifdef CONFIG_MEMORY_HOTPLUG + /* see spanned/present_pages for more description */ +diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h +index 5624e4e2763c..53988cb3c05a 100644 +--- a/include/linux/nfs_xdr.h ++++ b/include/linux/nfs_xdr.h +@@ -1247,11 +1247,22 @@ struct nfs41_free_stateid_res { + unsigned int status; + }; + ++static inline void ++nfs_free_pnfs_ds_cinfo(struct pnfs_ds_commit_info *cinfo) ++{ ++ kfree(cinfo->buckets); ++} ++ + #else + + struct pnfs_ds_commit_info { + }; + ++static inline void ++nfs_free_pnfs_ds_cinfo(struct pnfs_ds_commit_info *cinfo) ++{ ++} ++ + #endif /* CONFIG_NFS_V4_1 */ + + struct nfs_page; +diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h +index 1710d1b060ba..09c1b03867d9 100644 +--- a/include/linux/pagemap.h ++++ b/include/linux/pagemap.h +@@ -243,12 +243,20 @@ static inline struct page *page_cache_alloc_readahead(struct address_space *x) + + typedef int filler_t(void *, struct page *); + +-extern struct page * find_get_page(struct address_space *mapping, +- pgoff_t index); +-extern struct page * find_lock_page(struct address_space *mapping, +- pgoff_t index); +-extern struct page * find_or_create_page(struct address_space *mapping, +- pgoff_t index, gfp_t gfp_mask); ++pgoff_t page_cache_next_hole(struct address_space *mapping, ++ pgoff_t index, unsigned long max_scan); ++pgoff_t page_cache_prev_hole(struct address_space *mapping, ++ pgoff_t index, unsigned long max_scan); ++ ++struct page *find_get_entry(struct address_space *mapping, pgoff_t offset); ++struct page *find_get_page(struct address_space *mapping, pgoff_t offset); ++struct page *find_lock_entry(struct address_space *mapping, pgoff_t offset); ++struct page *find_lock_page(struct address_space *mapping, pgoff_t offset); ++struct page *find_or_create_page(struct address_space *mapping, pgoff_t index, ++ gfp_t gfp_mask); ++unsigned find_get_entries(struct address_space *mapping, pgoff_t start, ++ unsigned int nr_entries, struct page **entries, ++ pgoff_t *indices); + unsigned find_get_pages(struct address_space *mapping, pgoff_t start, + unsigned int nr_pages, struct page **pages); + unsigned find_get_pages_contig(struct address_space *mapping, pgoff_t start, +@@ -270,8 +278,6 @@ static inline struct page *grab_cache_page(struct address_space *mapping, + + extern struct page * grab_cache_page_nowait(struct address_space *mapping, + pgoff_t index); +-extern struct page * read_cache_page_async(struct address_space *mapping, +- pgoff_t index, filler_t *filler, void *data); + extern struct page * read_cache_page(struct address_space *mapping, + pgoff_t index, filler_t *filler, void *data); + extern struct page * read_cache_page_gfp(struct address_space *mapping, +@@ -279,14 +285,6 @@ extern struct page * read_cache_page_gfp(struct address_space *mapping, + extern int read_cache_pages(struct address_space *mapping, + struct list_head *pages, filler_t *filler, void *data); + +-static inline struct page *read_mapping_page_async( +- struct address_space *mapping, +- pgoff_t index, void *data) +-{ +- filler_t *filler = (filler_t *)mapping->a_ops->readpage; +- return read_cache_page_async(mapping, index, filler, data); +-} +- + static inline struct page *read_mapping_page(struct address_space *mapping, + pgoff_t index, void *data) + { +diff --git a/include/linux/pagevec.h b/include/linux/pagevec.h +index e4dbfab37729..b45d391b4540 100644 +--- a/include/linux/pagevec.h ++++ b/include/linux/pagevec.h +@@ -22,6 +22,11 @@ struct pagevec { + + void __pagevec_release(struct pagevec *pvec); + void __pagevec_lru_add(struct pagevec *pvec); ++unsigned pagevec_lookup_entries(struct pagevec *pvec, ++ struct address_space *mapping, ++ pgoff_t start, unsigned nr_entries, ++ pgoff_t *indices); ++void pagevec_remove_exceptionals(struct pagevec *pvec); + unsigned pagevec_lookup(struct pagevec *pvec, struct address_space *mapping, + pgoff_t start, unsigned nr_pages); + unsigned pagevec_lookup_tag(struct pagevec *pvec, +diff --git a/include/linux/power/charger-manager.h b/include/linux/power/charger-manager.h +index 07e7945a1ff2..e97fc656a058 100644 +--- a/include/linux/power/charger-manager.h ++++ b/include/linux/power/charger-manager.h +@@ -253,9 +253,6 @@ struct charger_manager { + struct device *dev; + struct charger_desc *desc; + +- struct power_supply *fuel_gauge; +- struct power_supply **charger_stat; +- + #ifdef CONFIG_THERMAL + struct thermal_zone_device *tzd_batt; + #endif +diff --git a/include/linux/radix-tree.h b/include/linux/radix-tree.h +index 403940787be1..e8be53ecfc45 100644 +--- a/include/linux/radix-tree.h ++++ b/include/linux/radix-tree.h +@@ -219,6 +219,7 @@ static inline void radix_tree_replace_slot(void **pslot, void *item) + int radix_tree_insert(struct radix_tree_root *, unsigned long, void *); + void *radix_tree_lookup(struct radix_tree_root *, unsigned long); + void **radix_tree_lookup_slot(struct radix_tree_root *, unsigned long); ++void *radix_tree_delete_item(struct radix_tree_root *, unsigned long, void *); + void *radix_tree_delete(struct radix_tree_root *, unsigned long); + unsigned int + radix_tree_gang_lookup(struct radix_tree_root *root, void **results, +@@ -226,10 +227,6 @@ radix_tree_gang_lookup(struct radix_tree_root *root, void **results, + unsigned int radix_tree_gang_lookup_slot(struct radix_tree_root *root, + void ***results, unsigned long *indices, + unsigned long first_index, unsigned int max_items); +-unsigned long radix_tree_next_hole(struct radix_tree_root *root, +- unsigned long index, unsigned long max_scan); +-unsigned long radix_tree_prev_hole(struct radix_tree_root *root, +- unsigned long index, unsigned long max_scan); + int radix_tree_preload(gfp_t gfp_mask); + int radix_tree_maybe_preload(gfp_t gfp_mask); + void radix_tree_init(void); +diff --git a/include/linux/shmem_fs.h b/include/linux/shmem_fs.h +index 9d55438bc4ad..4d1771c2d29f 100644 +--- a/include/linux/shmem_fs.h ++++ b/include/linux/shmem_fs.h +@@ -51,6 +51,7 @@ extern struct file *shmem_kernel_file_setup(const char *name, loff_t size, + unsigned long flags); + extern int shmem_zero_setup(struct vm_area_struct *); + extern int shmem_lock(struct file *file, int lock, struct user_struct *user); ++extern bool shmem_mapping(struct address_space *mapping); + extern void shmem_unlock_mapping(struct address_space *mapping); + extern struct page *shmem_read_mapping_page_gfp(struct address_space *mapping, + pgoff_t index, gfp_t gfp_mask); +diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h +index a3353f45ef94..ba41e01ebc54 100644 +--- a/include/net/sctp/sctp.h ++++ b/include/net/sctp/sctp.h +@@ -433,6 +433,11 @@ static inline void sctp_assoc_pending_pmtu(struct sock *sk, struct sctp_associat + asoc->pmtu_pending = 0; + } + ++static inline bool sctp_chunk_pending(const struct sctp_chunk *chunk) ++{ ++ return !list_empty(&chunk->list); ++} ++ + /* Walk through a list of TLV parameters. Don't trust the + * individual parameter lengths and instead depend on + * the chunk length to indicate when to stop. Make sure +diff --git a/include/net/sctp/sm.h b/include/net/sctp/sm.h +index 7f4eeb340a54..72a31db47ded 100644 +--- a/include/net/sctp/sm.h ++++ b/include/net/sctp/sm.h +@@ -248,9 +248,9 @@ struct sctp_chunk *sctp_make_asconf_update_ip(struct sctp_association *, + int, __be16); + struct sctp_chunk *sctp_make_asconf_set_prim(struct sctp_association *asoc, + union sctp_addr *addr); +-int sctp_verify_asconf(const struct sctp_association *asoc, +- struct sctp_paramhdr *param_hdr, void *chunk_end, +- struct sctp_paramhdr **errp); ++bool sctp_verify_asconf(const struct sctp_association *asoc, ++ struct sctp_chunk *chunk, bool addr_param_needed, ++ struct sctp_paramhdr **errp); + struct sctp_chunk *sctp_process_asconf(struct sctp_association *asoc, + struct sctp_chunk *asconf); + int sctp_process_asconf_ack(struct sctp_association *asoc, +diff --git a/include/trace/events/compaction.h b/include/trace/events/compaction.h +index 06f544ef2f6f..c6814b917bdf 100644 +--- a/include/trace/events/compaction.h ++++ b/include/trace/events/compaction.h +@@ -5,6 +5,7 @@ + #define _TRACE_COMPACTION_H + + #include <linux/types.h> ++#include <linux/list.h> + #include <linux/tracepoint.h> + #include <trace/events/gfpflags.h> + +@@ -47,10 +48,11 @@ DEFINE_EVENT(mm_compaction_isolate_template, mm_compaction_isolate_freepages, + + TRACE_EVENT(mm_compaction_migratepages, + +- TP_PROTO(unsigned long nr_migrated, +- unsigned long nr_failed), ++ TP_PROTO(unsigned long nr_all, ++ int migrate_rc, ++ struct list_head *migratepages), + +- TP_ARGS(nr_migrated, nr_failed), ++ TP_ARGS(nr_all, migrate_rc, migratepages), + + TP_STRUCT__entry( + __field(unsigned long, nr_migrated) +@@ -58,7 +60,22 @@ TRACE_EVENT(mm_compaction_migratepages, + ), + + TP_fast_assign( +- __entry->nr_migrated = nr_migrated; ++ unsigned long nr_failed = 0; ++ struct list_head *page_lru; ++ ++ /* ++ * migrate_pages() returns either a non-negative number ++ * with the number of pages that failed migration, or an ++ * error code, in which case we need to count the remaining ++ * pages manually ++ */ ++ if (migrate_rc >= 0) ++ nr_failed = migrate_rc; ++ else ++ list_for_each(page_lru, migratepages) ++ nr_failed++; ++ ++ __entry->nr_migrated = nr_all - nr_failed; + __entry->nr_failed = nr_failed; + ), + +diff --git a/include/uapi/linux/netfilter/xt_bpf.h b/include/uapi/linux/netfilter/xt_bpf.h +index 5dda450eb55b..2ec9fbcd06f9 100644 +--- a/include/uapi/linux/netfilter/xt_bpf.h ++++ b/include/uapi/linux/netfilter/xt_bpf.h +@@ -6,6 +6,8 @@ + + #define XT_BPF_MAX_NUM_INSTR 64 + ++struct sk_filter; ++ + struct xt_bpf_info { + __u16 bpf_program_num_elem; + struct sock_filter bpf_program[XT_BPF_MAX_NUM_INSTR]; +diff --git a/ipc/ipc_sysctl.c b/ipc/ipc_sysctl.c +index 17028648cfeb..cadddc8388f3 100644 +--- a/ipc/ipc_sysctl.c ++++ b/ipc/ipc_sysctl.c +@@ -123,7 +123,6 @@ static int proc_ipcauto_dointvec_minmax(ctl_table *table, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) + { + struct ctl_table ipc_table; +- size_t lenp_bef = *lenp; + int oldval; + int rc; + +@@ -133,7 +132,7 @@ static int proc_ipcauto_dointvec_minmax(ctl_table *table, int write, + + rc = proc_dointvec_minmax(&ipc_table, write, buffer, lenp, ppos); + +- if (write && !rc && lenp_bef == *lenp) { ++ if (write && !rc) { + int newval = *((int *)(ipc_table.data)); + /* + * The file "auto_msgmni" has correctly been set. +diff --git a/kernel/audit.c b/kernel/audit.c +index 2c0ecd1753de..b45b2daa9f92 100644 +--- a/kernel/audit.c ++++ b/kernel/audit.c +@@ -687,7 +687,7 @@ static int audit_get_feature(struct sk_buff *skb) + + seq = nlmsg_hdr(skb)->nlmsg_seq; + +- audit_send_reply(skb, seq, AUDIT_GET, 0, 0, &af, sizeof(af)); ++ audit_send_reply(skb, seq, AUDIT_GET_FEATURE, 0, 0, &af, sizeof(af)); + + return 0; + } +@@ -702,7 +702,7 @@ static void audit_log_feature_change(int which, u32 old_feature, u32 new_feature + + ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_FEATURE_CHANGE); + audit_log_task_info(ab, current); +- audit_log_format(ab, "feature=%s old=%u new=%u old_lock=%u new_lock=%u res=%d", ++ audit_log_format(ab, " feature=%s old=%u new=%u old_lock=%u new_lock=%u res=%d", + audit_feature_names[which], !!old_feature, !!new_feature, + !!old_lock, !!new_lock, res); + audit_log_end(ab); +diff --git a/kernel/audit_tree.c b/kernel/audit_tree.c +index 135944a7b28a..a79db03990db 100644 +--- a/kernel/audit_tree.c ++++ b/kernel/audit_tree.c +@@ -154,6 +154,7 @@ static struct audit_chunk *alloc_chunk(int count) + chunk->owners[i].index = i; + } + fsnotify_init_mark(&chunk->mark, audit_tree_destroy_watch); ++ chunk->mark.mask = FS_IN_IGNORED; + return chunk; + } + +diff --git a/kernel/events/core.c b/kernel/events/core.c +index 4ced342f1ba9..4bbb27adf23d 100644 +--- a/kernel/events/core.c ++++ b/kernel/events/core.c +@@ -39,6 +39,7 @@ + #include <linux/hw_breakpoint.h> + #include <linux/mm_types.h> + #include <linux/cgroup.h> ++#include <linux/compat.h> + + #include "internal.h" + +@@ -3693,6 +3694,26 @@ static long perf_ioctl(struct file *file, unsigned int cmd, unsigned long arg) + return 0; + } + ++#ifdef CONFIG_COMPAT ++static long perf_compat_ioctl(struct file *file, unsigned int cmd, ++ unsigned long arg) ++{ ++ switch (_IOC_NR(cmd)) { ++ case _IOC_NR(PERF_EVENT_IOC_SET_FILTER): ++ case _IOC_NR(PERF_EVENT_IOC_ID): ++ /* Fix up pointer size (usually 4 -> 8 in 32-on-64-bit case */ ++ if (_IOC_SIZE(cmd) == sizeof(compat_uptr_t)) { ++ cmd &= ~IOCSIZE_MASK; ++ cmd |= sizeof(void *) << IOCSIZE_SHIFT; ++ } ++ break; ++ } ++ return perf_ioctl(file, cmd, arg); ++} ++#else ++# define perf_compat_ioctl NULL ++#endif ++ + int perf_event_task_enable(void) + { + struct perf_event *event; +@@ -4185,7 +4206,7 @@ static const struct file_operations perf_fops = { + .read = perf_read, + .poll = perf_poll, + .unlocked_ioctl = perf_ioctl, +- .compat_ioctl = perf_ioctl, ++ .compat_ioctl = perf_compat_ioctl, + .mmap = perf_mmap, + .fasync = perf_fasync, + }; +diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c +index b3d116cd072d..6705d947ef14 100644 +--- a/kernel/rcu/tree.c ++++ b/kernel/rcu/tree.c +@@ -1228,6 +1228,22 @@ static int rcu_future_gp_cleanup(struct rcu_state *rsp, struct rcu_node *rnp) + } + + /* ++ * Awaken the grace-period kthread for the specified flavor of RCU. ++ * Don't do a self-awaken, and don't bother awakening when there is ++ * nothing for the grace-period kthread to do (as in several CPUs ++ * raced to awaken, and we lost), and finally don't try to awaken ++ * a kthread that has not yet been created. ++ */ ++static void rcu_gp_kthread_wake(struct rcu_state *rsp) ++{ ++ if (current == rsp->gp_kthread || ++ !ACCESS_ONCE(rsp->gp_flags) || ++ !rsp->gp_kthread) ++ return; ++ wake_up(&rsp->gp_wq); ++} ++ ++/* + * If there is room, assign a ->completed number to any callbacks on + * this CPU that have not already been assigned. Also accelerate any + * callbacks that were previously assigned a ->completed number that has +@@ -1670,7 +1686,7 @@ static void rsp_wakeup(struct irq_work *work) + struct rcu_state *rsp = container_of(work, struct rcu_state, wakeup_work); + + /* Wake up rcu_gp_kthread() to start the grace period. */ +- wake_up(&rsp->gp_wq); ++ rcu_gp_kthread_wake(rsp); + } + + /* +@@ -1746,7 +1762,7 @@ static void rcu_report_qs_rsp(struct rcu_state *rsp, unsigned long flags) + { + WARN_ON_ONCE(!rcu_gp_in_progress(rsp)); + raw_spin_unlock_irqrestore(&rcu_get_root(rsp)->lock, flags); +- wake_up(&rsp->gp_wq); /* Memory barrier implied by wake_up() path. */ ++ rcu_gp_kthread_wake(rsp); + } + + /* +@@ -2322,7 +2338,7 @@ static void force_quiescent_state(struct rcu_state *rsp) + } + rsp->gp_flags |= RCU_GP_FLAG_FQS; + raw_spin_unlock_irqrestore(&rnp_old->lock, flags); +- wake_up(&rsp->gp_wq); /* Memory barrier implied by wake_up() path. */ ++ rcu_gp_kthread_wake(rsp); + } + + /* +diff --git a/lib/radix-tree.c b/lib/radix-tree.c +index bd4a8dfdf0b8..7e30d2a7f346 100644 +--- a/lib/radix-tree.c ++++ b/lib/radix-tree.c +@@ -946,81 +946,6 @@ next: + } + EXPORT_SYMBOL(radix_tree_range_tag_if_tagged); + +- +-/** +- * radix_tree_next_hole - find the next hole (not-present entry) +- * @root: tree root +- * @index: index key +- * @max_scan: maximum range to search +- * +- * Search the set [index, min(index+max_scan-1, MAX_INDEX)] for the lowest +- * indexed hole. +- * +- * Returns: the index of the hole if found, otherwise returns an index +- * outside of the set specified (in which case 'return - index >= max_scan' +- * will be true). In rare cases of index wrap-around, 0 will be returned. +- * +- * radix_tree_next_hole may be called under rcu_read_lock. However, like +- * radix_tree_gang_lookup, this will not atomically search a snapshot of +- * the tree at a single point in time. For example, if a hole is created +- * at index 5, then subsequently a hole is created at index 10, +- * radix_tree_next_hole covering both indexes may return 10 if called +- * under rcu_read_lock. +- */ +-unsigned long radix_tree_next_hole(struct radix_tree_root *root, +- unsigned long index, unsigned long max_scan) +-{ +- unsigned long i; +- +- for (i = 0; i < max_scan; i++) { +- if (!radix_tree_lookup(root, index)) +- break; +- index++; +- if (index == 0) +- break; +- } +- +- return index; +-} +-EXPORT_SYMBOL(radix_tree_next_hole); +- +-/** +- * radix_tree_prev_hole - find the prev hole (not-present entry) +- * @root: tree root +- * @index: index key +- * @max_scan: maximum range to search +- * +- * Search backwards in the range [max(index-max_scan+1, 0), index] +- * for the first hole. +- * +- * Returns: the index of the hole if found, otherwise returns an index +- * outside of the set specified (in which case 'index - return >= max_scan' +- * will be true). In rare cases of wrap-around, ULONG_MAX will be returned. +- * +- * radix_tree_next_hole may be called under rcu_read_lock. However, like +- * radix_tree_gang_lookup, this will not atomically search a snapshot of +- * the tree at a single point in time. For example, if a hole is created +- * at index 10, then subsequently a hole is created at index 5, +- * radix_tree_prev_hole covering both indexes may return 5 if called under +- * rcu_read_lock. +- */ +-unsigned long radix_tree_prev_hole(struct radix_tree_root *root, +- unsigned long index, unsigned long max_scan) +-{ +- unsigned long i; +- +- for (i = 0; i < max_scan; i++) { +- if (!radix_tree_lookup(root, index)) +- break; +- index--; +- if (index == ULONG_MAX) +- break; +- } +- +- return index; +-} +-EXPORT_SYMBOL(radix_tree_prev_hole); +- + /** + * radix_tree_gang_lookup - perform multiple lookup on a radix tree + * @root: radix tree root +@@ -1337,15 +1262,18 @@ static inline void radix_tree_shrink(struct radix_tree_root *root) + } + + /** +- * radix_tree_delete - delete an item from a radix tree ++ * radix_tree_delete_item - delete an item from a radix tree + * @root: radix tree root + * @index: index key ++ * @item: expected item + * +- * Remove the item at @index from the radix tree rooted at @root. ++ * Remove @item at @index from the radix tree rooted at @root. + * +- * Returns the address of the deleted item, or NULL if it was not present. ++ * Returns the address of the deleted item, or NULL if it was not present ++ * or the entry at the given @index was not @item. + */ +-void *radix_tree_delete(struct radix_tree_root *root, unsigned long index) ++void *radix_tree_delete_item(struct radix_tree_root *root, ++ unsigned long index, void *item) + { + struct radix_tree_node *node = NULL; + struct radix_tree_node *slot = NULL; +@@ -1380,6 +1308,11 @@ void *radix_tree_delete(struct radix_tree_root *root, unsigned long index) + if (slot == NULL) + goto out; + ++ if (item && slot != item) { ++ slot = NULL; ++ goto out; ++ } ++ + /* + * Clear all tags associated with the item to be deleted. + * This way of doing it would be inefficient, but seldom is any set. +@@ -1424,6 +1357,21 @@ void *radix_tree_delete(struct radix_tree_root *root, unsigned long index) + out: + return slot; + } ++EXPORT_SYMBOL(radix_tree_delete_item); ++ ++/** ++ * radix_tree_delete - delete an item from a radix tree ++ * @root: radix tree root ++ * @index: index key ++ * ++ * Remove the item at @index from the radix tree rooted at @root. ++ * ++ * Returns the address of the deleted item, or NULL if it was not present. ++ */ ++void *radix_tree_delete(struct radix_tree_root *root, unsigned long index) ++{ ++ return radix_tree_delete_item(root, index, NULL); ++} + EXPORT_SYMBOL(radix_tree_delete); + + /** +diff --git a/mm/compaction.c b/mm/compaction.c +index 5e38e5706f62..4229fc22a477 100644 +--- a/mm/compaction.c ++++ b/mm/compaction.c +@@ -89,7 +89,8 @@ static void __reset_isolation_suitable(struct zone *zone) + unsigned long end_pfn = zone_end_pfn(zone); + unsigned long pfn; + +- zone->compact_cached_migrate_pfn = start_pfn; ++ zone->compact_cached_migrate_pfn[0] = start_pfn; ++ zone->compact_cached_migrate_pfn[1] = start_pfn; + zone->compact_cached_free_pfn = end_pfn; + zone->compact_blockskip_flush = false; + +@@ -131,9 +132,10 @@ void reset_isolation_suitable(pg_data_t *pgdat) + */ + static void update_pageblock_skip(struct compact_control *cc, + struct page *page, unsigned long nr_isolated, +- bool migrate_scanner) ++ bool set_unsuitable, bool migrate_scanner) + { + struct zone *zone = cc->zone; ++ unsigned long pfn; + + if (cc->ignore_skip_hint) + return; +@@ -141,20 +143,32 @@ static void update_pageblock_skip(struct compact_control *cc, + if (!page) + return; + +- if (!nr_isolated) { +- unsigned long pfn = page_to_pfn(page); ++ if (nr_isolated) ++ return; ++ ++ /* ++ * Only skip pageblocks when all forms of compaction will be known to ++ * fail in the near future. ++ */ ++ if (set_unsuitable) + set_pageblock_skip(page); + +- /* Update where compaction should restart */ +- if (migrate_scanner) { +- if (!cc->finished_update_migrate && +- pfn > zone->compact_cached_migrate_pfn) +- zone->compact_cached_migrate_pfn = pfn; +- } else { +- if (!cc->finished_update_free && +- pfn < zone->compact_cached_free_pfn) +- zone->compact_cached_free_pfn = pfn; +- } ++ pfn = page_to_pfn(page); ++ ++ /* Update where async and sync compaction should restart */ ++ if (migrate_scanner) { ++ if (cc->finished_update_migrate) ++ return; ++ if (pfn > zone->compact_cached_migrate_pfn[0]) ++ zone->compact_cached_migrate_pfn[0] = pfn; ++ if (cc->mode != MIGRATE_ASYNC && ++ pfn > zone->compact_cached_migrate_pfn[1]) ++ zone->compact_cached_migrate_pfn[1] = pfn; ++ } else { ++ if (cc->finished_update_free) ++ return; ++ if (pfn < zone->compact_cached_free_pfn) ++ zone->compact_cached_free_pfn = pfn; + } + } + #else +@@ -166,7 +180,7 @@ static inline bool isolation_suitable(struct compact_control *cc, + + static void update_pageblock_skip(struct compact_control *cc, + struct page *page, unsigned long nr_isolated, +- bool migrate_scanner) ++ bool set_unsuitable, bool migrate_scanner) + { + } + #endif /* CONFIG_COMPACTION */ +@@ -195,7 +209,7 @@ static bool compact_checklock_irqsave(spinlock_t *lock, unsigned long *flags, + } + + /* async aborts if taking too long or contended */ +- if (!cc->sync) { ++ if (cc->mode == MIGRATE_ASYNC) { + cc->contended = true; + return false; + } +@@ -208,10 +222,28 @@ static bool compact_checklock_irqsave(spinlock_t *lock, unsigned long *flags, + return true; + } + +-static inline bool compact_trylock_irqsave(spinlock_t *lock, +- unsigned long *flags, struct compact_control *cc) ++/* ++ * Aside from avoiding lock contention, compaction also periodically checks ++ * need_resched() and either schedules in sync compaction or aborts async ++ * compaction. This is similar to what compact_checklock_irqsave() does, but ++ * is used where no lock is concerned. ++ * ++ * Returns false when no scheduling was needed, or sync compaction scheduled. ++ * Returns true when async compaction should abort. ++ */ ++static inline bool compact_should_abort(struct compact_control *cc) + { +- return compact_checklock_irqsave(lock, flags, false, cc); ++ /* async compaction aborts if contended */ ++ if (need_resched()) { ++ if (cc->mode == MIGRATE_ASYNC) { ++ cc->contended = true; ++ return true; ++ } ++ ++ cond_resched(); ++ } ++ ++ return false; + } + + /* Returns true if the page is within a block suitable for migration to */ +@@ -329,7 +361,8 @@ isolate_fail: + + /* Update the pageblock-skip if the whole pageblock was scanned */ + if (blockpfn == end_pfn) +- update_pageblock_skip(cc, valid_page, total_isolated, false); ++ update_pageblock_skip(cc, valid_page, total_isolated, true, ++ false); + + count_compact_events(COMPACTFREE_SCANNED, nr_scanned); + if (total_isolated) +@@ -464,8 +497,9 @@ isolate_migratepages_range(struct zone *zone, struct compact_control *cc, + unsigned long flags; + bool locked = false; + struct page *page = NULL, *valid_page = NULL; +- bool skipped_async_unsuitable = false; +- const isolate_mode_t mode = (!cc->sync ? ISOLATE_ASYNC_MIGRATE : 0) | ++ bool set_unsuitable = true; ++ const isolate_mode_t mode = (cc->mode == MIGRATE_ASYNC ? ++ ISOLATE_ASYNC_MIGRATE : 0) | + (unevictable ? ISOLATE_UNEVICTABLE : 0); + + /* +@@ -475,7 +509,7 @@ isolate_migratepages_range(struct zone *zone, struct compact_control *cc, + */ + while (unlikely(too_many_isolated(zone))) { + /* async migration should just abort */ +- if (!cc->sync) ++ if (cc->mode == MIGRATE_ASYNC) + return 0; + + congestion_wait(BLK_RW_ASYNC, HZ/10); +@@ -484,8 +518,10 @@ isolate_migratepages_range(struct zone *zone, struct compact_control *cc, + return 0; + } + ++ if (compact_should_abort(cc)) ++ return 0; ++ + /* Time to isolate some pages for migration */ +- cond_resched(); + for (; low_pfn < end_pfn; low_pfn++) { + /* give a chance to irqs before checking need_resched() */ + if (locked && !(low_pfn % SWAP_CLUSTER_MAX)) { +@@ -540,9 +576,9 @@ isolate_migratepages_range(struct zone *zone, struct compact_control *cc, + * the minimum amount of work satisfies the allocation + */ + mt = get_pageblock_migratetype(page); +- if (!cc->sync && !migrate_async_suitable(mt)) { +- cc->finished_update_migrate = true; +- skipped_async_unsuitable = true; ++ if (cc->mode == MIGRATE_ASYNC && ++ !migrate_async_suitable(mt)) { ++ set_unsuitable = false; + goto next_pageblock; + } + } +@@ -646,11 +682,10 @@ next_pageblock: + /* + * Update the pageblock-skip information and cached scanner pfn, + * if the whole pageblock was scanned without isolating any page. +- * This is not done when pageblock was skipped due to being unsuitable +- * for async compaction, so that eventual sync compaction can try. + */ +- if (low_pfn == end_pfn && !skipped_async_unsuitable) +- update_pageblock_skip(cc, valid_page, nr_isolated, true); ++ if (low_pfn == end_pfn) ++ update_pageblock_skip(cc, valid_page, nr_isolated, ++ set_unsuitable, true); + + trace_mm_compaction_isolate_migratepages(nr_scanned, nr_isolated); + +@@ -671,7 +706,9 @@ static void isolate_freepages(struct zone *zone, + struct compact_control *cc) + { + struct page *page; +- unsigned long high_pfn, low_pfn, pfn, z_end_pfn; ++ unsigned long block_start_pfn; /* start of current pageblock */ ++ unsigned long block_end_pfn; /* end of current pageblock */ ++ unsigned long low_pfn; /* lowest pfn scanner is able to scan */ + int nr_freepages = cc->nr_freepages; + struct list_head *freelist = &cc->freepages; + +@@ -679,41 +716,38 @@ static void isolate_freepages(struct zone *zone, + * Initialise the free scanner. The starting point is where we last + * successfully isolated from, zone-cached value, or the end of the + * zone when isolating for the first time. We need this aligned to +- * the pageblock boundary, because we do pfn -= pageblock_nr_pages +- * in the for loop. ++ * the pageblock boundary, because we do ++ * block_start_pfn -= pageblock_nr_pages in the for loop. ++ * For ending point, take care when isolating in last pageblock of a ++ * a zone which ends in the middle of a pageblock. + * The low boundary is the end of the pageblock the migration scanner + * is using. + */ +- pfn = cc->free_pfn & ~(pageblock_nr_pages-1); ++ block_start_pfn = cc->free_pfn & ~(pageblock_nr_pages-1); ++ block_end_pfn = min(block_start_pfn + pageblock_nr_pages, ++ zone_end_pfn(zone)); + low_pfn = ALIGN(cc->migrate_pfn + 1, pageblock_nr_pages); + + /* +- * Take care that if the migration scanner is at the end of the zone +- * that the free scanner does not accidentally move to the next zone +- * in the next isolation cycle. +- */ +- high_pfn = min(low_pfn, pfn); +- +- z_end_pfn = zone_end_pfn(zone); +- +- /* + * Isolate free pages until enough are available to migrate the + * pages on cc->migratepages. We stop searching if the migrate + * and free page scanners meet or enough free pages are isolated. + */ +- for (; pfn >= low_pfn && cc->nr_migratepages > nr_freepages; +- pfn -= pageblock_nr_pages) { ++ for (; block_start_pfn >= low_pfn && cc->nr_migratepages > nr_freepages; ++ block_end_pfn = block_start_pfn, ++ block_start_pfn -= pageblock_nr_pages) { + unsigned long isolated; +- unsigned long end_pfn; + + /* + * This can iterate a massively long zone without finding any + * suitable migration targets, so periodically check if we need +- * to schedule. ++ * to schedule, or even abort async compaction. + */ +- cond_resched(); ++ if (!(block_start_pfn % (SWAP_CLUSTER_MAX * pageblock_nr_pages)) ++ && compact_should_abort(cc)) ++ break; + +- if (!pfn_valid(pfn)) ++ if (!pfn_valid(block_start_pfn)) + continue; + + /* +@@ -723,7 +757,7 @@ static void isolate_freepages(struct zone *zone, + * i.e. it's possible that all pages within a zones range of + * pages do not belong to a single zone. + */ +- page = pfn_to_page(pfn); ++ page = pfn_to_page(block_start_pfn); + if (page_zone(page) != zone) + continue; + +@@ -736,26 +770,26 @@ static void isolate_freepages(struct zone *zone, + continue; + + /* Found a block suitable for isolating free pages from */ +- isolated = 0; ++ cc->free_pfn = block_start_pfn; ++ isolated = isolate_freepages_block(cc, block_start_pfn, ++ block_end_pfn, freelist, false); ++ nr_freepages += isolated; + + /* +- * Take care when isolating in last pageblock of a zone which +- * ends in the middle of a pageblock. ++ * Set a flag that we successfully isolated in this pageblock. ++ * In the next loop iteration, zone->compact_cached_free_pfn ++ * will not be updated and thus it will effectively contain the ++ * highest pageblock we isolated pages from. + */ +- end_pfn = min(pfn + pageblock_nr_pages, z_end_pfn); +- isolated = isolate_freepages_block(cc, pfn, end_pfn, +- freelist, false); +- nr_freepages += isolated; ++ if (isolated) ++ cc->finished_update_free = true; + + /* +- * Record the highest PFN we isolated pages from. When next +- * looking for free pages, the search will restart here as +- * page migration may have returned some pages to the allocator ++ * isolate_freepages_block() might have aborted due to async ++ * compaction being contended + */ +- if (isolated) { +- cc->finished_update_free = true; +- high_pfn = max(high_pfn, pfn); +- } ++ if (cc->contended) ++ break; + } + + /* split_free_page does not map the pages */ +@@ -765,10 +799,9 @@ static void isolate_freepages(struct zone *zone, + * If we crossed the migrate scanner, we want to keep it that way + * so that compact_finished() may detect this + */ +- if (pfn < low_pfn) +- cc->free_pfn = max(pfn, zone->zone_start_pfn); +- else +- cc->free_pfn = high_pfn; ++ if (block_start_pfn < low_pfn) ++ cc->free_pfn = cc->migrate_pfn; ++ + cc->nr_freepages = nr_freepages; + } + +@@ -783,9 +816,13 @@ static struct page *compaction_alloc(struct page *migratepage, + struct compact_control *cc = (struct compact_control *)data; + struct page *freepage; + +- /* Isolate free pages if necessary */ ++ /* ++ * Isolate free pages if necessary, and if we are not aborting due to ++ * contention. ++ */ + if (list_empty(&cc->freepages)) { +- isolate_freepages(cc->zone, cc); ++ if (!cc->contended) ++ isolate_freepages(cc->zone, cc); + + if (list_empty(&cc->freepages)) + return NULL; +@@ -799,23 +836,16 @@ static struct page *compaction_alloc(struct page *migratepage, + } + + /* +- * We cannot control nr_migratepages and nr_freepages fully when migration is +- * running as migrate_pages() has no knowledge of compact_control. When +- * migration is complete, we count the number of pages on the lists by hand. ++ * This is a migrate-callback that "frees" freepages back to the isolated ++ * freelist. All pages on the freelist are from the same zone, so there is no ++ * special handling needed for NUMA. + */ +-static void update_nr_listpages(struct compact_control *cc) ++static void compaction_free(struct page *page, unsigned long data) + { +- int nr_migratepages = 0; +- int nr_freepages = 0; +- struct page *page; +- +- list_for_each_entry(page, &cc->migratepages, lru) +- nr_migratepages++; +- list_for_each_entry(page, &cc->freepages, lru) +- nr_freepages++; ++ struct compact_control *cc = (struct compact_control *)data; + +- cc->nr_migratepages = nr_migratepages; +- cc->nr_freepages = nr_freepages; ++ list_add(&page->lru, &cc->freepages); ++ cc->nr_freepages++; + } + + /* possible outcome of isolate_migratepages */ +@@ -862,13 +892,14 @@ static int compact_finished(struct zone *zone, + unsigned int order; + unsigned long watermark; + +- if (fatal_signal_pending(current)) ++ if (cc->contended || fatal_signal_pending(current)) + return COMPACT_PARTIAL; + + /* Compaction run completes if the migrate and free scanner meet */ + if (cc->free_pfn <= cc->migrate_pfn) { + /* Let the next compaction start anew. */ +- zone->compact_cached_migrate_pfn = zone->zone_start_pfn; ++ zone->compact_cached_migrate_pfn[0] = zone->zone_start_pfn; ++ zone->compact_cached_migrate_pfn[1] = zone->zone_start_pfn; + zone->compact_cached_free_pfn = zone_end_pfn(zone); + + /* +@@ -968,6 +999,7 @@ static int compact_zone(struct zone *zone, struct compact_control *cc) + int ret; + unsigned long start_pfn = zone->zone_start_pfn; + unsigned long end_pfn = zone_end_pfn(zone); ++ const bool sync = cc->mode != MIGRATE_ASYNC; + + ret = compaction_suitable(zone, cc->order); + switch (ret) { +@@ -993,7 +1025,7 @@ static int compact_zone(struct zone *zone, struct compact_control *cc) + * information on where the scanners should start but check that it + * is initialised by ensuring the values are within zone boundaries. + */ +- cc->migrate_pfn = zone->compact_cached_migrate_pfn; ++ cc->migrate_pfn = zone->compact_cached_migrate_pfn[sync]; + cc->free_pfn = zone->compact_cached_free_pfn; + if (cc->free_pfn < start_pfn || cc->free_pfn > end_pfn) { + cc->free_pfn = end_pfn & ~(pageblock_nr_pages-1); +@@ -1001,7 +1033,8 @@ static int compact_zone(struct zone *zone, struct compact_control *cc) + } + if (cc->migrate_pfn < start_pfn || cc->migrate_pfn > end_pfn) { + cc->migrate_pfn = start_pfn; +- zone->compact_cached_migrate_pfn = cc->migrate_pfn; ++ zone->compact_cached_migrate_pfn[0] = cc->migrate_pfn; ++ zone->compact_cached_migrate_pfn[1] = cc->migrate_pfn; + } + + trace_mm_compaction_begin(start_pfn, cc->migrate_pfn, cc->free_pfn, end_pfn); +@@ -1009,7 +1042,6 @@ static int compact_zone(struct zone *zone, struct compact_control *cc) + migrate_prep_local(); + + while ((ret = compact_finished(zone, cc)) == COMPACT_CONTINUE) { +- unsigned long nr_migrate, nr_remaining; + int err; + + switch (isolate_migratepages(zone, cc)) { +@@ -1024,21 +1056,20 @@ static int compact_zone(struct zone *zone, struct compact_control *cc) + ; + } + +- nr_migrate = cc->nr_migratepages; ++ if (!cc->nr_migratepages) ++ continue; ++ + err = migrate_pages(&cc->migratepages, compaction_alloc, +- (unsigned long)cc, +- cc->sync ? MIGRATE_SYNC_LIGHT : MIGRATE_ASYNC, ++ compaction_free, (unsigned long)cc, cc->mode, + MR_COMPACTION); +- update_nr_listpages(cc); +- nr_remaining = cc->nr_migratepages; + +- trace_mm_compaction_migratepages(nr_migrate - nr_remaining, +- nr_remaining); ++ trace_mm_compaction_migratepages(cc->nr_migratepages, err, ++ &cc->migratepages); + +- /* Release isolated pages not migrated */ ++ /* All pages were either migrated or will be released */ ++ cc->nr_migratepages = 0; + if (err) { + putback_movable_pages(&cc->migratepages); +- cc->nr_migratepages = 0; + /* + * migrate_pages() may return -ENOMEM when scanners meet + * and we want compact_finished() to detect it +@@ -1060,9 +1091,8 @@ out: + return ret; + } + +-static unsigned long compact_zone_order(struct zone *zone, +- int order, gfp_t gfp_mask, +- bool sync, bool *contended) ++static unsigned long compact_zone_order(struct zone *zone, int order, ++ gfp_t gfp_mask, enum migrate_mode mode, bool *contended) + { + unsigned long ret; + struct compact_control cc = { +@@ -1071,7 +1101,7 @@ static unsigned long compact_zone_order(struct zone *zone, + .order = order, + .migratetype = allocflags_to_migratetype(gfp_mask), + .zone = zone, +- .sync = sync, ++ .mode = mode, + }; + INIT_LIST_HEAD(&cc.freepages); + INIT_LIST_HEAD(&cc.migratepages); +@@ -1093,7 +1123,7 @@ int sysctl_extfrag_threshold = 500; + * @order: The order of the current allocation + * @gfp_mask: The GFP mask of the current allocation + * @nodemask: The allowed nodes to allocate from +- * @sync: Whether migration is synchronous or not ++ * @mode: The migration mode for async, sync light, or sync migration + * @contended: Return value that is true if compaction was aborted due to lock contention + * @page: Optionally capture a free page of the requested order during compaction + * +@@ -1101,7 +1131,7 @@ int sysctl_extfrag_threshold = 500; + */ + unsigned long try_to_compact_pages(struct zonelist *zonelist, + int order, gfp_t gfp_mask, nodemask_t *nodemask, +- bool sync, bool *contended) ++ enum migrate_mode mode, bool *contended) + { + enum zone_type high_zoneidx = gfp_zone(gfp_mask); + int may_enter_fs = gfp_mask & __GFP_FS; +@@ -1126,7 +1156,7 @@ unsigned long try_to_compact_pages(struct zonelist *zonelist, + nodemask) { + int status; + +- status = compact_zone_order(zone, order, gfp_mask, sync, ++ status = compact_zone_order(zone, order, gfp_mask, mode, + contended); + rc = max(status, rc); + +@@ -1165,9 +1195,6 @@ static void __compact_pgdat(pg_data_t *pgdat, struct compact_control *cc) + if (zone_watermark_ok(zone, cc->order, + low_wmark_pages(zone), 0, 0)) + compaction_defer_reset(zone, cc->order, false); +- /* Currently async compaction is never deferred. */ +- else if (cc->sync) +- defer_compaction(zone, cc->order); + } + + VM_BUG_ON(!list_empty(&cc->freepages)); +@@ -1179,7 +1206,7 @@ void compact_pgdat(pg_data_t *pgdat, int order) + { + struct compact_control cc = { + .order = order, +- .sync = false, ++ .mode = MIGRATE_ASYNC, + }; + + if (!order) +@@ -1192,7 +1219,7 @@ static void compact_node(int nid) + { + struct compact_control cc = { + .order = -1, +- .sync = true, ++ .mode = MIGRATE_SYNC, + .ignore_skip_hint = true, + }; + +diff --git a/mm/filemap.c b/mm/filemap.c +index c2cc7c95eff1..bdaa21555abe 100644 +--- a/mm/filemap.c ++++ b/mm/filemap.c +@@ -448,6 +448,29 @@ int replace_page_cache_page(struct page *old, struct page *new, gfp_t gfp_mask) + } + EXPORT_SYMBOL_GPL(replace_page_cache_page); + ++static int page_cache_tree_insert(struct address_space *mapping, ++ struct page *page) ++{ ++ void **slot; ++ int error; ++ ++ slot = radix_tree_lookup_slot(&mapping->page_tree, page->index); ++ if (slot) { ++ void *p; ++ ++ p = radix_tree_deref_slot_protected(slot, &mapping->tree_lock); ++ if (!radix_tree_exceptional_entry(p)) ++ return -EEXIST; ++ radix_tree_replace_slot(slot, page); ++ mapping->nrpages++; ++ return 0; ++ } ++ error = radix_tree_insert(&mapping->page_tree, page->index, page); ++ if (!error) ++ mapping->nrpages++; ++ return error; ++} ++ + /** + * add_to_page_cache_locked - add a locked page to the pagecache + * @page: page to add +@@ -482,11 +505,10 @@ int add_to_page_cache_locked(struct page *page, struct address_space *mapping, + page->index = offset; + + spin_lock_irq(&mapping->tree_lock); +- error = radix_tree_insert(&mapping->page_tree, offset, page); ++ error = page_cache_tree_insert(mapping, page); + radix_tree_preload_end(); + if (unlikely(error)) + goto err_insert; +- mapping->nrpages++; + __inc_zone_page_state(page, NR_FILE_PAGES); + spin_unlock_irq(&mapping->tree_lock); + trace_mm_filemap_add_to_page_cache(page); +@@ -688,14 +710,101 @@ int __lock_page_or_retry(struct page *page, struct mm_struct *mm, + } + + /** +- * find_get_page - find and get a page reference ++ * page_cache_next_hole - find the next hole (not-present entry) ++ * @mapping: mapping ++ * @index: index ++ * @max_scan: maximum range to search ++ * ++ * Search the set [index, min(index+max_scan-1, MAX_INDEX)] for the ++ * lowest indexed hole. ++ * ++ * Returns: the index of the hole if found, otherwise returns an index ++ * outside of the set specified (in which case 'return - index >= ++ * max_scan' will be true). In rare cases of index wrap-around, 0 will ++ * be returned. ++ * ++ * page_cache_next_hole may be called under rcu_read_lock. However, ++ * like radix_tree_gang_lookup, this will not atomically search a ++ * snapshot of the tree at a single point in time. For example, if a ++ * hole is created at index 5, then subsequently a hole is created at ++ * index 10, page_cache_next_hole covering both indexes may return 10 ++ * if called under rcu_read_lock. ++ */ ++pgoff_t page_cache_next_hole(struct address_space *mapping, ++ pgoff_t index, unsigned long max_scan) ++{ ++ unsigned long i; ++ ++ for (i = 0; i < max_scan; i++) { ++ struct page *page; ++ ++ page = radix_tree_lookup(&mapping->page_tree, index); ++ if (!page || radix_tree_exceptional_entry(page)) ++ break; ++ index++; ++ if (index == 0) ++ break; ++ } ++ ++ return index; ++} ++EXPORT_SYMBOL(page_cache_next_hole); ++ ++/** ++ * page_cache_prev_hole - find the prev hole (not-present entry) ++ * @mapping: mapping ++ * @index: index ++ * @max_scan: maximum range to search ++ * ++ * Search backwards in the range [max(index-max_scan+1, 0), index] for ++ * the first hole. ++ * ++ * Returns: the index of the hole if found, otherwise returns an index ++ * outside of the set specified (in which case 'index - return >= ++ * max_scan' will be true). In rare cases of wrap-around, ULONG_MAX ++ * will be returned. ++ * ++ * page_cache_prev_hole may be called under rcu_read_lock. However, ++ * like radix_tree_gang_lookup, this will not atomically search a ++ * snapshot of the tree at a single point in time. For example, if a ++ * hole is created at index 10, then subsequently a hole is created at ++ * index 5, page_cache_prev_hole covering both indexes may return 5 if ++ * called under rcu_read_lock. ++ */ ++pgoff_t page_cache_prev_hole(struct address_space *mapping, ++ pgoff_t index, unsigned long max_scan) ++{ ++ unsigned long i; ++ ++ for (i = 0; i < max_scan; i++) { ++ struct page *page; ++ ++ page = radix_tree_lookup(&mapping->page_tree, index); ++ if (!page || radix_tree_exceptional_entry(page)) ++ break; ++ index--; ++ if (index == ULONG_MAX) ++ break; ++ } ++ ++ return index; ++} ++EXPORT_SYMBOL(page_cache_prev_hole); ++ ++/** ++ * find_get_entry - find and get a page cache entry + * @mapping: the address_space to search +- * @offset: the page index ++ * @offset: the page cache index + * +- * Is there a pagecache struct page at the given (mapping, offset) tuple? +- * If yes, increment its refcount and return it; if no, return NULL. ++ * Looks up the page cache slot at @mapping & @offset. If there is a ++ * page cache page, it is returned with an increased refcount. ++ * ++ * If the slot holds a shadow entry of a previously evicted page, it ++ * is returned. ++ * ++ * Otherwise, %NULL is returned. + */ +-struct page *find_get_page(struct address_space *mapping, pgoff_t offset) ++struct page *find_get_entry(struct address_space *mapping, pgoff_t offset) + { + void **pagep; + struct page *page; +@@ -736,24 +845,50 @@ out: + + return page; + } +-EXPORT_SYMBOL(find_get_page); ++EXPORT_SYMBOL(find_get_entry); + + /** +- * find_lock_page - locate, pin and lock a pagecache page ++ * find_get_page - find and get a page reference + * @mapping: the address_space to search + * @offset: the page index + * +- * Locates the desired pagecache page, locks it, increments its reference +- * count and returns its address. ++ * Looks up the page cache slot at @mapping & @offset. If there is a ++ * page cache page, it is returned with an increased refcount. + * +- * Returns zero if the page was not present. find_lock_page() may sleep. ++ * Otherwise, %NULL is returned. + */ +-struct page *find_lock_page(struct address_space *mapping, pgoff_t offset) ++struct page *find_get_page(struct address_space *mapping, pgoff_t offset) ++{ ++ struct page *page = find_get_entry(mapping, offset); ++ ++ if (radix_tree_exceptional_entry(page)) ++ page = NULL; ++ return page; ++} ++EXPORT_SYMBOL(find_get_page); ++ ++/** ++ * find_lock_entry - locate, pin and lock a page cache entry ++ * @mapping: the address_space to search ++ * @offset: the page cache index ++ * ++ * Looks up the page cache slot at @mapping & @offset. If there is a ++ * page cache page, it is returned locked and with an increased ++ * refcount. ++ * ++ * If the slot holds a shadow entry of a previously evicted page, it ++ * is returned. ++ * ++ * Otherwise, %NULL is returned. ++ * ++ * find_lock_entry() may sleep. ++ */ ++struct page *find_lock_entry(struct address_space *mapping, pgoff_t offset) + { + struct page *page; + + repeat: +- page = find_get_page(mapping, offset); ++ page = find_get_entry(mapping, offset); + if (page && !radix_tree_exception(page)) { + lock_page(page); + /* Has the page been truncated? */ +@@ -766,6 +901,29 @@ repeat: + } + return page; + } ++EXPORT_SYMBOL(find_lock_entry); ++ ++/** ++ * find_lock_page - locate, pin and lock a pagecache page ++ * @mapping: the address_space to search ++ * @offset: the page index ++ * ++ * Looks up the page cache slot at @mapping & @offset. If there is a ++ * page cache page, it is returned locked and with an increased ++ * refcount. ++ * ++ * Otherwise, %NULL is returned. ++ * ++ * find_lock_page() may sleep. ++ */ ++struct page *find_lock_page(struct address_space *mapping, pgoff_t offset) ++{ ++ struct page *page = find_lock_entry(mapping, offset); ++ ++ if (radix_tree_exceptional_entry(page)) ++ page = NULL; ++ return page; ++} + EXPORT_SYMBOL(find_lock_page); + + /** +@@ -774,16 +932,18 @@ EXPORT_SYMBOL(find_lock_page); + * @index: the page's index into the mapping + * @gfp_mask: page allocation mode + * +- * Locates a page in the pagecache. If the page is not present, a new page +- * is allocated using @gfp_mask and is added to the pagecache and to the VM's +- * LRU list. The returned page is locked and has its reference count +- * incremented. ++ * Looks up the page cache slot at @mapping & @offset. If there is a ++ * page cache page, it is returned locked and with an increased ++ * refcount. ++ * ++ * If the page is not present, a new page is allocated using @gfp_mask ++ * and added to the page cache and the VM's LRU list. The page is ++ * returned locked and with an increased refcount. + * +- * find_or_create_page() may sleep, even if @gfp_flags specifies an atomic +- * allocation! ++ * On memory exhaustion, %NULL is returned. + * +- * find_or_create_page() returns the desired page's address, or zero on +- * memory exhaustion. ++ * find_or_create_page() may sleep, even if @gfp_flags specifies an ++ * atomic allocation! + */ + struct page *find_or_create_page(struct address_space *mapping, + pgoff_t index, gfp_t gfp_mask) +@@ -816,6 +976,76 @@ repeat: + EXPORT_SYMBOL(find_or_create_page); + + /** ++ * find_get_entries - gang pagecache lookup ++ * @mapping: The address_space to search ++ * @start: The starting page cache index ++ * @nr_entries: The maximum number of entries ++ * @entries: Where the resulting entries are placed ++ * @indices: The cache indices corresponding to the entries in @entries ++ * ++ * find_get_entries() will search for and return a group of up to ++ * @nr_entries entries in the mapping. The entries are placed at ++ * @entries. find_get_entries() takes a reference against any actual ++ * pages it returns. ++ * ++ * The search returns a group of mapping-contiguous page cache entries ++ * with ascending indexes. There may be holes in the indices due to ++ * not-present pages. ++ * ++ * Any shadow entries of evicted pages are included in the returned ++ * array. ++ * ++ * find_get_entries() returns the number of pages and shadow entries ++ * which were found. ++ */ ++unsigned find_get_entries(struct address_space *mapping, ++ pgoff_t start, unsigned int nr_entries, ++ struct page **entries, pgoff_t *indices) ++{ ++ void **slot; ++ unsigned int ret = 0; ++ struct radix_tree_iter iter; ++ ++ if (!nr_entries) ++ return 0; ++ ++ rcu_read_lock(); ++restart: ++ radix_tree_for_each_slot(slot, &mapping->page_tree, &iter, start) { ++ struct page *page; ++repeat: ++ page = radix_tree_deref_slot(slot); ++ if (unlikely(!page)) ++ continue; ++ if (radix_tree_exception(page)) { ++ if (radix_tree_deref_retry(page)) ++ goto restart; ++ /* ++ * Otherwise, we must be storing a swap entry ++ * here as an exceptional entry: so return it ++ * without attempting to raise page count. ++ */ ++ goto export; ++ } ++ if (!page_cache_get_speculative(page)) ++ goto repeat; ++ ++ /* Has the page moved? */ ++ if (unlikely(page != *slot)) { ++ page_cache_release(page); ++ goto repeat; ++ } ++export: ++ indices[ret] = iter.index; ++ entries[ret] = page; ++ if (++ret == nr_entries) ++ break; ++ } ++ rcu_read_unlock(); ++ return ret; ++} ++ ++/** + * find_get_pages - gang pagecache lookup + * @mapping: The address_space to search + * @start: The starting page index +@@ -1797,6 +2027,18 @@ int generic_file_readonly_mmap(struct file * file, struct vm_area_struct * vma) + EXPORT_SYMBOL(generic_file_mmap); + EXPORT_SYMBOL(generic_file_readonly_mmap); + ++static struct page *wait_on_page_read(struct page *page) ++{ ++ if (!IS_ERR(page)) { ++ wait_on_page_locked(page); ++ if (!PageUptodate(page)) { ++ page_cache_release(page); ++ page = ERR_PTR(-EIO); ++ } ++ } ++ return page; ++} ++ + static struct page *__read_cache_page(struct address_space *mapping, + pgoff_t index, + int (*filler)(void *, struct page *), +@@ -1823,6 +2065,8 @@ repeat: + if (err < 0) { + page_cache_release(page); + page = ERR_PTR(err); ++ } else { ++ page = wait_on_page_read(page); + } + } + return page; +@@ -1859,6 +2103,10 @@ retry: + if (err < 0) { + page_cache_release(page); + return ERR_PTR(err); ++ } else { ++ page = wait_on_page_read(page); ++ if (IS_ERR(page)) ++ return page; + } + out: + mark_page_accessed(page); +@@ -1866,40 +2114,25 @@ out: + } + + /** +- * read_cache_page_async - read into page cache, fill it if needed ++ * read_cache_page - read into page cache, fill it if needed + * @mapping: the page's address_space + * @index: the page index + * @filler: function to perform the read + * @data: first arg to filler(data, page) function, often left as NULL + * +- * Same as read_cache_page, but don't wait for page to become unlocked +- * after submitting it to the filler. +- * + * Read into the page cache. If a page already exists, and PageUptodate() is +- * not set, try to fill the page but don't wait for it to become unlocked. ++ * not set, try to fill the page and wait for it to become unlocked. + * + * If the page does not get brought uptodate, return -EIO. + */ +-struct page *read_cache_page_async(struct address_space *mapping, ++struct page *read_cache_page(struct address_space *mapping, + pgoff_t index, + int (*filler)(void *, struct page *), + void *data) + { + return do_read_cache_page(mapping, index, filler, data, mapping_gfp_mask(mapping)); + } +-EXPORT_SYMBOL(read_cache_page_async); +- +-static struct page *wait_on_page_read(struct page *page) +-{ +- if (!IS_ERR(page)) { +- wait_on_page_locked(page); +- if (!PageUptodate(page)) { +- page_cache_release(page); +- page = ERR_PTR(-EIO); +- } +- } +- return page; +-} ++EXPORT_SYMBOL(read_cache_page); + + /** + * read_cache_page_gfp - read into page cache, using specified page allocation flags. +@@ -1918,31 +2151,10 @@ struct page *read_cache_page_gfp(struct address_space *mapping, + { + filler_t *filler = (filler_t *)mapping->a_ops->readpage; + +- return wait_on_page_read(do_read_cache_page(mapping, index, filler, NULL, gfp)); ++ return do_read_cache_page(mapping, index, filler, NULL, gfp); + } + EXPORT_SYMBOL(read_cache_page_gfp); + +-/** +- * read_cache_page - read into page cache, fill it if needed +- * @mapping: the page's address_space +- * @index: the page index +- * @filler: function to perform the read +- * @data: first arg to filler(data, page) function, often left as NULL +- * +- * Read into the page cache. If a page already exists, and PageUptodate() is +- * not set, try to fill the page then wait for it to become unlocked. +- * +- * If the page does not get brought uptodate, return -EIO. +- */ +-struct page *read_cache_page(struct address_space *mapping, +- pgoff_t index, +- int (*filler)(void *, struct page *), +- void *data) +-{ +- return wait_on_page_read(read_cache_page_async(mapping, index, filler, data)); +-} +-EXPORT_SYMBOL(read_cache_page); +- + static size_t __iovec_copy_from_user_inatomic(char *vaddr, + const struct iovec *iov, size_t base, size_t bytes) + { +@@ -1976,7 +2188,6 @@ size_t iov_iter_copy_from_user_atomic(struct page *page, + char *kaddr; + size_t copied; + +- BUG_ON(!in_atomic()); + kaddr = kmap_atomic(page); + if (likely(i->nr_segs == 1)) { + int left; +@@ -2350,9 +2561,7 @@ again: + if (mapping_writably_mapped(mapping)) + flush_dcache_page(page); + +- pagefault_disable(); + copied = iov_iter_copy_from_user_atomic(page, i, offset, bytes); +- pagefault_enable(); + flush_dcache_page(page); + + mark_page_accessed(page); +diff --git a/mm/internal.h b/mm/internal.h +index 3e910000fda4..1a8a0d4b687a 100644 +--- a/mm/internal.h ++++ b/mm/internal.h +@@ -11,6 +11,7 @@ + #ifndef __MM_INTERNAL_H + #define __MM_INTERNAL_H + ++#include <linux/fs.h> + #include <linux/mm.h> + + void free_pgtables(struct mmu_gather *tlb, struct vm_area_struct *start_vma, +@@ -21,6 +22,20 @@ static inline void set_page_count(struct page *page, int v) + atomic_set(&page->_count, v); + } + ++extern int __do_page_cache_readahead(struct address_space *mapping, ++ struct file *filp, pgoff_t offset, unsigned long nr_to_read, ++ unsigned long lookahead_size); ++ ++/* ++ * Submit IO for the read-ahead request in file_ra_state. ++ */ ++static inline unsigned long ra_submit(struct file_ra_state *ra, ++ struct address_space *mapping, struct file *filp) ++{ ++ return __do_page_cache_readahead(mapping, filp, ++ ra->start, ra->size, ra->async_size); ++} ++ + /* + * Turn a non-refcounted page (->_count == 0) into refcounted with + * a count of one. +@@ -119,7 +134,7 @@ struct compact_control { + unsigned long nr_migratepages; /* Number of pages to migrate */ + unsigned long free_pfn; /* isolate_freepages search base */ + unsigned long migrate_pfn; /* isolate_migratepages search base */ +- bool sync; /* Synchronous migration */ ++ enum migrate_mode mode; /* Async or sync migration mode */ + bool ignore_skip_hint; /* Scan blocks even if marked skip */ + bool finished_update_free; /* True when the zone cached pfns are + * no longer being updated +@@ -129,7 +144,10 @@ struct compact_control { + int order; /* order a direct compactor needs */ + int migratetype; /* MOVABLE, RECLAIMABLE etc */ + struct zone *zone; +- bool contended; /* True if a lock was contended */ ++ bool contended; /* True if a lock was contended, or ++ * need_resched() true during async ++ * compaction ++ */ + }; + + unsigned long +diff --git a/mm/madvise.c b/mm/madvise.c +index 539eeb96b323..a402f8fdc68e 100644 +--- a/mm/madvise.c ++++ b/mm/madvise.c +@@ -195,7 +195,7 @@ static void force_shm_swapin_readahead(struct vm_area_struct *vma, + for (; start < end; start += PAGE_SIZE) { + index = ((start - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff; + +- page = find_get_page(mapping, index); ++ page = find_get_entry(mapping, index); + if (!radix_tree_exceptional_entry(page)) { + if (page) + page_cache_release(page); +diff --git a/mm/memory-failure.c b/mm/memory-failure.c +index 33365e9ce6a7..a98c7fce470a 100644 +--- a/mm/memory-failure.c ++++ b/mm/memory-failure.c +@@ -1540,7 +1540,7 @@ static int soft_offline_huge_page(struct page *page, int flags) + + /* Keep page count to indicate a given hugepage is isolated. */ + list_move(&hpage->lru, &pagelist); +- ret = migrate_pages(&pagelist, new_page, MPOL_MF_MOVE_ALL, ++ ret = migrate_pages(&pagelist, new_page, NULL, MPOL_MF_MOVE_ALL, + MIGRATE_SYNC, MR_MEMORY_FAILURE); + if (ret) { + pr_info("soft offline: %#lx: migration failed %d, type %lx\n", +@@ -1621,7 +1621,7 @@ static int __soft_offline_page(struct page *page, int flags) + inc_zone_page_state(page, NR_ISOLATED_ANON + + page_is_file_cache(page)); + list_add(&page->lru, &pagelist); +- ret = migrate_pages(&pagelist, new_page, MPOL_MF_MOVE_ALL, ++ ret = migrate_pages(&pagelist, new_page, NULL, MPOL_MF_MOVE_ALL, + MIGRATE_SYNC, MR_MEMORY_FAILURE); + if (ret) { + if (!list_empty(&pagelist)) { +diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c +index a650db29606f..f6f23833de44 100644 +--- a/mm/memory_hotplug.c ++++ b/mm/memory_hotplug.c +@@ -1332,7 +1332,7 @@ do_migrate_range(unsigned long start_pfn, unsigned long end_pfn) + * alloc_migrate_target should be improooooved!! + * migrate_pages returns # of failed pages. + */ +- ret = migrate_pages(&source, alloc_migrate_target, 0, ++ ret = migrate_pages(&source, alloc_migrate_target, NULL, 0, + MIGRATE_SYNC, MR_MEMORY_HOTPLUG); + if (ret) + putback_movable_pages(&source); +diff --git a/mm/mempolicy.c b/mm/mempolicy.c +index 796c7e6cf93b..e8fff0fa1202 100644 +--- a/mm/mempolicy.c ++++ b/mm/mempolicy.c +@@ -1060,7 +1060,7 @@ static int migrate_to_node(struct mm_struct *mm, int source, int dest, + flags | MPOL_MF_DISCONTIG_OK, &pagelist); + + if (!list_empty(&pagelist)) { +- err = migrate_pages(&pagelist, new_node_page, dest, ++ err = migrate_pages(&pagelist, new_node_page, NULL, dest, + MIGRATE_SYNC, MR_SYSCALL); + if (err) + putback_movable_pages(&pagelist); +@@ -1306,7 +1306,7 @@ static long do_mbind(unsigned long start, unsigned long len, + + if (!list_empty(&pagelist)) { + WARN_ON_ONCE(flags & MPOL_MF_LAZY); +- nr_failed = migrate_pages(&pagelist, new_page, ++ nr_failed = migrate_pages(&pagelist, new_page, NULL, + start, MIGRATE_SYNC, MR_MEMPOLICY_MBIND); + if (nr_failed) + putback_movable_pages(&pagelist); +diff --git a/mm/migrate.c b/mm/migrate.c +index 13f47fbe3550..3acac4a62c4b 100644 +--- a/mm/migrate.c ++++ b/mm/migrate.c +@@ -941,8 +941,9 @@ out: + * Obtain the lock on page, remove all ptes and migrate the page + * to the newly allocated page in newpage. + */ +-static int unmap_and_move(new_page_t get_new_page, unsigned long private, +- struct page *page, int force, enum migrate_mode mode) ++static int unmap_and_move(new_page_t get_new_page, free_page_t put_new_page, ++ unsigned long private, struct page *page, int force, ++ enum migrate_mode mode) + { + int rc = 0; + int *result = NULL; +@@ -986,11 +987,18 @@ out: + page_is_file_cache(page)); + putback_lru_page(page); + } ++ + /* +- * Move the new page to the LRU. If migration was not successful +- * then this will free the page. ++ * If migration was not successful and there's a freeing callback, use ++ * it. Otherwise, putback_lru_page() will drop the reference grabbed ++ * during isolation. + */ +- putback_lru_page(newpage); ++ if (rc != MIGRATEPAGE_SUCCESS && put_new_page) { ++ ClearPageSwapBacked(newpage); ++ put_new_page(newpage, private); ++ } else ++ putback_lru_page(newpage); ++ + if (result) { + if (rc) + *result = rc; +@@ -1019,8 +1027,9 @@ out: + * will wait in the page fault for migration to complete. + */ + static int unmap_and_move_huge_page(new_page_t get_new_page, +- unsigned long private, struct page *hpage, +- int force, enum migrate_mode mode) ++ free_page_t put_new_page, unsigned long private, ++ struct page *hpage, int force, ++ enum migrate_mode mode) + { + int rc = 0; + int *result = NULL; +@@ -1059,20 +1068,30 @@ static int unmap_and_move_huge_page(new_page_t get_new_page, + if (!page_mapped(hpage)) + rc = move_to_new_page(new_hpage, hpage, 1, mode); + +- if (rc) ++ if (rc != MIGRATEPAGE_SUCCESS) + remove_migration_ptes(hpage, hpage); + + if (anon_vma) + put_anon_vma(anon_vma); + +- if (!rc) ++ if (rc == MIGRATEPAGE_SUCCESS) + hugetlb_cgroup_migrate(hpage, new_hpage); + + unlock_page(hpage); + out: + if (rc != -EAGAIN) + putback_active_hugepage(hpage); +- put_page(new_hpage); ++ ++ /* ++ * If migration was not successful and there's a freeing callback, use ++ * it. Otherwise, put_page() will drop the reference grabbed during ++ * isolation. ++ */ ++ if (rc != MIGRATEPAGE_SUCCESS && put_new_page) ++ put_new_page(new_hpage, private); ++ else ++ put_page(new_hpage); ++ + if (result) { + if (rc) + *result = rc; +@@ -1089,6 +1108,8 @@ out: + * @from: The list of pages to be migrated. + * @get_new_page: The function used to allocate free pages to be used + * as the target of the page migration. ++ * @put_new_page: The function used to free target pages if migration ++ * fails, or NULL if no special handling is necessary. + * @private: Private data to be passed on to get_new_page() + * @mode: The migration mode that specifies the constraints for + * page migration, if any. +@@ -1102,7 +1123,8 @@ out: + * Returns the number of pages that were not migrated, or an error code. + */ + int migrate_pages(struct list_head *from, new_page_t get_new_page, +- unsigned long private, enum migrate_mode mode, int reason) ++ free_page_t put_new_page, unsigned long private, ++ enum migrate_mode mode, int reason) + { + int retry = 1; + int nr_failed = 0; +@@ -1124,10 +1146,11 @@ int migrate_pages(struct list_head *from, new_page_t get_new_page, + + if (PageHuge(page)) + rc = unmap_and_move_huge_page(get_new_page, +- private, page, pass > 2, mode); ++ put_new_page, private, page, ++ pass > 2, mode); + else +- rc = unmap_and_move(get_new_page, private, +- page, pass > 2, mode); ++ rc = unmap_and_move(get_new_page, put_new_page, ++ private, page, pass > 2, mode); + + switch(rc) { + case -ENOMEM: +@@ -1276,7 +1299,7 @@ set_status: + + err = 0; + if (!list_empty(&pagelist)) { +- err = migrate_pages(&pagelist, new_page_node, ++ err = migrate_pages(&pagelist, new_page_node, NULL, + (unsigned long)pm, MIGRATE_SYNC, MR_SYSCALL); + if (err) + putback_movable_pages(&pagelist); +@@ -1732,7 +1755,8 @@ int migrate_misplaced_page(struct page *page, struct vm_area_struct *vma, + + list_add(&page->lru, &migratepages); + nr_remaining = migrate_pages(&migratepages, alloc_misplaced_dst_page, +- node, MIGRATE_ASYNC, MR_NUMA_MISPLACED); ++ NULL, node, MIGRATE_ASYNC, ++ MR_NUMA_MISPLACED); + if (nr_remaining) { + if (!list_empty(&migratepages)) { + list_del(&page->lru); +diff --git a/mm/mincore.c b/mm/mincore.c +index 101623378fbf..725c80961048 100644 +--- a/mm/mincore.c ++++ b/mm/mincore.c +@@ -70,13 +70,21 @@ static unsigned char mincore_page(struct address_space *mapping, pgoff_t pgoff) + * any other file mapping (ie. marked !present and faulted in with + * tmpfs's .fault). So swapped out tmpfs mappings are tested here. + */ +- page = find_get_page(mapping, pgoff); + #ifdef CONFIG_SWAP +- /* shmem/tmpfs may return swap: account for swapcache page too. */ +- if (radix_tree_exceptional_entry(page)) { +- swp_entry_t swap = radix_to_swp_entry(page); +- page = find_get_page(swap_address_space(swap), swap.val); +- } ++ if (shmem_mapping(mapping)) { ++ page = find_get_entry(mapping, pgoff); ++ /* ++ * shmem/tmpfs may return swap: account for swapcache ++ * page too. ++ */ ++ if (radix_tree_exceptional_entry(page)) { ++ swp_entry_t swp = radix_to_swp_entry(page); ++ page = find_get_page(swap_address_space(swp), swp.val); ++ } ++ } else ++ page = find_get_page(mapping, pgoff); ++#else ++ page = find_get_page(mapping, pgoff); + #endif + if (page) { + present = PageUptodate(page); +diff --git a/mm/page_alloc.c b/mm/page_alloc.c +index 7b2611a055a7..4b258297cc7c 100644 +--- a/mm/page_alloc.c ++++ b/mm/page_alloc.c +@@ -943,6 +943,7 @@ struct page *__rmqueue_smallest(struct zone *zone, unsigned int order, + rmv_page_order(page); + area->nr_free--; + expand(zone, page, order, current_order, area, migratetype); ++ set_freepage_migratetype(page, migratetype); + return page; + } + +@@ -1069,7 +1070,9 @@ static int try_to_steal_freepages(struct zone *zone, struct page *page, + + /* + * When borrowing from MIGRATE_CMA, we need to release the excess +- * buddy pages to CMA itself. ++ * buddy pages to CMA itself. We also ensure the freepage_migratetype ++ * is set to CMA so it is returned to the correct freelist in case ++ * the page ends up being not actually allocated from the pcp lists. + */ + if (is_migrate_cma(fallback_type)) + return fallback_type; +@@ -1137,6 +1140,12 @@ __rmqueue_fallback(struct zone *zone, int order, int start_migratetype) + + expand(zone, page, order, current_order, area, + new_type); ++ /* The freepage_migratetype may differ from pageblock's ++ * migratetype depending on the decisions in ++ * try_to_steal_freepages. This is OK as long as it does ++ * not differ for MIGRATE_CMA type. ++ */ ++ set_freepage_migratetype(page, new_type); + + trace_mm_page_alloc_extfrag(page, order, current_order, + start_migratetype, migratetype, new_type); +@@ -1187,7 +1196,7 @@ static int rmqueue_bulk(struct zone *zone, unsigned int order, + unsigned long count, struct list_head *list, + int migratetype, int cold) + { +- int mt = migratetype, i; ++ int i; + + spin_lock(&zone->lock); + for (i = 0; i < count; ++i) { +@@ -1208,14 +1217,8 @@ static int rmqueue_bulk(struct zone *zone, unsigned int order, + list_add(&page->lru, list); + else + list_add_tail(&page->lru, list); +- if (IS_ENABLED(CONFIG_CMA)) { +- mt = get_pageblock_migratetype(page); +- if (!is_migrate_cma(mt) && !is_migrate_isolate(mt)) +- mt = migratetype; +- } +- set_freepage_migratetype(page, mt); + list = &page->lru; +- if (is_migrate_cma(mt)) ++ if (is_migrate_cma(get_freepage_migratetype(page))) + __mod_zone_page_state(zone, NR_FREE_CMA_PAGES, + -(1 << order)); + } +@@ -1584,7 +1587,7 @@ again: + if (!page) + goto failed; + __mod_zone_freepage_state(zone, -(1 << order), +- get_pageblock_migratetype(page)); ++ get_freepage_migratetype(page)); + } + + __mod_zone_page_state(zone, NR_ALLOC_BATCH, -(1 << order)); +@@ -2246,7 +2249,7 @@ static struct page * + __alloc_pages_direct_compact(gfp_t gfp_mask, unsigned int order, + struct zonelist *zonelist, enum zone_type high_zoneidx, + nodemask_t *nodemask, int alloc_flags, struct zone *preferred_zone, +- int migratetype, bool sync_migration, ++ int migratetype, enum migrate_mode mode, + bool *contended_compaction, bool *deferred_compaction, + unsigned long *did_some_progress) + { +@@ -2260,7 +2263,7 @@ __alloc_pages_direct_compact(gfp_t gfp_mask, unsigned int order, + + current->flags |= PF_MEMALLOC; + *did_some_progress = try_to_compact_pages(zonelist, order, gfp_mask, +- nodemask, sync_migration, ++ nodemask, mode, + contended_compaction); + current->flags &= ~PF_MEMALLOC; + +@@ -2293,7 +2296,7 @@ __alloc_pages_direct_compact(gfp_t gfp_mask, unsigned int order, + * As async compaction considers a subset of pageblocks, only + * defer if the failure was a sync compaction failure. + */ +- if (sync_migration) ++ if (mode != MIGRATE_ASYNC) + defer_compaction(preferred_zone, order); + + cond_resched(); +@@ -2306,9 +2309,8 @@ static inline struct page * + __alloc_pages_direct_compact(gfp_t gfp_mask, unsigned int order, + struct zonelist *zonelist, enum zone_type high_zoneidx, + nodemask_t *nodemask, int alloc_flags, struct zone *preferred_zone, +- int migratetype, bool sync_migration, +- bool *contended_compaction, bool *deferred_compaction, +- unsigned long *did_some_progress) ++ int migratetype, enum migrate_mode mode, bool *contended_compaction, ++ bool *deferred_compaction, unsigned long *did_some_progress) + { + return NULL; + } +@@ -2503,7 +2505,7 @@ __alloc_pages_slowpath(gfp_t gfp_mask, unsigned int order, + int alloc_flags; + unsigned long pages_reclaimed = 0; + unsigned long did_some_progress; +- bool sync_migration = false; ++ enum migrate_mode migration_mode = MIGRATE_ASYNC; + bool deferred_compaction = false; + bool contended_compaction = false; + +@@ -2597,17 +2599,15 @@ rebalance: + * Try direct compaction. The first pass is asynchronous. Subsequent + * attempts after direct reclaim are synchronous + */ +- page = __alloc_pages_direct_compact(gfp_mask, order, +- zonelist, high_zoneidx, +- nodemask, +- alloc_flags, preferred_zone, +- migratetype, sync_migration, +- &contended_compaction, ++ page = __alloc_pages_direct_compact(gfp_mask, order, zonelist, ++ high_zoneidx, nodemask, alloc_flags, ++ preferred_zone, migratetype, ++ migration_mode, &contended_compaction, + &deferred_compaction, + &did_some_progress); + if (page) + goto got_pg; +- sync_migration = true; ++ migration_mode = MIGRATE_SYNC_LIGHT; + + /* + * If compaction is deferred for high-order allocations, it is because +@@ -2682,12 +2682,10 @@ rebalance: + * direct reclaim and reclaim/compaction depends on compaction + * being called after reclaim so call directly if necessary + */ +- page = __alloc_pages_direct_compact(gfp_mask, order, +- zonelist, high_zoneidx, +- nodemask, +- alloc_flags, preferred_zone, +- migratetype, sync_migration, +- &contended_compaction, ++ page = __alloc_pages_direct_compact(gfp_mask, order, zonelist, ++ high_zoneidx, nodemask, alloc_flags, ++ preferred_zone, migratetype, ++ migration_mode, &contended_compaction, + &deferred_compaction, + &did_some_progress); + if (page) +@@ -6261,7 +6259,7 @@ static int __alloc_contig_migrate_range(struct compact_control *cc, + cc->nr_migratepages -= nr_reclaimed; + + ret = migrate_pages(&cc->migratepages, alloc_migrate_target, +- 0, MIGRATE_SYNC, MR_CMA); ++ NULL, 0, cc->mode, MR_CMA); + } + if (ret < 0) { + putback_movable_pages(&cc->migratepages); +@@ -6300,7 +6298,7 @@ int alloc_contig_range(unsigned long start, unsigned long end, + .nr_migratepages = 0, + .order = -1, + .zone = page_zone(pfn_to_page(start)), +- .sync = true, ++ .mode = MIGRATE_SYNC, + .ignore_skip_hint = true, + }; + INIT_LIST_HEAD(&cc.migratepages); +diff --git a/mm/readahead.c b/mm/readahead.c +index 1fa0d6fca556..0ca36a7770b1 100644 +--- a/mm/readahead.c ++++ b/mm/readahead.c +@@ -8,9 +8,7 @@ + */ + + #include <linux/kernel.h> +-#include <linux/fs.h> + #include <linux/gfp.h> +-#include <linux/mm.h> + #include <linux/export.h> + #include <linux/blkdev.h> + #include <linux/backing-dev.h> +@@ -20,6 +18,8 @@ + #include <linux/syscalls.h> + #include <linux/file.h> + ++#include "internal.h" ++ + /* + * Initialise a struct file's readahead state. Assumes that the caller has + * memset *ra to zero. +@@ -149,8 +149,7 @@ out: + * + * Returns the number of pages requested, or the maximum amount of I/O allowed. + */ +-static int +-__do_page_cache_readahead(struct address_space *mapping, struct file *filp, ++int __do_page_cache_readahead(struct address_space *mapping, struct file *filp, + pgoff_t offset, unsigned long nr_to_read, + unsigned long lookahead_size) + { +@@ -179,7 +178,7 @@ __do_page_cache_readahead(struct address_space *mapping, struct file *filp, + rcu_read_lock(); + page = radix_tree_lookup(&mapping->page_tree, page_offset); + rcu_read_unlock(); +- if (page) ++ if (page && !radix_tree_exceptional_entry(page)) + continue; + + page = page_cache_alloc_readahead(mapping); +@@ -244,20 +243,6 @@ unsigned long max_sane_readahead(unsigned long nr) + } + + /* +- * Submit IO for the read-ahead request in file_ra_state. +- */ +-unsigned long ra_submit(struct file_ra_state *ra, +- struct address_space *mapping, struct file *filp) +-{ +- int actual; +- +- actual = __do_page_cache_readahead(mapping, filp, +- ra->start, ra->size, ra->async_size); +- +- return actual; +-} +- +-/* + * Set the initial window size, round to next power of 2 and square + * for small size, x 4 for medium, and x 2 for large + * for 128k (32 page) max ra +@@ -347,7 +332,7 @@ static pgoff_t count_history_pages(struct address_space *mapping, + pgoff_t head; + + rcu_read_lock(); +- head = radix_tree_prev_hole(&mapping->page_tree, offset - 1, max); ++ head = page_cache_prev_hole(mapping, offset - 1, max); + rcu_read_unlock(); + + return offset - 1 - head; +@@ -427,7 +412,7 @@ ondemand_readahead(struct address_space *mapping, + pgoff_t start; + + rcu_read_lock(); +- start = radix_tree_next_hole(&mapping->page_tree, offset+1,max); ++ start = page_cache_next_hole(mapping, offset + 1, max); + rcu_read_unlock(); + + if (!start || start - offset > max) +diff --git a/mm/shmem.c b/mm/shmem.c +index f0d698ba7d0f..0f1447563f17 100644 +--- a/mm/shmem.c ++++ b/mm/shmem.c +@@ -243,19 +243,17 @@ static int shmem_radix_tree_replace(struct address_space *mapping, + pgoff_t index, void *expected, void *replacement) + { + void **pslot; +- void *item = NULL; ++ void *item; + + VM_BUG_ON(!expected); ++ VM_BUG_ON(!replacement); + pslot = radix_tree_lookup_slot(&mapping->page_tree, index); +- if (pslot) +- item = radix_tree_deref_slot_protected(pslot, +- &mapping->tree_lock); ++ if (!pslot) ++ return -ENOENT; ++ item = radix_tree_deref_slot_protected(pslot, &mapping->tree_lock); + if (item != expected) + return -ENOENT; +- if (replacement) +- radix_tree_replace_slot(pslot, replacement); +- else +- radix_tree_delete(&mapping->page_tree, index); ++ radix_tree_replace_slot(pslot, replacement); + return 0; + } + +@@ -332,84 +330,20 @@ static void shmem_delete_from_page_cache(struct page *page, void *radswap) + } + + /* +- * Like find_get_pages, but collecting swap entries as well as pages. +- */ +-static unsigned shmem_find_get_pages_and_swap(struct address_space *mapping, +- pgoff_t start, unsigned int nr_pages, +- struct page **pages, pgoff_t *indices) +-{ +- void **slot; +- unsigned int ret = 0; +- struct radix_tree_iter iter; +- +- if (!nr_pages) +- return 0; +- +- rcu_read_lock(); +-restart: +- radix_tree_for_each_slot(slot, &mapping->page_tree, &iter, start) { +- struct page *page; +-repeat: +- page = radix_tree_deref_slot(slot); +- if (unlikely(!page)) +- continue; +- if (radix_tree_exception(page)) { +- if (radix_tree_deref_retry(page)) +- goto restart; +- /* +- * Otherwise, we must be storing a swap entry +- * here as an exceptional entry: so return it +- * without attempting to raise page count. +- */ +- goto export; +- } +- if (!page_cache_get_speculative(page)) +- goto repeat; +- +- /* Has the page moved? */ +- if (unlikely(page != *slot)) { +- page_cache_release(page); +- goto repeat; +- } +-export: +- indices[ret] = iter.index; +- pages[ret] = page; +- if (++ret == nr_pages) +- break; +- } +- rcu_read_unlock(); +- return ret; +-} +- +-/* + * Remove swap entry from radix tree, free the swap and its page cache. + */ + static int shmem_free_swap(struct address_space *mapping, + pgoff_t index, void *radswap) + { +- int error; ++ void *old; + + spin_lock_irq(&mapping->tree_lock); +- error = shmem_radix_tree_replace(mapping, index, radswap, NULL); ++ old = radix_tree_delete_item(&mapping->page_tree, index, radswap); + spin_unlock_irq(&mapping->tree_lock); +- if (!error) +- free_swap_and_cache(radix_to_swp_entry(radswap)); +- return error; +-} +- +-/* +- * Pagevec may contain swap entries, so shuffle up pages before releasing. +- */ +-static void shmem_deswap_pagevec(struct pagevec *pvec) +-{ +- int i, j; +- +- for (i = 0, j = 0; i < pagevec_count(pvec); i++) { +- struct page *page = pvec->pages[i]; +- if (!radix_tree_exceptional_entry(page)) +- pvec->pages[j++] = page; +- } +- pvec->nr = j; ++ if (old != radswap) ++ return -ENOENT; ++ free_swap_and_cache(radix_to_swp_entry(radswap)); ++ return 0; + } + + /* +@@ -430,12 +364,12 @@ void shmem_unlock_mapping(struct address_space *mapping) + * Avoid pagevec_lookup(): find_get_pages() returns 0 as if it + * has finished, if it hits a row of PAGEVEC_SIZE swap entries. + */ +- pvec.nr = shmem_find_get_pages_and_swap(mapping, index, +- PAGEVEC_SIZE, pvec.pages, indices); ++ pvec.nr = find_get_entries(mapping, index, ++ PAGEVEC_SIZE, pvec.pages, indices); + if (!pvec.nr) + break; + index = indices[pvec.nr - 1] + 1; +- shmem_deswap_pagevec(&pvec); ++ pagevec_remove_exceptionals(&pvec); + check_move_unevictable_pages(pvec.pages, pvec.nr); + pagevec_release(&pvec); + cond_resched(); +@@ -467,9 +401,9 @@ static void shmem_undo_range(struct inode *inode, loff_t lstart, loff_t lend, + pagevec_init(&pvec, 0); + index = start; + while (index < end) { +- pvec.nr = shmem_find_get_pages_and_swap(mapping, index, +- min(end - index, (pgoff_t)PAGEVEC_SIZE), +- pvec.pages, indices); ++ pvec.nr = find_get_entries(mapping, index, ++ min(end - index, (pgoff_t)PAGEVEC_SIZE), ++ pvec.pages, indices); + if (!pvec.nr) + break; + mem_cgroup_uncharge_start(); +@@ -498,7 +432,7 @@ static void shmem_undo_range(struct inode *inode, loff_t lstart, loff_t lend, + } + unlock_page(page); + } +- shmem_deswap_pagevec(&pvec); ++ pagevec_remove_exceptionals(&pvec); + pagevec_release(&pvec); + mem_cgroup_uncharge_end(); + cond_resched(); +@@ -536,9 +470,10 @@ static void shmem_undo_range(struct inode *inode, loff_t lstart, loff_t lend, + index = start; + while (index < end) { + cond_resched(); +- pvec.nr = shmem_find_get_pages_and_swap(mapping, index, ++ ++ pvec.nr = find_get_entries(mapping, index, + min(end - index, (pgoff_t)PAGEVEC_SIZE), +- pvec.pages, indices); ++ pvec.pages, indices); + if (!pvec.nr) { + /* If all gone or hole-punch or unfalloc, we're done */ + if (index == start || end != -1) +@@ -581,7 +516,7 @@ static void shmem_undo_range(struct inode *inode, loff_t lstart, loff_t lend, + } + unlock_page(page); + } +- shmem_deswap_pagevec(&pvec); ++ pagevec_remove_exceptionals(&pvec); + pagevec_release(&pvec); + mem_cgroup_uncharge_end(); + index++; +@@ -1088,7 +1023,7 @@ static int shmem_getpage_gfp(struct inode *inode, pgoff_t index, + return -EFBIG; + repeat: + swap.val = 0; +- page = find_lock_page(mapping, index); ++ page = find_lock_entry(mapping, index); + if (radix_tree_exceptional_entry(page)) { + swap = radix_to_swp_entry(page); + page = NULL; +@@ -1483,6 +1418,11 @@ static struct inode *shmem_get_inode(struct super_block *sb, const struct inode + return inode; + } + ++bool shmem_mapping(struct address_space *mapping) ++{ ++ return mapping->backing_dev_info == &shmem_backing_dev_info; ++} ++ + #ifdef CONFIG_TMPFS + static const struct inode_operations shmem_symlink_inode_operations; + static const struct inode_operations shmem_short_symlink_operations; +@@ -1795,7 +1735,7 @@ static pgoff_t shmem_seek_hole_data(struct address_space *mapping, + pagevec_init(&pvec, 0); + pvec.nr = 1; /* start small: we may be there already */ + while (!done) { +- pvec.nr = shmem_find_get_pages_and_swap(mapping, index, ++ pvec.nr = find_get_entries(mapping, index, + pvec.nr, pvec.pages, indices); + if (!pvec.nr) { + if (whence == SEEK_DATA) +@@ -1822,7 +1762,7 @@ static pgoff_t shmem_seek_hole_data(struct address_space *mapping, + break; + } + } +- shmem_deswap_pagevec(&pvec); ++ pagevec_remove_exceptionals(&pvec); + pagevec_release(&pvec); + pvec.nr = PAGEVEC_SIZE; + cond_resched(); +diff --git a/mm/swap.c b/mm/swap.c +index 0092097b3f4c..c8048d71c642 100644 +--- a/mm/swap.c ++++ b/mm/swap.c +@@ -948,6 +948,57 @@ void __pagevec_lru_add(struct pagevec *pvec) + EXPORT_SYMBOL(__pagevec_lru_add); + + /** ++ * pagevec_lookup_entries - gang pagecache lookup ++ * @pvec: Where the resulting entries are placed ++ * @mapping: The address_space to search ++ * @start: The starting entry index ++ * @nr_entries: The maximum number of entries ++ * @indices: The cache indices corresponding to the entries in @pvec ++ * ++ * pagevec_lookup_entries() will search for and return a group of up ++ * to @nr_entries pages and shadow entries in the mapping. All ++ * entries are placed in @pvec. pagevec_lookup_entries() takes a ++ * reference against actual pages in @pvec. ++ * ++ * The search returns a group of mapping-contiguous entries with ++ * ascending indexes. There may be holes in the indices due to ++ * not-present entries. ++ * ++ * pagevec_lookup_entries() returns the number of entries which were ++ * found. ++ */ ++unsigned pagevec_lookup_entries(struct pagevec *pvec, ++ struct address_space *mapping, ++ pgoff_t start, unsigned nr_pages, ++ pgoff_t *indices) ++{ ++ pvec->nr = find_get_entries(mapping, start, nr_pages, ++ pvec->pages, indices); ++ return pagevec_count(pvec); ++} ++ ++/** ++ * pagevec_remove_exceptionals - pagevec exceptionals pruning ++ * @pvec: The pagevec to prune ++ * ++ * pagevec_lookup_entries() fills both pages and exceptional radix ++ * tree entries into the pagevec. This function prunes all ++ * exceptionals from @pvec without leaving holes, so that it can be ++ * passed on to page-only pagevec operations. ++ */ ++void pagevec_remove_exceptionals(struct pagevec *pvec) ++{ ++ int i, j; ++ ++ for (i = 0, j = 0; i < pagevec_count(pvec); i++) { ++ struct page *page = pvec->pages[i]; ++ if (!radix_tree_exceptional_entry(page)) ++ pvec->pages[j++] = page; ++ } ++ pvec->nr = j; ++} ++ ++/** + * pagevec_lookup - gang pagecache lookup + * @pvec: Where the resulting pages are placed + * @mapping: The address_space to search +diff --git a/mm/truncate.c b/mm/truncate.c +index ac18edc30649..827ad8d2b5cd 100644 +--- a/mm/truncate.c ++++ b/mm/truncate.c +@@ -23,6 +23,22 @@ + #include <linux/rmap.h> + #include "internal.h" + ++static void clear_exceptional_entry(struct address_space *mapping, ++ pgoff_t index, void *entry) ++{ ++ /* Handled by shmem itself */ ++ if (shmem_mapping(mapping)) ++ return; ++ ++ spin_lock_irq(&mapping->tree_lock); ++ /* ++ * Regular page slots are stabilized by the page lock even ++ * without the tree itself locked. These unlocked entries ++ * need verification under the tree lock. ++ */ ++ radix_tree_delete_item(&mapping->page_tree, index, entry); ++ spin_unlock_irq(&mapping->tree_lock); ++} + + /** + * do_invalidatepage - invalidate part or all of a page +@@ -209,6 +225,7 @@ void truncate_inode_pages_range(struct address_space *mapping, + unsigned int partial_start; /* inclusive */ + unsigned int partial_end; /* exclusive */ + struct pagevec pvec; ++ pgoff_t indices[PAGEVEC_SIZE]; + pgoff_t index; + int i; + +@@ -239,17 +256,23 @@ void truncate_inode_pages_range(struct address_space *mapping, + + pagevec_init(&pvec, 0); + index = start; +- while (index < end && pagevec_lookup(&pvec, mapping, index, +- min(end - index, (pgoff_t)PAGEVEC_SIZE))) { ++ while (index < end && pagevec_lookup_entries(&pvec, mapping, index, ++ min(end - index, (pgoff_t)PAGEVEC_SIZE), ++ indices)) { + mem_cgroup_uncharge_start(); + for (i = 0; i < pagevec_count(&pvec); i++) { + struct page *page = pvec.pages[i]; + + /* We rely upon deletion not changing page->index */ +- index = page->index; ++ index = indices[i]; + if (index >= end) + break; + ++ if (radix_tree_exceptional_entry(page)) { ++ clear_exceptional_entry(mapping, index, page); ++ continue; ++ } ++ + if (!trylock_page(page)) + continue; + WARN_ON(page->index != index); +@@ -260,6 +283,7 @@ void truncate_inode_pages_range(struct address_space *mapping, + truncate_inode_page(mapping, page); + unlock_page(page); + } ++ pagevec_remove_exceptionals(&pvec); + pagevec_release(&pvec); + mem_cgroup_uncharge_end(); + cond_resched(); +@@ -308,14 +332,16 @@ void truncate_inode_pages_range(struct address_space *mapping, + index = start; + for ( ; ; ) { + cond_resched(); +- if (!pagevec_lookup(&pvec, mapping, index, +- min(end - index, (pgoff_t)PAGEVEC_SIZE))) { ++ if (!pagevec_lookup_entries(&pvec, mapping, index, ++ min(end - index, (pgoff_t)PAGEVEC_SIZE), ++ indices)) { + if (index == start) + break; + index = start; + continue; + } +- if (index == start && pvec.pages[0]->index >= end) { ++ if (index == start && indices[0] >= end) { ++ pagevec_remove_exceptionals(&pvec); + pagevec_release(&pvec); + break; + } +@@ -324,16 +350,22 @@ void truncate_inode_pages_range(struct address_space *mapping, + struct page *page = pvec.pages[i]; + + /* We rely upon deletion not changing page->index */ +- index = page->index; ++ index = indices[i]; + if (index >= end) + break; + ++ if (radix_tree_exceptional_entry(page)) { ++ clear_exceptional_entry(mapping, index, page); ++ continue; ++ } ++ + lock_page(page); + WARN_ON(page->index != index); + wait_on_page_writeback(page); + truncate_inode_page(mapping, page); + unlock_page(page); + } ++ pagevec_remove_exceptionals(&pvec); + pagevec_release(&pvec); + mem_cgroup_uncharge_end(); + index++; +@@ -376,6 +408,7 @@ EXPORT_SYMBOL(truncate_inode_pages); + unsigned long invalidate_mapping_pages(struct address_space *mapping, + pgoff_t start, pgoff_t end) + { ++ pgoff_t indices[PAGEVEC_SIZE]; + struct pagevec pvec; + pgoff_t index = start; + unsigned long ret; +@@ -391,17 +424,23 @@ unsigned long invalidate_mapping_pages(struct address_space *mapping, + */ + + pagevec_init(&pvec, 0); +- while (index <= end && pagevec_lookup(&pvec, mapping, index, +- min(end - index, (pgoff_t)PAGEVEC_SIZE - 1) + 1)) { ++ while (index <= end && pagevec_lookup_entries(&pvec, mapping, index, ++ min(end - index, (pgoff_t)PAGEVEC_SIZE - 1) + 1, ++ indices)) { + mem_cgroup_uncharge_start(); + for (i = 0; i < pagevec_count(&pvec); i++) { + struct page *page = pvec.pages[i]; + + /* We rely upon deletion not changing page->index */ +- index = page->index; ++ index = indices[i]; + if (index > end) + break; + ++ if (radix_tree_exceptional_entry(page)) { ++ clear_exceptional_entry(mapping, index, page); ++ continue; ++ } ++ + if (!trylock_page(page)) + continue; + WARN_ON(page->index != index); +@@ -415,6 +454,7 @@ unsigned long invalidate_mapping_pages(struct address_space *mapping, + deactivate_page(page); + count += ret; + } ++ pagevec_remove_exceptionals(&pvec); + pagevec_release(&pvec); + mem_cgroup_uncharge_end(); + cond_resched(); +@@ -482,6 +522,7 @@ static int do_launder_page(struct address_space *mapping, struct page *page) + int invalidate_inode_pages2_range(struct address_space *mapping, + pgoff_t start, pgoff_t end) + { ++ pgoff_t indices[PAGEVEC_SIZE]; + struct pagevec pvec; + pgoff_t index; + int i; +@@ -492,17 +533,23 @@ int invalidate_inode_pages2_range(struct address_space *mapping, + cleancache_invalidate_inode(mapping); + pagevec_init(&pvec, 0); + index = start; +- while (index <= end && pagevec_lookup(&pvec, mapping, index, +- min(end - index, (pgoff_t)PAGEVEC_SIZE - 1) + 1)) { ++ while (index <= end && pagevec_lookup_entries(&pvec, mapping, index, ++ min(end - index, (pgoff_t)PAGEVEC_SIZE - 1) + 1, ++ indices)) { + mem_cgroup_uncharge_start(); + for (i = 0; i < pagevec_count(&pvec); i++) { + struct page *page = pvec.pages[i]; + + /* We rely upon deletion not changing page->index */ +- index = page->index; ++ index = indices[i]; + if (index > end) + break; + ++ if (radix_tree_exceptional_entry(page)) { ++ clear_exceptional_entry(mapping, index, page); ++ continue; ++ } ++ + lock_page(page); + WARN_ON(page->index != index); + if (page->mapping != mapping) { +@@ -540,6 +587,7 @@ int invalidate_inode_pages2_range(struct address_space *mapping, + ret = ret2; + unlock_page(page); + } ++ pagevec_remove_exceptionals(&pvec); + pagevec_release(&pvec); + mem_cgroup_uncharge_end(); + cond_resched(); +diff --git a/mm/vmscan.c b/mm/vmscan.c +index 0c0b36e5b4f8..deb139e6b8ed 100644 +--- a/mm/vmscan.c ++++ b/mm/vmscan.c +@@ -2018,13 +2018,27 @@ static void shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc) + unsigned long nr_reclaimed = 0; + unsigned long nr_to_reclaim = sc->nr_to_reclaim; + struct blk_plug plug; +- bool scan_adjusted = false; ++ bool scan_adjusted; + + get_scan_count(lruvec, sc, nr); + + /* Record the original scan target for proportional adjustments later */ + memcpy(targets, nr, sizeof(nr)); + ++ /* ++ * Global reclaiming within direct reclaim at DEF_PRIORITY is a normal ++ * event that can occur when there is little memory pressure e.g. ++ * multiple streaming readers/writers. Hence, we do not abort scanning ++ * when the requested number of pages are reclaimed when scanning at ++ * DEF_PRIORITY on the assumption that the fact we are direct ++ * reclaiming implies that kswapd is not keeping up and it is best to ++ * do a batch of work at once. For memcg reclaim one check is made to ++ * abort proportional reclaim if either the file or anon lru has already ++ * dropped to zero at the first pass. ++ */ ++ scan_adjusted = (global_reclaim(sc) && !current_is_kswapd() && ++ sc->priority == DEF_PRIORITY); ++ + blk_start_plug(&plug); + while (nr[LRU_INACTIVE_ANON] || nr[LRU_ACTIVE_FILE] || + nr[LRU_INACTIVE_FILE]) { +@@ -2045,17 +2059,8 @@ static void shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc) + continue; + + /* +- * For global direct reclaim, reclaim only the number of pages +- * requested. Less care is taken to scan proportionally as it +- * is more important to minimise direct reclaim stall latency +- * than it is to properly age the LRU lists. +- */ +- if (global_reclaim(sc) && !current_is_kswapd()) +- break; +- +- /* + * For kswapd and memcg, reclaim at least the number of pages +- * requested. Ensure that the anon and file LRUs shrink ++ * requested. Ensure that the anon and file LRUs are scanned + * proportionally what was requested by get_scan_count(). We + * stop reclaiming one LRU and reduce the amount scanning + * proportional to the original scan target. +@@ -2063,6 +2068,15 @@ static void shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc) + nr_file = nr[LRU_INACTIVE_FILE] + nr[LRU_ACTIVE_FILE]; + nr_anon = nr[LRU_INACTIVE_ANON] + nr[LRU_ACTIVE_ANON]; + ++ /* ++ * It's just vindictive to attack the larger once the smaller ++ * has gone to zero. And given the way we stop scanning the ++ * smaller below, this makes sure that we only make one nudge ++ * towards proportionality once we've got nr_to_reclaim. ++ */ ++ if (!nr_file || !nr_anon) ++ break; ++ + if (nr_file > nr_anon) { + unsigned long scan_target = targets[LRU_INACTIVE_ANON] + + targets[LRU_ACTIVE_ANON] + 1; +diff --git a/net/ceph/crypto.c b/net/ceph/crypto.c +index 6e7a236525b6..06f19b9e159a 100644 +--- a/net/ceph/crypto.c ++++ b/net/ceph/crypto.c +@@ -89,11 +89,82 @@ static struct crypto_blkcipher *ceph_crypto_alloc_cipher(void) + + static const u8 *aes_iv = (u8 *)CEPH_AES_IV; + ++/* ++ * Should be used for buffers allocated with ceph_kvmalloc(). ++ * Currently these are encrypt out-buffer (ceph_buffer) and decrypt ++ * in-buffer (msg front). ++ * ++ * Dispose of @sgt with teardown_sgtable(). ++ * ++ * @prealloc_sg is to avoid memory allocation inside sg_alloc_table() ++ * in cases where a single sg is sufficient. No attempt to reduce the ++ * number of sgs by squeezing physically contiguous pages together is ++ * made though, for simplicity. ++ */ ++static int setup_sgtable(struct sg_table *sgt, struct scatterlist *prealloc_sg, ++ const void *buf, unsigned int buf_len) ++{ ++ struct scatterlist *sg; ++ const bool is_vmalloc = is_vmalloc_addr(buf); ++ unsigned int off = offset_in_page(buf); ++ unsigned int chunk_cnt = 1; ++ unsigned int chunk_len = PAGE_ALIGN(off + buf_len); ++ int i; ++ int ret; ++ ++ if (buf_len == 0) { ++ memset(sgt, 0, sizeof(*sgt)); ++ return -EINVAL; ++ } ++ ++ if (is_vmalloc) { ++ chunk_cnt = chunk_len >> PAGE_SHIFT; ++ chunk_len = PAGE_SIZE; ++ } ++ ++ if (chunk_cnt > 1) { ++ ret = sg_alloc_table(sgt, chunk_cnt, GFP_NOFS); ++ if (ret) ++ return ret; ++ } else { ++ WARN_ON(chunk_cnt != 1); ++ sg_init_table(prealloc_sg, 1); ++ sgt->sgl = prealloc_sg; ++ sgt->nents = sgt->orig_nents = 1; ++ } ++ ++ for_each_sg(sgt->sgl, sg, sgt->orig_nents, i) { ++ struct page *page; ++ unsigned int len = min(chunk_len - off, buf_len); ++ ++ if (is_vmalloc) ++ page = vmalloc_to_page(buf); ++ else ++ page = virt_to_page(buf); ++ ++ sg_set_page(sg, page, len, off); ++ ++ off = 0; ++ buf += len; ++ buf_len -= len; ++ } ++ WARN_ON(buf_len != 0); ++ ++ return 0; ++} ++ ++static void teardown_sgtable(struct sg_table *sgt) ++{ ++ if (sgt->orig_nents > 1) ++ sg_free_table(sgt); ++} ++ + static int ceph_aes_encrypt(const void *key, int key_len, + void *dst, size_t *dst_len, + const void *src, size_t src_len) + { +- struct scatterlist sg_in[2], sg_out[1]; ++ struct scatterlist sg_in[2], prealloc_sg; ++ struct sg_table sg_out; + struct crypto_blkcipher *tfm = ceph_crypto_alloc_cipher(); + struct blkcipher_desc desc = { .tfm = tfm, .flags = 0 }; + int ret; +@@ -109,16 +180,18 @@ static int ceph_aes_encrypt(const void *key, int key_len, + + *dst_len = src_len + zero_padding; + +- crypto_blkcipher_setkey((void *)tfm, key, key_len); + sg_init_table(sg_in, 2); + sg_set_buf(&sg_in[0], src, src_len); + sg_set_buf(&sg_in[1], pad, zero_padding); +- sg_init_table(sg_out, 1); +- sg_set_buf(sg_out, dst, *dst_len); ++ ret = setup_sgtable(&sg_out, &prealloc_sg, dst, *dst_len); ++ if (ret) ++ goto out_tfm; ++ ++ crypto_blkcipher_setkey((void *)tfm, key, key_len); + iv = crypto_blkcipher_crt(tfm)->iv; + ivsize = crypto_blkcipher_ivsize(tfm); +- + memcpy(iv, aes_iv, ivsize); ++ + /* + print_hex_dump(KERN_ERR, "enc key: ", DUMP_PREFIX_NONE, 16, 1, + key, key_len, 1); +@@ -127,16 +200,22 @@ static int ceph_aes_encrypt(const void *key, int key_len, + print_hex_dump(KERN_ERR, "enc pad: ", DUMP_PREFIX_NONE, 16, 1, + pad, zero_padding, 1); + */ +- ret = crypto_blkcipher_encrypt(&desc, sg_out, sg_in, ++ ret = crypto_blkcipher_encrypt(&desc, sg_out.sgl, sg_in, + src_len + zero_padding); +- crypto_free_blkcipher(tfm); +- if (ret < 0) ++ if (ret < 0) { + pr_err("ceph_aes_crypt failed %d\n", ret); ++ goto out_sg; ++ } + /* + print_hex_dump(KERN_ERR, "enc out: ", DUMP_PREFIX_NONE, 16, 1, + dst, *dst_len, 1); + */ +- return 0; ++ ++out_sg: ++ teardown_sgtable(&sg_out); ++out_tfm: ++ crypto_free_blkcipher(tfm); ++ return ret; + } + + static int ceph_aes_encrypt2(const void *key, int key_len, void *dst, +@@ -144,7 +223,8 @@ static int ceph_aes_encrypt2(const void *key, int key_len, void *dst, + const void *src1, size_t src1_len, + const void *src2, size_t src2_len) + { +- struct scatterlist sg_in[3], sg_out[1]; ++ struct scatterlist sg_in[3], prealloc_sg; ++ struct sg_table sg_out; + struct crypto_blkcipher *tfm = ceph_crypto_alloc_cipher(); + struct blkcipher_desc desc = { .tfm = tfm, .flags = 0 }; + int ret; +@@ -160,17 +240,19 @@ static int ceph_aes_encrypt2(const void *key, int key_len, void *dst, + + *dst_len = src1_len + src2_len + zero_padding; + +- crypto_blkcipher_setkey((void *)tfm, key, key_len); + sg_init_table(sg_in, 3); + sg_set_buf(&sg_in[0], src1, src1_len); + sg_set_buf(&sg_in[1], src2, src2_len); + sg_set_buf(&sg_in[2], pad, zero_padding); +- sg_init_table(sg_out, 1); +- sg_set_buf(sg_out, dst, *dst_len); ++ ret = setup_sgtable(&sg_out, &prealloc_sg, dst, *dst_len); ++ if (ret) ++ goto out_tfm; ++ ++ crypto_blkcipher_setkey((void *)tfm, key, key_len); + iv = crypto_blkcipher_crt(tfm)->iv; + ivsize = crypto_blkcipher_ivsize(tfm); +- + memcpy(iv, aes_iv, ivsize); ++ + /* + print_hex_dump(KERN_ERR, "enc key: ", DUMP_PREFIX_NONE, 16, 1, + key, key_len, 1); +@@ -181,23 +263,30 @@ static int ceph_aes_encrypt2(const void *key, int key_len, void *dst, + print_hex_dump(KERN_ERR, "enc pad: ", DUMP_PREFIX_NONE, 16, 1, + pad, zero_padding, 1); + */ +- ret = crypto_blkcipher_encrypt(&desc, sg_out, sg_in, ++ ret = crypto_blkcipher_encrypt(&desc, sg_out.sgl, sg_in, + src1_len + src2_len + zero_padding); +- crypto_free_blkcipher(tfm); +- if (ret < 0) ++ if (ret < 0) { + pr_err("ceph_aes_crypt2 failed %d\n", ret); ++ goto out_sg; ++ } + /* + print_hex_dump(KERN_ERR, "enc out: ", DUMP_PREFIX_NONE, 16, 1, + dst, *dst_len, 1); + */ +- return 0; ++ ++out_sg: ++ teardown_sgtable(&sg_out); ++out_tfm: ++ crypto_free_blkcipher(tfm); ++ return ret; + } + + static int ceph_aes_decrypt(const void *key, int key_len, + void *dst, size_t *dst_len, + const void *src, size_t src_len) + { +- struct scatterlist sg_in[1], sg_out[2]; ++ struct sg_table sg_in; ++ struct scatterlist sg_out[2], prealloc_sg; + struct crypto_blkcipher *tfm = ceph_crypto_alloc_cipher(); + struct blkcipher_desc desc = { .tfm = tfm }; + char pad[16]; +@@ -209,16 +298,16 @@ static int ceph_aes_decrypt(const void *key, int key_len, + if (IS_ERR(tfm)) + return PTR_ERR(tfm); + +- crypto_blkcipher_setkey((void *)tfm, key, key_len); +- sg_init_table(sg_in, 1); + sg_init_table(sg_out, 2); +- sg_set_buf(sg_in, src, src_len); + sg_set_buf(&sg_out[0], dst, *dst_len); + sg_set_buf(&sg_out[1], pad, sizeof(pad)); ++ ret = setup_sgtable(&sg_in, &prealloc_sg, src, src_len); ++ if (ret) ++ goto out_tfm; + ++ crypto_blkcipher_setkey((void *)tfm, key, key_len); + iv = crypto_blkcipher_crt(tfm)->iv; + ivsize = crypto_blkcipher_ivsize(tfm); +- + memcpy(iv, aes_iv, ivsize); + + /* +@@ -227,12 +316,10 @@ static int ceph_aes_decrypt(const void *key, int key_len, + print_hex_dump(KERN_ERR, "dec in: ", DUMP_PREFIX_NONE, 16, 1, + src, src_len, 1); + */ +- +- ret = crypto_blkcipher_decrypt(&desc, sg_out, sg_in, src_len); +- crypto_free_blkcipher(tfm); ++ ret = crypto_blkcipher_decrypt(&desc, sg_out, sg_in.sgl, src_len); + if (ret < 0) { + pr_err("ceph_aes_decrypt failed %d\n", ret); +- return ret; ++ goto out_sg; + } + + if (src_len <= *dst_len) +@@ -250,7 +337,12 @@ static int ceph_aes_decrypt(const void *key, int key_len, + print_hex_dump(KERN_ERR, "dec out: ", DUMP_PREFIX_NONE, 16, 1, + dst, *dst_len, 1); + */ +- return 0; ++ ++out_sg: ++ teardown_sgtable(&sg_in); ++out_tfm: ++ crypto_free_blkcipher(tfm); ++ return ret; + } + + static int ceph_aes_decrypt2(const void *key, int key_len, +@@ -258,7 +350,8 @@ static int ceph_aes_decrypt2(const void *key, int key_len, + void *dst2, size_t *dst2_len, + const void *src, size_t src_len) + { +- struct scatterlist sg_in[1], sg_out[3]; ++ struct sg_table sg_in; ++ struct scatterlist sg_out[3], prealloc_sg; + struct crypto_blkcipher *tfm = ceph_crypto_alloc_cipher(); + struct blkcipher_desc desc = { .tfm = tfm }; + char pad[16]; +@@ -270,17 +363,17 @@ static int ceph_aes_decrypt2(const void *key, int key_len, + if (IS_ERR(tfm)) + return PTR_ERR(tfm); + +- sg_init_table(sg_in, 1); +- sg_set_buf(sg_in, src, src_len); + sg_init_table(sg_out, 3); + sg_set_buf(&sg_out[0], dst1, *dst1_len); + sg_set_buf(&sg_out[1], dst2, *dst2_len); + sg_set_buf(&sg_out[2], pad, sizeof(pad)); ++ ret = setup_sgtable(&sg_in, &prealloc_sg, src, src_len); ++ if (ret) ++ goto out_tfm; + + crypto_blkcipher_setkey((void *)tfm, key, key_len); + iv = crypto_blkcipher_crt(tfm)->iv; + ivsize = crypto_blkcipher_ivsize(tfm); +- + memcpy(iv, aes_iv, ivsize); + + /* +@@ -289,12 +382,10 @@ static int ceph_aes_decrypt2(const void *key, int key_len, + print_hex_dump(KERN_ERR, "dec in: ", DUMP_PREFIX_NONE, 16, 1, + src, src_len, 1); + */ +- +- ret = crypto_blkcipher_decrypt(&desc, sg_out, sg_in, src_len); +- crypto_free_blkcipher(tfm); ++ ret = crypto_blkcipher_decrypt(&desc, sg_out, sg_in.sgl, src_len); + if (ret < 0) { + pr_err("ceph_aes_decrypt failed %d\n", ret); +- return ret; ++ goto out_sg; + } + + if (src_len <= *dst1_len) +@@ -324,7 +415,11 @@ static int ceph_aes_decrypt2(const void *key, int key_len, + dst2, *dst2_len, 1); + */ + +- return 0; ++out_sg: ++ teardown_sgtable(&sg_in); ++out_tfm: ++ crypto_free_blkcipher(tfm); ++ return ret; + } + + +diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c +index cb57aa862177..b27f6d34762b 100644 +--- a/net/ipv6/ip6_gre.c ++++ b/net/ipv6/ip6_gre.c +@@ -962,8 +962,6 @@ static void ip6gre_tnl_link_config(struct ip6_tnl *t, int set_mtu) + else + dev->flags &= ~IFF_POINTOPOINT; + +- dev->iflink = p->link; +- + /* Precalculate GRE options length */ + if (t->parms.o_flags&(GRE_CSUM|GRE_KEY|GRE_SEQ)) { + if (t->parms.o_flags&GRE_CSUM) +@@ -1273,6 +1271,7 @@ static int ip6gre_tunnel_init(struct net_device *dev) + u64_stats_init(&ip6gre_tunnel_stats->syncp); + } + ++ dev->iflink = tunnel->parms.link; + + return 0; + } +@@ -1474,6 +1473,8 @@ static int ip6gre_tap_init(struct net_device *dev) + u64_stats_init(&ip6gre_tap_stats->syncp); + } + ++ dev->iflink = tunnel->parms.link; ++ + return 0; + } + +diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c +index 912033957ad3..657639d39f70 100644 +--- a/net/ipv6/ip6_tunnel.c ++++ b/net/ipv6/ip6_tunnel.c +@@ -272,9 +272,6 @@ static int ip6_tnl_create2(struct net_device *dev) + int err; + + t = netdev_priv(dev); +- err = ip6_tnl_dev_init(dev); +- if (err < 0) +- goto out; + + err = register_netdevice(dev); + if (err < 0) +@@ -1456,6 +1453,7 @@ ip6_tnl_change_mtu(struct net_device *dev, int new_mtu) + + + static const struct net_device_ops ip6_tnl_netdev_ops = { ++ .ndo_init = ip6_tnl_dev_init, + .ndo_uninit = ip6_tnl_dev_uninit, + .ndo_start_xmit = ip6_tnl_xmit, + .ndo_do_ioctl = ip6_tnl_ioctl, +@@ -1547,16 +1545,10 @@ static int __net_init ip6_fb_tnl_dev_init(struct net_device *dev) + struct ip6_tnl *t = netdev_priv(dev); + struct net *net = dev_net(dev); + struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id); +- int err = ip6_tnl_dev_init_gen(dev); +- +- if (err) +- return err; + + t->parms.proto = IPPROTO_IPV6; + dev_hold(dev); + +- ip6_tnl_link_config(t); +- + rcu_assign_pointer(ip6n->tnls_wc[0], t); + return 0; + } +diff --git a/net/ipv6/ip6_vti.c b/net/ipv6/ip6_vti.c +index 2d19272b8cee..9a5339fcb450 100644 +--- a/net/ipv6/ip6_vti.c ++++ b/net/ipv6/ip6_vti.c +@@ -172,10 +172,6 @@ static int vti6_tnl_create2(struct net_device *dev) + struct vti6_net *ip6n = net_generic(net, vti6_net_id); + int err; + +- err = vti6_dev_init(dev); +- if (err < 0) +- goto out; +- + err = register_netdevice(dev); + if (err < 0) + goto out; +@@ -693,6 +689,7 @@ static int vti6_change_mtu(struct net_device *dev, int new_mtu) + } + + static const struct net_device_ops vti6_netdev_ops = { ++ .ndo_init = vti6_dev_init, + .ndo_uninit = vti6_dev_uninit, + .ndo_start_xmit = vti6_tnl_xmit, + .ndo_do_ioctl = vti6_ioctl, +@@ -772,16 +769,10 @@ static int __net_init vti6_fb_tnl_dev_init(struct net_device *dev) + struct ip6_tnl *t = netdev_priv(dev); + struct net *net = dev_net(dev); + struct vti6_net *ip6n = net_generic(net, vti6_net_id); +- int err = vti6_dev_init_gen(dev); +- +- if (err) +- return err; + + t->parms.proto = IPPROTO_IPV6; + dev_hold(dev); + +- vti6_link_config(t); +- + rcu_assign_pointer(ip6n->tnls_wc[0], t); + return 0; + } +diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c +index b12b11b123ff..317b6dbf3190 100644 +--- a/net/ipv6/sit.c ++++ b/net/ipv6/sit.c +@@ -195,10 +195,8 @@ static int ipip6_tunnel_create(struct net_device *dev) + struct sit_net *sitn = net_generic(net, sit_net_id); + int err; + +- err = ipip6_tunnel_init(dev); +- if (err < 0) +- goto out; +- ipip6_tunnel_clone_6rd(dev, sitn); ++ memcpy(dev->dev_addr, &t->parms.iph.saddr, 4); ++ memcpy(dev->broadcast, &t->parms.iph.daddr, 4); + + if ((__force u16)t->parms.i_flags & SIT_ISATAP) + dev->priv_flags |= IFF_ISATAP; +@@ -207,7 +205,8 @@ static int ipip6_tunnel_create(struct net_device *dev) + if (err < 0) + goto out; + +- strcpy(t->parms.name, dev->name); ++ ipip6_tunnel_clone_6rd(dev, sitn); ++ + dev->rtnl_link_ops = &sit_link_ops; + + dev_hold(dev); +@@ -1321,6 +1320,7 @@ static int ipip6_tunnel_change_mtu(struct net_device *dev, int new_mtu) + } + + static const struct net_device_ops ipip6_netdev_ops = { ++ .ndo_init = ipip6_tunnel_init, + .ndo_uninit = ipip6_tunnel_uninit, + .ndo_start_xmit = sit_tunnel_xmit, + .ndo_do_ioctl = ipip6_tunnel_ioctl, +@@ -1367,9 +1367,7 @@ static int ipip6_tunnel_init(struct net_device *dev) + + tunnel->dev = dev; + tunnel->net = dev_net(dev); +- +- memcpy(dev->dev_addr, &tunnel->parms.iph.saddr, 4); +- memcpy(dev->broadcast, &tunnel->parms.iph.daddr, 4); ++ strcpy(tunnel->parms.name, dev->name); + + ipip6_tunnel_bind_dev(dev); + dev->tstats = alloc_percpu(struct pcpu_sw_netstats); +@@ -1401,7 +1399,6 @@ static int __net_init ipip6_fb_tunnel_init(struct net_device *dev) + + tunnel->dev = dev; + tunnel->net = dev_net(dev); +- strcpy(tunnel->parms.name, dev->name); + + iph->version = 4; + iph->protocol = IPPROTO_IPV6; +diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c +index ea7013cb7e52..3f076b9c9308 100644 +--- a/net/mac80211/ibss.c ++++ b/net/mac80211/ibss.c +@@ -815,7 +815,7 @@ ieee80211_ibss_process_chanswitch(struct ieee80211_sub_if_data *sdata, + + memset(¶ms, 0, sizeof(params)); + memset(&csa_ie, 0, sizeof(csa_ie)); +- err = ieee80211_parse_ch_switch_ie(sdata, elems, beacon, ++ err = ieee80211_parse_ch_switch_ie(sdata, elems, + ifibss->chandef.chan->band, + sta_flags, ifibss->bssid, &csa_ie); + /* can't switch to destination channel, fail */ +diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h +index b127902361f4..bf7a1bbb975f 100644 +--- a/net/mac80211/ieee80211_i.h ++++ b/net/mac80211/ieee80211_i.h +@@ -1569,7 +1569,6 @@ void ieee80211_process_measurement_req(struct ieee80211_sub_if_data *sdata, + * ieee80211_parse_ch_switch_ie - parses channel switch IEs + * @sdata: the sdata of the interface which has received the frame + * @elems: parsed 802.11 elements received with the frame +- * @beacon: indicates if the frame was a beacon or probe response + * @current_band: indicates the current band + * @sta_flags: contains information about own capabilities and restrictions + * to decide which channel switch announcements can be accepted. Only the +@@ -1583,7 +1582,7 @@ void ieee80211_process_measurement_req(struct ieee80211_sub_if_data *sdata, + * Return: 0 on success, <0 on error and >0 if there is nothing to parse. + */ + int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata, +- struct ieee802_11_elems *elems, bool beacon, ++ struct ieee802_11_elems *elems, + enum ieee80211_band current_band, + u32 sta_flags, u8 *bssid, + struct ieee80211_csa_ie *csa_ie); +diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c +index 8f7fabc46c97..06f5de4e4fbb 100644 +--- a/net/mac80211/iface.c ++++ b/net/mac80211/iface.c +@@ -760,10 +760,12 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, + int i, flushed; + struct ps_data *ps; + struct cfg80211_chan_def chandef; ++ bool cancel_scan; + + clear_bit(SDATA_STATE_RUNNING, &sdata->state); + +- if (rcu_access_pointer(local->scan_sdata) == sdata) ++ cancel_scan = rcu_access_pointer(local->scan_sdata) == sdata; ++ if (cancel_scan) + ieee80211_scan_cancel(local); + + /* +@@ -973,6 +975,9 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, + + ieee80211_recalc_ps(local, -1); + ++ if (cancel_scan) ++ flush_delayed_work(&local->scan_work); ++ + if (local->open_count == 0) { + ieee80211_stop_device(local); + +diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c +index 5b919cab1de0..3d52d1d68431 100644 +--- a/net/mac80211/mesh.c ++++ b/net/mac80211/mesh.c +@@ -885,7 +885,7 @@ ieee80211_mesh_process_chnswitch(struct ieee80211_sub_if_data *sdata, + + memset(¶ms, 0, sizeof(params)); + memset(&csa_ie, 0, sizeof(csa_ie)); +- err = ieee80211_parse_ch_switch_ie(sdata, elems, beacon, band, ++ err = ieee80211_parse_ch_switch_ie(sdata, elems, band, + sta_flags, sdata->vif.addr, + &csa_ie); + if (err < 0) +diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c +index 189eef014c4f..c9535a976b56 100644 +--- a/net/mac80211/mlme.c ++++ b/net/mac80211/mlme.c +@@ -1001,7 +1001,7 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, + + current_band = cbss->channel->band; + memset(&csa_ie, 0, sizeof(csa_ie)); +- res = ieee80211_parse_ch_switch_ie(sdata, elems, beacon, current_band, ++ res = ieee80211_parse_ch_switch_ie(sdata, elems, current_band, + ifmgd->flags, + ifmgd->associated->bssid, &csa_ie); + if (res < 0) +@@ -1086,7 +1086,8 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, + ieee80211_queue_work(&local->hw, &ifmgd->chswitch_work); + else + mod_timer(&ifmgd->chswitch_timer, +- TU_TO_EXP_TIME(csa_ie.count * cbss->beacon_interval)); ++ TU_TO_EXP_TIME((csa_ie.count - 1) * ++ cbss->beacon_interval)); + } + + static u32 ieee80211_handle_pwr_constr(struct ieee80211_sub_if_data *sdata, +diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c +index 3e57f96c9666..095c16037bc5 100644 +--- a/net/mac80211/rx.c ++++ b/net/mac80211/rx.c +@@ -1679,11 +1679,14 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) + sc = le16_to_cpu(hdr->seq_ctrl); + frag = sc & IEEE80211_SCTL_FRAG; + +- if (likely((!ieee80211_has_morefrags(fc) && frag == 0) || +- is_multicast_ether_addr(hdr->addr1))) { +- /* not fragmented */ ++ if (likely(!ieee80211_has_morefrags(fc) && frag == 0)) ++ goto out; ++ ++ if (is_multicast_ether_addr(hdr->addr1)) { ++ rx->local->dot11MulticastReceivedFrameCount++; + goto out; + } ++ + I802_DEBUG_INC(rx->local->rx_handlers_fragments); + + if (skb_linearize(rx->skb)) +@@ -1776,10 +1779,7 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) + out: + if (rx->sta) + rx->sta->rx_packets++; +- if (is_multicast_ether_addr(hdr->addr1)) +- rx->local->dot11MulticastReceivedFrameCount++; +- else +- ieee80211_led_rx(rx->local); ++ ieee80211_led_rx(rx->local); + return RX_CONTINUE; + } + +diff --git a/net/mac80211/spectmgmt.c b/net/mac80211/spectmgmt.c +index 6ab009070084..efeba56c913b 100644 +--- a/net/mac80211/spectmgmt.c ++++ b/net/mac80211/spectmgmt.c +@@ -22,7 +22,7 @@ + #include "wme.h" + + int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata, +- struct ieee802_11_elems *elems, bool beacon, ++ struct ieee802_11_elems *elems, + enum ieee80211_band current_band, + u32 sta_flags, u8 *bssid, + struct ieee80211_csa_ie *csa_ie) +@@ -91,19 +91,13 @@ int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata, + return -EINVAL; + } + +- if (!beacon && sec_chan_offs) { ++ if (sec_chan_offs) { + secondary_channel_offset = sec_chan_offs->sec_chan_offs; +- } else if (beacon && ht_oper) { +- secondary_channel_offset = +- ht_oper->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET; + } else if (!(sta_flags & IEEE80211_STA_DISABLE_HT)) { +- /* If it's not a beacon, HT is enabled and the IE not present, +- * it's 20 MHz, 802.11-2012 8.5.2.6: +- * This element [the Secondary Channel Offset Element] is +- * present when switching to a 40 MHz channel. It may be +- * present when switching to a 20 MHz channel (in which +- * case the secondary channel offset is set to SCN). +- */ ++ /* If the secondary channel offset IE is not present, ++ * we can't know what's the post-CSA offset, so the ++ * best we can do is use 20MHz. ++ */ + secondary_channel_offset = IEEE80211_HT_PARAM_CHA_SEC_NONE; + } + +diff --git a/net/netfilter/ipset/ip_set_core.c b/net/netfilter/ipset/ip_set_core.c +index de770ec39e51..cf9937743abb 100644 +--- a/net/netfilter/ipset/ip_set_core.c ++++ b/net/netfilter/ipset/ip_set_core.c +@@ -636,7 +636,7 @@ ip_set_nfnl_get_byindex(struct net *net, ip_set_id_t index) + struct ip_set *set; + struct ip_set_net *inst = ip_set_pernet(net); + +- if (index > inst->ip_set_max) ++ if (index >= inst->ip_set_max) + return IPSET_INVALID_ID; + + nfnl_lock(NFNL_SUBSYS_IPSET); +diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c +index a155d19a225e..6ff12a191400 100644 +--- a/net/netfilter/nfnetlink_log.c ++++ b/net/netfilter/nfnetlink_log.c +@@ -45,7 +45,8 @@ + #define NFULNL_NLBUFSIZ_DEFAULT NLMSG_GOODSIZE + #define NFULNL_TIMEOUT_DEFAULT 100 /* every second */ + #define NFULNL_QTHRESH_DEFAULT 100 /* 100 packets */ +-#define NFULNL_COPY_RANGE_MAX 0xFFFF /* max packet size is limited by 16-bit struct nfattr nfa_len field */ ++/* max packet size is limited by 16-bit struct nfattr nfa_len field */ ++#define NFULNL_COPY_RANGE_MAX (0xFFFF - NLA_HDRLEN) + + #define PRINTR(x, args...) do { if (net_ratelimit()) \ + printk(x, ## args); } while (0); +@@ -255,6 +256,8 @@ nfulnl_set_mode(struct nfulnl_instance *inst, u_int8_t mode, + + case NFULNL_COPY_PACKET: + inst->copy_mode = mode; ++ if (range == 0) ++ range = NFULNL_COPY_RANGE_MAX; + inst->copy_range = min_t(unsigned int, + range, NFULNL_COPY_RANGE_MAX); + break; +@@ -346,26 +349,25 @@ nfulnl_alloc_skb(struct net *net, u32 peer_portid, unsigned int inst_size, + return skb; + } + +-static int ++static void + __nfulnl_send(struct nfulnl_instance *inst) + { +- int status = -1; +- + if (inst->qlen > 1) { + struct nlmsghdr *nlh = nlmsg_put(inst->skb, 0, 0, + NLMSG_DONE, + sizeof(struct nfgenmsg), + 0); +- if (!nlh) ++ if (WARN_ONCE(!nlh, "bad nlskb size: %u, tailroom %d\n", ++ inst->skb->len, skb_tailroom(inst->skb))) { ++ kfree_skb(inst->skb); + goto out; ++ } + } +- status = nfnetlink_unicast(inst->skb, inst->net, inst->peer_portid, +- MSG_DONTWAIT); +- ++ nfnetlink_unicast(inst->skb, inst->net, inst->peer_portid, ++ MSG_DONTWAIT); ++out: + inst->qlen = 0; + inst->skb = NULL; +-out: +- return status; + } + + static void +@@ -652,7 +654,8 @@ nfulnl_log_packet(struct net *net, + + nla_total_size(sizeof(u_int32_t)) /* gid */ + + nla_total_size(plen) /* prefix */ + + nla_total_size(sizeof(struct nfulnl_msg_packet_hw)) +- + nla_total_size(sizeof(struct nfulnl_msg_packet_timestamp)); ++ + nla_total_size(sizeof(struct nfulnl_msg_packet_timestamp)) ++ + nla_total_size(sizeof(struct nfgenmsg)); /* NLMSG_DONE */ + + if (in && skb_mac_header_was_set(skb)) { + size += nla_total_size(skb->dev->hard_header_len) +@@ -681,8 +684,7 @@ nfulnl_log_packet(struct net *net, + break; + + case NFULNL_COPY_PACKET: +- if (inst->copy_range == 0 +- || inst->copy_range > skb->len) ++ if (inst->copy_range > skb->len) + data_len = skb->len; + else + data_len = inst->copy_range; +@@ -695,8 +697,7 @@ nfulnl_log_packet(struct net *net, + goto unlock_and_release; + } + +- if (inst->skb && +- size > skb_tailroom(inst->skb) - sizeof(struct nfgenmsg)) { ++ if (inst->skb && size > skb_tailroom(inst->skb)) { + /* either the queue len is too high or we don't have + * enough room in the skb left. flush to userspace. */ + __nfulnl_flush(inst); +diff --git a/net/netfilter/nft_compat.c b/net/netfilter/nft_compat.c +index 82cb8236f8a1..ad979612238a 100644 +--- a/net/netfilter/nft_compat.c ++++ b/net/netfilter/nft_compat.c +@@ -678,7 +678,7 @@ nft_target_select_ops(const struct nft_ctx *ctx, + family = ctx->afi->family; + + /* Re-use the existing target if it's already loaded. */ +- list_for_each_entry(nft_target, &nft_match_list, head) { ++ list_for_each_entry(nft_target, &nft_target_list, head) { + struct xt_target *target = nft_target->ops.data; + + if (strcmp(target->name, tg_name) == 0 && +diff --git a/net/sctp/associola.c b/net/sctp/associola.c +index 5d97d8fe4be7..d477d476714d 100644 +--- a/net/sctp/associola.c ++++ b/net/sctp/associola.c +@@ -1627,6 +1627,8 @@ struct sctp_chunk *sctp_assoc_lookup_asconf_ack( + * ack chunk whose serial number matches that of the request. + */ + list_for_each_entry(ack, &asoc->asconf_ack_list, transmitted_list) { ++ if (sctp_chunk_pending(ack)) ++ continue; + if (ack->subh.addip_hdr->serial == serial) { + sctp_chunk_hold(ack); + return ack; +diff --git a/net/sctp/auth.c b/net/sctp/auth.c +index 0e8529113dc5..fb7976aee61c 100644 +--- a/net/sctp/auth.c ++++ b/net/sctp/auth.c +@@ -862,8 +862,6 @@ int sctp_auth_set_key(struct sctp_endpoint *ep, + list_add(&cur_key->key_list, sh_keys); + + cur_key->key = key; +- sctp_auth_key_hold(key); +- + return 0; + nomem: + if (!replace) +diff --git a/net/sctp/inqueue.c b/net/sctp/inqueue.c +index 4de12afa13d4..7e8a16c77039 100644 +--- a/net/sctp/inqueue.c ++++ b/net/sctp/inqueue.c +@@ -140,18 +140,9 @@ struct sctp_chunk *sctp_inq_pop(struct sctp_inq *queue) + } else { + /* Nothing to do. Next chunk in the packet, please. */ + ch = (sctp_chunkhdr_t *) chunk->chunk_end; +- + /* Force chunk->skb->data to chunk->chunk_end. */ +- skb_pull(chunk->skb, +- chunk->chunk_end - chunk->skb->data); +- +- /* Verify that we have at least chunk headers +- * worth of buffer left. +- */ +- if (skb_headlen(chunk->skb) < sizeof(sctp_chunkhdr_t)) { +- sctp_chunk_free(chunk); +- chunk = queue->in_progress = NULL; +- } ++ skb_pull(chunk->skb, chunk->chunk_end - chunk->skb->data); ++ /* We are guaranteed to pull a SCTP header. */ + } + } + +@@ -187,24 +178,14 @@ struct sctp_chunk *sctp_inq_pop(struct sctp_inq *queue) + skb_pull(chunk->skb, sizeof(sctp_chunkhdr_t)); + chunk->subh.v = NULL; /* Subheader is no longer valid. */ + +- if (chunk->chunk_end < skb_tail_pointer(chunk->skb)) { ++ if (chunk->chunk_end + sizeof(sctp_chunkhdr_t) < ++ skb_tail_pointer(chunk->skb)) { + /* This is not a singleton */ + chunk->singleton = 0; + } else if (chunk->chunk_end > skb_tail_pointer(chunk->skb)) { +- /* RFC 2960, Section 6.10 Bundling +- * +- * Partial chunks MUST NOT be placed in an SCTP packet. +- * If the receiver detects a partial chunk, it MUST drop +- * the chunk. +- * +- * Since the end of the chunk is past the end of our buffer +- * (which contains the whole packet, we can freely discard +- * the whole packet. +- */ +- sctp_chunk_free(chunk); +- chunk = queue->in_progress = NULL; +- +- return NULL; ++ /* Discard inside state machine. */ ++ chunk->pdiscard = 1; ++ chunk->chunk_end = skb_tail_pointer(chunk->skb); + } else { + /* We are at the end of the packet, so mark the chunk + * in case we need to send a SACK. +diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c +index fee5552ddf92..43abb643f3a1 100644 +--- a/net/sctp/sm_make_chunk.c ++++ b/net/sctp/sm_make_chunk.c +@@ -2609,6 +2609,9 @@ do_addr_param: + addr_param = param.v + sizeof(sctp_addip_param_t); + + af = sctp_get_af_specific(param_type2af(param.p->type)); ++ if (af == NULL) ++ break; ++ + af->from_addr_param(&addr, addr_param, + htons(asoc->peer.port), 0); + +@@ -3110,50 +3113,63 @@ static __be16 sctp_process_asconf_param(struct sctp_association *asoc, + return SCTP_ERROR_NO_ERROR; + } + +-/* Verify the ASCONF packet before we process it. */ +-int sctp_verify_asconf(const struct sctp_association *asoc, +- struct sctp_paramhdr *param_hdr, void *chunk_end, +- struct sctp_paramhdr **errp) { +- sctp_addip_param_t *asconf_param; ++/* Verify the ASCONF packet before we process it. */ ++bool sctp_verify_asconf(const struct sctp_association *asoc, ++ struct sctp_chunk *chunk, bool addr_param_needed, ++ struct sctp_paramhdr **errp) ++{ ++ sctp_addip_chunk_t *addip = (sctp_addip_chunk_t *) chunk->chunk_hdr; + union sctp_params param; +- int length, plen; ++ bool addr_param_seen = false; + +- param.v = (sctp_paramhdr_t *) param_hdr; +- while (param.v <= chunk_end - sizeof(sctp_paramhdr_t)) { +- length = ntohs(param.p->length); +- *errp = param.p; +- +- if (param.v > chunk_end - length || +- length < sizeof(sctp_paramhdr_t)) +- return 0; ++ sctp_walk_params(param, addip, addip_hdr.params) { ++ size_t length = ntohs(param.p->length); + ++ *errp = param.p; + switch (param.p->type) { ++ case SCTP_PARAM_ERR_CAUSE: ++ break; ++ case SCTP_PARAM_IPV4_ADDRESS: ++ if (length != sizeof(sctp_ipv4addr_param_t)) ++ return false; ++ addr_param_seen = true; ++ break; ++ case SCTP_PARAM_IPV6_ADDRESS: ++ if (length != sizeof(sctp_ipv6addr_param_t)) ++ return false; ++ addr_param_seen = true; ++ break; + case SCTP_PARAM_ADD_IP: + case SCTP_PARAM_DEL_IP: + case SCTP_PARAM_SET_PRIMARY: +- asconf_param = (sctp_addip_param_t *)param.v; +- plen = ntohs(asconf_param->param_hdr.length); +- if (plen < sizeof(sctp_addip_param_t) + +- sizeof(sctp_paramhdr_t)) +- return 0; ++ /* In ASCONF chunks, these need to be first. */ ++ if (addr_param_needed && !addr_param_seen) ++ return false; ++ length = ntohs(param.addip->param_hdr.length); ++ if (length < sizeof(sctp_addip_param_t) + ++ sizeof(sctp_paramhdr_t)) ++ return false; + break; + case SCTP_PARAM_SUCCESS_REPORT: + case SCTP_PARAM_ADAPTATION_LAYER_IND: + if (length != sizeof(sctp_addip_param_t)) +- return 0; +- ++ return false; + break; + default: +- break; ++ /* This is unkown to us, reject! */ ++ return false; + } +- +- param.v += WORD_ROUND(length); + } + +- if (param.v != chunk_end) +- return 0; ++ /* Remaining sanity checks. */ ++ if (addr_param_needed && !addr_param_seen) ++ return false; ++ if (!addr_param_needed && addr_param_seen) ++ return false; ++ if (param.v != chunk->chunk_end) ++ return false; + +- return 1; ++ return true; + } + + /* Process an incoming ASCONF chunk with the next expected serial no. and +@@ -3162,16 +3178,17 @@ int sctp_verify_asconf(const struct sctp_association *asoc, + struct sctp_chunk *sctp_process_asconf(struct sctp_association *asoc, + struct sctp_chunk *asconf) + { ++ sctp_addip_chunk_t *addip = (sctp_addip_chunk_t *) asconf->chunk_hdr; ++ bool all_param_pass = true; ++ union sctp_params param; + sctp_addiphdr_t *hdr; + union sctp_addr_param *addr_param; + sctp_addip_param_t *asconf_param; + struct sctp_chunk *asconf_ack; +- + __be16 err_code; + int length = 0; + int chunk_len; + __u32 serial; +- int all_param_pass = 1; + + chunk_len = ntohs(asconf->chunk_hdr->length) - sizeof(sctp_chunkhdr_t); + hdr = (sctp_addiphdr_t *)asconf->skb->data; +@@ -3199,9 +3216,14 @@ struct sctp_chunk *sctp_process_asconf(struct sctp_association *asoc, + goto done; + + /* Process the TLVs contained within the ASCONF chunk. */ +- while (chunk_len > 0) { ++ sctp_walk_params(param, addip, addip_hdr.params) { ++ /* Skip preceeding address parameters. */ ++ if (param.p->type == SCTP_PARAM_IPV4_ADDRESS || ++ param.p->type == SCTP_PARAM_IPV6_ADDRESS) ++ continue; ++ + err_code = sctp_process_asconf_param(asoc, asconf, +- asconf_param); ++ param.addip); + /* ADDIP 4.1 A7) + * If an error response is received for a TLV parameter, + * all TLVs with no response before the failed TLV are +@@ -3209,28 +3231,20 @@ struct sctp_chunk *sctp_process_asconf(struct sctp_association *asoc, + * the failed response are considered unsuccessful unless + * a specific success indication is present for the parameter. + */ +- if (SCTP_ERROR_NO_ERROR != err_code) +- all_param_pass = 0; +- ++ if (err_code != SCTP_ERROR_NO_ERROR) ++ all_param_pass = false; + if (!all_param_pass) +- sctp_add_asconf_response(asconf_ack, +- asconf_param->crr_id, err_code, +- asconf_param); ++ sctp_add_asconf_response(asconf_ack, param.addip->crr_id, ++ err_code, param.addip); + + /* ADDIP 4.3 D11) When an endpoint receiving an ASCONF to add + * an IP address sends an 'Out of Resource' in its response, it + * MUST also fail any subsequent add or delete requests bundled + * in the ASCONF. + */ +- if (SCTP_ERROR_RSRC_LOW == err_code) ++ if (err_code == SCTP_ERROR_RSRC_LOW) + goto done; +- +- /* Move to the next ASCONF param. */ +- length = ntohs(asconf_param->param_hdr.length); +- asconf_param = (void *)asconf_param + length; +- chunk_len -= length; + } +- + done: + asoc->peer.addip_serial++; + +diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c +index 7194fe8589b0..3e287a3fa03b 100644 +--- a/net/sctp/sm_statefuns.c ++++ b/net/sctp/sm_statefuns.c +@@ -170,6 +170,9 @@ sctp_chunk_length_valid(struct sctp_chunk *chunk, + { + __u16 chunk_length = ntohs(chunk->chunk_hdr->length); + ++ /* Previously already marked? */ ++ if (unlikely(chunk->pdiscard)) ++ return 0; + if (unlikely(chunk_length < required_length)) + return 0; + +@@ -3591,9 +3594,7 @@ sctp_disposition_t sctp_sf_do_asconf(struct net *net, + struct sctp_chunk *asconf_ack = NULL; + struct sctp_paramhdr *err_param = NULL; + sctp_addiphdr_t *hdr; +- union sctp_addr_param *addr_param; + __u32 serial; +- int length; + + if (!sctp_vtag_verify(chunk, asoc)) { + sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_BAD_TAG, +@@ -3618,17 +3619,8 @@ sctp_disposition_t sctp_sf_do_asconf(struct net *net, + hdr = (sctp_addiphdr_t *)chunk->skb->data; + serial = ntohl(hdr->serial); + +- addr_param = (union sctp_addr_param *)hdr->params; +- length = ntohs(addr_param->p.length); +- if (length < sizeof(sctp_paramhdr_t)) +- return sctp_sf_violation_paramlen(net, ep, asoc, type, arg, +- (void *)addr_param, commands); +- + /* Verify the ASCONF chunk before processing it. */ +- if (!sctp_verify_asconf(asoc, +- (sctp_paramhdr_t *)((void *)addr_param + length), +- (void *)chunk->chunk_end, +- &err_param)) ++ if (!sctp_verify_asconf(asoc, chunk, true, &err_param)) + return sctp_sf_violation_paramlen(net, ep, asoc, type, arg, + (void *)err_param, commands); + +@@ -3745,10 +3737,7 @@ sctp_disposition_t sctp_sf_do_asconf_ack(struct net *net, + rcvd_serial = ntohl(addip_hdr->serial); + + /* Verify the ASCONF-ACK chunk before processing it. */ +- if (!sctp_verify_asconf(asoc, +- (sctp_paramhdr_t *)addip_hdr->params, +- (void *)asconf_ack->chunk_end, +- &err_param)) ++ if (!sctp_verify_asconf(asoc, asconf_ack, false, &err_param)) + return sctp_sf_violation_paramlen(net, ep, asoc, type, arg, + (void *)err_param, commands); + +diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c +index f4b12c216f1c..5a723df670b4 100644 +--- a/sound/usb/mixer_quirks.c ++++ b/sound/usb/mixer_quirks.c +@@ -885,6 +885,11 @@ static int snd_ftu_eff_switch_put(struct snd_kcontrol *kctl, + return changed; + } + ++static void kctl_private_value_free(struct snd_kcontrol *kctl) ++{ ++ kfree((void *)kctl->private_value); ++} ++ + static int snd_ftu_create_effect_switch(struct usb_mixer_interface *mixer, + int validx, int bUnitID) + { +@@ -919,6 +924,7 @@ static int snd_ftu_create_effect_switch(struct usb_mixer_interface *mixer, + return -ENOMEM; + } + ++ kctl->private_free = kctl_private_value_free; + err = snd_ctl_add(mixer->chip->card, kctl); + if (err < 0) + return err; |