mirror of
https://github.com/armbian/build.git
synced 2025-12-24 10:41:41 +01:00
3722 lines
122 KiB
Diff
3722 lines
122 KiB
Diff
diff --git a/Makefile b/Makefile
|
|
index 8c5c94ca56d9..9db9095e0d7b 100644
|
|
--- a/Makefile
|
|
+++ b/Makefile
|
|
@@ -1,6 +1,6 @@
|
|
VERSION = 4
|
|
PATCHLEVEL = 11
|
|
-SUBLEVEL = 8
|
|
+SUBLEVEL = 9
|
|
EXTRAVERSION =
|
|
NAME = Fearless Coyote
|
|
|
|
diff --git a/arch/arm/mach-davinci/pm.c b/arch/arm/mach-davinci/pm.c
|
|
index 0afd201ab980..28255af5f2d8 100644
|
|
--- a/arch/arm/mach-davinci/pm.c
|
|
+++ b/arch/arm/mach-davinci/pm.c
|
|
@@ -154,7 +154,8 @@ int __init davinci_pm_init(void)
|
|
davinci_sram_suspend = sram_alloc(davinci_cpu_suspend_sz, NULL);
|
|
if (!davinci_sram_suspend) {
|
|
pr_err("PM: cannot allocate SRAM memory\n");
|
|
- return -ENOMEM;
|
|
+ ret = -ENOMEM;
|
|
+ goto no_sram_mem;
|
|
}
|
|
|
|
davinci_sram_push(davinci_sram_suspend, davinci_cpu_suspend,
|
|
@@ -162,6 +163,10 @@ int __init davinci_pm_init(void)
|
|
|
|
suspend_set_ops(&davinci_pm_ops);
|
|
|
|
+ return 0;
|
|
+
|
|
+no_sram_mem:
|
|
+ iounmap(pm_config.ddrpsc_reg_base);
|
|
no_ddrpsc_mem:
|
|
iounmap(pm_config.ddrpll_reg_base);
|
|
no_ddrpll_mem:
|
|
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
|
|
index 347cca965783..2a343349d4c4 100644
|
|
--- a/arch/arm/mm/mmu.c
|
|
+++ b/arch/arm/mm/mmu.c
|
|
@@ -1216,15 +1216,15 @@ void __init adjust_lowmem_bounds(void)
|
|
|
|
high_memory = __va(arm_lowmem_limit - 1) + 1;
|
|
|
|
+ if (!memblock_limit)
|
|
+ memblock_limit = arm_lowmem_limit;
|
|
+
|
|
/*
|
|
* Round the memblock limit down to a pmd size. This
|
|
* helps to ensure that we will allocate memory from the
|
|
* last full pmd, which should be mapped.
|
|
*/
|
|
- if (memblock_limit)
|
|
- memblock_limit = round_down(memblock_limit, PMD_SIZE);
|
|
- if (!memblock_limit)
|
|
- memblock_limit = arm_lowmem_limit;
|
|
+ memblock_limit = round_down(memblock_limit, PMD_SIZE);
|
|
|
|
if (!IS_ENABLED(CONFIG_HIGHMEM) || cache_is_vipt_aliasing()) {
|
|
if (memblock_end_of_DRAM() > arm_lowmem_limit) {
|
|
diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
|
|
index c1976c0adca7..ae66f5ef11f1 100644
|
|
--- a/arch/arm64/include/asm/acpi.h
|
|
+++ b/arch/arm64/include/asm/acpi.h
|
|
@@ -23,9 +23,9 @@
|
|
#define ACPI_MADT_GICC_LENGTH \
|
|
(acpi_gbl_FADT.header.revision < 6 ? 76 : 80)
|
|
|
|
-#define BAD_MADT_GICC_ENTRY(entry, end) \
|
|
- (!(entry) || (unsigned long)(entry) + sizeof(*(entry)) > (end) || \
|
|
- (entry)->header.length != ACPI_MADT_GICC_LENGTH)
|
|
+#define BAD_MADT_GICC_ENTRY(entry, end) \
|
|
+ (!(entry) || (entry)->header.length != ACPI_MADT_GICC_LENGTH || \
|
|
+ (unsigned long)(entry) + ACPI_MADT_GICC_LENGTH > (end))
|
|
|
|
/* Basic configuration for ACPI */
|
|
#ifdef CONFIG_ACPI
|
|
diff --git a/arch/arm64/kernel/pci.c b/arch/arm64/kernel/pci.c
|
|
index 4f0e3ebfea4b..c7e3e6387a49 100644
|
|
--- a/arch/arm64/kernel/pci.c
|
|
+++ b/arch/arm64/kernel/pci.c
|
|
@@ -191,8 +191,10 @@ struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)
|
|
return NULL;
|
|
|
|
root_ops = kzalloc_node(sizeof(*root_ops), GFP_KERNEL, node);
|
|
- if (!root_ops)
|
|
+ if (!root_ops) {
|
|
+ kfree(ri);
|
|
return NULL;
|
|
+ }
|
|
|
|
ri->cfg = pci_acpi_setup_ecam_mapping(root);
|
|
if (!ri->cfg) {
|
|
diff --git a/arch/mips/kernel/entry.S b/arch/mips/kernel/entry.S
|
|
index 8d83fc2a96b7..38a302919e6b 100644
|
|
--- a/arch/mips/kernel/entry.S
|
|
+++ b/arch/mips/kernel/entry.S
|
|
@@ -11,6 +11,7 @@
|
|
#include <asm/asm.h>
|
|
#include <asm/asmmacro.h>
|
|
#include <asm/compiler.h>
|
|
+#include <asm/irqflags.h>
|
|
#include <asm/regdef.h>
|
|
#include <asm/mipsregs.h>
|
|
#include <asm/stackframe.h>
|
|
@@ -119,6 +120,7 @@ work_pending:
|
|
andi t0, a2, _TIF_NEED_RESCHED # a2 is preloaded with TI_FLAGS
|
|
beqz t0, work_notifysig
|
|
work_resched:
|
|
+ TRACE_IRQS_OFF
|
|
jal schedule
|
|
|
|
local_irq_disable # make sure need_resched and
|
|
@@ -155,6 +157,7 @@ syscall_exit_work:
|
|
beqz t0, work_pending # trace bit set?
|
|
local_irq_enable # could let syscall_trace_leave()
|
|
# call schedule() instead
|
|
+ TRACE_IRQS_ON
|
|
move a0, sp
|
|
jal syscall_trace_leave
|
|
b resume_userspace
|
|
diff --git a/arch/mips/kernel/head.S b/arch/mips/kernel/head.S
|
|
index cf052204eb0a..d1bb506adc10 100644
|
|
--- a/arch/mips/kernel/head.S
|
|
+++ b/arch/mips/kernel/head.S
|
|
@@ -106,8 +106,8 @@ NESTED(kernel_entry, 16, sp) # kernel entry point
|
|
beq t0, t1, dtb_found
|
|
#endif
|
|
li t1, -2
|
|
- beq a0, t1, dtb_found
|
|
move t2, a1
|
|
+ beq a0, t1, dtb_found
|
|
|
|
li t2, 0
|
|
dtb_found:
|
|
diff --git a/arch/mips/kernel/pm-cps.c b/arch/mips/kernel/pm-cps.c
|
|
index 5f928c34c148..d99416094ba9 100644
|
|
--- a/arch/mips/kernel/pm-cps.c
|
|
+++ b/arch/mips/kernel/pm-cps.c
|
|
@@ -56,7 +56,6 @@ DECLARE_BITMAP(state_support, CPS_PM_STATE_COUNT);
|
|
* state. Actually per-core rather than per-CPU.
|
|
*/
|
|
static DEFINE_PER_CPU_ALIGNED(u32*, ready_count);
|
|
-static DEFINE_PER_CPU_ALIGNED(void*, ready_count_alloc);
|
|
|
|
/* Indicates online CPUs coupled with the current CPU */
|
|
static DEFINE_PER_CPU_ALIGNED(cpumask_t, online_coupled);
|
|
@@ -642,7 +641,6 @@ static int cps_pm_online_cpu(unsigned int cpu)
|
|
{
|
|
enum cps_pm_state state;
|
|
unsigned core = cpu_data[cpu].core;
|
|
- unsigned dlinesz = cpu_data[cpu].dcache.linesz;
|
|
void *entry_fn, *core_rc;
|
|
|
|
for (state = CPS_PM_NC_WAIT; state < CPS_PM_STATE_COUNT; state++) {
|
|
@@ -662,16 +660,11 @@ static int cps_pm_online_cpu(unsigned int cpu)
|
|
}
|
|
|
|
if (!per_cpu(ready_count, core)) {
|
|
- core_rc = kmalloc(dlinesz * 2, GFP_KERNEL);
|
|
+ core_rc = kmalloc(sizeof(u32), GFP_KERNEL);
|
|
if (!core_rc) {
|
|
pr_err("Failed allocate core %u ready_count\n", core);
|
|
return -ENOMEM;
|
|
}
|
|
- per_cpu(ready_count_alloc, core) = core_rc;
|
|
-
|
|
- /* Ensure ready_count is aligned to a cacheline boundary */
|
|
- core_rc += dlinesz - 1;
|
|
- core_rc = (void *)((unsigned long)core_rc & ~(dlinesz - 1));
|
|
per_cpu(ready_count, core) = core_rc;
|
|
}
|
|
|
|
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
|
|
index b49e7bf9f950..0b675023b9c6 100644
|
|
--- a/arch/mips/kernel/traps.c
|
|
+++ b/arch/mips/kernel/traps.c
|
|
@@ -201,6 +201,8 @@ void show_stack(struct task_struct *task, unsigned long *sp)
|
|
{
|
|
struct pt_regs regs;
|
|
mm_segment_t old_fs = get_fs();
|
|
+
|
|
+ regs.cp0_status = KSU_KERNEL;
|
|
if (sp) {
|
|
regs.regs[29] = (unsigned long)sp;
|
|
regs.regs[31] = 0;
|
|
diff --git a/arch/x86/boot/compressed/kaslr.c b/arch/x86/boot/compressed/kaslr.c
|
|
index 8b7c9e75edcb..8fad8a64d670 100644
|
|
--- a/arch/x86/boot/compressed/kaslr.c
|
|
+++ b/arch/x86/boot/compressed/kaslr.c
|
|
@@ -564,9 +564,6 @@ void choose_random_location(unsigned long input,
|
|
{
|
|
unsigned long random_addr, min_addr;
|
|
|
|
- /* By default, keep output position unchanged. */
|
|
- *virt_addr = *output;
|
|
-
|
|
if (cmdline_find_option_bool("nokaslr")) {
|
|
warn("KASLR disabled: 'nokaslr' on cmdline.");
|
|
return;
|
|
diff --git a/arch/x86/boot/compressed/misc.c b/arch/x86/boot/compressed/misc.c
|
|
index b3c5a5f030ce..c945acd8fa33 100644
|
|
--- a/arch/x86/boot/compressed/misc.c
|
|
+++ b/arch/x86/boot/compressed/misc.c
|
|
@@ -338,7 +338,7 @@ asmlinkage __visible void *extract_kernel(void *rmode, memptr heap,
|
|
unsigned long output_len)
|
|
{
|
|
const unsigned long kernel_total_size = VO__end - VO__text;
|
|
- unsigned long virt_addr = (unsigned long)output;
|
|
+ unsigned long virt_addr = LOAD_PHYSICAL_ADDR;
|
|
|
|
/* Retain x86 boot parameters pointer passed from startup_32/64. */
|
|
boot_params = rmode;
|
|
@@ -397,7 +397,7 @@ asmlinkage __visible void *extract_kernel(void *rmode, memptr heap,
|
|
#ifndef CONFIG_RELOCATABLE
|
|
if ((unsigned long)output != LOAD_PHYSICAL_ADDR)
|
|
error("Destination address does not match LOAD_PHYSICAL_ADDR");
|
|
- if ((unsigned long)output != virt_addr)
|
|
+ if (virt_addr != LOAD_PHYSICAL_ADDR)
|
|
error("Destination virtual address changed when not relocatable");
|
|
#endif
|
|
|
|
diff --git a/arch/x86/boot/compressed/misc.h b/arch/x86/boot/compressed/misc.h
|
|
index 1c8355eadbd1..766a5211f827 100644
|
|
--- a/arch/x86/boot/compressed/misc.h
|
|
+++ b/arch/x86/boot/compressed/misc.h
|
|
@@ -81,8 +81,6 @@ static inline void choose_random_location(unsigned long input,
|
|
unsigned long output_size,
|
|
unsigned long *virt_addr)
|
|
{
|
|
- /* No change from existing output location. */
|
|
- *virt_addr = *output;
|
|
}
|
|
#endif
|
|
|
|
diff --git a/arch/x86/entry/entry_32.S b/arch/x86/entry/entry_32.S
|
|
index 57f7ec35216e..701d29f8e4d3 100644
|
|
--- a/arch/x86/entry/entry_32.S
|
|
+++ b/arch/x86/entry/entry_32.S
|
|
@@ -255,6 +255,23 @@ ENTRY(__switch_to_asm)
|
|
END(__switch_to_asm)
|
|
|
|
/*
|
|
+ * The unwinder expects the last frame on the stack to always be at the same
|
|
+ * offset from the end of the page, which allows it to validate the stack.
|
|
+ * Calling schedule_tail() directly would break that convention because its an
|
|
+ * asmlinkage function so its argument has to be pushed on the stack. This
|
|
+ * wrapper creates a proper "end of stack" frame header before the call.
|
|
+ */
|
|
+ENTRY(schedule_tail_wrapper)
|
|
+ FRAME_BEGIN
|
|
+
|
|
+ pushl %eax
|
|
+ call schedule_tail
|
|
+ popl %eax
|
|
+
|
|
+ FRAME_END
|
|
+ ret
|
|
+ENDPROC(schedule_tail_wrapper)
|
|
+/*
|
|
* A newly forked process directly context switches into this address.
|
|
*
|
|
* eax: prev task we switched from
|
|
@@ -262,24 +279,15 @@ END(__switch_to_asm)
|
|
* edi: kernel thread arg
|
|
*/
|
|
ENTRY(ret_from_fork)
|
|
- FRAME_BEGIN /* help unwinder find end of stack */
|
|
-
|
|
- /*
|
|
- * schedule_tail() is asmlinkage so we have to put its 'prev' argument
|
|
- * on the stack.
|
|
- */
|
|
- pushl %eax
|
|
- call schedule_tail
|
|
- popl %eax
|
|
+ call schedule_tail_wrapper
|
|
|
|
testl %ebx, %ebx
|
|
jnz 1f /* kernel threads are uncommon */
|
|
|
|
2:
|
|
/* When we fork, we trace the syscall return in the child, too. */
|
|
- leal FRAME_OFFSET(%esp), %eax
|
|
+ movl %esp, %eax
|
|
call syscall_return_slowpath
|
|
- FRAME_END
|
|
jmp restore_all
|
|
|
|
/* kernel thread */
|
|
diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
|
|
index 044d18ebc43c..5b219707c2f2 100644
|
|
--- a/arch/x86/entry/entry_64.S
|
|
+++ b/arch/x86/entry/entry_64.S
|
|
@@ -36,7 +36,6 @@
|
|
#include <asm/smap.h>
|
|
#include <asm/pgtable_types.h>
|
|
#include <asm/export.h>
|
|
-#include <asm/frame.h>
|
|
#include <linux/err.h>
|
|
|
|
.code64
|
|
@@ -409,19 +408,17 @@ END(__switch_to_asm)
|
|
* r12: kernel thread arg
|
|
*/
|
|
ENTRY(ret_from_fork)
|
|
- FRAME_BEGIN /* help unwinder find end of stack */
|
|
movq %rax, %rdi
|
|
- call schedule_tail /* rdi: 'prev' task parameter */
|
|
+ call schedule_tail /* rdi: 'prev' task parameter */
|
|
|
|
- testq %rbx, %rbx /* from kernel_thread? */
|
|
- jnz 1f /* kernel threads are uncommon */
|
|
+ testq %rbx, %rbx /* from kernel_thread? */
|
|
+ jnz 1f /* kernel threads are uncommon */
|
|
|
|
2:
|
|
- leaq FRAME_OFFSET(%rsp),%rdi /* pt_regs pointer */
|
|
+ movq %rsp, %rdi
|
|
call syscall_return_slowpath /* returns with IRQs disabled */
|
|
TRACE_IRQS_ON /* user mode is traced as IRQS on */
|
|
SWAPGS
|
|
- FRAME_END
|
|
jmp restore_regs_and_iret
|
|
|
|
1:
|
|
diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c
|
|
index 65c2ca578556..78da7b646cd0 100644
|
|
--- a/arch/x86/events/intel/core.c
|
|
+++ b/arch/x86/events/intel/core.c
|
|
@@ -2130,7 +2130,7 @@ static int intel_pmu_handle_irq(struct pt_regs *regs)
|
|
* counters from the GLOBAL_STATUS mask and we always process PEBS
|
|
* events via drain_pebs().
|
|
*/
|
|
- status &= ~cpuc->pebs_enabled;
|
|
+ status &= ~(cpuc->pebs_enabled & PEBS_COUNTER_MASK);
|
|
|
|
/*
|
|
* PEBS overflow sets bit 62 in the global status register
|
|
diff --git a/arch/x86/events/intel/ds.c b/arch/x86/events/intel/ds.c
|
|
index 9dfeeeca0ea8..c6d23ffe422d 100644
|
|
--- a/arch/x86/events/intel/ds.c
|
|
+++ b/arch/x86/events/intel/ds.c
|
|
@@ -1222,7 +1222,7 @@ get_next_pebs_record_by_bit(void *base, void *top, int bit)
|
|
|
|
/* clear non-PEBS bit and re-check */
|
|
pebs_status = p->status & cpuc->pebs_enabled;
|
|
- pebs_status &= (1ULL << MAX_PEBS_EVENTS) - 1;
|
|
+ pebs_status &= PEBS_COUNTER_MASK;
|
|
if (pebs_status == (1 << bit))
|
|
return at;
|
|
}
|
|
diff --git a/arch/x86/events/intel/uncore.c b/arch/x86/events/intel/uncore.c
|
|
index 758c1aa5009d..44ec523287f6 100644
|
|
--- a/arch/x86/events/intel/uncore.c
|
|
+++ b/arch/x86/events/intel/uncore.c
|
|
@@ -1170,7 +1170,7 @@ static int uncore_event_cpu_online(unsigned int cpu)
|
|
pmu = type->pmus;
|
|
for (i = 0; i < type->num_boxes; i++, pmu++) {
|
|
box = pmu->boxes[pkg];
|
|
- if (!box && atomic_inc_return(&box->refcnt) == 1)
|
|
+ if (box && atomic_inc_return(&box->refcnt) == 1)
|
|
uncore_box_init(box);
|
|
}
|
|
}
|
|
diff --git a/arch/x86/events/perf_event.h b/arch/x86/events/perf_event.h
|
|
index bcbb1d2ae10b..be3d36254040 100644
|
|
--- a/arch/x86/events/perf_event.h
|
|
+++ b/arch/x86/events/perf_event.h
|
|
@@ -79,6 +79,7 @@ struct amd_nb {
|
|
|
|
/* The maximal number of PEBS events: */
|
|
#define MAX_PEBS_EVENTS 8
|
|
+#define PEBS_COUNTER_MASK ((1ULL << MAX_PEBS_EVENTS) - 1)
|
|
|
|
/*
|
|
* Flags PEBS can handle without an PMI.
|
|
diff --git a/arch/x86/include/asm/kvm_emulate.h b/arch/x86/include/asm/kvm_emulate.h
|
|
index d5f83cda1dea..722d0e568863 100644
|
|
--- a/arch/x86/include/asm/kvm_emulate.h
|
|
+++ b/arch/x86/include/asm/kvm_emulate.h
|
|
@@ -221,6 +221,9 @@ struct x86_emulate_ops {
|
|
void (*get_cpuid)(struct x86_emulate_ctxt *ctxt,
|
|
u32 *eax, u32 *ebx, u32 *ecx, u32 *edx);
|
|
void (*set_nmi_mask)(struct x86_emulate_ctxt *ctxt, bool masked);
|
|
+
|
|
+ unsigned (*get_hflags)(struct x86_emulate_ctxt *ctxt);
|
|
+ void (*set_hflags)(struct x86_emulate_ctxt *ctxt, unsigned hflags);
|
|
};
|
|
|
|
typedef u32 __attribute__((vector_size(16))) sse128_t;
|
|
@@ -290,7 +293,6 @@ struct x86_emulate_ctxt {
|
|
|
|
/* interruptibility state, as a result of execution of STI or MOV SS */
|
|
int interruptibility;
|
|
- int emul_flags;
|
|
|
|
bool perm_ok; /* do not check permissions if true */
|
|
bool ud; /* inject an #UD if host doesn't support insn */
|
|
diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
|
|
index 7c9c895432a9..6a348b6f73a2 100644
|
|
--- a/arch/x86/include/asm/mshyperv.h
|
|
+++ b/arch/x86/include/asm/mshyperv.h
|
|
@@ -2,8 +2,7 @@
|
|
#define _ASM_X86_MSHYPER_H
|
|
|
|
#include <linux/types.h>
|
|
-#include <linux/interrupt.h>
|
|
-#include <linux/clocksource.h>
|
|
+#include <linux/atomic.h>
|
|
#include <asm/hyperv.h>
|
|
|
|
/*
|
|
diff --git a/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c b/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c
|
|
index 9ac2a5cdd9c2..e79fb6b3dffe 100644
|
|
--- a/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c
|
|
+++ b/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c
|
|
@@ -767,11 +767,13 @@ static struct dentry *rdt_mount(struct file_system_type *fs_type,
|
|
dentry = kernfs_mount(fs_type, flags, rdt_root,
|
|
RDTGROUP_SUPER_MAGIC, NULL);
|
|
if (IS_ERR(dentry))
|
|
- goto out_cdp;
|
|
+ goto out_destroy;
|
|
|
|
static_branch_enable(&rdt_enable_key);
|
|
goto out;
|
|
|
|
+out_destroy:
|
|
+ kernfs_remove(kn_info);
|
|
out_cdp:
|
|
cdp_disable();
|
|
out:
|
|
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
|
|
index ce7f80baa664..0fca363787ff 100644
|
|
--- a/arch/x86/kvm/emulate.c
|
|
+++ b/arch/x86/kvm/emulate.c
|
|
@@ -2547,7 +2547,7 @@ static int em_rsm(struct x86_emulate_ctxt *ctxt)
|
|
u64 smbase;
|
|
int ret;
|
|
|
|
- if ((ctxt->emul_flags & X86EMUL_SMM_MASK) == 0)
|
|
+ if ((ctxt->ops->get_hflags(ctxt) & X86EMUL_SMM_MASK) == 0)
|
|
return emulate_ud(ctxt);
|
|
|
|
/*
|
|
@@ -2596,11 +2596,11 @@ static int em_rsm(struct x86_emulate_ctxt *ctxt)
|
|
return X86EMUL_UNHANDLEABLE;
|
|
}
|
|
|
|
- if ((ctxt->emul_flags & X86EMUL_SMM_INSIDE_NMI_MASK) == 0)
|
|
+ if ((ctxt->ops->get_hflags(ctxt) & X86EMUL_SMM_INSIDE_NMI_MASK) == 0)
|
|
ctxt->ops->set_nmi_mask(ctxt, false);
|
|
|
|
- ctxt->emul_flags &= ~X86EMUL_SMM_INSIDE_NMI_MASK;
|
|
- ctxt->emul_flags &= ~X86EMUL_SMM_MASK;
|
|
+ ctxt->ops->set_hflags(ctxt, ctxt->ops->get_hflags(ctxt) &
|
|
+ ~(X86EMUL_SMM_INSIDE_NMI_MASK | X86EMUL_SMM_MASK));
|
|
return X86EMUL_CONTINUE;
|
|
}
|
|
|
|
@@ -5317,6 +5317,7 @@ int x86_emulate_insn(struct x86_emulate_ctxt *ctxt)
|
|
const struct x86_emulate_ops *ops = ctxt->ops;
|
|
int rc = X86EMUL_CONTINUE;
|
|
int saved_dst_type = ctxt->dst.type;
|
|
+ unsigned emul_flags;
|
|
|
|
ctxt->mem_read.pos = 0;
|
|
|
|
@@ -5331,6 +5332,7 @@ int x86_emulate_insn(struct x86_emulate_ctxt *ctxt)
|
|
goto done;
|
|
}
|
|
|
|
+ emul_flags = ctxt->ops->get_hflags(ctxt);
|
|
if (unlikely(ctxt->d &
|
|
(No64|Undefined|Sse|Mmx|Intercept|CheckPerm|Priv|Prot|String))) {
|
|
if ((ctxt->mode == X86EMUL_MODE_PROT64 && (ctxt->d & No64)) ||
|
|
@@ -5364,7 +5366,7 @@ int x86_emulate_insn(struct x86_emulate_ctxt *ctxt)
|
|
fetch_possible_mmx_operand(ctxt, &ctxt->dst);
|
|
}
|
|
|
|
- if (unlikely(ctxt->emul_flags & X86EMUL_GUEST_MASK) && ctxt->intercept) {
|
|
+ if (unlikely(emul_flags & X86EMUL_GUEST_MASK) && ctxt->intercept) {
|
|
rc = emulator_check_intercept(ctxt, ctxt->intercept,
|
|
X86_ICPT_PRE_EXCEPT);
|
|
if (rc != X86EMUL_CONTINUE)
|
|
@@ -5393,7 +5395,7 @@ int x86_emulate_insn(struct x86_emulate_ctxt *ctxt)
|
|
goto done;
|
|
}
|
|
|
|
- if (unlikely(ctxt->emul_flags & X86EMUL_GUEST_MASK) && (ctxt->d & Intercept)) {
|
|
+ if (unlikely(emul_flags & X86EMUL_GUEST_MASK) && (ctxt->d & Intercept)) {
|
|
rc = emulator_check_intercept(ctxt, ctxt->intercept,
|
|
X86_ICPT_POST_EXCEPT);
|
|
if (rc != X86EMUL_CONTINUE)
|
|
@@ -5447,7 +5449,7 @@ int x86_emulate_insn(struct x86_emulate_ctxt *ctxt)
|
|
|
|
special_insn:
|
|
|
|
- if (unlikely(ctxt->emul_flags & X86EMUL_GUEST_MASK) && (ctxt->d & Intercept)) {
|
|
+ if (unlikely(emul_flags & X86EMUL_GUEST_MASK) && (ctxt->d & Intercept)) {
|
|
rc = emulator_check_intercept(ctxt, ctxt->intercept,
|
|
X86_ICPT_POST_MEMACCESS);
|
|
if (rc != X86EMUL_CONTINUE)
|
|
diff --git a/arch/x86/kvm/pmu_intel.c b/arch/x86/kvm/pmu_intel.c
|
|
index 9d4a8504a95a..5ab4a364348e 100644
|
|
--- a/arch/x86/kvm/pmu_intel.c
|
|
+++ b/arch/x86/kvm/pmu_intel.c
|
|
@@ -294,7 +294,7 @@ static void intel_pmu_refresh(struct kvm_vcpu *vcpu)
|
|
((u64)1 << edx.split.bit_width_fixed) - 1;
|
|
}
|
|
|
|
- pmu->global_ctrl = ((1 << pmu->nr_arch_gp_counters) - 1) |
|
|
+ pmu->global_ctrl = ((1ull << pmu->nr_arch_gp_counters) - 1) |
|
|
(((1ull << pmu->nr_arch_fixed_counters) - 1) << INTEL_PMC_IDX_FIXED);
|
|
pmu->global_ctrl_mask = ~pmu->global_ctrl;
|
|
|
|
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
|
|
index 259e9b28ccf8..e06ec5333da1 100644
|
|
--- a/arch/x86/kvm/vmx.c
|
|
+++ b/arch/x86/kvm/vmx.c
|
|
@@ -2436,7 +2436,7 @@ static int nested_vmx_check_exception(struct kvm_vcpu *vcpu, unsigned nr)
|
|
if (!(vmcs12->exception_bitmap & (1u << nr)))
|
|
return 0;
|
|
|
|
- nested_vmx_vmexit(vcpu, to_vmx(vcpu)->exit_reason,
|
|
+ nested_vmx_vmexit(vcpu, EXIT_REASON_EXCEPTION_NMI,
|
|
vmcs_read32(VM_EXIT_INTR_INFO),
|
|
vmcs_readl(EXIT_QUALIFICATION));
|
|
return 1;
|
|
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
|
|
index dd1fe338c5f5..4e957185d5b3 100644
|
|
--- a/arch/x86/kvm/x86.c
|
|
+++ b/arch/x86/kvm/x86.c
|
|
@@ -5098,6 +5098,8 @@ static bool emulator_get_segment(struct x86_emulate_ctxt *ctxt, u16 *selector,
|
|
|
|
if (var.unusable) {
|
|
memset(desc, 0, sizeof(*desc));
|
|
+ if (base3)
|
|
+ *base3 = 0;
|
|
return false;
|
|
}
|
|
|
|
@@ -5248,6 +5250,16 @@ static void emulator_set_nmi_mask(struct x86_emulate_ctxt *ctxt, bool masked)
|
|
kvm_x86_ops->set_nmi_mask(emul_to_vcpu(ctxt), masked);
|
|
}
|
|
|
|
+static unsigned emulator_get_hflags(struct x86_emulate_ctxt *ctxt)
|
|
+{
|
|
+ return emul_to_vcpu(ctxt)->arch.hflags;
|
|
+}
|
|
+
|
|
+static void emulator_set_hflags(struct x86_emulate_ctxt *ctxt, unsigned emul_flags)
|
|
+{
|
|
+ kvm_set_hflags(emul_to_vcpu(ctxt), emul_flags);
|
|
+}
|
|
+
|
|
static const struct x86_emulate_ops emulate_ops = {
|
|
.read_gpr = emulator_read_gpr,
|
|
.write_gpr = emulator_write_gpr,
|
|
@@ -5287,6 +5299,8 @@ static const struct x86_emulate_ops emulate_ops = {
|
|
.intercept = emulator_intercept,
|
|
.get_cpuid = emulator_get_cpuid,
|
|
.set_nmi_mask = emulator_set_nmi_mask,
|
|
+ .get_hflags = emulator_get_hflags,
|
|
+ .set_hflags = emulator_set_hflags,
|
|
};
|
|
|
|
static void toggle_interruptibility(struct kvm_vcpu *vcpu, u32 mask)
|
|
@@ -5341,7 +5355,6 @@ static void init_emulate_ctxt(struct kvm_vcpu *vcpu)
|
|
BUILD_BUG_ON(HF_GUEST_MASK != X86EMUL_GUEST_MASK);
|
|
BUILD_BUG_ON(HF_SMM_MASK != X86EMUL_SMM_MASK);
|
|
BUILD_BUG_ON(HF_SMM_INSIDE_NMI_MASK != X86EMUL_SMM_INSIDE_NMI_MASK);
|
|
- ctxt->emul_flags = vcpu->arch.hflags;
|
|
|
|
init_decode_cache(ctxt);
|
|
vcpu->arch.emulate_regs_need_sync_from_vcpu = false;
|
|
@@ -5744,8 +5757,6 @@ int x86_emulate_instruction(struct kvm_vcpu *vcpu,
|
|
unsigned long rflags = kvm_x86_ops->get_rflags(vcpu);
|
|
toggle_interruptibility(vcpu, ctxt->interruptibility);
|
|
vcpu->arch.emulate_regs_need_sync_to_vcpu = false;
|
|
- if (vcpu->arch.hflags != ctxt->emul_flags)
|
|
- kvm_set_hflags(vcpu, ctxt->emul_flags);
|
|
kvm_rip_write(vcpu, ctxt->eip);
|
|
if (r == EMULATE_DONE &&
|
|
(ctxt->tf || (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP)))
|
|
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
|
|
index 15173d37f399..e1e3f7b4bdb0 100644
|
|
--- a/arch/x86/mm/init_64.c
|
|
+++ b/arch/x86/mm/init_64.c
|
|
@@ -94,10 +94,10 @@ __setup("noexec32=", nonx32_setup);
|
|
*/
|
|
void sync_global_pgds(unsigned long start, unsigned long end)
|
|
{
|
|
- unsigned long address;
|
|
+ unsigned long addr;
|
|
|
|
- for (address = start; address <= end; address += PGDIR_SIZE) {
|
|
- const pgd_t *pgd_ref = pgd_offset_k(address);
|
|
+ for (addr = start; addr <= end; addr = ALIGN(addr + 1, PGDIR_SIZE)) {
|
|
+ const pgd_t *pgd_ref = pgd_offset_k(addr);
|
|
struct page *page;
|
|
|
|
if (pgd_none(*pgd_ref))
|
|
@@ -108,7 +108,7 @@ void sync_global_pgds(unsigned long start, unsigned long end)
|
|
pgd_t *pgd;
|
|
spinlock_t *pgt_lock;
|
|
|
|
- pgd = (pgd_t *)page_address(page) + pgd_index(address);
|
|
+ pgd = (pgd_t *)page_address(page) + pgd_index(addr);
|
|
/* the pgt_lock only for Xen */
|
|
pgt_lock = &pgd_page_get_mm(page)->page_table_lock;
|
|
spin_lock(pgt_lock);
|
|
diff --git a/arch/x86/mm/mpx.c b/arch/x86/mm/mpx.c
|
|
index cd44ae727df7..1c34b767c84c 100644
|
|
--- a/arch/x86/mm/mpx.c
|
|
+++ b/arch/x86/mm/mpx.c
|
|
@@ -526,15 +526,7 @@ int mpx_handle_bd_fault(void)
|
|
if (!kernel_managing_mpx_tables(current->mm))
|
|
return -EINVAL;
|
|
|
|
- if (do_mpx_bt_fault()) {
|
|
- force_sig(SIGSEGV, current);
|
|
- /*
|
|
- * The force_sig() is essentially "handling" this
|
|
- * exception, so we do not pass up the error
|
|
- * from do_mpx_bt_fault().
|
|
- */
|
|
- }
|
|
- return 0;
|
|
+ return do_mpx_bt_fault();
|
|
}
|
|
|
|
/*
|
|
diff --git a/arch/x86/mm/tlb.c b/arch/x86/mm/tlb.c
|
|
index a7655f6caf7d..75fb01109f94 100644
|
|
--- a/arch/x86/mm/tlb.c
|
|
+++ b/arch/x86/mm/tlb.c
|
|
@@ -263,8 +263,6 @@ void native_flush_tlb_others(const struct cpumask *cpumask,
|
|
{
|
|
struct flush_tlb_info info;
|
|
|
|
- if (end == 0)
|
|
- end = start + PAGE_SIZE;
|
|
info.flush_mm = mm;
|
|
info.flush_start = start;
|
|
info.flush_end = end;
|
|
@@ -393,7 +391,7 @@ void flush_tlb_page(struct vm_area_struct *vma, unsigned long start)
|
|
}
|
|
|
|
if (cpumask_any_but(mm_cpumask(mm), smp_processor_id()) < nr_cpu_ids)
|
|
- flush_tlb_others(mm_cpumask(mm), mm, start, 0UL);
|
|
+ flush_tlb_others(mm_cpumask(mm), mm, start, start + PAGE_SIZE);
|
|
|
|
preempt_enable();
|
|
}
|
|
diff --git a/drivers/block/xen-blkback/blkback.c b/drivers/block/xen-blkback/blkback.c
|
|
index fbe0dfdffc0d..0e824091a12f 100644
|
|
--- a/drivers/block/xen-blkback/blkback.c
|
|
+++ b/drivers/block/xen-blkback/blkback.c
|
|
@@ -609,8 +609,6 @@ int xen_blkif_schedule(void *arg)
|
|
unsigned long timeout;
|
|
int ret;
|
|
|
|
- xen_blkif_get(blkif);
|
|
-
|
|
set_freezable();
|
|
while (!kthread_should_stop()) {
|
|
if (try_to_freeze())
|
|
@@ -665,7 +663,6 @@ int xen_blkif_schedule(void *arg)
|
|
print_stats(ring);
|
|
|
|
ring->xenblkd = NULL;
|
|
- xen_blkif_put(blkif);
|
|
|
|
return 0;
|
|
}
|
|
diff --git a/drivers/block/xen-blkback/xenbus.c b/drivers/block/xen-blkback/xenbus.c
|
|
index dcabf52425ff..1ccb5a7bbdfe 100644
|
|
--- a/drivers/block/xen-blkback/xenbus.c
|
|
+++ b/drivers/block/xen-blkback/xenbus.c
|
|
@@ -255,7 +255,6 @@ static int xen_blkif_disconnect(struct xen_blkif *blkif)
|
|
if (ring->xenblkd) {
|
|
kthread_stop(ring->xenblkd);
|
|
wake_up(&ring->shutdown_wq);
|
|
- ring->xenblkd = NULL;
|
|
}
|
|
|
|
/* The above kthread_stop() guarantees that at this point we
|
|
@@ -316,8 +315,10 @@ static int xen_blkif_disconnect(struct xen_blkif *blkif)
|
|
static void xen_blkif_free(struct xen_blkif *blkif)
|
|
{
|
|
|
|
- xen_blkif_disconnect(blkif);
|
|
+ WARN_ON(xen_blkif_disconnect(blkif));
|
|
xen_vbd_free(&blkif->vbd);
|
|
+ kfree(blkif->be->mode);
|
|
+ kfree(blkif->be);
|
|
|
|
/* Make sure everything is drained before shutting down */
|
|
kmem_cache_free(xen_blkif_cachep, blkif);
|
|
@@ -512,8 +513,6 @@ static int xen_blkbk_remove(struct xenbus_device *dev)
|
|
|
|
/* Put the reference we set in xen_blkif_alloc(). */
|
|
xen_blkif_put(be->blkif);
|
|
- kfree(be->mode);
|
|
- kfree(be);
|
|
return 0;
|
|
}
|
|
|
|
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
|
|
index 8b4d721d6d63..b5a43d66878a 100644
|
|
--- a/drivers/gpio/gpiolib.c
|
|
+++ b/drivers/gpio/gpiolib.c
|
|
@@ -708,7 +708,8 @@ static irqreturn_t lineevent_irq_thread(int irq, void *p)
|
|
|
|
ge.timestamp = ktime_get_real_ns();
|
|
|
|
- if (le->eflags & GPIOEVENT_REQUEST_BOTH_EDGES) {
|
|
+ if (le->eflags & GPIOEVENT_REQUEST_RISING_EDGE
|
|
+ && le->eflags & GPIOEVENT_REQUEST_FALLING_EDGE) {
|
|
int level = gpiod_get_value_cansleep(le->desc);
|
|
|
|
if (level)
|
|
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c b/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c
|
|
index 13db8a2851ed..1f013d45c9e9 100644
|
|
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c
|
|
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c
|
|
@@ -321,6 +321,7 @@ void vmw_cmdbuf_res_man_destroy(struct vmw_cmdbuf_res_manager *man)
|
|
list_for_each_entry_safe(entry, next, &man->list, head)
|
|
vmw_cmdbuf_res_free(man, entry);
|
|
|
|
+ drm_ht_remove(&man->resources);
|
|
kfree(man);
|
|
}
|
|
|
|
diff --git a/drivers/hsi/clients/ssi_protocol.c b/drivers/hsi/clients/ssi_protocol.c
|
|
index 7ef819680acd..8251fa2904b6 100644
|
|
--- a/drivers/hsi/clients/ssi_protocol.c
|
|
+++ b/drivers/hsi/clients/ssi_protocol.c
|
|
@@ -1065,7 +1065,7 @@ static void ssip_pn_setup(struct net_device *dev)
|
|
dev->addr_len = 1;
|
|
dev->tx_queue_len = SSIP_TXQUEUE_LEN;
|
|
|
|
- dev->destructor = free_netdev;
|
|
+ dev->needs_free_netdev = true;
|
|
dev->header_ops = &phonet_header_ops;
|
|
}
|
|
|
|
diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c
|
|
index b8111b0c8877..d4b3ca3dd0e4 100644
|
|
--- a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c
|
|
+++ b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c
|
|
@@ -1851,6 +1851,7 @@ void hns_roce_v1_cq_set_ci(struct hns_roce_cq *hr_cq, u32 cons_index)
|
|
u32 doorbell[2];
|
|
|
|
doorbell[0] = cons_index & ((hr_cq->cq_depth << 1) - 1);
|
|
+ doorbell[1] = 0;
|
|
roce_set_bit(doorbell[1], ROCEE_DB_OTHERS_H_ROCEE_DB_OTH_HW_SYNS_S, 1);
|
|
roce_set_field(doorbell[1], ROCEE_DB_OTHERS_H_ROCEE_DB_OTH_CMD_M,
|
|
ROCEE_DB_OTHERS_H_ROCEE_DB_OTH_CMD_S, 3);
|
|
diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
|
|
index b17536d6e69b..3f25d881b343 100644
|
|
--- a/drivers/iommu/amd_iommu.c
|
|
+++ b/drivers/iommu/amd_iommu.c
|
|
@@ -3879,11 +3879,9 @@ static void irte_ga_prepare(void *entry,
|
|
u8 vector, u32 dest_apicid, int devid)
|
|
{
|
|
struct irte_ga *irte = (struct irte_ga *) entry;
|
|
- struct iommu_dev_data *dev_data = search_dev_data(devid);
|
|
|
|
irte->lo.val = 0;
|
|
irte->hi.val = 0;
|
|
- irte->lo.fields_remap.guest_mode = dev_data ? dev_data->use_vapic : 0;
|
|
irte->lo.fields_remap.int_type = delivery_mode;
|
|
irte->lo.fields_remap.dm = dest_mode;
|
|
irte->hi.fields.vector = vector;
|
|
@@ -3939,10 +3937,10 @@ static void irte_ga_set_affinity(void *entry, u16 devid, u16 index,
|
|
struct irte_ga *irte = (struct irte_ga *) entry;
|
|
struct iommu_dev_data *dev_data = search_dev_data(devid);
|
|
|
|
- if (!dev_data || !dev_data->use_vapic) {
|
|
+ if (!dev_data || !dev_data->use_vapic ||
|
|
+ !irte->lo.fields_remap.guest_mode) {
|
|
irte->hi.fields.vector = vector;
|
|
irte->lo.fields_remap.destination = dest_apicid;
|
|
- irte->lo.fields_remap.guest_mode = 0;
|
|
modify_irte_ga(devid, index, irte, NULL);
|
|
}
|
|
}
|
|
diff --git a/drivers/iommu/amd_iommu_v2.c b/drivers/iommu/amd_iommu_v2.c
|
|
index 063343909b0d..6629c472eafd 100644
|
|
--- a/drivers/iommu/amd_iommu_v2.c
|
|
+++ b/drivers/iommu/amd_iommu_v2.c
|
|
@@ -696,9 +696,9 @@ int amd_iommu_bind_pasid(struct pci_dev *pdev, int pasid,
|
|
|
|
out_unregister:
|
|
mmu_notifier_unregister(&pasid_state->mn, mm);
|
|
+ mmput(mm);
|
|
|
|
out_free:
|
|
- mmput(mm);
|
|
free_pasid_state(pasid_state);
|
|
|
|
out:
|
|
diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c
|
|
index 48d36ce59efb..1e0983488a8d 100644
|
|
--- a/drivers/iommu/dma-iommu.c
|
|
+++ b/drivers/iommu/dma-iommu.c
|
|
@@ -175,8 +175,7 @@ static void iova_reserve_pci_windows(struct pci_dev *dev,
|
|
unsigned long lo, hi;
|
|
|
|
resource_list_for_each_entry(window, &bridge->windows) {
|
|
- if (resource_type(window->res) != IORESOURCE_MEM &&
|
|
- resource_type(window->res) != IORESOURCE_IO)
|
|
+ if (resource_type(window->res) != IORESOURCE_MEM)
|
|
continue;
|
|
|
|
lo = iova_pfn(iovad, window->res->start - window->offset);
|
|
diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c
|
|
index 5742e5eb0704..f68e8c5ca386 100644
|
|
--- a/drivers/md/dm-thin.c
|
|
+++ b/drivers/md/dm-thin.c
|
|
@@ -1094,6 +1094,19 @@ static void process_prepared_discard_passdown_pt1(struct dm_thin_new_mapping *m)
|
|
return;
|
|
}
|
|
|
|
+ /*
|
|
+ * Increment the unmapped blocks. This prevents a race between the
|
|
+ * passdown io and reallocation of freed blocks.
|
|
+ */
|
|
+ r = dm_pool_inc_data_range(pool->pmd, m->data_block, data_end);
|
|
+ if (r) {
|
|
+ metadata_operation_failed(pool, "dm_pool_inc_data_range", r);
|
|
+ bio_io_error(m->bio);
|
|
+ cell_defer_no_holder(tc, m->cell);
|
|
+ mempool_free(m, pool->mapping_pool);
|
|
+ return;
|
|
+ }
|
|
+
|
|
discard_parent = bio_alloc(GFP_NOIO, 1);
|
|
if (!discard_parent) {
|
|
DMWARN("%s: unable to allocate top level discard bio for passdown. Skipping passdown.",
|
|
@@ -1114,19 +1127,6 @@ static void process_prepared_discard_passdown_pt1(struct dm_thin_new_mapping *m)
|
|
end_discard(&op, r);
|
|
}
|
|
}
|
|
-
|
|
- /*
|
|
- * Increment the unmapped blocks. This prevents a race between the
|
|
- * passdown io and reallocation of freed blocks.
|
|
- */
|
|
- r = dm_pool_inc_data_range(pool->pmd, m->data_block, data_end);
|
|
- if (r) {
|
|
- metadata_operation_failed(pool, "dm_pool_inc_data_range", r);
|
|
- bio_io_error(m->bio);
|
|
- cell_defer_no_holder(tc, m->cell);
|
|
- mempool_free(m, pool->mapping_pool);
|
|
- return;
|
|
- }
|
|
}
|
|
|
|
static void process_prepared_discard_passdown_pt2(struct dm_thin_new_mapping *m)
|
|
diff --git a/drivers/mtd/nand/brcmnand/brcmnand.c b/drivers/mtd/nand/brcmnand/brcmnand.c
|
|
index 42ebd73f821d..7419c5ce63f8 100644
|
|
--- a/drivers/mtd/nand/brcmnand/brcmnand.c
|
|
+++ b/drivers/mtd/nand/brcmnand/brcmnand.c
|
|
@@ -101,6 +101,9 @@ struct brcm_nand_dma_desc {
|
|
#define BRCMNAND_MIN_BLOCKSIZE (8 * 1024)
|
|
#define BRCMNAND_MIN_DEVSIZE (4ULL * 1024 * 1024)
|
|
|
|
+#define NAND_CTRL_RDY (INTFC_CTLR_READY | INTFC_FLASH_READY)
|
|
+#define NAND_POLL_STATUS_TIMEOUT_MS 100
|
|
+
|
|
/* Controller feature flags */
|
|
enum {
|
|
BRCMNAND_HAS_1K_SECTORS = BIT(0),
|
|
@@ -765,6 +768,31 @@ enum {
|
|
CS_SELECT_AUTO_DEVICE_ID_CFG = BIT(30),
|
|
};
|
|
|
|
+static int bcmnand_ctrl_poll_status(struct brcmnand_controller *ctrl,
|
|
+ u32 mask, u32 expected_val,
|
|
+ unsigned long timeout_ms)
|
|
+{
|
|
+ unsigned long limit;
|
|
+ u32 val;
|
|
+
|
|
+ if (!timeout_ms)
|
|
+ timeout_ms = NAND_POLL_STATUS_TIMEOUT_MS;
|
|
+
|
|
+ limit = jiffies + msecs_to_jiffies(timeout_ms);
|
|
+ do {
|
|
+ val = brcmnand_read_reg(ctrl, BRCMNAND_INTFC_STATUS);
|
|
+ if ((val & mask) == expected_val)
|
|
+ return 0;
|
|
+
|
|
+ cpu_relax();
|
|
+ } while (time_after(limit, jiffies));
|
|
+
|
|
+ dev_warn(ctrl->dev, "timeout on status poll (expected %x got %x)\n",
|
|
+ expected_val, val & mask);
|
|
+
|
|
+ return -ETIMEDOUT;
|
|
+}
|
|
+
|
|
static inline void brcmnand_set_wp(struct brcmnand_controller *ctrl, bool en)
|
|
{
|
|
u32 val = en ? CS_SELECT_NAND_WP : 0;
|
|
@@ -1024,12 +1052,39 @@ static void brcmnand_wp(struct mtd_info *mtd, int wp)
|
|
|
|
if ((ctrl->features & BRCMNAND_HAS_WP) && wp_on == 1) {
|
|
static int old_wp = -1;
|
|
+ int ret;
|
|
|
|
if (old_wp != wp) {
|
|
dev_dbg(ctrl->dev, "WP %s\n", wp ? "on" : "off");
|
|
old_wp = wp;
|
|
}
|
|
+
|
|
+ /*
|
|
+ * make sure ctrl/flash ready before and after
|
|
+ * changing state of #WP pin
|
|
+ */
|
|
+ ret = bcmnand_ctrl_poll_status(ctrl, NAND_CTRL_RDY |
|
|
+ NAND_STATUS_READY,
|
|
+ NAND_CTRL_RDY |
|
|
+ NAND_STATUS_READY, 0);
|
|
+ if (ret)
|
|
+ return;
|
|
+
|
|
brcmnand_set_wp(ctrl, wp);
|
|
+ chip->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1);
|
|
+ /* NAND_STATUS_WP 0x00 = protected, 0x80 = not protected */
|
|
+ ret = bcmnand_ctrl_poll_status(ctrl,
|
|
+ NAND_CTRL_RDY |
|
|
+ NAND_STATUS_READY |
|
|
+ NAND_STATUS_WP,
|
|
+ NAND_CTRL_RDY |
|
|
+ NAND_STATUS_READY |
|
|
+ (wp ? 0 : NAND_STATUS_WP), 0);
|
|
+
|
|
+ if (ret)
|
|
+ dev_err_ratelimited(&host->pdev->dev,
|
|
+ "nand #WP expected %s\n",
|
|
+ wp ? "on" : "off");
|
|
}
|
|
}
|
|
|
|
@@ -1157,15 +1212,15 @@ static irqreturn_t brcmnand_dma_irq(int irq, void *data)
|
|
static void brcmnand_send_cmd(struct brcmnand_host *host, int cmd)
|
|
{
|
|
struct brcmnand_controller *ctrl = host->ctrl;
|
|
- u32 intfc;
|
|
+ int ret;
|
|
|
|
dev_dbg(ctrl->dev, "send native cmd %d addr_lo 0x%x\n", cmd,
|
|
brcmnand_read_reg(ctrl, BRCMNAND_CMD_ADDRESS));
|
|
BUG_ON(ctrl->cmd_pending != 0);
|
|
ctrl->cmd_pending = cmd;
|
|
|
|
- intfc = brcmnand_read_reg(ctrl, BRCMNAND_INTFC_STATUS);
|
|
- WARN_ON(!(intfc & INTFC_CTLR_READY));
|
|
+ ret = bcmnand_ctrl_poll_status(ctrl, NAND_CTRL_RDY, NAND_CTRL_RDY, 0);
|
|
+ WARN_ON(ret);
|
|
|
|
mb(); /* flush previous writes */
|
|
brcmnand_write_reg(ctrl, BRCMNAND_CMD_START,
|
|
diff --git a/drivers/mtd/nand/fsmc_nand.c b/drivers/mtd/nand/fsmc_nand.c
|
|
index bda1e4667138..66aece9cc2cc 100644
|
|
--- a/drivers/mtd/nand/fsmc_nand.c
|
|
+++ b/drivers/mtd/nand/fsmc_nand.c
|
|
@@ -150,7 +150,6 @@ struct fsmc_nand_platform_data {
|
|
struct mtd_partition *partitions;
|
|
unsigned int nr_partitions;
|
|
unsigned int options;
|
|
- unsigned int width;
|
|
unsigned int bank;
|
|
|
|
enum access_mode mode;
|
|
@@ -844,18 +843,19 @@ static int fsmc_nand_probe_config_dt(struct platform_device *pdev,
|
|
u32 val;
|
|
int ret;
|
|
|
|
- /* Set default NAND width to 8 bits */
|
|
- pdata->width = 8;
|
|
+ pdata->options = 0;
|
|
+
|
|
if (!of_property_read_u32(np, "bank-width", &val)) {
|
|
if (val == 2) {
|
|
- pdata->width = 16;
|
|
+ pdata->options |= NAND_BUSWIDTH_16;
|
|
} else if (val != 1) {
|
|
dev_err(&pdev->dev, "invalid bank-width %u\n", val);
|
|
return -EINVAL;
|
|
}
|
|
}
|
|
+
|
|
if (of_get_property(np, "nand-skip-bbtscan", NULL))
|
|
- pdata->options = NAND_SKIP_BBTSCAN;
|
|
+ pdata->options |= NAND_SKIP_BBTSCAN;
|
|
|
|
pdata->nand_timings = devm_kzalloc(&pdev->dev,
|
|
sizeof(*pdata->nand_timings), GFP_KERNEL);
|
|
@@ -992,9 +992,6 @@ static int __init fsmc_nand_probe(struct platform_device *pdev)
|
|
nand->badblockbits = 7;
|
|
nand_set_flash_node(nand, np);
|
|
|
|
- if (pdata->width == FSMC_NAND_BW16)
|
|
- nand->options |= NAND_BUSWIDTH_16;
|
|
-
|
|
switch (host->mode) {
|
|
case USE_DMA_ACCESS:
|
|
dma_cap_zero(mask);
|
|
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
|
|
index 34481c9be1d1..6d80067e087f 100644
|
|
--- a/drivers/net/bonding/bond_main.c
|
|
+++ b/drivers/net/bonding/bond_main.c
|
|
@@ -4163,7 +4163,6 @@ static void bond_destructor(struct net_device *bond_dev)
|
|
struct bonding *bond = netdev_priv(bond_dev);
|
|
if (bond->wq)
|
|
destroy_workqueue(bond->wq);
|
|
- free_netdev(bond_dev);
|
|
}
|
|
|
|
void bond_setup(struct net_device *bond_dev)
|
|
@@ -4183,7 +4182,8 @@ void bond_setup(struct net_device *bond_dev)
|
|
bond_dev->netdev_ops = &bond_netdev_ops;
|
|
bond_dev->ethtool_ops = &bond_ethtool_ops;
|
|
|
|
- bond_dev->destructor = bond_destructor;
|
|
+ bond_dev->needs_free_netdev = true;
|
|
+ bond_dev->priv_destructor = bond_destructor;
|
|
|
|
SET_NETDEV_DEVTYPE(bond_dev, &bond_type);
|
|
|
|
@@ -4689,7 +4689,7 @@ int bond_create(struct net *net, const char *name)
|
|
|
|
rtnl_unlock();
|
|
if (res < 0)
|
|
- bond_destructor(bond_dev);
|
|
+ free_netdev(bond_dev);
|
|
return res;
|
|
}
|
|
|
|
diff --git a/drivers/net/caif/caif_hsi.c b/drivers/net/caif/caif_hsi.c
|
|
index ddabce759456..71a7c3b44fdd 100644
|
|
--- a/drivers/net/caif/caif_hsi.c
|
|
+++ b/drivers/net/caif/caif_hsi.c
|
|
@@ -1121,7 +1121,7 @@ static void cfhsi_setup(struct net_device *dev)
|
|
dev->flags = IFF_POINTOPOINT | IFF_NOARP;
|
|
dev->mtu = CFHSI_MAX_CAIF_FRAME_SZ;
|
|
dev->priv_flags |= IFF_NO_QUEUE;
|
|
- dev->destructor = free_netdev;
|
|
+ dev->needs_free_netdev = true;
|
|
dev->netdev_ops = &cfhsi_netdevops;
|
|
for (i = 0; i < CFHSI_PRIO_LAST; ++i)
|
|
skb_queue_head_init(&cfhsi->qhead[i]);
|
|
diff --git a/drivers/net/caif/caif_serial.c b/drivers/net/caif/caif_serial.c
|
|
index c2dea4916e5d..76e1d3545105 100644
|
|
--- a/drivers/net/caif/caif_serial.c
|
|
+++ b/drivers/net/caif/caif_serial.c
|
|
@@ -428,7 +428,7 @@ static void caifdev_setup(struct net_device *dev)
|
|
dev->flags = IFF_POINTOPOINT | IFF_NOARP;
|
|
dev->mtu = CAIF_MAX_MTU;
|
|
dev->priv_flags |= IFF_NO_QUEUE;
|
|
- dev->destructor = free_netdev;
|
|
+ dev->needs_free_netdev = true;
|
|
skb_queue_head_init(&serdev->head);
|
|
serdev->common.link_select = CAIF_LINK_LOW_LATENCY;
|
|
serdev->common.use_frag = true;
|
|
diff --git a/drivers/net/caif/caif_spi.c b/drivers/net/caif/caif_spi.c
|
|
index 3a529fbe539f..fc21afe852b9 100644
|
|
--- a/drivers/net/caif/caif_spi.c
|
|
+++ b/drivers/net/caif/caif_spi.c
|
|
@@ -712,7 +712,7 @@ static void cfspi_setup(struct net_device *dev)
|
|
dev->flags = IFF_NOARP | IFF_POINTOPOINT;
|
|
dev->priv_flags |= IFF_NO_QUEUE;
|
|
dev->mtu = SPI_MAX_PAYLOAD_SIZE;
|
|
- dev->destructor = free_netdev;
|
|
+ dev->needs_free_netdev = true;
|
|
skb_queue_head_init(&cfspi->qhead);
|
|
skb_queue_head_init(&cfspi->chead);
|
|
cfspi->cfdev.link_select = CAIF_LINK_HIGH_BANDW;
|
|
diff --git a/drivers/net/caif/caif_virtio.c b/drivers/net/caif/caif_virtio.c
|
|
index bc0eb47eccee..8bffd251165c 100644
|
|
--- a/drivers/net/caif/caif_virtio.c
|
|
+++ b/drivers/net/caif/caif_virtio.c
|
|
@@ -617,7 +617,7 @@ static void cfv_netdev_setup(struct net_device *netdev)
|
|
netdev->tx_queue_len = 100;
|
|
netdev->flags = IFF_POINTOPOINT | IFF_NOARP;
|
|
netdev->mtu = CFV_DEF_MTU_SIZE;
|
|
- netdev->destructor = free_netdev;
|
|
+ netdev->needs_free_netdev = true;
|
|
}
|
|
|
|
/* Create debugfs counters for the device */
|
|
diff --git a/drivers/net/can/slcan.c b/drivers/net/can/slcan.c
|
|
index eb7173713bbc..6a6e896e52fa 100644
|
|
--- a/drivers/net/can/slcan.c
|
|
+++ b/drivers/net/can/slcan.c
|
|
@@ -417,7 +417,7 @@ static int slc_open(struct net_device *dev)
|
|
static void slc_free_netdev(struct net_device *dev)
|
|
{
|
|
int i = dev->base_addr;
|
|
- free_netdev(dev);
|
|
+
|
|
slcan_devs[i] = NULL;
|
|
}
|
|
|
|
@@ -436,7 +436,8 @@ static const struct net_device_ops slc_netdev_ops = {
|
|
static void slc_setup(struct net_device *dev)
|
|
{
|
|
dev->netdev_ops = &slc_netdev_ops;
|
|
- dev->destructor = slc_free_netdev;
|
|
+ dev->needs_free_netdev = true;
|
|
+ dev->priv_destructor = slc_free_netdev;
|
|
|
|
dev->hard_header_len = 0;
|
|
dev->addr_len = 0;
|
|
@@ -761,8 +762,6 @@ static void __exit slcan_exit(void)
|
|
if (sl->tty) {
|
|
printk(KERN_ERR "%s: tty discipline still running\n",
|
|
dev->name);
|
|
- /* Intentionally leak the control block. */
|
|
- dev->destructor = NULL;
|
|
}
|
|
|
|
unregister_netdev(dev);
|
|
diff --git a/drivers/net/can/vcan.c b/drivers/net/can/vcan.c
|
|
index 674f367087c5..25d12099593e 100644
|
|
--- a/drivers/net/can/vcan.c
|
|
+++ b/drivers/net/can/vcan.c
|
|
@@ -160,7 +160,7 @@ static void vcan_setup(struct net_device *dev)
|
|
dev->flags |= IFF_ECHO;
|
|
|
|
dev->netdev_ops = &vcan_netdev_ops;
|
|
- dev->destructor = free_netdev;
|
|
+ dev->needs_free_netdev = true;
|
|
}
|
|
|
|
static struct rtnl_link_ops vcan_link_ops __read_mostly = {
|
|
diff --git a/drivers/net/dummy.c b/drivers/net/dummy.c
|
|
index 2c80611b94ae..b66fbe51ceb1 100644
|
|
--- a/drivers/net/dummy.c
|
|
+++ b/drivers/net/dummy.c
|
|
@@ -313,7 +313,6 @@ static void dummy_free_netdev(struct net_device *dev)
|
|
struct dummy_priv *priv = netdev_priv(dev);
|
|
|
|
kfree(priv->vfinfo);
|
|
- free_netdev(dev);
|
|
}
|
|
|
|
static void dummy_setup(struct net_device *dev)
|
|
@@ -323,7 +322,8 @@ static void dummy_setup(struct net_device *dev)
|
|
/* Initialize the device structure. */
|
|
dev->netdev_ops = &dummy_netdev_ops;
|
|
dev->ethtool_ops = &dummy_ethtool_ops;
|
|
- dev->destructor = dummy_free_netdev;
|
|
+ dev->needs_free_netdev = true;
|
|
+ dev->priv_destructor = dummy_free_netdev;
|
|
|
|
/* Fill in device structure with ethernet-generic values. */
|
|
dev->flags |= IFF_NOARP;
|
|
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
|
|
index 1238c4ec5215..fb0951929be9 100644
|
|
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
|
|
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
|
|
@@ -4530,7 +4530,7 @@ static void dummy_setup(struct net_device *dev)
|
|
/* Initialize the device structure. */
|
|
dev->netdev_ops = &cxgb4_mgmt_netdev_ops;
|
|
dev->ethtool_ops = &cxgb4_mgmt_ethtool_ops;
|
|
- dev->destructor = free_netdev;
|
|
+ dev->needs_free_netdev = true;
|
|
}
|
|
|
|
static int config_mgmt_dev(struct pci_dev *pdev)
|
|
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h
|
|
index 3d9490cd2db1..8f7108c94802 100644
|
|
--- a/drivers/net/ethernet/mellanox/mlx5/core/en.h
|
|
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h
|
|
@@ -313,13 +313,15 @@ struct mlx5e_dma_info {
|
|
|
|
struct mlx5e_rx_am_stats {
|
|
int ppms; /* packets per msec */
|
|
+ int bpms; /* bytes per msec */
|
|
int epms; /* events per msec */
|
|
};
|
|
|
|
struct mlx5e_rx_am_sample {
|
|
- ktime_t time;
|
|
- unsigned int pkt_ctr;
|
|
- u16 event_ctr;
|
|
+ ktime_t time;
|
|
+ u32 pkt_ctr;
|
|
+ u32 byte_ctr;
|
|
+ u16 event_ctr;
|
|
};
|
|
|
|
struct mlx5e_rx_am { /* Adaptive Moderation */
|
|
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
|
|
index 949fbadd7817..aae8b6c0edbd 100644
|
|
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
|
|
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
|
|
@@ -1205,11 +1205,11 @@ static int mlx5e_get_ts_info(struct net_device *dev,
|
|
SOF_TIMESTAMPING_RX_HARDWARE |
|
|
SOF_TIMESTAMPING_RAW_HARDWARE;
|
|
|
|
- info->tx_types = (BIT(1) << HWTSTAMP_TX_OFF) |
|
|
- (BIT(1) << HWTSTAMP_TX_ON);
|
|
+ info->tx_types = BIT(HWTSTAMP_TX_OFF) |
|
|
+ BIT(HWTSTAMP_TX_ON);
|
|
|
|
- info->rx_filters = (BIT(1) << HWTSTAMP_FILTER_NONE) |
|
|
- (BIT(1) << HWTSTAMP_FILTER_ALL);
|
|
+ info->rx_filters = BIT(HWTSTAMP_FILTER_NONE) |
|
|
+ BIT(HWTSTAMP_FILTER_ALL);
|
|
|
|
return 0;
|
|
}
|
|
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
|
|
index 15cc7b469d2e..f778436a2d28 100644
|
|
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
|
|
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
|
|
@@ -3885,7 +3885,8 @@ struct net_device *mlx5e_create_netdev(struct mlx5_core_dev *mdev,
|
|
return netdev;
|
|
|
|
err_cleanup_nic:
|
|
- profile->cleanup(priv);
|
|
+ if (profile->cleanup)
|
|
+ profile->cleanup(priv);
|
|
free_netdev(netdev);
|
|
|
|
return NULL;
|
|
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
|
|
index f621373bd7a5..4be6b346f14a 100644
|
|
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
|
|
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
|
|
@@ -424,6 +424,8 @@ static void mlx5e_build_rep_netdev_priv(struct mlx5_core_dev *mdev,
|
|
priv->params.lro_wqe_sz =
|
|
MLX5E_PARAMS_DEFAULT_LRO_WQE_SZ;
|
|
|
|
+ mlx5_query_min_inline(mdev, &priv->params.tx_min_inline_mode);
|
|
+
|
|
priv->mdev = mdev;
|
|
priv->netdev = netdev;
|
|
priv->params.num_channels = profile->max_nch(mdev);
|
|
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rx_am.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rx_am.c
|
|
index cbfac06b7ffd..23ccec4cb7f5 100644
|
|
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rx_am.c
|
|
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rx_am.c
|
|
@@ -183,28 +183,27 @@ static void mlx5e_am_exit_parking(struct mlx5e_rx_am *am)
|
|
mlx5e_am_step(am);
|
|
}
|
|
|
|
+#define IS_SIGNIFICANT_DIFF(val, ref) \
|
|
+ (((100 * abs((val) - (ref))) / (ref)) > 10) /* more than 10% difference */
|
|
+
|
|
static int mlx5e_am_stats_compare(struct mlx5e_rx_am_stats *curr,
|
|
struct mlx5e_rx_am_stats *prev)
|
|
{
|
|
- int diff;
|
|
-
|
|
- if (!prev->ppms)
|
|
- return curr->ppms ? MLX5E_AM_STATS_BETTER :
|
|
+ if (!prev->bpms)
|
|
+ return curr->bpms ? MLX5E_AM_STATS_BETTER :
|
|
MLX5E_AM_STATS_SAME;
|
|
|
|
- diff = curr->ppms - prev->ppms;
|
|
- if (((100 * abs(diff)) / prev->ppms) > 10) /* more than 10% diff */
|
|
- return (diff > 0) ? MLX5E_AM_STATS_BETTER :
|
|
- MLX5E_AM_STATS_WORSE;
|
|
+ if (IS_SIGNIFICANT_DIFF(curr->bpms, prev->bpms))
|
|
+ return (curr->bpms > prev->bpms) ? MLX5E_AM_STATS_BETTER :
|
|
+ MLX5E_AM_STATS_WORSE;
|
|
|
|
- if (!prev->epms)
|
|
- return curr->epms ? MLX5E_AM_STATS_WORSE :
|
|
- MLX5E_AM_STATS_SAME;
|
|
+ if (IS_SIGNIFICANT_DIFF(curr->ppms, prev->ppms))
|
|
+ return (curr->ppms > prev->ppms) ? MLX5E_AM_STATS_BETTER :
|
|
+ MLX5E_AM_STATS_WORSE;
|
|
|
|
- diff = curr->epms - prev->epms;
|
|
- if (((100 * abs(diff)) / prev->epms) > 10) /* more than 10% diff */
|
|
- return (diff < 0) ? MLX5E_AM_STATS_BETTER :
|
|
- MLX5E_AM_STATS_WORSE;
|
|
+ if (IS_SIGNIFICANT_DIFF(curr->epms, prev->epms))
|
|
+ return (curr->epms < prev->epms) ? MLX5E_AM_STATS_BETTER :
|
|
+ MLX5E_AM_STATS_WORSE;
|
|
|
|
return MLX5E_AM_STATS_SAME;
|
|
}
|
|
@@ -266,10 +265,13 @@ static void mlx5e_am_sample(struct mlx5e_rq *rq,
|
|
{
|
|
s->time = ktime_get();
|
|
s->pkt_ctr = rq->stats.packets;
|
|
+ s->byte_ctr = rq->stats.bytes;
|
|
s->event_ctr = rq->cq.event_ctr;
|
|
}
|
|
|
|
#define MLX5E_AM_NEVENTS 64
|
|
+#define BITS_PER_TYPE(type) (sizeof(type) * BITS_PER_BYTE)
|
|
+#define BIT_GAP(bits, end, start) ((((end) - (start)) + BIT_ULL(bits)) & (BIT_ULL(bits) - 1))
|
|
|
|
static void mlx5e_am_calc_stats(struct mlx5e_rx_am_sample *start,
|
|
struct mlx5e_rx_am_sample *end,
|
|
@@ -277,13 +279,17 @@ static void mlx5e_am_calc_stats(struct mlx5e_rx_am_sample *start,
|
|
{
|
|
/* u32 holds up to 71 minutes, should be enough */
|
|
u32 delta_us = ktime_us_delta(end->time, start->time);
|
|
- unsigned int npkts = end->pkt_ctr - start->pkt_ctr;
|
|
+ u32 npkts = BIT_GAP(BITS_PER_TYPE(u32), end->pkt_ctr, start->pkt_ctr);
|
|
+ u32 nbytes = BIT_GAP(BITS_PER_TYPE(u32), end->byte_ctr,
|
|
+ start->byte_ctr);
|
|
|
|
if (!delta_us)
|
|
return;
|
|
|
|
- curr_stats->ppms = (npkts * USEC_PER_MSEC) / delta_us;
|
|
- curr_stats->epms = (MLX5E_AM_NEVENTS * USEC_PER_MSEC) / delta_us;
|
|
+ curr_stats->ppms = DIV_ROUND_UP(npkts * USEC_PER_MSEC, delta_us);
|
|
+ curr_stats->bpms = DIV_ROUND_UP(nbytes * USEC_PER_MSEC, delta_us);
|
|
+ curr_stats->epms = DIV_ROUND_UP(MLX5E_AM_NEVENTS * USEC_PER_MSEC,
|
|
+ delta_us);
|
|
}
|
|
|
|
void mlx5e_rx_am_work(struct work_struct *work)
|
|
@@ -308,7 +314,8 @@ void mlx5e_rx_am(struct mlx5e_rq *rq)
|
|
|
|
switch (am->state) {
|
|
case MLX5E_AM_MEASURE_IN_PROGRESS:
|
|
- nevents = rq->cq.event_ctr - am->start_sample.event_ctr;
|
|
+ nevents = BIT_GAP(BITS_PER_TYPE(u16), rq->cq.event_ctr,
|
|
+ am->start_sample.event_ctr);
|
|
if (nevents < MLX5E_AM_NEVENTS)
|
|
break;
|
|
mlx5e_am_sample(rq, &end_sample);
|
|
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_stats.h b/drivers/net/ethernet/mellanox/mlx5/core/en_stats.h
|
|
index 53e4992d6511..f81c3aa60b46 100644
|
|
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_stats.h
|
|
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_stats.h
|
|
@@ -417,20 +417,13 @@ struct mlx5e_stats {
|
|
};
|
|
|
|
static const struct counter_desc mlx5e_pme_status_desc[] = {
|
|
- { "module_plug", 0 },
|
|
{ "module_unplug", 8 },
|
|
};
|
|
|
|
static const struct counter_desc mlx5e_pme_error_desc[] = {
|
|
- { "module_pwr_budget_exd", 0 }, /* power budget exceed */
|
|
- { "module_long_range", 8 }, /* long range for non MLNX cable */
|
|
- { "module_bus_stuck", 16 }, /* bus stuck (I2C or data shorted) */
|
|
- { "module_no_eeprom", 24 }, /* no eeprom/retry time out */
|
|
- { "module_enforce_part", 32 }, /* enforce part number list */
|
|
- { "module_unknown_id", 40 }, /* unknown identifier */
|
|
- { "module_high_temp", 48 }, /* high temperature */
|
|
+ { "module_bus_stuck", 16 }, /* bus stuck (I2C or data shorted) */
|
|
+ { "module_high_temp", 48 }, /* high temperature */
|
|
{ "module_bad_shorted", 56 }, /* bad or shorted cable/module */
|
|
- { "module_unknown_status", 64 },
|
|
};
|
|
|
|
#endif /* __MLX5_EN_STATS_H__ */
|
|
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c
|
|
index 0ad66324247f..9862a741b32a 100644
|
|
--- a/drivers/net/ethernet/mellanox/mlx5/core/main.c
|
|
+++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c
|
|
@@ -175,8 +175,9 @@ static struct mlx5_profile profile[] = {
|
|
},
|
|
};
|
|
|
|
-#define FW_INIT_TIMEOUT_MILI 2000
|
|
-#define FW_INIT_WAIT_MS 2
|
|
+#define FW_INIT_TIMEOUT_MILI 2000
|
|
+#define FW_INIT_WAIT_MS 2
|
|
+#define FW_PRE_INIT_TIMEOUT_MILI 10000
|
|
|
|
static int wait_fw_init(struct mlx5_core_dev *dev, u32 max_wait_mili)
|
|
{
|
|
@@ -537,8 +538,10 @@ static int handle_hca_cap(struct mlx5_core_dev *dev)
|
|
/* disable cmdif checksum */
|
|
MLX5_SET(cmd_hca_cap, set_hca_cap, cmdif_checksum, 0);
|
|
|
|
- /* If the HCA supports 4K UARs use it */
|
|
- if (MLX5_CAP_GEN_MAX(dev, uar_4k))
|
|
+ /* Enable 4K UAR only when HCA supports it and page size is bigger
|
|
+ * than 4K.
|
|
+ */
|
|
+ if (MLX5_CAP_GEN_MAX(dev, uar_4k) && PAGE_SIZE > 4096)
|
|
MLX5_SET(cmd_hca_cap, set_hca_cap, uar_4k, 1);
|
|
|
|
MLX5_SET(cmd_hca_cap, set_hca_cap, log_uar_page_sz, PAGE_SHIFT - 12);
|
|
@@ -1019,6 +1022,15 @@ static int mlx5_load_one(struct mlx5_core_dev *dev, struct mlx5_priv *priv,
|
|
*/
|
|
dev->state = MLX5_DEVICE_STATE_UP;
|
|
|
|
+ /* wait for firmware to accept initialization segments configurations
|
|
+ */
|
|
+ err = wait_fw_init(dev, FW_PRE_INIT_TIMEOUT_MILI);
|
|
+ if (err) {
|
|
+ dev_err(&dev->pdev->dev, "Firmware over %d MS in pre-initializing state, aborting\n",
|
|
+ FW_PRE_INIT_TIMEOUT_MILI);
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
err = mlx5_cmd_init(dev);
|
|
if (err) {
|
|
dev_err(&pdev->dev, "Failed initializing command interface, aborting\n");
|
|
diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c
|
|
index 6ebb0f559a42..199459bd6961 100644
|
|
--- a/drivers/net/geneve.c
|
|
+++ b/drivers/net/geneve.c
|
|
@@ -1007,7 +1007,7 @@ static void geneve_setup(struct net_device *dev)
|
|
|
|
dev->netdev_ops = &geneve_netdev_ops;
|
|
dev->ethtool_ops = &geneve_ethtool_ops;
|
|
- dev->destructor = free_netdev;
|
|
+ dev->needs_free_netdev = true;
|
|
|
|
SET_NETDEV_DEVTYPE(dev, &geneve_type);
|
|
|
|
diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c
|
|
index 89698741682f..429387083dce 100644
|
|
--- a/drivers/net/gtp.c
|
|
+++ b/drivers/net/gtp.c
|
|
@@ -618,7 +618,7 @@ static const struct net_device_ops gtp_netdev_ops = {
|
|
static void gtp_link_setup(struct net_device *dev)
|
|
{
|
|
dev->netdev_ops = >p_netdev_ops;
|
|
- dev->destructor = free_netdev;
|
|
+ dev->needs_free_netdev = true;
|
|
|
|
dev->hard_header_len = 0;
|
|
dev->addr_len = 0;
|
|
diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c
|
|
index 922bf440e9f1..021a8ec411ab 100644
|
|
--- a/drivers/net/hamradio/6pack.c
|
|
+++ b/drivers/net/hamradio/6pack.c
|
|
@@ -311,7 +311,7 @@ static void sp_setup(struct net_device *dev)
|
|
{
|
|
/* Finish setting up the DEVICE info. */
|
|
dev->netdev_ops = &sp_netdev_ops;
|
|
- dev->destructor = free_netdev;
|
|
+ dev->needs_free_netdev = true;
|
|
dev->mtu = SIXP_MTU;
|
|
dev->hard_header_len = AX25_MAX_HEADER_LEN;
|
|
dev->header_ops = &ax25_header_ops;
|
|
diff --git a/drivers/net/hamradio/bpqether.c b/drivers/net/hamradio/bpqether.c
|
|
index f62e7f325cf9..78a6414c5fd9 100644
|
|
--- a/drivers/net/hamradio/bpqether.c
|
|
+++ b/drivers/net/hamradio/bpqether.c
|
|
@@ -476,7 +476,7 @@ static const struct net_device_ops bpq_netdev_ops = {
|
|
static void bpq_setup(struct net_device *dev)
|
|
{
|
|
dev->netdev_ops = &bpq_netdev_ops;
|
|
- dev->destructor = free_netdev;
|
|
+ dev->needs_free_netdev = true;
|
|
|
|
memcpy(dev->broadcast, &ax25_bcast, AX25_ADDR_LEN);
|
|
memcpy(dev->dev_addr, &ax25_defaddr, AX25_ADDR_LEN);
|
|
diff --git a/drivers/net/ifb.c b/drivers/net/ifb.c
|
|
index 312fce7302d3..144ea5ae8ab4 100644
|
|
--- a/drivers/net/ifb.c
|
|
+++ b/drivers/net/ifb.c
|
|
@@ -207,7 +207,6 @@ static void ifb_dev_free(struct net_device *dev)
|
|
__skb_queue_purge(&txp->tq);
|
|
}
|
|
kfree(dp->tx_private);
|
|
- free_netdev(dev);
|
|
}
|
|
|
|
static void ifb_setup(struct net_device *dev)
|
|
@@ -230,7 +229,8 @@ static void ifb_setup(struct net_device *dev)
|
|
dev->priv_flags &= ~IFF_TX_SKB_SHARING;
|
|
netif_keep_dst(dev);
|
|
eth_hw_addr_random(dev);
|
|
- dev->destructor = ifb_dev_free;
|
|
+ dev->needs_free_netdev = true;
|
|
+ dev->priv_destructor = ifb_dev_free;
|
|
}
|
|
|
|
static netdev_tx_t ifb_xmit(struct sk_buff *skb, struct net_device *dev)
|
|
diff --git a/drivers/net/ipvlan/ipvlan_main.c b/drivers/net/ipvlan/ipvlan_main.c
|
|
index aa8575ccbce3..48e6c4e4914e 100644
|
|
--- a/drivers/net/ipvlan/ipvlan_main.c
|
|
+++ b/drivers/net/ipvlan/ipvlan_main.c
|
|
@@ -621,7 +621,7 @@ void ipvlan_link_setup(struct net_device *dev)
|
|
dev->priv_flags &= ~(IFF_XMIT_DST_RELEASE | IFF_TX_SKB_SHARING);
|
|
dev->priv_flags |= IFF_UNICAST_FLT | IFF_NO_QUEUE;
|
|
dev->netdev_ops = &ipvlan_netdev_ops;
|
|
- dev->destructor = free_netdev;
|
|
+ dev->needs_free_netdev = true;
|
|
dev->header_ops = &ipvlan_header_ops;
|
|
dev->ethtool_ops = &ipvlan_ethtool_ops;
|
|
}
|
|
diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c
|
|
index b23b71981fd5..80e3ace493cd 100644
|
|
--- a/drivers/net/loopback.c
|
|
+++ b/drivers/net/loopback.c
|
|
@@ -145,7 +145,6 @@ static void loopback_dev_free(struct net_device *dev)
|
|
{
|
|
dev_net(dev)->loopback_dev = NULL;
|
|
free_percpu(dev->lstats);
|
|
- free_netdev(dev);
|
|
}
|
|
|
|
static const struct net_device_ops loopback_ops = {
|
|
@@ -183,7 +182,8 @@ static void loopback_setup(struct net_device *dev)
|
|
dev->ethtool_ops = &loopback_ethtool_ops;
|
|
dev->header_ops = ð_header_ops;
|
|
dev->netdev_ops = &loopback_ops;
|
|
- dev->destructor = loopback_dev_free;
|
|
+ dev->needs_free_netdev = true;
|
|
+ dev->priv_destructor = loopback_dev_free;
|
|
}
|
|
|
|
/* Setup and register the loopback device. */
|
|
diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c
|
|
index 49ce4e9f4a0f..43f3e1b2d3ca 100644
|
|
--- a/drivers/net/macsec.c
|
|
+++ b/drivers/net/macsec.c
|
|
@@ -2994,7 +2994,6 @@ static void macsec_free_netdev(struct net_device *dev)
|
|
free_percpu(macsec->secy.tx_sc.stats);
|
|
|
|
dev_put(real_dev);
|
|
- free_netdev(dev);
|
|
}
|
|
|
|
static void macsec_setup(struct net_device *dev)
|
|
@@ -3004,7 +3003,8 @@ static void macsec_setup(struct net_device *dev)
|
|
dev->max_mtu = ETH_MAX_MTU;
|
|
dev->priv_flags |= IFF_NO_QUEUE;
|
|
dev->netdev_ops = &macsec_netdev_ops;
|
|
- dev->destructor = macsec_free_netdev;
|
|
+ dev->needs_free_netdev = true;
|
|
+ dev->priv_destructor = macsec_free_netdev;
|
|
SET_NETDEV_DEVTYPE(dev, &macsec_type);
|
|
|
|
eth_zero_addr(dev->broadcast);
|
|
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
|
|
index b34eaaae03fd..b8cec52547d7 100644
|
|
--- a/drivers/net/macvlan.c
|
|
+++ b/drivers/net/macvlan.c
|
|
@@ -1089,7 +1089,7 @@ void macvlan_common_setup(struct net_device *dev)
|
|
netif_keep_dst(dev);
|
|
dev->priv_flags |= IFF_UNICAST_FLT;
|
|
dev->netdev_ops = &macvlan_netdev_ops;
|
|
- dev->destructor = free_netdev;
|
|
+ dev->needs_free_netdev = true;
|
|
dev->header_ops = &macvlan_hard_header_ops;
|
|
dev->ethtool_ops = &macvlan_ethtool_ops;
|
|
}
|
|
diff --git a/drivers/net/nlmon.c b/drivers/net/nlmon.c
|
|
index b91603835d26..c4b3362da4a2 100644
|
|
--- a/drivers/net/nlmon.c
|
|
+++ b/drivers/net/nlmon.c
|
|
@@ -113,7 +113,7 @@ static void nlmon_setup(struct net_device *dev)
|
|
|
|
dev->netdev_ops = &nlmon_ops;
|
|
dev->ethtool_ops = &nlmon_ethtool_ops;
|
|
- dev->destructor = free_netdev;
|
|
+ dev->needs_free_netdev = true;
|
|
|
|
dev->features = NETIF_F_SG | NETIF_F_FRAGLIST |
|
|
NETIF_F_HIGHDMA | NETIF_F_LLTX;
|
|
diff --git a/drivers/net/slip/slip.c b/drivers/net/slip/slip.c
|
|
index 1da31dc47f86..74b907206aa7 100644
|
|
--- a/drivers/net/slip/slip.c
|
|
+++ b/drivers/net/slip/slip.c
|
|
@@ -629,7 +629,7 @@ static void sl_uninit(struct net_device *dev)
|
|
static void sl_free_netdev(struct net_device *dev)
|
|
{
|
|
int i = dev->base_addr;
|
|
- free_netdev(dev);
|
|
+
|
|
slip_devs[i] = NULL;
|
|
}
|
|
|
|
@@ -651,7 +651,8 @@ static const struct net_device_ops sl_netdev_ops = {
|
|
static void sl_setup(struct net_device *dev)
|
|
{
|
|
dev->netdev_ops = &sl_netdev_ops;
|
|
- dev->destructor = sl_free_netdev;
|
|
+ dev->needs_free_netdev = true;
|
|
+ dev->priv_destructor = sl_free_netdev;
|
|
|
|
dev->hard_header_len = 0;
|
|
dev->addr_len = 0;
|
|
@@ -1369,8 +1370,6 @@ static void __exit slip_exit(void)
|
|
if (sl->tty) {
|
|
printk(KERN_ERR "%s: tty discipline still running\n",
|
|
dev->name);
|
|
- /* Intentionally leak the control block. */
|
|
- dev->destructor = NULL;
|
|
}
|
|
|
|
unregister_netdev(dev);
|
|
diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c
|
|
index 85c01247f2e3..eaa6ee762230 100644
|
|
--- a/drivers/net/team/team.c
|
|
+++ b/drivers/net/team/team.c
|
|
@@ -1643,7 +1643,6 @@ static void team_destructor(struct net_device *dev)
|
|
struct team *team = netdev_priv(dev);
|
|
|
|
free_percpu(team->pcpu_stats);
|
|
- free_netdev(dev);
|
|
}
|
|
|
|
static int team_open(struct net_device *dev)
|
|
@@ -2079,7 +2078,8 @@ static void team_setup(struct net_device *dev)
|
|
|
|
dev->netdev_ops = &team_netdev_ops;
|
|
dev->ethtool_ops = &team_ethtool_ops;
|
|
- dev->destructor = team_destructor;
|
|
+ dev->needs_free_netdev = true;
|
|
+ dev->priv_destructor = team_destructor;
|
|
dev->priv_flags &= ~(IFF_XMIT_DST_RELEASE | IFF_TX_SKB_SHARING);
|
|
dev->priv_flags |= IFF_NO_QUEUE;
|
|
dev->priv_flags |= IFF_TEAM;
|
|
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
|
|
index cc88cd7856f5..7f3db4963fdd 100644
|
|
--- a/drivers/net/tun.c
|
|
+++ b/drivers/net/tun.c
|
|
@@ -1560,7 +1560,6 @@ static void tun_free_netdev(struct net_device *dev)
|
|
free_percpu(tun->pcpu_stats);
|
|
tun_flow_uninit(tun);
|
|
security_tun_dev_free_security(tun->security);
|
|
- free_netdev(dev);
|
|
}
|
|
|
|
static void tun_setup(struct net_device *dev)
|
|
@@ -1571,7 +1570,8 @@ static void tun_setup(struct net_device *dev)
|
|
tun->group = INVALID_GID;
|
|
|
|
dev->ethtool_ops = &tun_ethtool_ops;
|
|
- dev->destructor = tun_free_netdev;
|
|
+ dev->needs_free_netdev = true;
|
|
+ dev->priv_destructor = tun_free_netdev;
|
|
/* We prefer our own queue length */
|
|
dev->tx_queue_len = TUN_READQ_SIZE;
|
|
}
|
|
diff --git a/drivers/net/usb/cdc-phonet.c b/drivers/net/usb/cdc-phonet.c
|
|
index eb52de8205f0..c7a350bbaaa7 100644
|
|
--- a/drivers/net/usb/cdc-phonet.c
|
|
+++ b/drivers/net/usb/cdc-phonet.c
|
|
@@ -298,7 +298,7 @@ static void usbpn_setup(struct net_device *dev)
|
|
dev->addr_len = 1;
|
|
dev->tx_queue_len = 3;
|
|
|
|
- dev->destructor = free_netdev;
|
|
+ dev->needs_free_netdev = true;
|
|
}
|
|
|
|
/*
|
|
diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c
|
|
index 87746c2bc3d3..d4c8c96bc770 100644
|
|
--- a/drivers/net/usb/qmi_wwan.c
|
|
+++ b/drivers/net/usb/qmi_wwan.c
|
|
@@ -898,6 +898,8 @@ static const struct usb_device_id products[] = {
|
|
{QMI_FIXED_INTF(0x1199, 0x9056, 8)}, /* Sierra Wireless Modem */
|
|
{QMI_FIXED_INTF(0x1199, 0x9057, 8)},
|
|
{QMI_FIXED_INTF(0x1199, 0x9061, 8)}, /* Sierra Wireless Modem */
|
|
+ {QMI_FIXED_INTF(0x1199, 0x9063, 8)}, /* Sierra Wireless EM7305 */
|
|
+ {QMI_FIXED_INTF(0x1199, 0x9063, 10)}, /* Sierra Wireless EM7305 */
|
|
{QMI_FIXED_INTF(0x1199, 0x9071, 8)}, /* Sierra Wireless MC74xx */
|
|
{QMI_FIXED_INTF(0x1199, 0x9071, 10)}, /* Sierra Wireless MC74xx */
|
|
{QMI_FIXED_INTF(0x1199, 0x9079, 8)}, /* Sierra Wireless EM74xx */
|
|
@@ -912,6 +914,8 @@ static const struct usb_device_id products[] = {
|
|
{QMI_FIXED_INTF(0x1bc7, 0x1100, 3)}, /* Telit ME910 */
|
|
{QMI_FIXED_INTF(0x1bc7, 0x1200, 5)}, /* Telit LE920 */
|
|
{QMI_QUIRK_SET_DTR(0x1bc7, 0x1201, 2)}, /* Telit LE920, LE920A4 */
|
|
+ {QMI_FIXED_INTF(0x1c9e, 0x9801, 3)}, /* Telewell TW-3G HSPA+ */
|
|
+ {QMI_FIXED_INTF(0x1c9e, 0x9803, 4)}, /* Telewell TW-3G HSPA+ */
|
|
{QMI_FIXED_INTF(0x1c9e, 0x9b01, 3)}, /* XS Stick W100-2 from 4G Systems */
|
|
{QMI_FIXED_INTF(0x0b3c, 0xc000, 4)}, /* Olivetti Olicard 100 */
|
|
{QMI_FIXED_INTF(0x0b3c, 0xc001, 4)}, /* Olivetti Olicard 120 */
|
|
diff --git a/drivers/net/veth.c b/drivers/net/veth.c
|
|
index 8c39d6d690e5..2efbe98d0c67 100644
|
|
--- a/drivers/net/veth.c
|
|
+++ b/drivers/net/veth.c
|
|
@@ -227,7 +227,6 @@ static int veth_dev_init(struct net_device *dev)
|
|
static void veth_dev_free(struct net_device *dev)
|
|
{
|
|
free_percpu(dev->vstats);
|
|
- free_netdev(dev);
|
|
}
|
|
|
|
#ifdef CONFIG_NET_POLL_CONTROLLER
|
|
@@ -322,7 +321,8 @@ static void veth_setup(struct net_device *dev)
|
|
NETIF_F_HW_VLAN_STAG_TX |
|
|
NETIF_F_HW_VLAN_CTAG_RX |
|
|
NETIF_F_HW_VLAN_STAG_RX);
|
|
- dev->destructor = veth_dev_free;
|
|
+ dev->needs_free_netdev = true;
|
|
+ dev->priv_destructor = veth_dev_free;
|
|
dev->max_mtu = ETH_MAX_MTU;
|
|
|
|
dev->hw_features = VETH_FEATURES;
|
|
diff --git a/drivers/net/vrf.c b/drivers/net/vrf.c
|
|
index df74efcf237b..2e62c4d1b220 100644
|
|
--- a/drivers/net/vrf.c
|
|
+++ b/drivers/net/vrf.c
|
|
@@ -36,12 +36,14 @@
|
|
#include <net/addrconf.h>
|
|
#include <net/l3mdev.h>
|
|
#include <net/fib_rules.h>
|
|
+#include <net/netns/generic.h>
|
|
|
|
#define DRV_NAME "vrf"
|
|
#define DRV_VERSION "1.0"
|
|
|
|
#define FIB_RULE_PREF 1000 /* default preference for FIB rules */
|
|
-static bool add_fib_rules = true;
|
|
+
|
|
+static unsigned int vrf_net_id;
|
|
|
|
struct net_vrf {
|
|
struct rtable __rcu *rth;
|
|
@@ -1206,7 +1208,7 @@ static void vrf_setup(struct net_device *dev)
|
|
dev->netdev_ops = &vrf_netdev_ops;
|
|
dev->l3mdev_ops = &vrf_l3mdev_ops;
|
|
dev->ethtool_ops = &vrf_ethtool_ops;
|
|
- dev->destructor = free_netdev;
|
|
+ dev->needs_free_netdev = true;
|
|
|
|
/* Fill in device structure with ethernet-generic values. */
|
|
eth_hw_addr_random(dev);
|
|
@@ -1252,6 +1254,8 @@ static int vrf_newlink(struct net *src_net, struct net_device *dev,
|
|
struct nlattr *tb[], struct nlattr *data[])
|
|
{
|
|
struct net_vrf *vrf = netdev_priv(dev);
|
|
+ bool *add_fib_rules;
|
|
+ struct net *net;
|
|
int err;
|
|
|
|
if (!data || !data[IFLA_VRF_TABLE])
|
|
@@ -1267,13 +1271,15 @@ static int vrf_newlink(struct net *src_net, struct net_device *dev,
|
|
if (err)
|
|
goto out;
|
|
|
|
- if (add_fib_rules) {
|
|
+ net = dev_net(dev);
|
|
+ add_fib_rules = net_generic(net, vrf_net_id);
|
|
+ if (*add_fib_rules) {
|
|
err = vrf_add_fib_rules(dev);
|
|
if (err) {
|
|
unregister_netdevice(dev);
|
|
goto out;
|
|
}
|
|
- add_fib_rules = false;
|
|
+ *add_fib_rules = false;
|
|
}
|
|
|
|
out:
|
|
@@ -1356,16 +1362,38 @@ static struct notifier_block vrf_notifier_block __read_mostly = {
|
|
.notifier_call = vrf_device_event,
|
|
};
|
|
|
|
+/* Initialize per network namespace state */
|
|
+static int __net_init vrf_netns_init(struct net *net)
|
|
+{
|
|
+ bool *add_fib_rules = net_generic(net, vrf_net_id);
|
|
+
|
|
+ *add_fib_rules = true;
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static struct pernet_operations vrf_net_ops __net_initdata = {
|
|
+ .init = vrf_netns_init,
|
|
+ .id = &vrf_net_id,
|
|
+ .size = sizeof(bool),
|
|
+};
|
|
+
|
|
static int __init vrf_init_module(void)
|
|
{
|
|
int rc;
|
|
|
|
register_netdevice_notifier(&vrf_notifier_block);
|
|
|
|
- rc = rtnl_link_register(&vrf_link_ops);
|
|
+ rc = register_pernet_subsys(&vrf_net_ops);
|
|
if (rc < 0)
|
|
goto error;
|
|
|
|
+ rc = rtnl_link_register(&vrf_link_ops);
|
|
+ if (rc < 0) {
|
|
+ unregister_pernet_subsys(&vrf_net_ops);
|
|
+ goto error;
|
|
+ }
|
|
+
|
|
return 0;
|
|
|
|
error:
|
|
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
|
|
index 70dbd5a48b6b..4574b95c7938 100644
|
|
--- a/drivers/net/vxlan.c
|
|
+++ b/drivers/net/vxlan.c
|
|
@@ -2607,7 +2607,7 @@ static void vxlan_setup(struct net_device *dev)
|
|
eth_hw_addr_random(dev);
|
|
ether_setup(dev);
|
|
|
|
- dev->destructor = free_netdev;
|
|
+ dev->needs_free_netdev = true;
|
|
SET_NETDEV_DEVTYPE(dev, &vxlan_type);
|
|
|
|
dev->features |= NETIF_F_LLTX;
|
|
diff --git a/drivers/net/wan/dlci.c b/drivers/net/wan/dlci.c
|
|
index 65ee2a6f248c..a0d76f70c428 100644
|
|
--- a/drivers/net/wan/dlci.c
|
|
+++ b/drivers/net/wan/dlci.c
|
|
@@ -475,7 +475,7 @@ static void dlci_setup(struct net_device *dev)
|
|
dev->flags = 0;
|
|
dev->header_ops = &dlci_header_ops;
|
|
dev->netdev_ops = &dlci_netdev_ops;
|
|
- dev->destructor = free_netdev;
|
|
+ dev->needs_free_netdev = true;
|
|
|
|
dlp->receive = dlci_receive;
|
|
|
|
diff --git a/drivers/net/wan/hdlc_fr.c b/drivers/net/wan/hdlc_fr.c
|
|
index eb915281197e..78596e42a3f3 100644
|
|
--- a/drivers/net/wan/hdlc_fr.c
|
|
+++ b/drivers/net/wan/hdlc_fr.c
|
|
@@ -1106,7 +1106,7 @@ static int fr_add_pvc(struct net_device *frad, unsigned int dlci, int type)
|
|
return -EIO;
|
|
}
|
|
|
|
- dev->destructor = free_netdev;
|
|
+ dev->needs_free_netdev = true;
|
|
*get_dev_p(pvc, type) = dev;
|
|
if (!used) {
|
|
state(hdlc)->dce_changed = 1;
|
|
diff --git a/drivers/net/wan/lapbether.c b/drivers/net/wan/lapbether.c
|
|
index 9df9ed62beff..63f749078a1f 100644
|
|
--- a/drivers/net/wan/lapbether.c
|
|
+++ b/drivers/net/wan/lapbether.c
|
|
@@ -306,7 +306,7 @@ static const struct net_device_ops lapbeth_netdev_ops = {
|
|
static void lapbeth_setup(struct net_device *dev)
|
|
{
|
|
dev->netdev_ops = &lapbeth_netdev_ops;
|
|
- dev->destructor = free_netdev;
|
|
+ dev->needs_free_netdev = true;
|
|
dev->type = ARPHRD_X25;
|
|
dev->hard_header_len = 3;
|
|
dev->mtu = 1000;
|
|
diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c
|
|
index 91ee542de3d7..b90c77ef792e 100644
|
|
--- a/drivers/net/wireless/ath/ath6kl/main.c
|
|
+++ b/drivers/net/wireless/ath/ath6kl/main.c
|
|
@@ -1287,7 +1287,7 @@ void init_netdev(struct net_device *dev)
|
|
struct ath6kl *ar = ath6kl_priv(dev);
|
|
|
|
dev->netdev_ops = &ath6kl_netdev_ops;
|
|
- dev->destructor = free_netdev;
|
|
+ dev->needs_free_netdev = true;
|
|
dev->watchdog_timeo = ATH6KL_TX_TIMEOUT;
|
|
|
|
dev->needed_headroom = ETH_HLEN;
|
|
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
|
index 944b83cfc519..017e20b34304 100644
|
|
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
|
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
|
@@ -5209,7 +5209,6 @@ void brcmf_cfg80211_free_netdev(struct net_device *ndev)
|
|
|
|
if (vif)
|
|
brcmf_free_vif(vif);
|
|
- free_netdev(ndev);
|
|
}
|
|
|
|
static bool brcmf_is_linkup(const struct brcmf_event_msg *e)
|
|
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
|
|
index f6b17fb58877..d02e7f6ec4e0 100644
|
|
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
|
|
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
|
|
@@ -652,7 +652,8 @@ struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bsscfgidx, s32 ifidx,
|
|
if (!ndev)
|
|
return ERR_PTR(-ENOMEM);
|
|
|
|
- ndev->destructor = brcmf_cfg80211_free_netdev;
|
|
+ ndev->needs_free_netdev = true;
|
|
+ ndev->priv_destructor = brcmf_cfg80211_free_netdev;
|
|
ifp = netdev_priv(ndev);
|
|
ifp->ndev = ndev;
|
|
/* store mapping ifidx to bsscfgidx */
|
|
diff --git a/drivers/net/wireless/intersil/hostap/hostap_main.c b/drivers/net/wireless/intersil/hostap/hostap_main.c
|
|
index 544fc09dcb62..1372b20f931e 100644
|
|
--- a/drivers/net/wireless/intersil/hostap/hostap_main.c
|
|
+++ b/drivers/net/wireless/intersil/hostap/hostap_main.c
|
|
@@ -73,7 +73,7 @@ struct net_device * hostap_add_interface(struct local_info *local,
|
|
dev->mem_end = mdev->mem_end;
|
|
|
|
hostap_setup_dev(dev, local, type);
|
|
- dev->destructor = free_netdev;
|
|
+ dev->needs_free_netdev = true;
|
|
|
|
sprintf(dev->name, "%s%s", prefix, name);
|
|
if (!rtnl_locked)
|
|
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
|
|
index 50c219fb1a52..2aa5cc6e34ef 100644
|
|
--- a/drivers/net/wireless/mac80211_hwsim.c
|
|
+++ b/drivers/net/wireless/mac80211_hwsim.c
|
|
@@ -2807,7 +2807,7 @@ static const struct net_device_ops hwsim_netdev_ops = {
|
|
static void hwsim_mon_setup(struct net_device *dev)
|
|
{
|
|
dev->netdev_ops = &hwsim_netdev_ops;
|
|
- dev->destructor = free_netdev;
|
|
+ dev->needs_free_netdev = true;
|
|
ether_setup(dev);
|
|
dev->priv_flags |= IFF_NO_QUEUE;
|
|
dev->type = ARPHRD_IEEE80211_RADIOTAP;
|
|
diff --git a/drivers/net/wireless/marvell/mwifiex/main.c b/drivers/net/wireless/marvell/mwifiex/main.c
|
|
index b62e03d11c2e..46073bb554dd 100644
|
|
--- a/drivers/net/wireless/marvell/mwifiex/main.c
|
|
+++ b/drivers/net/wireless/marvell/mwifiex/main.c
|
|
@@ -1277,7 +1277,7 @@ void mwifiex_init_priv_params(struct mwifiex_private *priv,
|
|
struct net_device *dev)
|
|
{
|
|
dev->netdev_ops = &mwifiex_netdev_ops;
|
|
- dev->destructor = free_netdev;
|
|
+ dev->needs_free_netdev = true;
|
|
/* Initialize private structure */
|
|
priv->current_key_index = 0;
|
|
priv->media_connected = false;
|
|
diff --git a/drivers/pinctrl/pinctrl-amd.c b/drivers/pinctrl/pinctrl-amd.c
|
|
index d69e357a7a98..d8e81045cffe 100644
|
|
--- a/drivers/pinctrl/pinctrl-amd.c
|
|
+++ b/drivers/pinctrl/pinctrl-amd.c
|
|
@@ -495,64 +495,54 @@ static struct irq_chip amd_gpio_irqchip = {
|
|
.flags = IRQCHIP_SKIP_SET_WAKE,
|
|
};
|
|
|
|
-static void amd_gpio_irq_handler(struct irq_desc *desc)
|
|
+#define PIN_IRQ_PENDING (BIT(INTERRUPT_STS_OFF) | BIT(WAKE_STS_OFF))
|
|
+
|
|
+static irqreturn_t amd_gpio_irq_handler(int irq, void *dev_id)
|
|
{
|
|
- u32 i;
|
|
- u32 off;
|
|
- u32 reg;
|
|
- u32 pin_reg;
|
|
- u64 reg64;
|
|
- int handled = 0;
|
|
- unsigned int irq;
|
|
+ struct amd_gpio *gpio_dev = dev_id;
|
|
+ struct gpio_chip *gc = &gpio_dev->gc;
|
|
+ irqreturn_t ret = IRQ_NONE;
|
|
+ unsigned int i, irqnr;
|
|
unsigned long flags;
|
|
- struct irq_chip *chip = irq_desc_get_chip(desc);
|
|
- struct gpio_chip *gc = irq_desc_get_handler_data(desc);
|
|
- struct amd_gpio *gpio_dev = gpiochip_get_data(gc);
|
|
+ u32 *regs, regval;
|
|
+ u64 status, mask;
|
|
|
|
- chained_irq_enter(chip, desc);
|
|
- /*enable GPIO interrupt again*/
|
|
+ /* Read the wake status */
|
|
spin_lock_irqsave(&gpio_dev->lock, flags);
|
|
- reg = readl(gpio_dev->base + WAKE_INT_STATUS_REG1);
|
|
- reg64 = reg;
|
|
- reg64 = reg64 << 32;
|
|
-
|
|
- reg = readl(gpio_dev->base + WAKE_INT_STATUS_REG0);
|
|
- reg64 |= reg;
|
|
+ status = readl(gpio_dev->base + WAKE_INT_STATUS_REG1);
|
|
+ status <<= 32;
|
|
+ status |= readl(gpio_dev->base + WAKE_INT_STATUS_REG0);
|
|
spin_unlock_irqrestore(&gpio_dev->lock, flags);
|
|
|
|
- /*
|
|
- * first 46 bits indicates interrupt status.
|
|
- * one bit represents four interrupt sources.
|
|
- */
|
|
- for (off = 0; off < 46 ; off++) {
|
|
- if (reg64 & BIT(off)) {
|
|
- for (i = 0; i < 4; i++) {
|
|
- pin_reg = readl(gpio_dev->base +
|
|
- (off * 4 + i) * 4);
|
|
- if ((pin_reg & BIT(INTERRUPT_STS_OFF)) ||
|
|
- (pin_reg & BIT(WAKE_STS_OFF))) {
|
|
- irq = irq_find_mapping(gc->irqdomain,
|
|
- off * 4 + i);
|
|
- generic_handle_irq(irq);
|
|
- writel(pin_reg,
|
|
- gpio_dev->base
|
|
- + (off * 4 + i) * 4);
|
|
- handled++;
|
|
- }
|
|
- }
|
|
+ /* Bit 0-45 contain the relevant status bits */
|
|
+ status &= (1ULL << 46) - 1;
|
|
+ regs = gpio_dev->base;
|
|
+ for (mask = 1, irqnr = 0; status; mask <<= 1, regs += 4, irqnr += 4) {
|
|
+ if (!(status & mask))
|
|
+ continue;
|
|
+ status &= ~mask;
|
|
+
|
|
+ /* Each status bit covers four pins */
|
|
+ for (i = 0; i < 4; i++) {
|
|
+ regval = readl(regs + i);
|
|
+ if (!(regval & PIN_IRQ_PENDING))
|
|
+ continue;
|
|
+ irq = irq_find_mapping(gc->irqdomain, irqnr + i);
|
|
+ generic_handle_irq(irq);
|
|
+ /* Clear interrupt */
|
|
+ writel(regval, regs + i);
|
|
+ ret = IRQ_HANDLED;
|
|
}
|
|
}
|
|
|
|
- if (handled == 0)
|
|
- handle_bad_irq(desc);
|
|
-
|
|
+ /* Signal EOI to the GPIO unit */
|
|
spin_lock_irqsave(&gpio_dev->lock, flags);
|
|
- reg = readl(gpio_dev->base + WAKE_INT_MASTER_REG);
|
|
- reg |= EOI_MASK;
|
|
- writel(reg, gpio_dev->base + WAKE_INT_MASTER_REG);
|
|
+ regval = readl(gpio_dev->base + WAKE_INT_MASTER_REG);
|
|
+ regval |= EOI_MASK;
|
|
+ writel(regval, gpio_dev->base + WAKE_INT_MASTER_REG);
|
|
spin_unlock_irqrestore(&gpio_dev->lock, flags);
|
|
|
|
- chained_irq_exit(chip, desc);
|
|
+ return ret;
|
|
}
|
|
|
|
static int amd_get_groups_count(struct pinctrl_dev *pctldev)
|
|
@@ -821,10 +811,11 @@ static int amd_gpio_probe(struct platform_device *pdev)
|
|
goto out2;
|
|
}
|
|
|
|
- gpiochip_set_chained_irqchip(&gpio_dev->gc,
|
|
- &amd_gpio_irqchip,
|
|
- irq_base,
|
|
- amd_gpio_irq_handler);
|
|
+ ret = devm_request_irq(&pdev->dev, irq_base, amd_gpio_irq_handler, 0,
|
|
+ KBUILD_MODNAME, gpio_dev);
|
|
+ if (ret)
|
|
+ goto out2;
|
|
+
|
|
platform_set_drvdata(pdev, gpio_dev);
|
|
|
|
dev_dbg(&pdev->dev, "amd gpio driver loaded\n");
|
|
diff --git a/drivers/s390/net/netiucv.c b/drivers/s390/net/netiucv.c
|
|
index 3f85b97ab8d2..6d3494ba84cf 100644
|
|
--- a/drivers/s390/net/netiucv.c
|
|
+++ b/drivers/s390/net/netiucv.c
|
|
@@ -1954,7 +1954,6 @@ static void netiucv_free_netdevice(struct net_device *dev)
|
|
privptr->conn = NULL; privptr->fsm = NULL;
|
|
/* privptr gets freed by free_netdev() */
|
|
}
|
|
- free_netdev(dev);
|
|
}
|
|
|
|
/**
|
|
@@ -1972,7 +1971,8 @@ static void netiucv_setup_netdevice(struct net_device *dev)
|
|
dev->mtu = NETIUCV_MTU_DEFAULT;
|
|
dev->min_mtu = 576;
|
|
dev->max_mtu = NETIUCV_MTU_MAX;
|
|
- dev->destructor = netiucv_free_netdevice;
|
|
+ dev->needs_free_netdev = true;
|
|
+ dev->priv_destructor = netiucv_free_netdevice;
|
|
dev->hard_header_len = NETIUCV_HDRLEN;
|
|
dev->addr_len = 0;
|
|
dev->type = ARPHRD_SLIP;
|
|
diff --git a/drivers/staging/rtl8188eu/os_dep/mon.c b/drivers/staging/rtl8188eu/os_dep/mon.c
|
|
index cfe37eb026d6..859d0d6051cd 100644
|
|
--- a/drivers/staging/rtl8188eu/os_dep/mon.c
|
|
+++ b/drivers/staging/rtl8188eu/os_dep/mon.c
|
|
@@ -152,7 +152,7 @@ static const struct net_device_ops mon_netdev_ops = {
|
|
static void mon_setup(struct net_device *dev)
|
|
{
|
|
dev->netdev_ops = &mon_netdev_ops;
|
|
- dev->destructor = free_netdev;
|
|
+ dev->needs_free_netdev = true;
|
|
ether_setup(dev);
|
|
dev->priv_flags |= IFF_NO_QUEUE;
|
|
dev->type = ARPHRD_IEEE80211;
|
|
diff --git a/drivers/usb/gadget/function/f_phonet.c b/drivers/usb/gadget/function/f_phonet.c
|
|
index b4058f0000e4..6a1ce6a55158 100644
|
|
--- a/drivers/usb/gadget/function/f_phonet.c
|
|
+++ b/drivers/usb/gadget/function/f_phonet.c
|
|
@@ -281,7 +281,7 @@ static void pn_net_setup(struct net_device *dev)
|
|
dev->tx_queue_len = 1;
|
|
|
|
dev->netdev_ops = &pn_netdev_ops;
|
|
- dev->destructor = free_netdev;
|
|
+ dev->needs_free_netdev = true;
|
|
dev->header_ops = &phonet_header_ops;
|
|
}
|
|
|
|
diff --git a/drivers/watchdog/bcm_kona_wdt.c b/drivers/watchdog/bcm_kona_wdt.c
|
|
index 6fce17d5b9f1..a5775dfd8d5f 100644
|
|
--- a/drivers/watchdog/bcm_kona_wdt.c
|
|
+++ b/drivers/watchdog/bcm_kona_wdt.c
|
|
@@ -304,6 +304,8 @@ static int bcm_kona_wdt_probe(struct platform_device *pdev)
|
|
if (!wdt)
|
|
return -ENOMEM;
|
|
|
|
+ spin_lock_init(&wdt->lock);
|
|
+
|
|
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
|
wdt->base = devm_ioremap_resource(dev, res);
|
|
if (IS_ERR(wdt->base))
|
|
@@ -316,7 +318,6 @@ static int bcm_kona_wdt_probe(struct platform_device *pdev)
|
|
return ret;
|
|
}
|
|
|
|
- spin_lock_init(&wdt->lock);
|
|
platform_set_drvdata(pdev, wdt);
|
|
watchdog_set_drvdata(&bcm_kona_wdt_wdd, wdt);
|
|
bcm_kona_wdt_wdd.parent = &pdev->dev;
|
|
diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c
|
|
index 773774531aff..c5e27ebd8da8 100644
|
|
--- a/fs/nfs/callback.c
|
|
+++ b/fs/nfs/callback.c
|
|
@@ -280,7 +280,7 @@ static struct svc_serv *nfs_callback_create_svc(int minorversion)
|
|
printk(KERN_WARNING "nfs_callback_create_svc: no kthread, %d users??\n",
|
|
cb_info->users);
|
|
|
|
- serv = svc_create(&nfs4_callback_program, NFS4_CALLBACK_BUFSIZE, sv_ops);
|
|
+ serv = svc_create_pooled(&nfs4_callback_program, NFS4_CALLBACK_BUFSIZE, sv_ops);
|
|
if (!serv) {
|
|
printk(KERN_ERR "nfs_callback_create_svc: create service failed\n");
|
|
return ERR_PTR(-ENOMEM);
|
|
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
|
|
index f92ba8d6c556..66c743eddac9 100644
|
|
--- a/fs/nfs/dir.c
|
|
+++ b/fs/nfs/dir.c
|
|
@@ -2002,29 +2002,6 @@ nfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry)
|
|
}
|
|
EXPORT_SYMBOL_GPL(nfs_link);
|
|
|
|
-static void
|
|
-nfs_complete_rename(struct rpc_task *task, struct nfs_renamedata *data)
|
|
-{
|
|
- struct dentry *old_dentry = data->old_dentry;
|
|
- struct dentry *new_dentry = data->new_dentry;
|
|
- struct inode *old_inode = d_inode(old_dentry);
|
|
- struct inode *new_inode = d_inode(new_dentry);
|
|
-
|
|
- nfs_mark_for_revalidate(old_inode);
|
|
-
|
|
- switch (task->tk_status) {
|
|
- case 0:
|
|
- if (new_inode != NULL)
|
|
- nfs_drop_nlink(new_inode);
|
|
- d_move(old_dentry, new_dentry);
|
|
- nfs_set_verifier(new_dentry,
|
|
- nfs_save_change_attribute(data->new_dir));
|
|
- break;
|
|
- case -ENOENT:
|
|
- nfs_dentry_handle_enoent(old_dentry);
|
|
- }
|
|
-}
|
|
-
|
|
/*
|
|
* RENAME
|
|
* FIXME: Some nfsds, like the Linux user space nfsd, may generate a
|
|
@@ -2055,7 +2032,7 @@ int nfs_rename(struct inode *old_dir, struct dentry *old_dentry,
|
|
{
|
|
struct inode *old_inode = d_inode(old_dentry);
|
|
struct inode *new_inode = d_inode(new_dentry);
|
|
- struct dentry *dentry = NULL;
|
|
+ struct dentry *dentry = NULL, *rehash = NULL;
|
|
struct rpc_task *task;
|
|
int error = -EBUSY;
|
|
|
|
@@ -2078,8 +2055,10 @@ int nfs_rename(struct inode *old_dir, struct dentry *old_dentry,
|
|
* To prevent any new references to the target during the
|
|
* rename, we unhash the dentry in advance.
|
|
*/
|
|
- if (!d_unhashed(new_dentry))
|
|
+ if (!d_unhashed(new_dentry)) {
|
|
d_drop(new_dentry);
|
|
+ rehash = new_dentry;
|
|
+ }
|
|
|
|
if (d_count(new_dentry) > 2) {
|
|
int err;
|
|
@@ -2096,6 +2075,7 @@ int nfs_rename(struct inode *old_dir, struct dentry *old_dentry,
|
|
goto out;
|
|
|
|
new_dentry = dentry;
|
|
+ rehash = NULL;
|
|
new_inode = NULL;
|
|
}
|
|
}
|
|
@@ -2104,8 +2084,7 @@ int nfs_rename(struct inode *old_dir, struct dentry *old_dentry,
|
|
if (new_inode != NULL)
|
|
NFS_PROTO(new_inode)->return_delegation(new_inode);
|
|
|
|
- task = nfs_async_rename(old_dir, new_dir, old_dentry, new_dentry,
|
|
- nfs_complete_rename);
|
|
+ task = nfs_async_rename(old_dir, new_dir, old_dentry, new_dentry, NULL);
|
|
if (IS_ERR(task)) {
|
|
error = PTR_ERR(task);
|
|
goto out;
|
|
@@ -2115,9 +2094,27 @@ int nfs_rename(struct inode *old_dir, struct dentry *old_dentry,
|
|
if (error == 0)
|
|
error = task->tk_status;
|
|
rpc_put_task(task);
|
|
+ nfs_mark_for_revalidate(old_inode);
|
|
out:
|
|
+ if (rehash)
|
|
+ d_rehash(rehash);
|
|
trace_nfs_rename_exit(old_dir, old_dentry,
|
|
new_dir, new_dentry, error);
|
|
+ if (!error) {
|
|
+ if (new_inode != NULL)
|
|
+ nfs_drop_nlink(new_inode);
|
|
+ /*
|
|
+ * The d_move() should be here instead of in an async RPC completion
|
|
+ * handler because we need the proper locks to move the dentry. If
|
|
+ * we're interrupted by a signal, the async RPC completion handler
|
|
+ * should mark the directories for revalidation.
|
|
+ */
|
|
+ d_move(old_dentry, new_dentry);
|
|
+ nfs_set_verifier(new_dentry,
|
|
+ nfs_save_change_attribute(new_dir));
|
|
+ } else if (error == -ENOENT)
|
|
+ nfs_dentry_handle_enoent(old_dentry);
|
|
+
|
|
/* new dentry created? */
|
|
if (dentry)
|
|
dput(dentry);
|
|
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
|
|
index 8ba6c0d4d499..932a1461758d 100644
|
|
--- a/fs/nfs/nfs4proc.c
|
|
+++ b/fs/nfs/nfs4proc.c
|
|
@@ -2588,7 +2588,8 @@ static inline void nfs4_exclusive_attrset(struct nfs4_opendata *opendata,
|
|
|
|
/* Except MODE, it seems harmless of setting twice. */
|
|
if (opendata->o_arg.createmode != NFS4_CREATE_EXCLUSIVE &&
|
|
- attrset[1] & FATTR4_WORD1_MODE)
|
|
+ (attrset[1] & FATTR4_WORD1_MODE ||
|
|
+ attrset[2] & FATTR4_WORD2_MODE_UMASK))
|
|
sattr->ia_valid &= ~ATTR_MODE;
|
|
|
|
if (attrset[2] & FATTR4_WORD2_SECURITY_LABEL)
|
|
@@ -8429,6 +8430,7 @@ static void nfs4_layoutget_release(void *calldata)
|
|
size_t max_pages = max_response_pages(server);
|
|
|
|
dprintk("--> %s\n", __func__);
|
|
+ nfs4_sequence_free_slot(&lgp->res.seq_res);
|
|
nfs4_free_pages(lgp->args.layout.pages, max_pages);
|
|
pnfs_put_layout_hdr(NFS_I(inode)->layout);
|
|
put_nfs_open_context(lgp->args.ctx);
|
|
@@ -8503,7 +8505,6 @@ nfs4_proc_layoutget(struct nfs4_layoutget *lgp, long *timeout, gfp_t gfp_flags)
|
|
/* if layoutp->len is 0, nfs4_layoutget_prepare called rpc_exit */
|
|
if (status == 0 && lgp->res.layoutp->len)
|
|
lseg = pnfs_layout_process(lgp);
|
|
- nfs4_sequence_free_slot(&lgp->res.seq_res);
|
|
rpc_put_task(task);
|
|
dprintk("<-- %s status=%d\n", __func__, status);
|
|
if (status)
|
|
diff --git a/fs/ocfs2/cluster/heartbeat.c b/fs/ocfs2/cluster/heartbeat.c
|
|
index f6e871760f8d..0da0332725aa 100644
|
|
--- a/fs/ocfs2/cluster/heartbeat.c
|
|
+++ b/fs/ocfs2/cluster/heartbeat.c
|
|
@@ -2242,13 +2242,13 @@ static void o2hb_heartbeat_group_drop_item(struct config_group *group,
|
|
spin_unlock(&o2hb_live_lock);
|
|
}
|
|
|
|
-static ssize_t o2hb_heartbeat_group_threshold_show(struct config_item *item,
|
|
+static ssize_t o2hb_heartbeat_group_dead_threshold_show(struct config_item *item,
|
|
char *page)
|
|
{
|
|
return sprintf(page, "%u\n", o2hb_dead_threshold);
|
|
}
|
|
|
|
-static ssize_t o2hb_heartbeat_group_threshold_store(struct config_item *item,
|
|
+static ssize_t o2hb_heartbeat_group_dead_threshold_store(struct config_item *item,
|
|
const char *page, size_t count)
|
|
{
|
|
unsigned long tmp;
|
|
@@ -2297,11 +2297,11 @@ static ssize_t o2hb_heartbeat_group_mode_store(struct config_item *item,
|
|
|
|
}
|
|
|
|
-CONFIGFS_ATTR(o2hb_heartbeat_group_, threshold);
|
|
+CONFIGFS_ATTR(o2hb_heartbeat_group_, dead_threshold);
|
|
CONFIGFS_ATTR(o2hb_heartbeat_group_, mode);
|
|
|
|
static struct configfs_attribute *o2hb_heartbeat_group_attrs[] = {
|
|
- &o2hb_heartbeat_group_attr_threshold,
|
|
+ &o2hb_heartbeat_group_attr_dead_threshold,
|
|
&o2hb_heartbeat_group_attr_mode,
|
|
NULL,
|
|
};
|
|
diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c
|
|
index 3b7c937a36b5..4689940a953c 100644
|
|
--- a/fs/ocfs2/dlmglue.c
|
|
+++ b/fs/ocfs2/dlmglue.c
|
|
@@ -2591,6 +2591,10 @@ void ocfs2_inode_unlock_tracker(struct inode *inode,
|
|
struct ocfs2_lock_res *lockres;
|
|
|
|
lockres = &OCFS2_I(inode)->ip_inode_lockres;
|
|
+ /* had_lock means that the currect process already takes the cluster
|
|
+ * lock previously. If had_lock is 1, we have nothing to do here, and
|
|
+ * it will get unlocked where we got the lock.
|
|
+ */
|
|
if (!had_lock) {
|
|
ocfs2_remove_holder(lockres, oh);
|
|
ocfs2_inode_unlock(inode, ex);
|
|
diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c
|
|
index 3c5384d9b3a5..f70c3778d600 100644
|
|
--- a/fs/ocfs2/xattr.c
|
|
+++ b/fs/ocfs2/xattr.c
|
|
@@ -1328,20 +1328,21 @@ static int ocfs2_xattr_get(struct inode *inode,
|
|
void *buffer,
|
|
size_t buffer_size)
|
|
{
|
|
- int ret;
|
|
+ int ret, had_lock;
|
|
struct buffer_head *di_bh = NULL;
|
|
+ struct ocfs2_lock_holder oh;
|
|
|
|
- ret = ocfs2_inode_lock(inode, &di_bh, 0);
|
|
- if (ret < 0) {
|
|
- mlog_errno(ret);
|
|
- return ret;
|
|
+ had_lock = ocfs2_inode_lock_tracker(inode, &di_bh, 0, &oh);
|
|
+ if (had_lock < 0) {
|
|
+ mlog_errno(had_lock);
|
|
+ return had_lock;
|
|
}
|
|
down_read(&OCFS2_I(inode)->ip_xattr_sem);
|
|
ret = ocfs2_xattr_get_nolock(inode, di_bh, name_index,
|
|
name, buffer, buffer_size);
|
|
up_read(&OCFS2_I(inode)->ip_xattr_sem);
|
|
|
|
- ocfs2_inode_unlock(inode, 0);
|
|
+ ocfs2_inode_unlock_tracker(inode, 0, &oh, had_lock);
|
|
|
|
brelse(di_bh);
|
|
|
|
@@ -3537,11 +3538,12 @@ int ocfs2_xattr_set(struct inode *inode,
|
|
{
|
|
struct buffer_head *di_bh = NULL;
|
|
struct ocfs2_dinode *di;
|
|
- int ret, credits, ref_meta = 0, ref_credits = 0;
|
|
+ int ret, credits, had_lock, ref_meta = 0, ref_credits = 0;
|
|
struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
|
|
struct inode *tl_inode = osb->osb_tl_inode;
|
|
struct ocfs2_xattr_set_ctxt ctxt = { NULL, NULL, NULL, };
|
|
struct ocfs2_refcount_tree *ref_tree = NULL;
|
|
+ struct ocfs2_lock_holder oh;
|
|
|
|
struct ocfs2_xattr_info xi = {
|
|
.xi_name_index = name_index,
|
|
@@ -3572,8 +3574,9 @@ int ocfs2_xattr_set(struct inode *inode,
|
|
return -ENOMEM;
|
|
}
|
|
|
|
- ret = ocfs2_inode_lock(inode, &di_bh, 1);
|
|
- if (ret < 0) {
|
|
+ had_lock = ocfs2_inode_lock_tracker(inode, &di_bh, 1, &oh);
|
|
+ if (had_lock < 0) {
|
|
+ ret = had_lock;
|
|
mlog_errno(ret);
|
|
goto cleanup_nolock;
|
|
}
|
|
@@ -3670,7 +3673,7 @@ int ocfs2_xattr_set(struct inode *inode,
|
|
if (ret)
|
|
mlog_errno(ret);
|
|
}
|
|
- ocfs2_inode_unlock(inode, 1);
|
|
+ ocfs2_inode_unlock_tracker(inode, 1, &oh, had_lock);
|
|
cleanup_nolock:
|
|
brelse(di_bh);
|
|
brelse(xbs.xattr_bh);
|
|
diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c
|
|
index 5b14c16d1b77..e83e2dc7ae0b 100644
|
|
--- a/fs/overlayfs/copy_up.c
|
|
+++ b/fs/overlayfs/copy_up.c
|
|
@@ -252,15 +252,9 @@ static int ovl_copy_up_locked(struct dentry *workdir, struct dentry *upperdir,
|
|
.link = link
|
|
};
|
|
|
|
- upper = lookup_one_len(dentry->d_name.name, upperdir,
|
|
- dentry->d_name.len);
|
|
- err = PTR_ERR(upper);
|
|
- if (IS_ERR(upper))
|
|
- goto out;
|
|
-
|
|
err = security_inode_copy_up(dentry, &new_creds);
|
|
if (err < 0)
|
|
- goto out1;
|
|
+ goto out;
|
|
|
|
if (new_creds)
|
|
old_creds = override_creds(new_creds);
|
|
@@ -284,7 +278,7 @@ static int ovl_copy_up_locked(struct dentry *workdir, struct dentry *upperdir,
|
|
}
|
|
|
|
if (err)
|
|
- goto out2;
|
|
+ goto out;
|
|
|
|
if (S_ISREG(stat->mode)) {
|
|
struct path upperpath;
|
|
@@ -317,6 +311,14 @@ static int ovl_copy_up_locked(struct dentry *workdir, struct dentry *upperdir,
|
|
if (err)
|
|
goto out_cleanup;
|
|
|
|
+ upper = lookup_one_len(dentry->d_name.name, upperdir,
|
|
+ dentry->d_name.len);
|
|
+ if (IS_ERR(upper)) {
|
|
+ err = PTR_ERR(upper);
|
|
+ upper = NULL;
|
|
+ goto out_cleanup;
|
|
+ }
|
|
+
|
|
if (tmpfile)
|
|
err = ovl_do_link(temp, udir, upper, true);
|
|
else
|
|
@@ -330,17 +332,15 @@ static int ovl_copy_up_locked(struct dentry *workdir, struct dentry *upperdir,
|
|
|
|
/* Restore timestamps on parent (best effort) */
|
|
ovl_set_timestamps(upperdir, pstat);
|
|
-out2:
|
|
+out:
|
|
dput(temp);
|
|
-out1:
|
|
dput(upper);
|
|
-out:
|
|
return err;
|
|
|
|
out_cleanup:
|
|
if (!tmpfile)
|
|
ovl_cleanup(wdir, temp);
|
|
- goto out2;
|
|
+ goto out;
|
|
}
|
|
|
|
/*
|
|
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
|
|
index 97456b2539e4..aa38bb18c81c 100644
|
|
--- a/include/linux/netdevice.h
|
|
+++ b/include/linux/netdevice.h
|
|
@@ -1581,8 +1581,8 @@ enum netdev_priv_flags {
|
|
* @rtnl_link_state: This enum represents the phases of creating
|
|
* a new link
|
|
*
|
|
- * @destructor: Called from unregister,
|
|
- * can be used to call free_netdev
|
|
+ * @needs_free_netdev: Should unregister perform free_netdev?
|
|
+ * @priv_destructor: Called from unregister
|
|
* @npinfo: XXX: need comments on this one
|
|
* @nd_net: Network namespace this network device is inside
|
|
*
|
|
@@ -1838,7 +1838,8 @@ struct net_device {
|
|
RTNL_LINK_INITIALIZING,
|
|
} rtnl_link_state:16;
|
|
|
|
- void (*destructor)(struct net_device *dev);
|
|
+ bool needs_free_netdev;
|
|
+ void (*priv_destructor)(struct net_device *dev);
|
|
|
|
#ifdef CONFIG_NETPOLL
|
|
struct netpoll_info __rcu *npinfo;
|
|
@@ -4231,6 +4232,11 @@ static inline const char *netdev_name(const struct net_device *dev)
|
|
return dev->name;
|
|
}
|
|
|
|
+static inline bool netdev_unregistering(const struct net_device *dev)
|
|
+{
|
|
+ return dev->reg_state == NETREG_UNREGISTERING;
|
|
+}
|
|
+
|
|
static inline const char *netdev_reg_state(const struct net_device *dev)
|
|
{
|
|
switch (dev->reg_state) {
|
|
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
|
|
index 14d82bf16692..85bc8e7ade2e 100644
|
|
--- a/include/net/xfrm.h
|
|
+++ b/include/net/xfrm.h
|
|
@@ -945,10 +945,6 @@ struct xfrm_dst {
|
|
struct flow_cache_object flo;
|
|
struct xfrm_policy *pols[XFRM_POLICY_TYPE_MAX];
|
|
int num_pols, num_xfrms;
|
|
-#ifdef CONFIG_XFRM_SUB_POLICY
|
|
- struct flowi *origin;
|
|
- struct xfrm_selector *partner;
|
|
-#endif
|
|
u32 xfrm_genid;
|
|
u32 policy_genid;
|
|
u32 route_mtu_cached;
|
|
@@ -964,12 +960,6 @@ static inline void xfrm_dst_destroy(struct xfrm_dst *xdst)
|
|
dst_release(xdst->route);
|
|
if (likely(xdst->u.dst.xfrm))
|
|
xfrm_state_put(xdst->u.dst.xfrm);
|
|
-#ifdef CONFIG_XFRM_SUB_POLICY
|
|
- kfree(xdst->origin);
|
|
- xdst->origin = NULL;
|
|
- kfree(xdst->partner);
|
|
- xdst->partner = NULL;
|
|
-#endif
|
|
}
|
|
#endif
|
|
|
|
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
|
|
index 0b057628a7ba..926ef9e8c71b 100644
|
|
--- a/mm/vmalloc.c
|
|
+++ b/mm/vmalloc.c
|
|
@@ -287,10 +287,21 @@ struct page *vmalloc_to_page(const void *vmalloc_addr)
|
|
if (p4d_none(*p4d))
|
|
return NULL;
|
|
pud = pud_offset(p4d, addr);
|
|
- if (pud_none(*pud))
|
|
+
|
|
+ /*
|
|
+ * Don't dereference bad PUD or PMD (below) entries. This will also
|
|
+ * identify huge mappings, which we may encounter on architectures
|
|
+ * that define CONFIG_HAVE_ARCH_HUGE_VMAP=y. Such regions will be
|
|
+ * identified as vmalloc addresses by is_vmalloc_addr(), but are
|
|
+ * not [unambiguously] associated with a struct page, so there is
|
|
+ * no correct value to return for them.
|
|
+ */
|
|
+ WARN_ON_ONCE(pud_bad(*pud));
|
|
+ if (pud_none(*pud) || pud_bad(*pud))
|
|
return NULL;
|
|
pmd = pmd_offset(pud, addr);
|
|
- if (pmd_none(*pmd))
|
|
+ WARN_ON_ONCE(pmd_bad(*pmd));
|
|
+ if (pmd_none(*pmd) || pmd_bad(*pmd))
|
|
return NULL;
|
|
|
|
ptep = pte_offset_map(pmd, addr);
|
|
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c
|
|
index 467069b73ce1..9649579b5b9f 100644
|
|
--- a/net/8021q/vlan.c
|
|
+++ b/net/8021q/vlan.c
|
|
@@ -277,7 +277,8 @@ static int register_vlan_device(struct net_device *real_dev, u16 vlan_id)
|
|
return 0;
|
|
|
|
out_free_newdev:
|
|
- free_netdev(new_dev);
|
|
+ if (new_dev->reg_state == NETREG_UNINITIALIZED)
|
|
+ free_netdev(new_dev);
|
|
return err;
|
|
}
|
|
|
|
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c
|
|
index e97ab824e368..0064dfd328d4 100644
|
|
--- a/net/8021q/vlan_dev.c
|
|
+++ b/net/8021q/vlan_dev.c
|
|
@@ -807,7 +807,6 @@ static void vlan_dev_free(struct net_device *dev)
|
|
|
|
free_percpu(vlan->vlan_pcpu_stats);
|
|
vlan->vlan_pcpu_stats = NULL;
|
|
- free_netdev(dev);
|
|
}
|
|
|
|
void vlan_setup(struct net_device *dev)
|
|
@@ -820,7 +819,8 @@ void vlan_setup(struct net_device *dev)
|
|
netif_keep_dst(dev);
|
|
|
|
dev->netdev_ops = &vlan_netdev_ops;
|
|
- dev->destructor = vlan_dev_free;
|
|
+ dev->needs_free_netdev = true;
|
|
+ dev->priv_destructor = vlan_dev_free;
|
|
dev->ethtool_ops = &vlan_ethtool_ops;
|
|
|
|
dev->min_mtu = 0;
|
|
diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c
|
|
index d042c99af028..07ca0e8f30b2 100644
|
|
--- a/net/batman-adv/soft-interface.c
|
|
+++ b/net/batman-adv/soft-interface.c
|
|
@@ -961,8 +961,6 @@ static void batadv_softif_free(struct net_device *dev)
|
|
* netdev and its private data (bat_priv)
|
|
*/
|
|
rcu_barrier();
|
|
-
|
|
- free_netdev(dev);
|
|
}
|
|
|
|
/**
|
|
@@ -976,7 +974,8 @@ static void batadv_softif_init_early(struct net_device *dev)
|
|
ether_setup(dev);
|
|
|
|
dev->netdev_ops = &batadv_netdev_ops;
|
|
- dev->destructor = batadv_softif_free;
|
|
+ dev->needs_free_netdev = true;
|
|
+ dev->priv_destructor = batadv_softif_free;
|
|
dev->features |= NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_NETNS_LOCAL;
|
|
dev->priv_flags |= IFF_NO_QUEUE;
|
|
|
|
diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
|
|
index d491529332f4..7ffeca72e928 100644
|
|
--- a/net/bluetooth/6lowpan.c
|
|
+++ b/net/bluetooth/6lowpan.c
|
|
@@ -653,7 +653,7 @@ static void netdev_setup(struct net_device *dev)
|
|
|
|
dev->netdev_ops = &netdev_ops;
|
|
dev->header_ops = &header_ops;
|
|
- dev->destructor = free_netdev;
|
|
+ dev->needs_free_netdev = true;
|
|
}
|
|
|
|
static struct device_type bt_type = {
|
|
diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c
|
|
index 430b53e7d941..f0f3447e8aa4 100644
|
|
--- a/net/bridge/br_device.c
|
|
+++ b/net/bridge/br_device.c
|
|
@@ -379,7 +379,7 @@ void br_dev_setup(struct net_device *dev)
|
|
ether_setup(dev);
|
|
|
|
dev->netdev_ops = &br_netdev_ops;
|
|
- dev->destructor = free_netdev;
|
|
+ dev->needs_free_netdev = true;
|
|
dev->ethtool_ops = &br_ethtool_ops;
|
|
SET_NETDEV_DEVTYPE(dev, &br_type);
|
|
dev->priv_flags = IFF_EBRIDGE | IFF_NO_QUEUE;
|
|
diff --git a/net/caif/cfpkt_skbuff.c b/net/caif/cfpkt_skbuff.c
|
|
index 59ce1fcc220c..71b6ab240dea 100644
|
|
--- a/net/caif/cfpkt_skbuff.c
|
|
+++ b/net/caif/cfpkt_skbuff.c
|
|
@@ -81,11 +81,7 @@ static struct cfpkt *cfpkt_create_pfx(u16 len, u16 pfx)
|
|
{
|
|
struct sk_buff *skb;
|
|
|
|
- if (likely(in_interrupt()))
|
|
- skb = alloc_skb(len + pfx, GFP_ATOMIC);
|
|
- else
|
|
- skb = alloc_skb(len + pfx, GFP_KERNEL);
|
|
-
|
|
+ skb = alloc_skb(len + pfx, GFP_ATOMIC);
|
|
if (unlikely(skb == NULL))
|
|
return NULL;
|
|
|
|
diff --git a/net/caif/chnl_net.c b/net/caif/chnl_net.c
|
|
index 1816fc9f1ee7..fe3c53efb949 100644
|
|
--- a/net/caif/chnl_net.c
|
|
+++ b/net/caif/chnl_net.c
|
|
@@ -392,14 +392,14 @@ static void chnl_net_destructor(struct net_device *dev)
|
|
{
|
|
struct chnl_net *priv = netdev_priv(dev);
|
|
caif_free_client(&priv->chnl);
|
|
- free_netdev(dev);
|
|
}
|
|
|
|
static void ipcaif_net_setup(struct net_device *dev)
|
|
{
|
|
struct chnl_net *priv;
|
|
dev->netdev_ops = &netdev_ops;
|
|
- dev->destructor = chnl_net_destructor;
|
|
+ dev->needs_free_netdev = true;
|
|
+ dev->priv_destructor = chnl_net_destructor;
|
|
dev->flags |= IFF_NOARP;
|
|
dev->flags |= IFF_POINTOPOINT;
|
|
dev->mtu = GPRS_PDP_MTU;
|
|
diff --git a/net/core/dev.c b/net/core/dev.c
|
|
index 9b5875388c23..9debc1b26ce9 100644
|
|
--- a/net/core/dev.c
|
|
+++ b/net/core/dev.c
|
|
@@ -1251,8 +1251,9 @@ int dev_set_alias(struct net_device *dev, const char *alias, size_t len)
|
|
if (!new_ifalias)
|
|
return -ENOMEM;
|
|
dev->ifalias = new_ifalias;
|
|
+ memcpy(dev->ifalias, alias, len);
|
|
+ dev->ifalias[len] = 0;
|
|
|
|
- strlcpy(dev->ifalias, alias, len+1);
|
|
return len;
|
|
}
|
|
|
|
@@ -7345,6 +7346,8 @@ int register_netdevice(struct net_device *dev)
|
|
err_uninit:
|
|
if (dev->netdev_ops->ndo_uninit)
|
|
dev->netdev_ops->ndo_uninit(dev);
|
|
+ if (dev->priv_destructor)
|
|
+ dev->priv_destructor(dev);
|
|
goto out;
|
|
}
|
|
EXPORT_SYMBOL(register_netdevice);
|
|
@@ -7552,8 +7555,10 @@ void netdev_run_todo(void)
|
|
WARN_ON(rcu_access_pointer(dev->ip6_ptr));
|
|
WARN_ON(dev->dn_ptr);
|
|
|
|
- if (dev->destructor)
|
|
- dev->destructor(dev);
|
|
+ if (dev->priv_destructor)
|
|
+ dev->priv_destructor(dev);
|
|
+ if (dev->needs_free_netdev)
|
|
+ free_netdev(dev);
|
|
|
|
/* Report a network device has been unregistered */
|
|
rtnl_lock();
|
|
diff --git a/net/core/dst.c b/net/core/dst.c
|
|
index 6192f11beec9..13ba4a090c41 100644
|
|
--- a/net/core/dst.c
|
|
+++ b/net/core/dst.c
|
|
@@ -469,6 +469,20 @@ static int dst_dev_event(struct notifier_block *this, unsigned long event,
|
|
spin_lock_bh(&dst_garbage.lock);
|
|
dst = dst_garbage.list;
|
|
dst_garbage.list = NULL;
|
|
+ /* The code in dst_ifdown places a hold on the loopback device.
|
|
+ * If the gc entry processing is set to expire after a lengthy
|
|
+ * interval, this hold can cause netdev_wait_allrefs() to hang
|
|
+ * out and wait for a long time -- until the the loopback
|
|
+ * interface is released. If we're really unlucky, it'll emit
|
|
+ * pr_emerg messages to console too. Reset the interval here,
|
|
+ * so dst cleanups occur in a more timely fashion.
|
|
+ */
|
|
+ if (dst_garbage.timer_inc > DST_GC_INC) {
|
|
+ dst_garbage.timer_inc = DST_GC_INC;
|
|
+ dst_garbage.timer_expires = DST_GC_MIN;
|
|
+ mod_delayed_work(system_wq, &dst_gc_work,
|
|
+ dst_garbage.timer_expires);
|
|
+ }
|
|
spin_unlock_bh(&dst_garbage.lock);
|
|
|
|
if (last)
|
|
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
|
|
index 8d4a185a8143..05436c02fb7b 100644
|
|
--- a/net/core/rtnetlink.c
|
|
+++ b/net/core/rtnetlink.c
|
|
@@ -934,6 +934,7 @@ static noinline size_t if_nlmsg_size(const struct net_device *dev,
|
|
+ nla_total_size(1) /* IFLA_LINKMODE */
|
|
+ nla_total_size(4) /* IFLA_CARRIER_CHANGES */
|
|
+ nla_total_size(4) /* IFLA_LINK_NETNSID */
|
|
+ + nla_total_size(4) /* IFLA_GROUP */
|
|
+ nla_total_size(ext_filter_mask
|
|
& RTEXT_FILTER_VF ? 4 : 0) /* IFLA_NUM_VF */
|
|
+ rtnl_vfinfo_size(dev, ext_filter_mask) /* IFLA_VFINFO_LIST */
|
|
@@ -1127,6 +1128,8 @@ static noinline_for_stack int rtnl_fill_vfinfo(struct sk_buff *skb,
|
|
struct ifla_vf_mac vf_mac;
|
|
struct ifla_vf_info ivi;
|
|
|
|
+ memset(&ivi, 0, sizeof(ivi));
|
|
+
|
|
/* Not all SR-IOV capable drivers support the
|
|
* spoofcheck and "RSS query enable" query. Preset to
|
|
* -1 so the user space tool can detect that the driver
|
|
@@ -1135,7 +1138,6 @@ static noinline_for_stack int rtnl_fill_vfinfo(struct sk_buff *skb,
|
|
ivi.spoofchk = -1;
|
|
ivi.rss_query_en = -1;
|
|
ivi.trusted = -1;
|
|
- memset(ivi.mac, 0, sizeof(ivi.mac));
|
|
/* The default value for VF link state is "auto"
|
|
* IFLA_VF_LINK_STATE_AUTO which equals zero
|
|
*/
|
|
@@ -1461,6 +1463,7 @@ static const struct nla_policy ifla_policy[IFLA_MAX+1] = {
|
|
[IFLA_LINK_NETNSID] = { .type = NLA_S32 },
|
|
[IFLA_PROTO_DOWN] = { .type = NLA_U8 },
|
|
[IFLA_XDP] = { .type = NLA_NESTED },
|
|
+ [IFLA_GROUP] = { .type = NLA_U32 },
|
|
};
|
|
|
|
static const struct nla_policy ifla_info_policy[IFLA_INFO_MAX+1] = {
|
|
diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c
|
|
index b1dc096d22f8..403593bd2b83 100644
|
|
--- a/net/decnet/dn_route.c
|
|
+++ b/net/decnet/dn_route.c
|
|
@@ -188,12 +188,6 @@ static inline void dnrt_free(struct dn_route *rt)
|
|
call_rcu_bh(&rt->dst.rcu_head, dst_rcu_free);
|
|
}
|
|
|
|
-static inline void dnrt_drop(struct dn_route *rt)
|
|
-{
|
|
- dst_release(&rt->dst);
|
|
- call_rcu_bh(&rt->dst.rcu_head, dst_rcu_free);
|
|
-}
|
|
-
|
|
static void dn_dst_check_expire(unsigned long dummy)
|
|
{
|
|
int i;
|
|
@@ -248,7 +242,7 @@ static int dn_dst_gc(struct dst_ops *ops)
|
|
}
|
|
*rtp = rt->dst.dn_next;
|
|
rt->dst.dn_next = NULL;
|
|
- dnrt_drop(rt);
|
|
+ dnrt_free(rt);
|
|
break;
|
|
}
|
|
spin_unlock_bh(&dn_rt_hash_table[i].lock);
|
|
@@ -350,7 +344,7 @@ static int dn_insert_route(struct dn_route *rt, unsigned int hash, struct dn_rou
|
|
dst_use(&rth->dst, now);
|
|
spin_unlock_bh(&dn_rt_hash_table[hash].lock);
|
|
|
|
- dnrt_drop(rt);
|
|
+ dst_free(&rt->dst);
|
|
*rp = rth;
|
|
return 0;
|
|
}
|
|
@@ -380,7 +374,7 @@ static void dn_run_flush(unsigned long dummy)
|
|
for(; rt; rt = next) {
|
|
next = rcu_dereference_raw(rt->dst.dn_next);
|
|
RCU_INIT_POINTER(rt->dst.dn_next, NULL);
|
|
- dst_free((struct dst_entry *)rt);
|
|
+ dnrt_free(rt);
|
|
}
|
|
|
|
nothing_to_declare:
|
|
@@ -1187,7 +1181,7 @@ static int dn_route_output_slow(struct dst_entry **pprt, const struct flowidn *o
|
|
if (dev_out->flags & IFF_LOOPBACK)
|
|
flags |= RTCF_LOCAL;
|
|
|
|
- rt = dst_alloc(&dn_dst_ops, dev_out, 1, DST_OBSOLETE_NONE, DST_HOST);
|
|
+ rt = dst_alloc(&dn_dst_ops, dev_out, 0, DST_OBSOLETE_NONE, DST_HOST);
|
|
if (rt == NULL)
|
|
goto e_nobufs;
|
|
|
|
diff --git a/net/decnet/netfilter/dn_rtmsg.c b/net/decnet/netfilter/dn_rtmsg.c
|
|
index 85f2fdc360c2..29246bc9a7b4 100644
|
|
--- a/net/decnet/netfilter/dn_rtmsg.c
|
|
+++ b/net/decnet/netfilter/dn_rtmsg.c
|
|
@@ -102,7 +102,9 @@ static inline void dnrmg_receive_user_skb(struct sk_buff *skb)
|
|
{
|
|
struct nlmsghdr *nlh = nlmsg_hdr(skb);
|
|
|
|
- if (nlh->nlmsg_len < sizeof(*nlh) || skb->len < nlh->nlmsg_len)
|
|
+ if (skb->len < sizeof(*nlh) ||
|
|
+ nlh->nlmsg_len < sizeof(*nlh) ||
|
|
+ skb->len < nlh->nlmsg_len)
|
|
return;
|
|
|
|
if (!netlink_capable(skb, CAP_NET_ADMIN))
|
|
diff --git a/net/hsr/hsr_device.c b/net/hsr/hsr_device.c
|
|
index c73160fb11e7..0a0a392dc2bd 100644
|
|
--- a/net/hsr/hsr_device.c
|
|
+++ b/net/hsr/hsr_device.c
|
|
@@ -378,7 +378,6 @@ static void hsr_dev_destroy(struct net_device *hsr_dev)
|
|
del_timer_sync(&hsr->announce_timer);
|
|
|
|
synchronize_rcu();
|
|
- free_netdev(hsr_dev);
|
|
}
|
|
|
|
static const struct net_device_ops hsr_device_ops = {
|
|
@@ -404,7 +403,8 @@ void hsr_dev_setup(struct net_device *dev)
|
|
SET_NETDEV_DEVTYPE(dev, &hsr_type);
|
|
dev->priv_flags |= IFF_NO_QUEUE;
|
|
|
|
- dev->destructor = hsr_dev_destroy;
|
|
+ dev->needs_free_netdev = true;
|
|
+ dev->priv_destructor = hsr_dev_destroy;
|
|
|
|
dev->hw_features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HIGHDMA |
|
|
NETIF_F_GSO_MASK | NETIF_F_HW_CSUM |
|
|
diff --git a/net/ieee802154/6lowpan/core.c b/net/ieee802154/6lowpan/core.c
|
|
index d7efbf0dad20..0a866f332290 100644
|
|
--- a/net/ieee802154/6lowpan/core.c
|
|
+++ b/net/ieee802154/6lowpan/core.c
|
|
@@ -107,7 +107,7 @@ static void lowpan_setup(struct net_device *ldev)
|
|
|
|
ldev->netdev_ops = &lowpan_netdev_ops;
|
|
ldev->header_ops = &lowpan_header_ops;
|
|
- ldev->destructor = free_netdev;
|
|
+ ldev->needs_free_netdev = true;
|
|
ldev->features |= NETIF_F_NETNS_LOCAL;
|
|
}
|
|
|
|
diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c
|
|
index b1e24446e297..9708a32b1f26 100644
|
|
--- a/net/ipv4/esp4.c
|
|
+++ b/net/ipv4/esp4.c
|
|
@@ -212,6 +212,7 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb)
|
|
u8 *iv;
|
|
u8 *tail;
|
|
u8 *vaddr;
|
|
+ int esph_offset;
|
|
int blksize;
|
|
int clen;
|
|
int alen;
|
|
@@ -392,12 +393,14 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb)
|
|
}
|
|
|
|
cow:
|
|
+ esph_offset = (unsigned char *)esph - skb_transport_header(skb);
|
|
+
|
|
err = skb_cow_data(skb, tailen, &trailer);
|
|
if (err < 0)
|
|
goto error;
|
|
nfrags = err;
|
|
tail = skb_tail_pointer(trailer);
|
|
- esph = ip_esp_hdr(skb);
|
|
+ esph = (struct ip_esp_hdr *)(skb_transport_header(skb) + esph_offset);
|
|
|
|
skip_cow:
|
|
esp_output_fill_trailer(tail, tfclen, plen, proto);
|
|
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
|
|
index fc310db2708b..760311fd7c5b 100644
|
|
--- a/net/ipv4/icmp.c
|
|
+++ b/net/ipv4/icmp.c
|
|
@@ -674,8 +674,12 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info)
|
|
/* Needed by both icmp_global_allow and icmp_xmit_lock */
|
|
local_bh_disable();
|
|
|
|
- /* Check global sysctl_icmp_msgs_per_sec ratelimit */
|
|
- if (!icmpv4_global_allow(net, type, code))
|
|
+ /* Check global sysctl_icmp_msgs_per_sec ratelimit, unless
|
|
+ * incoming dev is loopback. If outgoing dev change to not be
|
|
+ * loopback, then peer ratelimit still work (in icmpv4_xrlim_allow)
|
|
+ */
|
|
+ if (!(skb_in->dev && (skb_in->dev->flags&IFF_LOOPBACK)) &&
|
|
+ !icmpv4_global_allow(net, type, code))
|
|
goto out_bh_enable;
|
|
|
|
sk = icmp_xmit_lock(net);
|
|
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
|
|
index 44fd86de2823..ec9a396fa466 100644
|
|
--- a/net/ipv4/igmp.c
|
|
+++ b/net/ipv4/igmp.c
|
|
@@ -1112,6 +1112,7 @@ static void igmpv3_add_delrec(struct in_device *in_dev, struct ip_mc_list *im)
|
|
pmc = kzalloc(sizeof(*pmc), GFP_KERNEL);
|
|
if (!pmc)
|
|
return;
|
|
+ spin_lock_init(&pmc->lock);
|
|
spin_lock_bh(&im->lock);
|
|
pmc->interface = im->interface;
|
|
in_dev_hold(in_dev);
|
|
@@ -2071,21 +2072,26 @@ static int ip_mc_add_src(struct in_device *in_dev, __be32 *pmca, int sfmode,
|
|
|
|
static void ip_mc_clear_src(struct ip_mc_list *pmc)
|
|
{
|
|
- struct ip_sf_list *psf, *nextpsf;
|
|
+ struct ip_sf_list *psf, *nextpsf, *tomb, *sources;
|
|
|
|
- for (psf = pmc->tomb; psf; psf = nextpsf) {
|
|
+ spin_lock_bh(&pmc->lock);
|
|
+ tomb = pmc->tomb;
|
|
+ pmc->tomb = NULL;
|
|
+ sources = pmc->sources;
|
|
+ pmc->sources = NULL;
|
|
+ pmc->sfmode = MCAST_EXCLUDE;
|
|
+ pmc->sfcount[MCAST_INCLUDE] = 0;
|
|
+ pmc->sfcount[MCAST_EXCLUDE] = 1;
|
|
+ spin_unlock_bh(&pmc->lock);
|
|
+
|
|
+ for (psf = tomb; psf; psf = nextpsf) {
|
|
nextpsf = psf->sf_next;
|
|
kfree(psf);
|
|
}
|
|
- pmc->tomb = NULL;
|
|
- for (psf = pmc->sources; psf; psf = nextpsf) {
|
|
+ for (psf = sources; psf; psf = nextpsf) {
|
|
nextpsf = psf->sf_next;
|
|
kfree(psf);
|
|
}
|
|
- pmc->sources = NULL;
|
|
- pmc->sfmode = MCAST_EXCLUDE;
|
|
- pmc->sfcount[MCAST_INCLUDE] = 0;
|
|
- pmc->sfcount[MCAST_EXCLUDE] = 1;
|
|
}
|
|
|
|
/* Join a multicast group
|
|
diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c
|
|
index 823abaef006b..b2d1be55ca94 100644
|
|
--- a/net/ipv4/ip_tunnel.c
|
|
+++ b/net/ipv4/ip_tunnel.c
|
|
@@ -961,7 +961,6 @@ static void ip_tunnel_dev_free(struct net_device *dev)
|
|
gro_cells_destroy(&tunnel->gro_cells);
|
|
dst_cache_destroy(&tunnel->dst_cache);
|
|
free_percpu(dev->tstats);
|
|
- free_netdev(dev);
|
|
}
|
|
|
|
void ip_tunnel_dellink(struct net_device *dev, struct list_head *head)
|
|
@@ -1148,7 +1147,8 @@ int ip_tunnel_init(struct net_device *dev)
|
|
struct iphdr *iph = &tunnel->parms.iph;
|
|
int err;
|
|
|
|
- dev->destructor = ip_tunnel_dev_free;
|
|
+ dev->needs_free_netdev = true;
|
|
+ dev->priv_destructor = ip_tunnel_dev_free;
|
|
dev->tstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats);
|
|
if (!dev->tstats)
|
|
return -ENOMEM;
|
|
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
|
|
index b036e85e093b..96c5681abb05 100644
|
|
--- a/net/ipv4/ipmr.c
|
|
+++ b/net/ipv4/ipmr.c
|
|
@@ -501,7 +501,7 @@ static void reg_vif_setup(struct net_device *dev)
|
|
dev->mtu = ETH_DATA_LEN - sizeof(struct iphdr) - 8;
|
|
dev->flags = IFF_NOARP;
|
|
dev->netdev_ops = ®_vif_netdev_ops;
|
|
- dev->destructor = free_netdev;
|
|
+ dev->needs_free_netdev = true;
|
|
dev->features |= NETIF_F_NETNS_LOCAL;
|
|
}
|
|
|
|
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
|
|
index 311f45641673..9725e8faf56d 100644
|
|
--- a/net/ipv6/addrconf.c
|
|
+++ b/net/ipv6/addrconf.c
|
|
@@ -328,9 +328,9 @@ static void addrconf_mod_rs_timer(struct inet6_dev *idev,
|
|
static void addrconf_mod_dad_work(struct inet6_ifaddr *ifp,
|
|
unsigned long delay)
|
|
{
|
|
- if (!delayed_work_pending(&ifp->dad_work))
|
|
- in6_ifa_hold(ifp);
|
|
- mod_delayed_work(addrconf_wq, &ifp->dad_work, delay);
|
|
+ in6_ifa_hold(ifp);
|
|
+ if (mod_delayed_work(addrconf_wq, &ifp->dad_work, delay))
|
|
+ in6_ifa_put(ifp);
|
|
}
|
|
|
|
static int snmp6_alloc_dev(struct inet6_dev *idev)
|
|
diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c
|
|
index eea23b57c6a5..ec849d88a662 100644
|
|
--- a/net/ipv6/fib6_rules.c
|
|
+++ b/net/ipv6/fib6_rules.c
|
|
@@ -32,7 +32,6 @@ struct fib6_rule {
|
|
struct dst_entry *fib6_rule_lookup(struct net *net, struct flowi6 *fl6,
|
|
int flags, pol_lookup_t lookup)
|
|
{
|
|
- struct rt6_info *rt;
|
|
struct fib_lookup_arg arg = {
|
|
.lookup_ptr = lookup,
|
|
.flags = FIB_LOOKUP_NOREF,
|
|
@@ -44,21 +43,11 @@ struct dst_entry *fib6_rule_lookup(struct net *net, struct flowi6 *fl6,
|
|
fib_rules_lookup(net->ipv6.fib6_rules_ops,
|
|
flowi6_to_flowi(fl6), flags, &arg);
|
|
|
|
- rt = arg.result;
|
|
+ if (arg.result)
|
|
+ return arg.result;
|
|
|
|
- if (!rt) {
|
|
- dst_hold(&net->ipv6.ip6_null_entry->dst);
|
|
- return &net->ipv6.ip6_null_entry->dst;
|
|
- }
|
|
-
|
|
- if (rt->rt6i_flags & RTF_REJECT &&
|
|
- rt->dst.error == -EAGAIN) {
|
|
- ip6_rt_put(rt);
|
|
- rt = net->ipv6.ip6_null_entry;
|
|
- dst_hold(&rt->dst);
|
|
- }
|
|
-
|
|
- return &rt->dst;
|
|
+ dst_hold(&net->ipv6.ip6_null_entry->dst);
|
|
+ return &net->ipv6.ip6_null_entry->dst;
|
|
}
|
|
|
|
static int fib6_rule_action(struct fib_rule *rule, struct flowi *flp,
|
|
@@ -121,7 +110,8 @@ static int fib6_rule_action(struct fib_rule *rule, struct flowi *flp,
|
|
flp6->saddr = saddr;
|
|
}
|
|
err = rt->dst.error;
|
|
- goto out;
|
|
+ if (err != -EAGAIN)
|
|
+ goto out;
|
|
}
|
|
again:
|
|
ip6_rt_put(rt);
|
|
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
|
|
index 230b5aac9f03..8d7b113958b1 100644
|
|
--- a/net/ipv6/icmp.c
|
|
+++ b/net/ipv6/icmp.c
|
|
@@ -491,7 +491,7 @@ static void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info,
|
|
local_bh_disable();
|
|
|
|
/* Check global sysctl_icmp_msgs_per_sec ratelimit */
|
|
- if (!icmpv6_global_allow(type))
|
|
+ if (!(skb->dev->flags&IFF_LOOPBACK) && !icmpv6_global_allow(type))
|
|
goto out_bh_enable;
|
|
|
|
mip6_addr_swap(skb);
|
|
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
|
|
index d4bf2c68a545..e6b78ba0e636 100644
|
|
--- a/net/ipv6/ip6_fib.c
|
|
+++ b/net/ipv6/ip6_fib.c
|
|
@@ -289,8 +289,7 @@ struct dst_entry *fib6_rule_lookup(struct net *net, struct flowi6 *fl6,
|
|
struct rt6_info *rt;
|
|
|
|
rt = lookup(net, net->ipv6.fib6_main_tbl, fl6, flags);
|
|
- if (rt->rt6i_flags & RTF_REJECT &&
|
|
- rt->dst.error == -EAGAIN) {
|
|
+ if (rt->dst.error == -EAGAIN) {
|
|
ip6_rt_put(rt);
|
|
rt = net->ipv6.ip6_null_entry;
|
|
dst_hold(&rt->dst);
|
|
diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c
|
|
index 4d60164c17e2..0f1c24935b7a 100644
|
|
--- a/net/ipv6/ip6_gre.c
|
|
+++ b/net/ipv6/ip6_gre.c
|
|
@@ -986,13 +986,13 @@ static void ip6gre_dev_free(struct net_device *dev)
|
|
|
|
dst_cache_destroy(&t->dst_cache);
|
|
free_percpu(dev->tstats);
|
|
- free_netdev(dev);
|
|
}
|
|
|
|
static void ip6gre_tunnel_setup(struct net_device *dev)
|
|
{
|
|
dev->netdev_ops = &ip6gre_netdev_ops;
|
|
- dev->destructor = ip6gre_dev_free;
|
|
+ dev->needs_free_netdev = true;
|
|
+ dev->priv_destructor = ip6gre_dev_free;
|
|
|
|
dev->type = ARPHRD_IP6GRE;
|
|
|
|
@@ -1143,7 +1143,7 @@ static int __net_init ip6gre_init_net(struct net *net)
|
|
return 0;
|
|
|
|
err_reg_dev:
|
|
- ip6gre_dev_free(ign->fb_tunnel_dev);
|
|
+ free_netdev(ign->fb_tunnel_dev);
|
|
err_alloc_dev:
|
|
return err;
|
|
}
|
|
@@ -1292,7 +1292,8 @@ static void ip6gre_tap_setup(struct net_device *dev)
|
|
ether_setup(dev);
|
|
|
|
dev->netdev_ops = &ip6gre_tap_netdev_ops;
|
|
- dev->destructor = ip6gre_dev_free;
|
|
+ dev->needs_free_netdev = true;
|
|
+ dev->priv_destructor = ip6gre_dev_free;
|
|
|
|
dev->features |= NETIF_F_NETNS_LOCAL;
|
|
dev->priv_flags &= ~IFF_TX_SKB_SHARING;
|
|
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
|
|
index e2d7867f3112..292f24c48c94 100644
|
|
--- a/net/ipv6/ip6_tunnel.c
|
|
+++ b/net/ipv6/ip6_tunnel.c
|
|
@@ -254,7 +254,6 @@ static void ip6_dev_free(struct net_device *dev)
|
|
gro_cells_destroy(&t->gro_cells);
|
|
dst_cache_destroy(&t->dst_cache);
|
|
free_percpu(dev->tstats);
|
|
- free_netdev(dev);
|
|
}
|
|
|
|
static int ip6_tnl_create2(struct net_device *dev)
|
|
@@ -322,7 +321,7 @@ static struct ip6_tnl *ip6_tnl_create(struct net *net, struct __ip6_tnl_parm *p)
|
|
return t;
|
|
|
|
failed_free:
|
|
- ip6_dev_free(dev);
|
|
+ free_netdev(dev);
|
|
failed:
|
|
return ERR_PTR(err);
|
|
}
|
|
@@ -1772,7 +1771,8 @@ static const struct net_device_ops ip6_tnl_netdev_ops = {
|
|
static void ip6_tnl_dev_setup(struct net_device *dev)
|
|
{
|
|
dev->netdev_ops = &ip6_tnl_netdev_ops;
|
|
- dev->destructor = ip6_dev_free;
|
|
+ dev->needs_free_netdev = true;
|
|
+ dev->priv_destructor = ip6_dev_free;
|
|
|
|
dev->type = ARPHRD_TUNNEL6;
|
|
dev->flags |= IFF_NOARP;
|
|
@@ -2211,7 +2211,7 @@ static int __net_init ip6_tnl_init_net(struct net *net)
|
|
return 0;
|
|
|
|
err_register:
|
|
- ip6_dev_free(ip6n->fb_tnl_dev);
|
|
+ free_netdev(ip6n->fb_tnl_dev);
|
|
err_alloc_dev:
|
|
return err;
|
|
}
|
|
diff --git a/net/ipv6/ip6_vti.c b/net/ipv6/ip6_vti.c
|
|
index 3d8a3b63b4fd..5659f4a40f38 100644
|
|
--- a/net/ipv6/ip6_vti.c
|
|
+++ b/net/ipv6/ip6_vti.c
|
|
@@ -180,7 +180,6 @@ vti6_tnl_unlink(struct vti6_net *ip6n, struct ip6_tnl *t)
|
|
static void vti6_dev_free(struct net_device *dev)
|
|
{
|
|
free_percpu(dev->tstats);
|
|
- free_netdev(dev);
|
|
}
|
|
|
|
static int vti6_tnl_create2(struct net_device *dev)
|
|
@@ -235,7 +234,7 @@ static struct ip6_tnl *vti6_tnl_create(struct net *net, struct __ip6_tnl_parm *p
|
|
return t;
|
|
|
|
failed_free:
|
|
- vti6_dev_free(dev);
|
|
+ free_netdev(dev);
|
|
failed:
|
|
return NULL;
|
|
}
|
|
@@ -841,7 +840,8 @@ static const struct net_device_ops vti6_netdev_ops = {
|
|
static void vti6_dev_setup(struct net_device *dev)
|
|
{
|
|
dev->netdev_ops = &vti6_netdev_ops;
|
|
- dev->destructor = vti6_dev_free;
|
|
+ dev->needs_free_netdev = true;
|
|
+ dev->priv_destructor = vti6_dev_free;
|
|
|
|
dev->type = ARPHRD_TUNNEL6;
|
|
dev->hard_header_len = LL_MAX_HEADER + sizeof(struct ipv6hdr);
|
|
@@ -1092,7 +1092,7 @@ static int __net_init vti6_init_net(struct net *net)
|
|
return 0;
|
|
|
|
err_register:
|
|
- vti6_dev_free(ip6n->fb_tnl_dev);
|
|
+ free_netdev(ip6n->fb_tnl_dev);
|
|
err_alloc_dev:
|
|
return err;
|
|
}
|
|
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c
|
|
index bf34d0950752..576fd9332235 100644
|
|
--- a/net/ipv6/ip6mr.c
|
|
+++ b/net/ipv6/ip6mr.c
|
|
@@ -733,7 +733,7 @@ static void reg_vif_setup(struct net_device *dev)
|
|
dev->mtu = 1500 - sizeof(struct ipv6hdr) - 8;
|
|
dev->flags = IFF_NOARP;
|
|
dev->netdev_ops = ®_vif_netdev_ops;
|
|
- dev->destructor = free_netdev;
|
|
+ dev->needs_free_netdev = true;
|
|
dev->features |= NETIF_F_NETNS_LOCAL;
|
|
}
|
|
|
|
diff --git a/net/ipv6/proc.c b/net/ipv6/proc.c
|
|
index cc8e3ae9ca73..e88bcb8ff0fd 100644
|
|
--- a/net/ipv6/proc.c
|
|
+++ b/net/ipv6/proc.c
|
|
@@ -219,7 +219,7 @@ static void snmp6_seq_show_item64(struct seq_file *seq, void __percpu *mib,
|
|
u64 buff64[SNMP_MIB_MAX];
|
|
int i;
|
|
|
|
- memset(buff64, 0, sizeof(unsigned long) * SNMP_MIB_MAX);
|
|
+ memset(buff64, 0, sizeof(u64) * SNMP_MIB_MAX);
|
|
|
|
snmp_get_cpu_field64_batch(buff64, itemlist, mib, syncpoff);
|
|
for (i = 0; itemlist[i].name; i++)
|
|
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
|
|
index d316d00e11ab..1072fc189708 100644
|
|
--- a/net/ipv6/route.c
|
|
+++ b/net/ipv6/route.c
|
|
@@ -2804,6 +2804,7 @@ static int fib6_ifdown(struct rt6_info *rt, void *arg)
|
|
if ((rt->dst.dev == dev || !dev) &&
|
|
rt != adn->net->ipv6.ip6_null_entry &&
|
|
(rt->rt6i_nsiblings == 0 ||
|
|
+ (dev && netdev_unregistering(dev)) ||
|
|
!rt->rt6i_idev->cnf.ignore_routes_with_linkdown))
|
|
return -1;
|
|
|
|
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
|
|
index 99853c6e33a8..4f07a211ac2a 100644
|
|
--- a/net/ipv6/sit.c
|
|
+++ b/net/ipv6/sit.c
|
|
@@ -265,7 +265,7 @@ static struct ip_tunnel *ipip6_tunnel_locate(struct net *net,
|
|
return nt;
|
|
|
|
failed_free:
|
|
- ipip6_dev_free(dev);
|
|
+ free_netdev(dev);
|
|
failed:
|
|
return NULL;
|
|
}
|
|
@@ -1333,7 +1333,6 @@ static void ipip6_dev_free(struct net_device *dev)
|
|
|
|
dst_cache_destroy(&tunnel->dst_cache);
|
|
free_percpu(dev->tstats);
|
|
- free_netdev(dev);
|
|
}
|
|
|
|
#define SIT_FEATURES (NETIF_F_SG | \
|
|
@@ -1348,7 +1347,8 @@ static void ipip6_tunnel_setup(struct net_device *dev)
|
|
int t_hlen = tunnel->hlen + sizeof(struct iphdr);
|
|
|
|
dev->netdev_ops = &ipip6_netdev_ops;
|
|
- dev->destructor = ipip6_dev_free;
|
|
+ dev->needs_free_netdev = true;
|
|
+ dev->priv_destructor = ipip6_dev_free;
|
|
|
|
dev->type = ARPHRD_SIT;
|
|
dev->hard_header_len = LL_MAX_HEADER + t_hlen;
|
|
diff --git a/net/ipv6/xfrm6_input.c b/net/ipv6/xfrm6_input.c
|
|
index 08a807b29298..3ef5d913e7a3 100644
|
|
--- a/net/ipv6/xfrm6_input.c
|
|
+++ b/net/ipv6/xfrm6_input.c
|
|
@@ -43,8 +43,8 @@ int xfrm6_transport_finish(struct sk_buff *skb, int async)
|
|
return 1;
|
|
#endif
|
|
|
|
- ipv6_hdr(skb)->payload_len = htons(skb->len);
|
|
__skb_push(skb, skb->data - skb_network_header(skb));
|
|
+ ipv6_hdr(skb)->payload_len = htons(skb->len - sizeof(struct ipv6hdr));
|
|
|
|
if (xo && (xo->flags & XFRM_GRO)) {
|
|
skb_mac_header_rebuild(skb);
|
|
diff --git a/net/irda/irlan/irlan_eth.c b/net/irda/irlan/irlan_eth.c
|
|
index 74d09f91709e..3be852808a9d 100644
|
|
--- a/net/irda/irlan/irlan_eth.c
|
|
+++ b/net/irda/irlan/irlan_eth.c
|
|
@@ -65,7 +65,7 @@ static void irlan_eth_setup(struct net_device *dev)
|
|
ether_setup(dev);
|
|
|
|
dev->netdev_ops = &irlan_eth_netdev_ops;
|
|
- dev->destructor = free_netdev;
|
|
+ dev->needs_free_netdev = true;
|
|
dev->min_mtu = 0;
|
|
dev->max_mtu = ETH_MAX_MTU;
|
|
|
|
diff --git a/net/key/af_key.c b/net/key/af_key.c
|
|
index be8cecc65002..358175c83180 100644
|
|
--- a/net/key/af_key.c
|
|
+++ b/net/key/af_key.c
|
|
@@ -1157,6 +1157,7 @@ static struct xfrm_state * pfkey_msg2xfrm_state(struct net *net,
|
|
goto out;
|
|
}
|
|
|
|
+ err = -ENOBUFS;
|
|
key = ext_hdrs[SADB_EXT_KEY_AUTH - 1];
|
|
if (sa->sadb_sa_auth) {
|
|
int keysize = 0;
|
|
@@ -1168,8 +1169,10 @@ static struct xfrm_state * pfkey_msg2xfrm_state(struct net *net,
|
|
if (key)
|
|
keysize = (key->sadb_key_bits + 7) / 8;
|
|
x->aalg = kmalloc(sizeof(*x->aalg) + keysize, GFP_KERNEL);
|
|
- if (!x->aalg)
|
|
+ if (!x->aalg) {
|
|
+ err = -ENOMEM;
|
|
goto out;
|
|
+ }
|
|
strcpy(x->aalg->alg_name, a->name);
|
|
x->aalg->alg_key_len = 0;
|
|
if (key) {
|
|
@@ -1188,8 +1191,10 @@ static struct xfrm_state * pfkey_msg2xfrm_state(struct net *net,
|
|
goto out;
|
|
}
|
|
x->calg = kmalloc(sizeof(*x->calg), GFP_KERNEL);
|
|
- if (!x->calg)
|
|
+ if (!x->calg) {
|
|
+ err = -ENOMEM;
|
|
goto out;
|
|
+ }
|
|
strcpy(x->calg->alg_name, a->name);
|
|
x->props.calgo = sa->sadb_sa_encrypt;
|
|
} else {
|
|
@@ -1203,8 +1208,10 @@ static struct xfrm_state * pfkey_msg2xfrm_state(struct net *net,
|
|
if (key)
|
|
keysize = (key->sadb_key_bits + 7) / 8;
|
|
x->ealg = kmalloc(sizeof(*x->ealg) + keysize, GFP_KERNEL);
|
|
- if (!x->ealg)
|
|
+ if (!x->ealg) {
|
|
+ err = -ENOMEM;
|
|
goto out;
|
|
+ }
|
|
strcpy(x->ealg->alg_name, a->name);
|
|
x->ealg->alg_key_len = 0;
|
|
if (key) {
|
|
@@ -1249,8 +1256,10 @@ static struct xfrm_state * pfkey_msg2xfrm_state(struct net *net,
|
|
struct xfrm_encap_tmpl *natt;
|
|
|
|
x->encap = kmalloc(sizeof(*x->encap), GFP_KERNEL);
|
|
- if (!x->encap)
|
|
+ if (!x->encap) {
|
|
+ err = -ENOMEM;
|
|
goto out;
|
|
+ }
|
|
|
|
natt = x->encap;
|
|
n_type = ext_hdrs[SADB_X_EXT_NAT_T_TYPE-1];
|
|
@@ -2755,6 +2764,8 @@ static int pfkey_spdflush(struct sock *sk, struct sk_buff *skb, const struct sad
|
|
int err, err2;
|
|
|
|
err = xfrm_policy_flush(net, XFRM_POLICY_TYPE_MAIN, true);
|
|
+ if (!err)
|
|
+ xfrm_garbage_collect(net);
|
|
err2 = unicast_flush_resp(sk, hdr);
|
|
if (err || err2) {
|
|
if (err == -ESRCH) /* empty table - old silent behavior */
|
|
diff --git a/net/l2tp/l2tp_eth.c b/net/l2tp/l2tp_eth.c
|
|
index 6fd41d7afe1e..cafb667b3c85 100644
|
|
--- a/net/l2tp/l2tp_eth.c
|
|
+++ b/net/l2tp/l2tp_eth.c
|
|
@@ -133,7 +133,7 @@ static void l2tp_eth_dev_setup(struct net_device *dev)
|
|
dev->priv_flags &= ~IFF_TX_SKB_SHARING;
|
|
dev->features |= NETIF_F_LLTX;
|
|
dev->netdev_ops = &l2tp_eth_netdev_ops;
|
|
- dev->destructor = free_netdev;
|
|
+ dev->needs_free_netdev = true;
|
|
}
|
|
|
|
static void l2tp_eth_dev_recv(struct l2tp_session *session, struct sk_buff *skb, int data_len)
|
|
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
|
|
index 5bb0c5012819..8f783d527f29 100644
|
|
--- a/net/mac80211/iface.c
|
|
+++ b/net/mac80211/iface.c
|
|
@@ -1198,7 +1198,6 @@ static const struct net_device_ops ieee80211_monitorif_ops = {
|
|
static void ieee80211_if_free(struct net_device *dev)
|
|
{
|
|
free_percpu(dev->tstats);
|
|
- free_netdev(dev);
|
|
}
|
|
|
|
static void ieee80211_if_setup(struct net_device *dev)
|
|
@@ -1206,7 +1205,8 @@ static void ieee80211_if_setup(struct net_device *dev)
|
|
ether_setup(dev);
|
|
dev->priv_flags &= ~IFF_TX_SKB_SHARING;
|
|
dev->netdev_ops = &ieee80211_dataif_ops;
|
|
- dev->destructor = ieee80211_if_free;
|
|
+ dev->needs_free_netdev = true;
|
|
+ dev->priv_destructor = ieee80211_if_free;
|
|
}
|
|
|
|
static void ieee80211_if_setup_no_queue(struct net_device *dev)
|
|
@@ -1810,6 +1810,7 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name,
|
|
ret = dev_alloc_name(ndev, ndev->name);
|
|
if (ret < 0) {
|
|
ieee80211_if_free(ndev);
|
|
+ free_netdev(ndev);
|
|
return ret;
|
|
}
|
|
|
|
@@ -1899,7 +1900,7 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name,
|
|
|
|
ret = register_netdevice(ndev);
|
|
if (ret) {
|
|
- ieee80211_if_free(ndev);
|
|
+ free_netdev(ndev);
|
|
return ret;
|
|
}
|
|
}
|
|
diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c
|
|
index 06019dba4b10..bd88a9b80773 100644
|
|
--- a/net/mac802154/iface.c
|
|
+++ b/net/mac802154/iface.c
|
|
@@ -526,8 +526,6 @@ static void mac802154_wpan_free(struct net_device *dev)
|
|
struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
|
|
|
|
mac802154_llsec_destroy(&sdata->sec);
|
|
-
|
|
- free_netdev(dev);
|
|
}
|
|
|
|
static void ieee802154_if_setup(struct net_device *dev)
|
|
@@ -593,7 +591,8 @@ ieee802154_setup_sdata(struct ieee802154_sub_if_data *sdata,
|
|
sdata->dev->dev_addr);
|
|
|
|
sdata->dev->header_ops = &mac802154_header_ops;
|
|
- sdata->dev->destructor = mac802154_wpan_free;
|
|
+ sdata->dev->needs_free_netdev = true;
|
|
+ sdata->dev->priv_destructor = mac802154_wpan_free;
|
|
sdata->dev->netdev_ops = &mac802154_wpan_ops;
|
|
sdata->dev->ml_priv = &mac802154_mlme_wpan;
|
|
wpan_dev->promiscuous_mode = false;
|
|
@@ -608,7 +607,7 @@ ieee802154_setup_sdata(struct ieee802154_sub_if_data *sdata,
|
|
|
|
break;
|
|
case NL802154_IFTYPE_MONITOR:
|
|
- sdata->dev->destructor = free_netdev;
|
|
+ sdata->dev->needs_free_netdev = true;
|
|
sdata->dev->netdev_ops = &mac802154_monitor_ops;
|
|
wpan_dev->promiscuous_mode = true;
|
|
break;
|
|
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
|
|
index dc7dfd68fafe..8555659d2e07 100644
|
|
--- a/net/netfilter/nf_conntrack_netlink.c
|
|
+++ b/net/netfilter/nf_conntrack_netlink.c
|
|
@@ -45,6 +45,8 @@
|
|
#include <net/netfilter/nf_conntrack_zones.h>
|
|
#include <net/netfilter/nf_conntrack_timestamp.h>
|
|
#include <net/netfilter/nf_conntrack_labels.h>
|
|
+#include <net/netfilter/nf_conntrack_seqadj.h>
|
|
+#include <net/netfilter/nf_conntrack_synproxy.h>
|
|
#ifdef CONFIG_NF_NAT_NEEDED
|
|
#include <net/netfilter/nf_nat_core.h>
|
|
#include <net/netfilter/nf_nat_l4proto.h>
|
|
@@ -1814,6 +1816,8 @@ ctnetlink_create_conntrack(struct net *net,
|
|
nf_ct_tstamp_ext_add(ct, GFP_ATOMIC);
|
|
nf_ct_ecache_ext_add(ct, 0, 0, GFP_ATOMIC);
|
|
nf_ct_labels_ext_add(ct);
|
|
+ nfct_seqadj_ext_add(ct);
|
|
+ nfct_synproxy_ext_add(ct);
|
|
|
|
/* we must add conntrack extensions before confirmation. */
|
|
ct->status |= IPS_CONFIRMED;
|
|
diff --git a/net/openvswitch/vport-internal_dev.c b/net/openvswitch/vport-internal_dev.c
|
|
index 89193a634da4..04a3128adcf0 100644
|
|
--- a/net/openvswitch/vport-internal_dev.c
|
|
+++ b/net/openvswitch/vport-internal_dev.c
|
|
@@ -94,7 +94,6 @@ static void internal_dev_destructor(struct net_device *dev)
|
|
struct vport *vport = ovs_internal_dev_get_vport(dev);
|
|
|
|
ovs_vport_free(vport);
|
|
- free_netdev(dev);
|
|
}
|
|
|
|
static void
|
|
@@ -156,7 +155,8 @@ static void do_setup(struct net_device *netdev)
|
|
netdev->priv_flags &= ~IFF_TX_SKB_SHARING;
|
|
netdev->priv_flags |= IFF_LIVE_ADDR_CHANGE | IFF_OPENVSWITCH |
|
|
IFF_PHONY_HEADROOM | IFF_NO_QUEUE;
|
|
- netdev->destructor = internal_dev_destructor;
|
|
+ netdev->needs_free_netdev = true;
|
|
+ netdev->priv_destructor = internal_dev_destructor;
|
|
netdev->ethtool_ops = &internal_dev_ethtool_ops;
|
|
netdev->rtnl_link_ops = &internal_dev_link_ops;
|
|
|
|
diff --git a/net/phonet/pep-gprs.c b/net/phonet/pep-gprs.c
|
|
index 21c28b51be94..2c9337946e30 100644
|
|
--- a/net/phonet/pep-gprs.c
|
|
+++ b/net/phonet/pep-gprs.c
|
|
@@ -236,7 +236,7 @@ static void gprs_setup(struct net_device *dev)
|
|
dev->tx_queue_len = 10;
|
|
|
|
dev->netdev_ops = &gprs_netdev_ops;
|
|
- dev->destructor = free_netdev;
|
|
+ dev->needs_free_netdev = true;
|
|
}
|
|
|
|
/*
|
|
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
|
|
index d9d4c92e06b3..74f761022450 100644
|
|
--- a/net/sctp/socket.c
|
|
+++ b/net/sctp/socket.c
|
|
@@ -4586,13 +4586,13 @@ int sctp_for_each_endpoint(int (*cb)(struct sctp_endpoint *, void *),
|
|
|
|
for (head = sctp_ep_hashtable; hash < sctp_ep_hashsize;
|
|
hash++, head++) {
|
|
- read_lock(&head->lock);
|
|
+ read_lock_bh(&head->lock);
|
|
sctp_for_each_hentry(epb, &head->chain) {
|
|
err = cb(sctp_ep(epb), p);
|
|
if (err)
|
|
break;
|
|
}
|
|
- read_unlock(&head->lock);
|
|
+ read_unlock_bh(&head->lock);
|
|
}
|
|
|
|
return err;
|
|
@@ -4630,9 +4630,8 @@ int sctp_for_each_transport(int (*cb)(struct sctp_transport *, void *),
|
|
if (err)
|
|
return err;
|
|
|
|
- sctp_transport_get_idx(net, &hti, pos);
|
|
- obj = sctp_transport_get_next(net, &hti);
|
|
- for (; obj && !IS_ERR(obj); obj = sctp_transport_get_next(net, &hti)) {
|
|
+ obj = sctp_transport_get_idx(net, &hti, pos + 1);
|
|
+ for (; !IS_ERR_OR_NULL(obj); obj = sctp_transport_get_next(net, &hti)) {
|
|
struct sctp_transport *transport = obj;
|
|
|
|
if (!sctp_transport_hold(transport))
|
|
diff --git a/net/tipc/msg.c b/net/tipc/msg.c
|
|
index 312ef7de57d7..ab3087687a32 100644
|
|
--- a/net/tipc/msg.c
|
|
+++ b/net/tipc/msg.c
|
|
@@ -508,7 +508,7 @@ bool tipc_msg_reverse(u32 own_node, struct sk_buff **skb, int err)
|
|
}
|
|
|
|
if (skb_cloned(_skb) &&
|
|
- pskb_expand_head(_skb, BUF_HEADROOM, BUF_TAILROOM, GFP_KERNEL))
|
|
+ pskb_expand_head(_skb, BUF_HEADROOM, BUF_TAILROOM, GFP_ATOMIC))
|
|
goto exit;
|
|
|
|
/* Now reverse the concerned fields */
|
|
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
|
|
index 928691c43408..475e1170597c 100644
|
|
--- a/net/unix/af_unix.c
|
|
+++ b/net/unix/af_unix.c
|
|
@@ -999,7 +999,8 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
|
|
struct path path = { NULL, NULL };
|
|
|
|
err = -EINVAL;
|
|
- if (sunaddr->sun_family != AF_UNIX)
|
|
+ if (addr_len < offsetofend(struct sockaddr_un, sun_family) ||
|
|
+ sunaddr->sun_family != AF_UNIX)
|
|
goto out;
|
|
|
|
if (addr_len == sizeof(short)) {
|
|
@@ -1110,6 +1111,10 @@ static int unix_dgram_connect(struct socket *sock, struct sockaddr *addr,
|
|
unsigned int hash;
|
|
int err;
|
|
|
|
+ err = -EINVAL;
|
|
+ if (alen < offsetofend(struct sockaddr, sa_family))
|
|
+ goto out;
|
|
+
|
|
if (addr->sa_family != AF_UNSPEC) {
|
|
err = unix_mkname(sunaddr, alen, &hash);
|
|
if (err < 0)
|
|
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
|
|
index dfc77b9c5e5a..56fba8f073f5 100644
|
|
--- a/net/xfrm/xfrm_policy.c
|
|
+++ b/net/xfrm/xfrm_policy.c
|
|
@@ -1006,10 +1006,6 @@ int xfrm_policy_flush(struct net *net, u8 type, bool task_valid)
|
|
err = -ESRCH;
|
|
out:
|
|
spin_unlock_bh(&net->xfrm.xfrm_policy_lock);
|
|
-
|
|
- if (cnt)
|
|
- xfrm_garbage_collect(net);
|
|
-
|
|
return err;
|
|
}
|
|
EXPORT_SYMBOL(xfrm_policy_flush);
|
|
@@ -1797,43 +1793,6 @@ static struct dst_entry *xfrm_bundle_create(struct xfrm_policy *policy,
|
|
goto out;
|
|
}
|
|
|
|
-#ifdef CONFIG_XFRM_SUB_POLICY
|
|
-static int xfrm_dst_alloc_copy(void **target, const void *src, int size)
|
|
-{
|
|
- if (!*target) {
|
|
- *target = kmalloc(size, GFP_ATOMIC);
|
|
- if (!*target)
|
|
- return -ENOMEM;
|
|
- }
|
|
-
|
|
- memcpy(*target, src, size);
|
|
- return 0;
|
|
-}
|
|
-#endif
|
|
-
|
|
-static int xfrm_dst_update_parent(struct dst_entry *dst,
|
|
- const struct xfrm_selector *sel)
|
|
-{
|
|
-#ifdef CONFIG_XFRM_SUB_POLICY
|
|
- struct xfrm_dst *xdst = (struct xfrm_dst *)dst;
|
|
- return xfrm_dst_alloc_copy((void **)&(xdst->partner),
|
|
- sel, sizeof(*sel));
|
|
-#else
|
|
- return 0;
|
|
-#endif
|
|
-}
|
|
-
|
|
-static int xfrm_dst_update_origin(struct dst_entry *dst,
|
|
- const struct flowi *fl)
|
|
-{
|
|
-#ifdef CONFIG_XFRM_SUB_POLICY
|
|
- struct xfrm_dst *xdst = (struct xfrm_dst *)dst;
|
|
- return xfrm_dst_alloc_copy((void **)&(xdst->origin), fl, sizeof(*fl));
|
|
-#else
|
|
- return 0;
|
|
-#endif
|
|
-}
|
|
-
|
|
static int xfrm_expand_policies(const struct flowi *fl, u16 family,
|
|
struct xfrm_policy **pols,
|
|
int *num_pols, int *num_xfrms)
|
|
@@ -1905,16 +1864,6 @@ xfrm_resolve_and_create_bundle(struct xfrm_policy **pols, int num_pols,
|
|
|
|
xdst = (struct xfrm_dst *)dst;
|
|
xdst->num_xfrms = err;
|
|
- if (num_pols > 1)
|
|
- err = xfrm_dst_update_parent(dst, &pols[1]->selector);
|
|
- else
|
|
- err = xfrm_dst_update_origin(dst, fl);
|
|
- if (unlikely(err)) {
|
|
- dst_free(dst);
|
|
- XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTBUNDLECHECKERROR);
|
|
- return ERR_PTR(err);
|
|
- }
|
|
-
|
|
xdst->num_pols = num_pols;
|
|
memcpy(xdst->pols, pols, sizeof(struct xfrm_policy *) * num_pols);
|
|
xdst->policy_genid = atomic_read(&pols[0]->genid);
|
|
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
|
|
index 40a8aa39220d..66698552fbd6 100644
|
|
--- a/net/xfrm/xfrm_user.c
|
|
+++ b/net/xfrm/xfrm_user.c
|
|
@@ -1999,6 +1999,7 @@ static int xfrm_flush_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
|
|
return 0;
|
|
return err;
|
|
}
|
|
+ xfrm_garbage_collect(net);
|
|
|
|
c.data.type = type;
|
|
c.event = nlh->nlmsg_type;
|
|
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
|
|
index f17f25245e52..a206320b8eea 100644
|
|
--- a/sound/pci/hda/hda_codec.h
|
|
+++ b/sound/pci/hda/hda_codec.h
|
|
@@ -294,6 +294,8 @@ struct hda_codec {
|
|
|
|
#define list_for_each_codec(c, bus) \
|
|
list_for_each_entry(c, &(bus)->core.codec_list, core.list)
|
|
+#define list_for_each_codec_safe(c, n, bus) \
|
|
+ list_for_each_entry_safe(c, n, &(bus)->core.codec_list, core.list)
|
|
|
|
/* snd_hda_codec_read/write optional flags */
|
|
#define HDA_RW_NO_RESPONSE_FALLBACK (1 << 0)
|
|
diff --git a/sound/pci/hda/hda_controller.c b/sound/pci/hda/hda_controller.c
|
|
index 3715a5725613..1c60beb5b70a 100644
|
|
--- a/sound/pci/hda/hda_controller.c
|
|
+++ b/sound/pci/hda/hda_controller.c
|
|
@@ -1337,8 +1337,12 @@ EXPORT_SYMBOL_GPL(azx_probe_codecs);
|
|
/* configure each codec instance */
|
|
int azx_codec_configure(struct azx *chip)
|
|
{
|
|
- struct hda_codec *codec;
|
|
- list_for_each_codec(codec, &chip->bus) {
|
|
+ struct hda_codec *codec, *next;
|
|
+
|
|
+ /* use _safe version here since snd_hda_codec_configure() deregisters
|
|
+ * the device upon error and deletes itself from the bus list.
|
|
+ */
|
|
+ list_for_each_codec_safe(codec, next, &chip->bus) {
|
|
snd_hda_codec_configure(codec);
|
|
}
|
|
return 0;
|
|
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c
|
|
index e7c8f4f076d5..b0bd29003b5d 100644
|
|
--- a/sound/pci/hda/hda_generic.c
|
|
+++ b/sound/pci/hda/hda_generic.c
|
|
@@ -3169,6 +3169,7 @@ static int check_dyn_adc_switch(struct hda_codec *codec)
|
|
spec->input_paths[i][nums]);
|
|
spec->input_paths[i][nums] =
|
|
spec->input_paths[i][n];
|
|
+ spec->input_paths[i][n] = 0;
|
|
}
|
|
}
|
|
nums++;
|
|
diff --git a/tools/arch/x86/lib/memcpy_64.S b/tools/arch/x86/lib/memcpy_64.S
|
|
index 49e6ebac7e73..98dcc112b363 100644
|
|
--- a/tools/arch/x86/lib/memcpy_64.S
|
|
+++ b/tools/arch/x86/lib/memcpy_64.S
|
|
@@ -286,7 +286,7 @@ ENDPROC(memcpy_mcsafe_unrolled)
|
|
_ASM_EXTABLE_FAULT(.L_copy_leading_bytes, .L_memcpy_mcsafe_fail)
|
|
_ASM_EXTABLE_FAULT(.L_cache_w0, .L_memcpy_mcsafe_fail)
|
|
_ASM_EXTABLE_FAULT(.L_cache_w1, .L_memcpy_mcsafe_fail)
|
|
- _ASM_EXTABLE_FAULT(.L_cache_w3, .L_memcpy_mcsafe_fail)
|
|
+ _ASM_EXTABLE_FAULT(.L_cache_w2, .L_memcpy_mcsafe_fail)
|
|
_ASM_EXTABLE_FAULT(.L_cache_w3, .L_memcpy_mcsafe_fail)
|
|
_ASM_EXTABLE_FAULT(.L_cache_w4, .L_memcpy_mcsafe_fail)
|
|
_ASM_EXTABLE_FAULT(.L_cache_w5, .L_memcpy_mcsafe_fail)
|