[PATCH V7 10/20] csky: IRQ handling
This patch adds IRQ handling files. Signed-off-by: Guo Ren --- arch/csky/include/asm/irqflags.h | 49 arch/csky/kernel/irq.c | 22 ++ 2 files changed, 71 insertions(+) create mode 100644 arch/csky/include/asm/irqflags.h create mode 100644 arch/csky/kernel/irq.c diff --git a/arch/csky/include/asm/irqflags.h b/arch/csky/include/asm/irqflags.h new file mode 100644 index 000..9e3a569 --- /dev/null +++ b/arch/csky/include/asm/irqflags.h @@ -0,0 +1,49 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef __ASM_CSKY_IRQFLAGS_H +#define __ASM_CSKY_IRQFLAGS_H +#include + +static inline unsigned long arch_local_irq_save(void) +{ + unsigned long flags; + + flags = mfcr("psr"); + asm volatile("psrclr ie\n":::"memory"); + return flags; +} +#define arch_local_irq_save arch_local_irq_save + +static inline void arch_local_irq_enable(void) +{ + asm volatile("psrset ee, ie\n":::"memory"); +} +#define arch_local_irq_enable arch_local_irq_enable + +static inline void arch_local_irq_disable(void) +{ + asm volatile("psrclr ie\n":::"memory"); +} +#define arch_local_irq_disable arch_local_irq_disable + +static inline unsigned long arch_local_save_flags(void) +{ + return mfcr("psr"); +} +#define arch_local_save_flags arch_local_save_flags + +static inline void arch_local_irq_restore(unsigned long flags) +{ + mtcr("psr", flags); +} +#define arch_local_irq_restore arch_local_irq_restore + +static inline int arch_irqs_disabled_flags(unsigned long flags) +{ + return !(flags & (1<<6)); +} +#define arch_irqs_disabled_flags arch_irqs_disabled_flags + +#include + +#endif /* __ASM_CSKY_IRQFLAGS_H */ diff --git a/arch/csky/kernel/irq.c b/arch/csky/kernel/irq.c new file mode 100644 index 000..03a1930 --- /dev/null +++ b/arch/csky/kernel/irq.c @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. + +#include +#include +#include +#include +#include +#include + +void __init init_IRQ(void) +{ + irqchip_init(); +#ifdef CONFIG_SMP + setup_smp_ipi(); +#endif +} + +asmlinkage void __irq_entry csky_do_IRQ(struct pt_regs *regs) +{ + handle_arch_irq(regs); +} -- 2.7.4
[PATCH V7 12/20] csky: ELF and module probe
This patch adds ELF definition and module relocate codes. Signed-off-by: Guo Ren --- arch/csky/abiv1/inc/abi/elf.h | 26 arch/csky/abiv2/inc/abi/elf.h | 43 arch/csky/include/asm/elf.h | 85 +++ arch/csky/kernel/module.c | 92 +++ 4 files changed, 246 insertions(+) create mode 100644 arch/csky/abiv1/inc/abi/elf.h create mode 100644 arch/csky/abiv2/inc/abi/elf.h create mode 100644 arch/csky/include/asm/elf.h create mode 100644 arch/csky/kernel/module.c diff --git a/arch/csky/abiv1/inc/abi/elf.h b/arch/csky/abiv1/inc/abi/elf.h new file mode 100644 index 000..3058cc0 --- /dev/null +++ b/arch/csky/abiv1/inc/abi/elf.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef __ABI_CSKY_ELF_H +#define __ABI_CSKY_ELF_H + +#define ELF_CORE_COPY_REGS(pr_reg, regs) do { \ + pr_reg[0] = regs->pc; \ + pr_reg[1] = regs->regs[9]; \ + pr_reg[2] = regs->usp; \ + pr_reg[3] = regs->sr; \ + pr_reg[4] = regs->a0; \ + pr_reg[5] = regs->a1; \ + pr_reg[6] = regs->a2; \ + pr_reg[7] = regs->a3; \ + pr_reg[8] = regs->regs[0]; \ + pr_reg[9] = regs->regs[1]; \ + pr_reg[10] = regs->regs[2]; \ + pr_reg[11] = regs->regs[3]; \ + pr_reg[12] = regs->regs[4]; \ + pr_reg[13] = regs->regs[5]; \ + pr_reg[14] = regs->regs[6]; \ + pr_reg[15] = regs->regs[7]; \ + pr_reg[16] = regs->regs[8]; \ + pr_reg[17] = regs->lr; \ +} while (0); +#endif /* __ABI_CSKY_ELF_H */ diff --git a/arch/csky/abiv2/inc/abi/elf.h b/arch/csky/abiv2/inc/abi/elf.h new file mode 100644 index 000..290f49e --- /dev/null +++ b/arch/csky/abiv2/inc/abi/elf.h @@ -0,0 +1,43 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef __ABI_CSKY_ELF_H +#define __ABI_CSKY_ELF_H + +/* The member sort in array pr_reg[x] is defined by GDB. */ +#define ELF_CORE_COPY_REGS(pr_reg, regs) do { \ + pr_reg[0] = regs->pc; \ + pr_reg[1] = regs->a1; \ + pr_reg[2] = regs->a0; \ + pr_reg[3] = regs->sr; \ + pr_reg[4] = regs->a2; \ + pr_reg[5] = regs->a3; \ + pr_reg[6] = regs->regs[0]; \ + pr_reg[7] = regs->regs[1]; \ + pr_reg[8] = regs->regs[2]; \ + pr_reg[9] = regs->regs[3]; \ + pr_reg[10] = regs->regs[4]; \ + pr_reg[11] = regs->regs[5]; \ + pr_reg[12] = regs->regs[6]; \ + pr_reg[13] = regs->regs[7]; \ + pr_reg[14] = regs->regs[8]; \ + pr_reg[15] = regs->regs[9]; \ + pr_reg[16] = regs->usp; \ + pr_reg[17] = regs->lr; \ + pr_reg[18] = regs->exregs[0]; \ + pr_reg[19] = regs->exregs[1]; \ + pr_reg[20] = regs->exregs[2]; \ + pr_reg[21] = regs->exregs[3]; \ + pr_reg[22] = regs->exregs[4]; \ + pr_reg[23] = regs->exregs[5]; \ + pr_reg[24] = regs->exregs[6]; \ + pr_reg[25] = regs->exregs[7]; \ + pr_reg[26] = regs->exregs[8]; \ + pr_reg[27] = regs->exregs[9]; \ + pr_reg[28] = regs->exregs[10]; \ + pr_reg[29] = regs->exregs[11]; \ + pr_reg[30] = regs->exregs[12]; \ + pr_reg[31] = regs->exregs[13]; \ + pr_reg[32] = regs->exregs[14]; \ + pr_reg[33] = regs->tls; \ +} while (0); +#endif /* __ABI_CSKY_ELF_H */ diff --git a/arch/csky/include/asm/elf.h b/arch/csky/include/asm/elf.h new file mode 100644 index 000..773b133 --- /dev/null +++ b/arch/csky/include/asm/elf.h @@ -0,0 +1,85 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. + +#ifndef __ASM_CSKY_ELF_H +#define __ASM_CSKY_ELF_H + +#include +#include + +#define ELF_ARCH 252 + +/* CSKY Relocations */ +#define R_CSKY_NONE 0 +#define R_CSKY_32 1 +#define R_CSKY_PCIMM8BY4 2 +#define R_CSKY_PCIMM11BY2 3 +#define R_CSKY_PCIMM4BY2 4 +#define R_CSKY_PC32 5 +#define R_CSKY_PCRELJSR_IMM11BY2 6 +#define R_CSKY_GNU_VTINHERIT 7 +#define R_CSKY_GNU_VTENTRY8 +#define R_CSKY_RELATIVE 9 +#define R_CSKY_COPY 10 +#define R_CSKY_GLOB_DAT 11 +#define R_CSKY_JUMP_SLOT 12 +#define R_CSKY_ADDR_HI16 24 +#define R_CSKY_ADDR_LO16 25 +#define R_CSKY_PCRELJSR_IMM26BY2
[PATCH V7 10/20] csky: IRQ handling
This patch adds IRQ handling files. Signed-off-by: Guo Ren --- arch/csky/include/asm/irqflags.h | 49 arch/csky/kernel/irq.c | 22 ++ 2 files changed, 71 insertions(+) create mode 100644 arch/csky/include/asm/irqflags.h create mode 100644 arch/csky/kernel/irq.c diff --git a/arch/csky/include/asm/irqflags.h b/arch/csky/include/asm/irqflags.h new file mode 100644 index 000..9e3a569 --- /dev/null +++ b/arch/csky/include/asm/irqflags.h @@ -0,0 +1,49 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef __ASM_CSKY_IRQFLAGS_H +#define __ASM_CSKY_IRQFLAGS_H +#include + +static inline unsigned long arch_local_irq_save(void) +{ + unsigned long flags; + + flags = mfcr("psr"); + asm volatile("psrclr ie\n":::"memory"); + return flags; +} +#define arch_local_irq_save arch_local_irq_save + +static inline void arch_local_irq_enable(void) +{ + asm volatile("psrset ee, ie\n":::"memory"); +} +#define arch_local_irq_enable arch_local_irq_enable + +static inline void arch_local_irq_disable(void) +{ + asm volatile("psrclr ie\n":::"memory"); +} +#define arch_local_irq_disable arch_local_irq_disable + +static inline unsigned long arch_local_save_flags(void) +{ + return mfcr("psr"); +} +#define arch_local_save_flags arch_local_save_flags + +static inline void arch_local_irq_restore(unsigned long flags) +{ + mtcr("psr", flags); +} +#define arch_local_irq_restore arch_local_irq_restore + +static inline int arch_irqs_disabled_flags(unsigned long flags) +{ + return !(flags & (1<<6)); +} +#define arch_irqs_disabled_flags arch_irqs_disabled_flags + +#include + +#endif /* __ASM_CSKY_IRQFLAGS_H */ diff --git a/arch/csky/kernel/irq.c b/arch/csky/kernel/irq.c new file mode 100644 index 000..03a1930 --- /dev/null +++ b/arch/csky/kernel/irq.c @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. + +#include +#include +#include +#include +#include +#include + +void __init init_IRQ(void) +{ + irqchip_init(); +#ifdef CONFIG_SMP + setup_smp_ipi(); +#endif +} + +asmlinkage void __irq_entry csky_do_IRQ(struct pt_regs *regs) +{ + handle_arch_irq(regs); +} -- 2.7.4
[PATCH V7 12/20] csky: ELF and module probe
This patch adds ELF definition and module relocate codes. Signed-off-by: Guo Ren --- arch/csky/abiv1/inc/abi/elf.h | 26 arch/csky/abiv2/inc/abi/elf.h | 43 arch/csky/include/asm/elf.h | 85 +++ arch/csky/kernel/module.c | 92 +++ 4 files changed, 246 insertions(+) create mode 100644 arch/csky/abiv1/inc/abi/elf.h create mode 100644 arch/csky/abiv2/inc/abi/elf.h create mode 100644 arch/csky/include/asm/elf.h create mode 100644 arch/csky/kernel/module.c diff --git a/arch/csky/abiv1/inc/abi/elf.h b/arch/csky/abiv1/inc/abi/elf.h new file mode 100644 index 000..3058cc0 --- /dev/null +++ b/arch/csky/abiv1/inc/abi/elf.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef __ABI_CSKY_ELF_H +#define __ABI_CSKY_ELF_H + +#define ELF_CORE_COPY_REGS(pr_reg, regs) do { \ + pr_reg[0] = regs->pc; \ + pr_reg[1] = regs->regs[9]; \ + pr_reg[2] = regs->usp; \ + pr_reg[3] = regs->sr; \ + pr_reg[4] = regs->a0; \ + pr_reg[5] = regs->a1; \ + pr_reg[6] = regs->a2; \ + pr_reg[7] = regs->a3; \ + pr_reg[8] = regs->regs[0]; \ + pr_reg[9] = regs->regs[1]; \ + pr_reg[10] = regs->regs[2]; \ + pr_reg[11] = regs->regs[3]; \ + pr_reg[12] = regs->regs[4]; \ + pr_reg[13] = regs->regs[5]; \ + pr_reg[14] = regs->regs[6]; \ + pr_reg[15] = regs->regs[7]; \ + pr_reg[16] = regs->regs[8]; \ + pr_reg[17] = regs->lr; \ +} while (0); +#endif /* __ABI_CSKY_ELF_H */ diff --git a/arch/csky/abiv2/inc/abi/elf.h b/arch/csky/abiv2/inc/abi/elf.h new file mode 100644 index 000..290f49e --- /dev/null +++ b/arch/csky/abiv2/inc/abi/elf.h @@ -0,0 +1,43 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef __ABI_CSKY_ELF_H +#define __ABI_CSKY_ELF_H + +/* The member sort in array pr_reg[x] is defined by GDB. */ +#define ELF_CORE_COPY_REGS(pr_reg, regs) do { \ + pr_reg[0] = regs->pc; \ + pr_reg[1] = regs->a1; \ + pr_reg[2] = regs->a0; \ + pr_reg[3] = regs->sr; \ + pr_reg[4] = regs->a2; \ + pr_reg[5] = regs->a3; \ + pr_reg[6] = regs->regs[0]; \ + pr_reg[7] = regs->regs[1]; \ + pr_reg[8] = regs->regs[2]; \ + pr_reg[9] = regs->regs[3]; \ + pr_reg[10] = regs->regs[4]; \ + pr_reg[11] = regs->regs[5]; \ + pr_reg[12] = regs->regs[6]; \ + pr_reg[13] = regs->regs[7]; \ + pr_reg[14] = regs->regs[8]; \ + pr_reg[15] = regs->regs[9]; \ + pr_reg[16] = regs->usp; \ + pr_reg[17] = regs->lr; \ + pr_reg[18] = regs->exregs[0]; \ + pr_reg[19] = regs->exregs[1]; \ + pr_reg[20] = regs->exregs[2]; \ + pr_reg[21] = regs->exregs[3]; \ + pr_reg[22] = regs->exregs[4]; \ + pr_reg[23] = regs->exregs[5]; \ + pr_reg[24] = regs->exregs[6]; \ + pr_reg[25] = regs->exregs[7]; \ + pr_reg[26] = regs->exregs[8]; \ + pr_reg[27] = regs->exregs[9]; \ + pr_reg[28] = regs->exregs[10]; \ + pr_reg[29] = regs->exregs[11]; \ + pr_reg[30] = regs->exregs[12]; \ + pr_reg[31] = regs->exregs[13]; \ + pr_reg[32] = regs->exregs[14]; \ + pr_reg[33] = regs->tls; \ +} while (0); +#endif /* __ABI_CSKY_ELF_H */ diff --git a/arch/csky/include/asm/elf.h b/arch/csky/include/asm/elf.h new file mode 100644 index 000..773b133 --- /dev/null +++ b/arch/csky/include/asm/elf.h @@ -0,0 +1,85 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. + +#ifndef __ASM_CSKY_ELF_H +#define __ASM_CSKY_ELF_H + +#include +#include + +#define ELF_ARCH 252 + +/* CSKY Relocations */ +#define R_CSKY_NONE 0 +#define R_CSKY_32 1 +#define R_CSKY_PCIMM8BY4 2 +#define R_CSKY_PCIMM11BY2 3 +#define R_CSKY_PCIMM4BY2 4 +#define R_CSKY_PC32 5 +#define R_CSKY_PCRELJSR_IMM11BY2 6 +#define R_CSKY_GNU_VTINHERIT 7 +#define R_CSKY_GNU_VTENTRY8 +#define R_CSKY_RELATIVE 9 +#define R_CSKY_COPY 10 +#define R_CSKY_GLOB_DAT 11 +#define R_CSKY_JUMP_SLOT 12 +#define R_CSKY_ADDR_HI16 24 +#define R_CSKY_ADDR_LO16 25 +#define R_CSKY_PCRELJSR_IMM26BY2
[PATCH V7 17/20] csky: Misc headers
This patch adds csky register definition, byteorder, asm-offsets codes. Signed-off-by: Guo Ren --- arch/csky/abiv1/inc/abi/reg_ops.h | 27 +++ arch/csky/abiv1/inc/abi/regdef.h | 26 ++ arch/csky/abiv2/inc/abi/reg_ops.h | 17 +++ arch/csky/abiv2/inc/abi/regdef.h | 26 ++ arch/csky/include/asm/bitops.h | 82 +++ arch/csky/include/asm/checksum.h | 50 +++ arch/csky/include/asm/reg_ops.h| 26 ++ arch/csky/include/uapi/asm/byteorder.h | 9 arch/csky/kernel/asm-offsets.c | 88 ++ 9 files changed, 351 insertions(+) create mode 100644 arch/csky/abiv1/inc/abi/reg_ops.h create mode 100644 arch/csky/abiv1/inc/abi/regdef.h create mode 100644 arch/csky/abiv2/inc/abi/reg_ops.h create mode 100644 arch/csky/abiv2/inc/abi/regdef.h create mode 100644 arch/csky/include/asm/bitops.h create mode 100644 arch/csky/include/asm/checksum.h create mode 100644 arch/csky/include/asm/reg_ops.h create mode 100644 arch/csky/include/uapi/asm/byteorder.h create mode 100644 arch/csky/kernel/asm-offsets.c diff --git a/arch/csky/abiv1/inc/abi/reg_ops.h b/arch/csky/abiv1/inc/abi/reg_ops.h new file mode 100644 index 000..a153bd3 --- /dev/null +++ b/arch/csky/abiv1/inc/abi/reg_ops.h @@ -0,0 +1,27 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. + +#ifndef __ABI_REG_OPS_H +#define __ABI_REG_OPS_H +#include + +#define cprcr(reg) \ +({ \ + unsigned int tmp; \ + asm volatile("cprcr %0, "reg"\n":"=b"(tmp));\ + tmp;\ +}) + +#define cpwcr(reg, val)\ +({ \ + asm volatile("cpwcr %0, "reg"\n"::"b"(val));\ +}) + +static inline unsigned int mfcr_hint(void) +{ + return mfcr("cr30"); +} + +static inline unsigned int mfcr_ccr2(void) { return 0; } + +#endif /* __ABI_REG_OPS_H */ diff --git a/arch/csky/abiv1/inc/abi/regdef.h b/arch/csky/abiv1/inc/abi/regdef.h new file mode 100644 index 000..8766892 --- /dev/null +++ b/arch/csky/abiv1/inc/abi/regdef.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. + +#ifndef __ASM_CSKY_REGDEF_H +#define __ASM_CSKY_REGDEF_H + +#define syscallid r1 +#define r11_sigr11 + +#define regs_syscallid(regs) regs->regs[9] + +/* + * PSR format: + * | 31 | 30-24 | 23-16 | 15 14 | 13-0 | + * S CPID VEC TM + * + *S: Super Mode + * CPID: Coprocessor id, only 15 for MMU + * VEC: Exception Number + * TM: Trace Mode + */ +#define DEFAULT_PSR_VALUE 0x8f00 + +#define SYSTRACE_SAVENUM 2 + +#endif /* __ASM_CSKY_REGDEF_H */ diff --git a/arch/csky/abiv2/inc/abi/reg_ops.h b/arch/csky/abiv2/inc/abi/reg_ops.h new file mode 100644 index 000..ae82c3f --- /dev/null +++ b/arch/csky/abiv2/inc/abi/reg_ops.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. + +#ifndef __ABI_REG_OPS_H +#define __ABI_REG_OPS_H +#include + +static inline unsigned int mfcr_hint(void) +{ + return mfcr("cr31"); +} + +static inline unsigned int mfcr_ccr2(void) +{ + return mfcr("cr23"); +} +#endif /* __ABI_REG_OPS_H */ diff --git a/arch/csky/abiv2/inc/abi/regdef.h b/arch/csky/abiv2/inc/abi/regdef.h new file mode 100644 index 000..c72abb7 --- /dev/null +++ b/arch/csky/abiv2/inc/abi/regdef.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. + +#ifndef __ASM_CSKY_REGDEF_H +#define __ASM_CSKY_REGDEF_H + +#define syscallid r7 +#define r11_sigr11 + +#define regs_syscallid(regs) regs->regs[3] + +/* + * PSR format: + * | 31 | 30-24 | 23-16 | 15 14 | 13-10 | 9 | 8-0 | + * S VEC TMMM + * + * S: Super Mode + * VEC: Exception Number + * TM: Trace Mode + * MM: Memory unaligned addr access + */ +#define DEFAULT_PSR_VALUE 0x8200 + +#define SYSTRACE_SAVENUM 5 + +#endif /* __ASM_CSKY_REGDEF_H */ diff --git a/arch/csky/include/asm/bitops.h b/arch/csky/include/asm/bitops.h new file mode 100644 index 000..335f288 --- /dev/null +++ b/arch/csky/include/asm/bitops.h @@ -0,0 +1,82 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. + +#ifndef __ASM_CSKY_BITOPS_H +#define __ASM_CSKY_BITOPS_H + +#include +#include + +/* + * asm-generic/bitops/ffs.h + */ +static inline int ffs(int x) +{ + if (!x) + return 0; + + asm volatile ( + "brev %0\n" + "ff1 %0\n" + "addi %0, 1\n" + : "="(x) + :
[PATCH V7 17/20] csky: Misc headers
This patch adds csky register definition, byteorder, asm-offsets codes. Signed-off-by: Guo Ren --- arch/csky/abiv1/inc/abi/reg_ops.h | 27 +++ arch/csky/abiv1/inc/abi/regdef.h | 26 ++ arch/csky/abiv2/inc/abi/reg_ops.h | 17 +++ arch/csky/abiv2/inc/abi/regdef.h | 26 ++ arch/csky/include/asm/bitops.h | 82 +++ arch/csky/include/asm/checksum.h | 50 +++ arch/csky/include/asm/reg_ops.h| 26 ++ arch/csky/include/uapi/asm/byteorder.h | 9 arch/csky/kernel/asm-offsets.c | 88 ++ 9 files changed, 351 insertions(+) create mode 100644 arch/csky/abiv1/inc/abi/reg_ops.h create mode 100644 arch/csky/abiv1/inc/abi/regdef.h create mode 100644 arch/csky/abiv2/inc/abi/reg_ops.h create mode 100644 arch/csky/abiv2/inc/abi/regdef.h create mode 100644 arch/csky/include/asm/bitops.h create mode 100644 arch/csky/include/asm/checksum.h create mode 100644 arch/csky/include/asm/reg_ops.h create mode 100644 arch/csky/include/uapi/asm/byteorder.h create mode 100644 arch/csky/kernel/asm-offsets.c diff --git a/arch/csky/abiv1/inc/abi/reg_ops.h b/arch/csky/abiv1/inc/abi/reg_ops.h new file mode 100644 index 000..a153bd3 --- /dev/null +++ b/arch/csky/abiv1/inc/abi/reg_ops.h @@ -0,0 +1,27 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. + +#ifndef __ABI_REG_OPS_H +#define __ABI_REG_OPS_H +#include + +#define cprcr(reg) \ +({ \ + unsigned int tmp; \ + asm volatile("cprcr %0, "reg"\n":"=b"(tmp));\ + tmp;\ +}) + +#define cpwcr(reg, val)\ +({ \ + asm volatile("cpwcr %0, "reg"\n"::"b"(val));\ +}) + +static inline unsigned int mfcr_hint(void) +{ + return mfcr("cr30"); +} + +static inline unsigned int mfcr_ccr2(void) { return 0; } + +#endif /* __ABI_REG_OPS_H */ diff --git a/arch/csky/abiv1/inc/abi/regdef.h b/arch/csky/abiv1/inc/abi/regdef.h new file mode 100644 index 000..8766892 --- /dev/null +++ b/arch/csky/abiv1/inc/abi/regdef.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. + +#ifndef __ASM_CSKY_REGDEF_H +#define __ASM_CSKY_REGDEF_H + +#define syscallid r1 +#define r11_sigr11 + +#define regs_syscallid(regs) regs->regs[9] + +/* + * PSR format: + * | 31 | 30-24 | 23-16 | 15 14 | 13-0 | + * S CPID VEC TM + * + *S: Super Mode + * CPID: Coprocessor id, only 15 for MMU + * VEC: Exception Number + * TM: Trace Mode + */ +#define DEFAULT_PSR_VALUE 0x8f00 + +#define SYSTRACE_SAVENUM 2 + +#endif /* __ASM_CSKY_REGDEF_H */ diff --git a/arch/csky/abiv2/inc/abi/reg_ops.h b/arch/csky/abiv2/inc/abi/reg_ops.h new file mode 100644 index 000..ae82c3f --- /dev/null +++ b/arch/csky/abiv2/inc/abi/reg_ops.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. + +#ifndef __ABI_REG_OPS_H +#define __ABI_REG_OPS_H +#include + +static inline unsigned int mfcr_hint(void) +{ + return mfcr("cr31"); +} + +static inline unsigned int mfcr_ccr2(void) +{ + return mfcr("cr23"); +} +#endif /* __ABI_REG_OPS_H */ diff --git a/arch/csky/abiv2/inc/abi/regdef.h b/arch/csky/abiv2/inc/abi/regdef.h new file mode 100644 index 000..c72abb7 --- /dev/null +++ b/arch/csky/abiv2/inc/abi/regdef.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. + +#ifndef __ASM_CSKY_REGDEF_H +#define __ASM_CSKY_REGDEF_H + +#define syscallid r7 +#define r11_sigr11 + +#define regs_syscallid(regs) regs->regs[3] + +/* + * PSR format: + * | 31 | 30-24 | 23-16 | 15 14 | 13-10 | 9 | 8-0 | + * S VEC TMMM + * + * S: Super Mode + * VEC: Exception Number + * TM: Trace Mode + * MM: Memory unaligned addr access + */ +#define DEFAULT_PSR_VALUE 0x8200 + +#define SYSTRACE_SAVENUM 5 + +#endif /* __ASM_CSKY_REGDEF_H */ diff --git a/arch/csky/include/asm/bitops.h b/arch/csky/include/asm/bitops.h new file mode 100644 index 000..335f288 --- /dev/null +++ b/arch/csky/include/asm/bitops.h @@ -0,0 +1,82 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. + +#ifndef __ASM_CSKY_BITOPS_H +#define __ASM_CSKY_BITOPS_H + +#include +#include + +/* + * asm-generic/bitops/ffs.h + */ +static inline int ffs(int x) +{ + if (!x) + return 0; + + asm volatile ( + "brev %0\n" + "ff1 %0\n" + "addi %0, 1\n" + : "="(x) + :
[PATCH V7 15/20] csky: Debug and Ptrace GDB
This patch adds arch ptrace implementation, stack dump and bug.h. Signed-off-by: Guo Ren --- arch/csky/include/asm/bug.h | 26 +++ arch/csky/include/uapi/asm/ptrace.h | 104 arch/csky/kernel/dumpstack.c| 66 arch/csky/kernel/ptrace.c | 314 4 files changed, 510 insertions(+) create mode 100644 arch/csky/include/asm/bug.h create mode 100644 arch/csky/include/uapi/asm/ptrace.h create mode 100644 arch/csky/kernel/dumpstack.c create mode 100644 arch/csky/kernel/ptrace.c diff --git a/arch/csky/include/asm/bug.h b/arch/csky/include/asm/bug.h new file mode 100644 index 000..bd7b323 --- /dev/null +++ b/arch/csky/include/asm/bug.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. + +#ifndef __ASM_CSKY_BUG_H +#define __ASM_CSKY_BUG_H + +#include +#include +#include + +#define BUG() \ +do { \ + asm volatile ("bkpt\n");\ + unreachable(); \ +} while (0) + +#define HAVE_ARCH_BUG + +#include + +struct pt_regs; + +void die_if_kernel(char *str, struct pt_regs *regs, int nr); +void show_regs(struct pt_regs *regs); + +#endif /* __ASM_CSKY_BUG_H */ diff --git a/arch/csky/include/uapi/asm/ptrace.h b/arch/csky/include/uapi/asm/ptrace.h new file mode 100644 index 000..f10d02c --- /dev/null +++ b/arch/csky/include/uapi/asm/ptrace.h @@ -0,0 +1,104 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. + +#ifndef _CSKY_PTRACE_H +#define _CSKY_PTRACE_H + +#ifndef __ASSEMBLY__ + +struct pt_regs { + unsigned long tls; + unsigned long lr; + unsigned long pc; + unsigned long sr; + unsigned long usp; + + /* +* a0, a1, a2, a3: +* abiv1: r2, r3, r4, r5 +* abiv2: r0, r1, r2, r3 +*/ + unsigned long orig_a0; + unsigned long a0; + unsigned long a1; + unsigned long a2; + unsigned long a3; + + /* +* ABIV2: r4 ~ r13 +* ABIV1: r6 ~ r14, r1 +*/ + unsigned long regs[10]; + +#if defined(__CSKYABIV2__) + /* r16 ~ r30 */ + unsigned long exregs[15]; + + unsigned long rhi; + unsigned long rlo; + unsigned long pad; /* reserved */ +#endif +}; + +struct user_fp { + unsigned long vr[96]; + unsigned long fcr; + unsigned long fesr; + unsigned long fid; + unsigned long reserved; +}; + +/* + * Switch stack for switch_to after push pt_regs. + * + * ABI_CSKYV2: r4 ~ r11, r15 ~ r17, r26 ~ r30; + * ABI_CSKYV1: r8 ~ r14, r15; + */ +struct switch_stack { +#if defined(__CSKYABIV2__) + unsigned long r4; + unsigned long r5; + unsigned long r6; + unsigned long r7; + unsigned long r8; + unsigned long r9; + unsigned long r10; + unsigned long r11; +#else + unsigned long r8; + unsigned long r9; + unsigned long r10; + unsigned long r11; + unsigned long r12; + unsigned long r13; + unsigned long r14; +#endif + unsigned long r15; +#if defined(__CSKYABIV2__) + unsigned long r16; + unsigned long r17; + unsigned long r26; + unsigned long r27; + unsigned long r28; + unsigned long r29; + unsigned long r30; +#endif +}; + +#ifdef __KERNEL__ + +#define PS_S 0x8000 /* Supervisor Mode */ + +#define arch_has_single_step() (1) +#define current_pt_regs() \ +({ (struct pt_regs *)((char *)current_thread_info() + THREAD_SIZE) - 1; }) + +#define user_stack_pointer(regs) ((regs)->usp) + +#define user_mode(regs) (!((regs)->sr & PS_S)) +#define instruction_pointer(regs) ((regs)->pc) +#define profile_pc(regs) instruction_pointer(regs) + +#endif /* __KERNEL__ */ +#endif /* __ASSEMBLY__ */ +#endif /* _CSKY_PTRACE_H */ diff --git a/arch/csky/kernel/dumpstack.c b/arch/csky/kernel/dumpstack.c new file mode 100644 index 000..a9a03ac --- /dev/null +++ b/arch/csky/kernel/dumpstack.c @@ -0,0 +1,66 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. + +#include + +int kstack_depth_to_print = 48; + +void show_trace(unsigned long *stack) +{ + unsigned long *endstack; + unsigned long addr; + int i; + + pr_info("Call Trace:\n"); + addr = (unsigned long)stack + THREAD_SIZE - 1; + endstack = (unsigned long *)(addr & -THREAD_SIZE); + i = 0; + while (stack + 1 <= endstack) { + addr = *stack++; + /* +* If the address is either in the text segment of the +* kernel, or in the region which contains vmalloc'ed +* memory, it *may* be the address of a calling +* routine; if so, print it so that someone
[PATCH V7 15/20] csky: Debug and Ptrace GDB
This patch adds arch ptrace implementation, stack dump and bug.h. Signed-off-by: Guo Ren --- arch/csky/include/asm/bug.h | 26 +++ arch/csky/include/uapi/asm/ptrace.h | 104 arch/csky/kernel/dumpstack.c| 66 arch/csky/kernel/ptrace.c | 314 4 files changed, 510 insertions(+) create mode 100644 arch/csky/include/asm/bug.h create mode 100644 arch/csky/include/uapi/asm/ptrace.h create mode 100644 arch/csky/kernel/dumpstack.c create mode 100644 arch/csky/kernel/ptrace.c diff --git a/arch/csky/include/asm/bug.h b/arch/csky/include/asm/bug.h new file mode 100644 index 000..bd7b323 --- /dev/null +++ b/arch/csky/include/asm/bug.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. + +#ifndef __ASM_CSKY_BUG_H +#define __ASM_CSKY_BUG_H + +#include +#include +#include + +#define BUG() \ +do { \ + asm volatile ("bkpt\n");\ + unreachable(); \ +} while (0) + +#define HAVE_ARCH_BUG + +#include + +struct pt_regs; + +void die_if_kernel(char *str, struct pt_regs *regs, int nr); +void show_regs(struct pt_regs *regs); + +#endif /* __ASM_CSKY_BUG_H */ diff --git a/arch/csky/include/uapi/asm/ptrace.h b/arch/csky/include/uapi/asm/ptrace.h new file mode 100644 index 000..f10d02c --- /dev/null +++ b/arch/csky/include/uapi/asm/ptrace.h @@ -0,0 +1,104 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. + +#ifndef _CSKY_PTRACE_H +#define _CSKY_PTRACE_H + +#ifndef __ASSEMBLY__ + +struct pt_regs { + unsigned long tls; + unsigned long lr; + unsigned long pc; + unsigned long sr; + unsigned long usp; + + /* +* a0, a1, a2, a3: +* abiv1: r2, r3, r4, r5 +* abiv2: r0, r1, r2, r3 +*/ + unsigned long orig_a0; + unsigned long a0; + unsigned long a1; + unsigned long a2; + unsigned long a3; + + /* +* ABIV2: r4 ~ r13 +* ABIV1: r6 ~ r14, r1 +*/ + unsigned long regs[10]; + +#if defined(__CSKYABIV2__) + /* r16 ~ r30 */ + unsigned long exregs[15]; + + unsigned long rhi; + unsigned long rlo; + unsigned long pad; /* reserved */ +#endif +}; + +struct user_fp { + unsigned long vr[96]; + unsigned long fcr; + unsigned long fesr; + unsigned long fid; + unsigned long reserved; +}; + +/* + * Switch stack for switch_to after push pt_regs. + * + * ABI_CSKYV2: r4 ~ r11, r15 ~ r17, r26 ~ r30; + * ABI_CSKYV1: r8 ~ r14, r15; + */ +struct switch_stack { +#if defined(__CSKYABIV2__) + unsigned long r4; + unsigned long r5; + unsigned long r6; + unsigned long r7; + unsigned long r8; + unsigned long r9; + unsigned long r10; + unsigned long r11; +#else + unsigned long r8; + unsigned long r9; + unsigned long r10; + unsigned long r11; + unsigned long r12; + unsigned long r13; + unsigned long r14; +#endif + unsigned long r15; +#if defined(__CSKYABIV2__) + unsigned long r16; + unsigned long r17; + unsigned long r26; + unsigned long r27; + unsigned long r28; + unsigned long r29; + unsigned long r30; +#endif +}; + +#ifdef __KERNEL__ + +#define PS_S 0x8000 /* Supervisor Mode */ + +#define arch_has_single_step() (1) +#define current_pt_regs() \ +({ (struct pt_regs *)((char *)current_thread_info() + THREAD_SIZE) - 1; }) + +#define user_stack_pointer(regs) ((regs)->usp) + +#define user_mode(regs) (!((regs)->sr & PS_S)) +#define instruction_pointer(regs) ((regs)->pc) +#define profile_pc(regs) instruction_pointer(regs) + +#endif /* __KERNEL__ */ +#endif /* __ASSEMBLY__ */ +#endif /* _CSKY_PTRACE_H */ diff --git a/arch/csky/kernel/dumpstack.c b/arch/csky/kernel/dumpstack.c new file mode 100644 index 000..a9a03ac --- /dev/null +++ b/arch/csky/kernel/dumpstack.c @@ -0,0 +1,66 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. + +#include + +int kstack_depth_to_print = 48; + +void show_trace(unsigned long *stack) +{ + unsigned long *endstack; + unsigned long addr; + int i; + + pr_info("Call Trace:\n"); + addr = (unsigned long)stack + THREAD_SIZE - 1; + endstack = (unsigned long *)(addr & -THREAD_SIZE); + i = 0; + while (stack + 1 <= endstack) { + addr = *stack++; + /* +* If the address is either in the text segment of the +* kernel, or in the region which contains vmalloc'ed +* memory, it *may* be the address of a calling +* routine; if so, print it so that someone
[PATCH V7 16/20] csky: SMP support
This patch adds boot, ipi, hotplug code for SMP. Changelog: - csky: remove irq_mapping from smp.c There are some feedbacks from irqchip, and we need to adjust "smp.c & smp.h" to match the csky_mp_timer modification. - Move IPI_IRQ define into drivers/irqchip/csky_mpintc.c, because it's a interrupt controller specific. - Bugfix request_irq with IPI_IRQ, we must use irq_mapping return value not directly use IPI_IRQ. The modification also involves csky_mp_intc. Signed-off-by: Guo Ren --- arch/csky/include/asm/smp.h | 30 ++ arch/csky/kernel/smp.c | 248 2 files changed, 278 insertions(+) create mode 100644 arch/csky/include/asm/smp.h create mode 100644 arch/csky/kernel/smp.c diff --git a/arch/csky/include/asm/smp.h b/arch/csky/include/asm/smp.h new file mode 100644 index 000..d77f582 --- /dev/null +++ b/arch/csky/include/asm/smp.h @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef __ASM_CSKY_SMP_H +#define __ASM_CSKY_SMP_H + +#include +#include +#include + +#ifdef CONFIG_SMP + +void __init setup_smp(void); + +void __init setup_smp_ipi(void); + +void __init enable_smp_ipi(void); + +void arch_send_call_function_ipi_mask(struct cpumask *mask); + +void arch_send_call_function_single_ipi(int cpu); + +void __init set_send_ipi(void (*func)(const unsigned long *)); + +void __init set_ipi_irq_mapping(int (*func)(void)); + +#define raw_smp_processor_id() (current_thread_info()->cpu) + +#endif /* CONFIG_SMP */ + +#endif /* __ASM_CSKY_SMP_H */ diff --git a/arch/csky/kernel/smp.c b/arch/csky/kernel/smp.c new file mode 100644 index 000..841cf72 --- /dev/null +++ b/arch/csky/kernel/smp.c @@ -0,0 +1,248 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static struct { + unsigned long bits cacheline_aligned; +} ipi_data[NR_CPUS] __cacheline_aligned; + +enum ipi_message_type { + IPI_EMPTY, + IPI_RESCHEDULE, + IPI_CALL_FUNC, + IPI_MAX +}; + +static irqreturn_t handle_ipi(int irq, void *dev) +{ + unsigned long *pending_ipis = _data[smp_processor_id()].bits; + + while (true) { + unsigned long ops; + + ops = xchg(pending_ipis, 0); + if (ops == 0) + return IRQ_HANDLED; + + if (ops & (1 << IPI_RESCHEDULE)) + scheduler_ipi(); + + if (ops & (1 << IPI_CALL_FUNC)) + generic_smp_call_function_interrupt(); + + BUG_ON((ops >> IPI_MAX) != 0); + } + + return IRQ_HANDLED; +} + +static void (*send_arch_ipi)(const unsigned long *mask); + +void __init set_send_ipi(void (*func)(const unsigned long *)) +{ + if (send_arch_ipi) + return; + + send_arch_ipi = func; +} + +static void +send_ipi_message(const struct cpumask *to_whom, enum ipi_message_type operation) +{ + int i; + + for_each_cpu(i, to_whom) + set_bit(operation, _data[i].bits); + + smp_mb(); + send_arch_ipi(cpumask_bits(to_whom)); +} + +void arch_send_call_function_ipi_mask(struct cpumask *mask) +{ + send_ipi_message(mask, IPI_CALL_FUNC); +} + +void arch_send_call_function_single_ipi(int cpu) +{ + send_ipi_message(cpumask_of(cpu), IPI_CALL_FUNC); +} + +static void ipi_stop(void *unused) +{ + while (1); +} + +void smp_send_stop(void) +{ + on_each_cpu(ipi_stop, NULL, 1); +} + +void smp_send_reschedule(int cpu) +{ + send_ipi_message(cpumask_of(cpu), IPI_RESCHEDULE); +} + +void *__cpu_up_stack_pointer[NR_CPUS]; +void *__cpu_up_task_pointer[NR_CPUS]; + +void __init smp_prepare_boot_cpu(void) +{ +} + +void __init smp_prepare_cpus(unsigned int max_cpus) +{ +} + +static int ipi_dummy_dev; +static int ipi_irq; + +void __init enable_smp_ipi(void) +{ + enable_percpu_irq(ipi_irq, 0); +} + +static int (*arch_ipi_irq_mapping)(void); + +void __init set_ipi_irq_mapping(int (*func)(void)) +{ + if (arch_ipi_irq_mapping) + return; + + arch_ipi_irq_mapping = func; +} + +void __init setup_smp_ipi(void) +{ + int rc; + + ipi_irq = arch_ipi_irq_mapping(); + if (ipi_irq == 0) + panic("%s IRQ mapping failed\n", __func__); + + rc = request_percpu_irq(ipi_irq, handle_ipi, "IPI Interrupt", + _dummy_dev); + if (rc) + panic("%s IRQ request failed\n", __func__); + + enable_smp_ipi(); +} + +void __init setup_smp(void) +{ + struct device_node *node = NULL; + int cpu; + + while ((node = of_find_node_by_type(node, "cpu"))) { + if (!of_device_is_available(node)) + continue; + + if (of_property_read_u32(node,
linux-next: manual merge of the akpm-current tree with the btrfs-kdave tree
Hi all, Today's linux-next merge of the akpm-current tree got a conflict in: include/linux/swap.h between commit: 0f83d16b8f1f ("mm: split SWP_FILE into SWP_ACTIVATED and SWP_FS") from the btrfs-kdave tree and commit: 26833300651e ("mm, swap: fix race between swapoff and some swap operations") from the akpm-current tree. I fixed it up (see below) and can carry the fix as necessary. This is now fixed as far as linux-next is concerned, but any non trivial conflicts should be mentioned to your upstream maintainer when your tree is submitted for merging. You may also want to consider cooperating with the maintainer of the conflicting tree to minimise any particularly complex conflicts. -- Cheers, Stephen Rothwell diff --cc include/linux/swap.h index 4fff094dbd53,f32f94639b13.. --- a/include/linux/swap.h +++ b/include/linux/swap.h @@@ -167,14 -167,14 +167,15 @@@ enum SWP_SOLIDSTATE = (1 << 4), /* blkdev seeks are cheap */ SWP_CONTINUED = (1 << 5), /* swap_map has count continuation */ SWP_BLKDEV = (1 << 6), /* its a block device */ - SWP_FILE= (1 << 7), /* set after swap_activate success */ - SWP_AREA_DISCARD = (1 << 8),/* single-time swap area discards */ - SWP_PAGE_DISCARD = (1 << 9),/* freed swap page-cluster discards */ - SWP_STABLE_WRITES = (1 << 10), /* no overwrite PG_writeback pages */ - SWP_SYNCHRONOUS_IO = (1 << 11), /* synchronous IO is efficient */ - SWP_VALID = (1 << 12),/* swap is valid to be operated on? */ + SWP_ACTIVATED = (1 << 7), /* set after swap_activate success */ + SWP_FS = (1 << 8), /* swap file goes through fs */ + SWP_AREA_DISCARD = (1 << 9),/* single-time swap area discards */ + SWP_PAGE_DISCARD = (1 << 10), /* freed swap page-cluster discards */ + SWP_STABLE_WRITES = (1 << 11), /* no overwrite PG_writeback pages */ + SWP_SYNCHRONOUS_IO = (1 << 12), /* synchronous IO is efficient */ ++ SWP_VALID = (1 << 13),/* swap is valid to be operated on? */ /* add others here before... */ -- SWP_SCANNING= (1 << 13),/* refcount in scan_swap_map */ ++ SWP_SCANNING= (1 << 14),/* refcount in scan_swap_map */ }; #define SWAP_CLUSTER_MAX 32UL @@@ -297,15 -297,20 +298,15 @@@ struct vma_swap_readahead /* linux/mm/workingset.c */ void *workingset_eviction(struct address_space *mapping, struct page *page); - bool workingset_refault(void *shadow); + void workingset_refault(struct page *page, void *shadow); void workingset_activation(struct page *page); -/* Do not use directly, use workingset_lookup_update */ -void workingset_update_node(struct radix_tree_node *node); - -/* Returns workingset_update_node() if the mapping has shadow entries. */ -#define workingset_lookup_update(mapping) \ -({\ - radix_tree_update_node_t __helper = workingset_update_node; \ - if (dax_mapping(mapping) || shmem_mapping(mapping)) \ - __helper = NULL;\ - __helper; \ -}) +/* Only track the nodes of mappings with shadow entries */ +void workingset_update_node(struct xa_node *node); +#define mapping_set_update(xas, mapping) do { \ + if (!dax_mapping(mapping) && !shmem_mapping(mapping)) \ + xas_set_update(xas, workingset_update_node);\ +} while (0) /* linux/mm/page_alloc.c */ extern unsigned long totalram_pages; pgp9X9mrlsK9W.pgp Description: OpenPGP digital signature
[PATCH V7 16/20] csky: SMP support
This patch adds boot, ipi, hotplug code for SMP. Changelog: - csky: remove irq_mapping from smp.c There are some feedbacks from irqchip, and we need to adjust "smp.c & smp.h" to match the csky_mp_timer modification. - Move IPI_IRQ define into drivers/irqchip/csky_mpintc.c, because it's a interrupt controller specific. - Bugfix request_irq with IPI_IRQ, we must use irq_mapping return value not directly use IPI_IRQ. The modification also involves csky_mp_intc. Signed-off-by: Guo Ren --- arch/csky/include/asm/smp.h | 30 ++ arch/csky/kernel/smp.c | 248 2 files changed, 278 insertions(+) create mode 100644 arch/csky/include/asm/smp.h create mode 100644 arch/csky/kernel/smp.c diff --git a/arch/csky/include/asm/smp.h b/arch/csky/include/asm/smp.h new file mode 100644 index 000..d77f582 --- /dev/null +++ b/arch/csky/include/asm/smp.h @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef __ASM_CSKY_SMP_H +#define __ASM_CSKY_SMP_H + +#include +#include +#include + +#ifdef CONFIG_SMP + +void __init setup_smp(void); + +void __init setup_smp_ipi(void); + +void __init enable_smp_ipi(void); + +void arch_send_call_function_ipi_mask(struct cpumask *mask); + +void arch_send_call_function_single_ipi(int cpu); + +void __init set_send_ipi(void (*func)(const unsigned long *)); + +void __init set_ipi_irq_mapping(int (*func)(void)); + +#define raw_smp_processor_id() (current_thread_info()->cpu) + +#endif /* CONFIG_SMP */ + +#endif /* __ASM_CSKY_SMP_H */ diff --git a/arch/csky/kernel/smp.c b/arch/csky/kernel/smp.c new file mode 100644 index 000..841cf72 --- /dev/null +++ b/arch/csky/kernel/smp.c @@ -0,0 +1,248 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static struct { + unsigned long bits cacheline_aligned; +} ipi_data[NR_CPUS] __cacheline_aligned; + +enum ipi_message_type { + IPI_EMPTY, + IPI_RESCHEDULE, + IPI_CALL_FUNC, + IPI_MAX +}; + +static irqreturn_t handle_ipi(int irq, void *dev) +{ + unsigned long *pending_ipis = _data[smp_processor_id()].bits; + + while (true) { + unsigned long ops; + + ops = xchg(pending_ipis, 0); + if (ops == 0) + return IRQ_HANDLED; + + if (ops & (1 << IPI_RESCHEDULE)) + scheduler_ipi(); + + if (ops & (1 << IPI_CALL_FUNC)) + generic_smp_call_function_interrupt(); + + BUG_ON((ops >> IPI_MAX) != 0); + } + + return IRQ_HANDLED; +} + +static void (*send_arch_ipi)(const unsigned long *mask); + +void __init set_send_ipi(void (*func)(const unsigned long *)) +{ + if (send_arch_ipi) + return; + + send_arch_ipi = func; +} + +static void +send_ipi_message(const struct cpumask *to_whom, enum ipi_message_type operation) +{ + int i; + + for_each_cpu(i, to_whom) + set_bit(operation, _data[i].bits); + + smp_mb(); + send_arch_ipi(cpumask_bits(to_whom)); +} + +void arch_send_call_function_ipi_mask(struct cpumask *mask) +{ + send_ipi_message(mask, IPI_CALL_FUNC); +} + +void arch_send_call_function_single_ipi(int cpu) +{ + send_ipi_message(cpumask_of(cpu), IPI_CALL_FUNC); +} + +static void ipi_stop(void *unused) +{ + while (1); +} + +void smp_send_stop(void) +{ + on_each_cpu(ipi_stop, NULL, 1); +} + +void smp_send_reschedule(int cpu) +{ + send_ipi_message(cpumask_of(cpu), IPI_RESCHEDULE); +} + +void *__cpu_up_stack_pointer[NR_CPUS]; +void *__cpu_up_task_pointer[NR_CPUS]; + +void __init smp_prepare_boot_cpu(void) +{ +} + +void __init smp_prepare_cpus(unsigned int max_cpus) +{ +} + +static int ipi_dummy_dev; +static int ipi_irq; + +void __init enable_smp_ipi(void) +{ + enable_percpu_irq(ipi_irq, 0); +} + +static int (*arch_ipi_irq_mapping)(void); + +void __init set_ipi_irq_mapping(int (*func)(void)) +{ + if (arch_ipi_irq_mapping) + return; + + arch_ipi_irq_mapping = func; +} + +void __init setup_smp_ipi(void) +{ + int rc; + + ipi_irq = arch_ipi_irq_mapping(); + if (ipi_irq == 0) + panic("%s IRQ mapping failed\n", __func__); + + rc = request_percpu_irq(ipi_irq, handle_ipi, "IPI Interrupt", + _dummy_dev); + if (rc) + panic("%s IRQ request failed\n", __func__); + + enable_smp_ipi(); +} + +void __init setup_smp(void) +{ + struct device_node *node = NULL; + int cpu; + + while ((node = of_find_node_by_type(node, "cpu"))) { + if (!of_device_is_available(node)) + continue; + + if (of_property_read_u32(node,
linux-next: manual merge of the akpm-current tree with the btrfs-kdave tree
Hi all, Today's linux-next merge of the akpm-current tree got a conflict in: include/linux/swap.h between commit: 0f83d16b8f1f ("mm: split SWP_FILE into SWP_ACTIVATED and SWP_FS") from the btrfs-kdave tree and commit: 26833300651e ("mm, swap: fix race between swapoff and some swap operations") from the akpm-current tree. I fixed it up (see below) and can carry the fix as necessary. This is now fixed as far as linux-next is concerned, but any non trivial conflicts should be mentioned to your upstream maintainer when your tree is submitted for merging. You may also want to consider cooperating with the maintainer of the conflicting tree to minimise any particularly complex conflicts. -- Cheers, Stephen Rothwell diff --cc include/linux/swap.h index 4fff094dbd53,f32f94639b13.. --- a/include/linux/swap.h +++ b/include/linux/swap.h @@@ -167,14 -167,14 +167,15 @@@ enum SWP_SOLIDSTATE = (1 << 4), /* blkdev seeks are cheap */ SWP_CONTINUED = (1 << 5), /* swap_map has count continuation */ SWP_BLKDEV = (1 << 6), /* its a block device */ - SWP_FILE= (1 << 7), /* set after swap_activate success */ - SWP_AREA_DISCARD = (1 << 8),/* single-time swap area discards */ - SWP_PAGE_DISCARD = (1 << 9),/* freed swap page-cluster discards */ - SWP_STABLE_WRITES = (1 << 10), /* no overwrite PG_writeback pages */ - SWP_SYNCHRONOUS_IO = (1 << 11), /* synchronous IO is efficient */ - SWP_VALID = (1 << 12),/* swap is valid to be operated on? */ + SWP_ACTIVATED = (1 << 7), /* set after swap_activate success */ + SWP_FS = (1 << 8), /* swap file goes through fs */ + SWP_AREA_DISCARD = (1 << 9),/* single-time swap area discards */ + SWP_PAGE_DISCARD = (1 << 10), /* freed swap page-cluster discards */ + SWP_STABLE_WRITES = (1 << 11), /* no overwrite PG_writeback pages */ + SWP_SYNCHRONOUS_IO = (1 << 12), /* synchronous IO is efficient */ ++ SWP_VALID = (1 << 13),/* swap is valid to be operated on? */ /* add others here before... */ -- SWP_SCANNING= (1 << 13),/* refcount in scan_swap_map */ ++ SWP_SCANNING= (1 << 14),/* refcount in scan_swap_map */ }; #define SWAP_CLUSTER_MAX 32UL @@@ -297,15 -297,20 +298,15 @@@ struct vma_swap_readahead /* linux/mm/workingset.c */ void *workingset_eviction(struct address_space *mapping, struct page *page); - bool workingset_refault(void *shadow); + void workingset_refault(struct page *page, void *shadow); void workingset_activation(struct page *page); -/* Do not use directly, use workingset_lookup_update */ -void workingset_update_node(struct radix_tree_node *node); - -/* Returns workingset_update_node() if the mapping has shadow entries. */ -#define workingset_lookup_update(mapping) \ -({\ - radix_tree_update_node_t __helper = workingset_update_node; \ - if (dax_mapping(mapping) || shmem_mapping(mapping)) \ - __helper = NULL;\ - __helper; \ -}) +/* Only track the nodes of mappings with shadow entries */ +void workingset_update_node(struct xa_node *node); +#define mapping_set_update(xas, mapping) do { \ + if (!dax_mapping(mapping) && !shmem_mapping(mapping)) \ + xas_set_update(xas, workingset_update_node);\ +} while (0) /* linux/mm/page_alloc.c */ extern unsigned long totalram_pages; pgp9X9mrlsK9W.pgp Description: OpenPGP digital signature
[PATCH V7 14/20] csky: User access
This patch adds "user access from kernel" codes. Signed-off-by: Guo Ren --- arch/csky/include/asm/uaccess.h | 416 arch/csky/lib/usercopy.c| 262 + 2 files changed, 678 insertions(+) create mode 100644 arch/csky/include/asm/uaccess.h create mode 100644 arch/csky/lib/usercopy.c diff --git a/arch/csky/include/asm/uaccess.h b/arch/csky/include/asm/uaccess.h new file mode 100644 index 000..acaf0e210 --- /dev/null +++ b/arch/csky/include/asm/uaccess.h @@ -0,0 +1,416 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. + +#ifndef __ASM_CSKY_UACCESS_H +#define __ASM_CSKY_UACCESS_H + +/* + * User space memory access functions + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#define VERIFY_READ0 +#define VERIFY_WRITE 1 + +static inline int access_ok(int type, const void *addr, unsigned long size) +{ + unsigned long limit = current_thread_info()->addr_limit.seg; + + return (((unsigned long)addr < limit) && + ((unsigned long)(addr + size) < limit)); +} + +static inline int verify_area(int type, const void *addr, unsigned long size) +{ + return access_ok(type, addr, size) ? 0 : -EFAULT; +} + +#define __addr_ok(addr) (access_ok(VERIFY_READ, addr, 0)) + +extern int __put_user_bad(void); + +/* + * Tell gcc we read from memory instead of writing: this is because + * we do not write to any memory gcc knows about, so there are no + * aliasing issues. + */ + +/* + * These are the main single-value transfer routines. They automatically + * use the right size if we just have the right pointer type. + * + * This gets kind of ugly. We want to return _two_ values in "get_user()" + * and yet we don't want to do any pointers, because that is too much + * of a performance impact. Thus we have a few rather ugly macros here, + * and hide all the ugliness from the user. + * + * The "__xxx" versions of the user access functions are versions that + * do not verify the address space, that must have been done previously + * with a separate "access_ok()" call (this is used when we do multiple + * accesses to the same area of user memory). + * + * As we use the same address space for kernel and user data on + * Ckcore, we can just do these as direct assignments. (Of course, the + * exception handling means that it's no longer "just"...) + */ + +#define put_user(x, ptr) \ + __put_user_check((x), (ptr), sizeof(*(ptr))) + +#define __put_user(x, ptr) \ + __put_user_nocheck((x), (ptr), sizeof(*(ptr))) + +#define __ptr(x) ((unsigned long *)(x)) + +#define get_user(x, ptr) \ + __get_user_check((x), (ptr), sizeof(*(ptr))) + +#define __get_user(x, ptr) \ + __get_user_nocheck((x), (ptr), sizeof(*(ptr))) + +#define __put_user_nocheck(x, ptr, size) \ +({ \ + long __pu_err = 0; \ + typeof(*(ptr)) *__pu_addr = (ptr); \ + typeof(*(ptr)) __pu_val = (typeof(*(ptr)))(x); \ + if (__pu_addr) \ + __put_user_size(__pu_val, (__pu_addr), (size), \ + __pu_err); \ + __pu_err; \ +}) + +#define __put_user_check(x, ptr, size) \ +({ \ + long __pu_err = -EFAULT;\ + typeof(*(ptr)) *__pu_addr = (ptr); \ + typeof(*(ptr)) __pu_val = (typeof(*(ptr)))(x); \ + if (access_ok(VERIFY_WRITE, __pu_addr, size) && __pu_addr) \ + __put_user_size(__pu_val, __pu_addr, (size), __pu_err); \ + __pu_err; \ +}) + +#define __put_user_size(x, ptr, size, retval) \ +do { \ + retval = 0; \ + switch (size) { \ + case 1: \ + __put_user_asm_b(x, ptr, retval); \ + break; \ + case 2: \ + __put_user_asm_h(x, ptr, retval); \ + break; \ + case 4: \ + __put_user_asm_w(x, ptr, retval); \ + break; \ + case 8: \ + __put_user_asm_64(x, ptr, retval); \ +
[PATCH V7 13/20] csky: Library functions
This patch adds string optimize codes and some auxiliary code. Changelog: - Use bt instead of jbt in asm, jbt will cause relocation problem. - remove kernel/platform.c Signed-off-by: Chen Linfei Signed-off-by: Mao Han Signed-off-by: Guo Ren --- arch/csky/abiv1/bswapdi.c| 12 ++ arch/csky/abiv1/bswapsi.c| 12 ++ arch/csky/abiv1/inc/abi/string.h | 13 ++ arch/csky/abiv1/memcpy.S | 347 +++ arch/csky/abiv1/memset.c | 37 + arch/csky/abiv1/strksyms.c | 7 + arch/csky/abiv2/inc/abi/string.h | 27 +++ arch/csky/abiv2/memcmp.S | 152 + arch/csky/abiv2/memcpy.S | 110 + arch/csky/abiv2/memmove.S| 108 arch/csky/abiv2/memset.S | 83 ++ arch/csky/abiv2/strcmp.S | 168 +++ arch/csky/abiv2/strcpy.S | 123 ++ arch/csky/abiv2/strksyms.c | 12 ++ arch/csky/abiv2/strlen.S | 97 +++ arch/csky/abiv2/sysdep.h | 30 arch/csky/include/asm/string.h | 13 ++ arch/csky/kernel/power.c | 30 arch/csky/lib/delay.c| 39 + 19 files changed, 1420 insertions(+) create mode 100644 arch/csky/abiv1/bswapdi.c create mode 100644 arch/csky/abiv1/bswapsi.c create mode 100644 arch/csky/abiv1/inc/abi/string.h create mode 100644 arch/csky/abiv1/memcpy.S create mode 100644 arch/csky/abiv1/memset.c create mode 100644 arch/csky/abiv1/strksyms.c create mode 100644 arch/csky/abiv2/inc/abi/string.h create mode 100644 arch/csky/abiv2/memcmp.S create mode 100644 arch/csky/abiv2/memcpy.S create mode 100644 arch/csky/abiv2/memmove.S create mode 100644 arch/csky/abiv2/memset.S create mode 100644 arch/csky/abiv2/strcmp.S create mode 100644 arch/csky/abiv2/strcpy.S create mode 100644 arch/csky/abiv2/strksyms.c create mode 100644 arch/csky/abiv2/strlen.S create mode 100644 arch/csky/abiv2/sysdep.h create mode 100644 arch/csky/include/asm/string.h create mode 100644 arch/csky/kernel/power.c create mode 100644 arch/csky/lib/delay.c diff --git a/arch/csky/abiv1/bswapdi.c b/arch/csky/abiv1/bswapdi.c new file mode 100644 index 000..f50a1d6 --- /dev/null +++ b/arch/csky/abiv1/bswapdi.c @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. + +#include +#include +#include + +unsigned long long notrace __bswapdi2(unsigned long long u) +{ + return ___constant_swab64(u); +} +EXPORT_SYMBOL(__bswapdi2); diff --git a/arch/csky/abiv1/bswapsi.c b/arch/csky/abiv1/bswapsi.c new file mode 100644 index 000..0f79182 --- /dev/null +++ b/arch/csky/abiv1/bswapsi.c @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. + +#include +#include +#include + +unsigned int notrace __bswapsi2(unsigned int u) +{ + return ___constant_swab32(u); +} +EXPORT_SYMBOL(__bswapsi2); diff --git a/arch/csky/abiv1/inc/abi/string.h b/arch/csky/abiv1/inc/abi/string.h new file mode 100644 index 000..5abe80b --- /dev/null +++ b/arch/csky/abiv1/inc/abi/string.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. + +#ifndef __ABI_CSKY_STRING_H +#define __ABI_CSKY_STRING_H + +#define __HAVE_ARCH_MEMCPY +extern void *memcpy(void *, const void *, __kernel_size_t); + +#define __HAVE_ARCH_MEMSET +extern void *memset(void *, int, __kernel_size_t); + +#endif /* __ABI_CSKY_STRING_H */ diff --git a/arch/csky/abiv1/memcpy.S b/arch/csky/abiv1/memcpy.S new file mode 100644 index 000..5078eb5 --- /dev/null +++ b/arch/csky/abiv1/memcpy.S @@ -0,0 +1,347 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. + +#include + +.macro GET_FRONT_BITS rx y +#ifdef __cskyLE__ + lsri\rx, \y +#else + lsli\rx, \y +#endif +.endm + +.macro GET_AFTER_BITS rx y +#ifdef __cskyLE__ + lsli\rx, \y +#else + lsri\rx, \y +#endif +.endm + +/* void *memcpy(void *dest, const void *src, size_t n); */ +ENTRY(memcpy) + mov r7, r2 + cmplti r4, 4 + bt .L_copy_by_byte + mov r6, r2 + andir6, 3 + cmpnei r6, 0 + jbt .L_dest_not_aligned + mov r6, r3 + andir6, 3 + cmpnei r6, 0 + jbt .L_dest_aligned_but_src_not_aligned +.L0: + cmplti r4, 16 + jbt .L_aligned_and_len_less_16bytes + subisp, 8 + stw r8, (sp, 0) +.L_aligned_and_len_larger_16bytes: + ldw r1, (r3, 0) + ldw r5, (r3, 4) + ldw r8, (r3, 8) + stw r1, (r7, 0) + ldw r1, (r3, 12) + stw r5, (r7, 4) + stw r8, (r7, 8) + stw r1, (r7, 12) + subir4, 16 + addir3, 16 + addir7, 16 + cmplti r4, 16 + jbf .L_aligned_and_len_larger_16bytes + ldw
[PATCH V7 13/20] csky: Library functions
This patch adds string optimize codes and some auxiliary code. Changelog: - Use bt instead of jbt in asm, jbt will cause relocation problem. - remove kernel/platform.c Signed-off-by: Chen Linfei Signed-off-by: Mao Han Signed-off-by: Guo Ren --- arch/csky/abiv1/bswapdi.c| 12 ++ arch/csky/abiv1/bswapsi.c| 12 ++ arch/csky/abiv1/inc/abi/string.h | 13 ++ arch/csky/abiv1/memcpy.S | 347 +++ arch/csky/abiv1/memset.c | 37 + arch/csky/abiv1/strksyms.c | 7 + arch/csky/abiv2/inc/abi/string.h | 27 +++ arch/csky/abiv2/memcmp.S | 152 + arch/csky/abiv2/memcpy.S | 110 + arch/csky/abiv2/memmove.S| 108 arch/csky/abiv2/memset.S | 83 ++ arch/csky/abiv2/strcmp.S | 168 +++ arch/csky/abiv2/strcpy.S | 123 ++ arch/csky/abiv2/strksyms.c | 12 ++ arch/csky/abiv2/strlen.S | 97 +++ arch/csky/abiv2/sysdep.h | 30 arch/csky/include/asm/string.h | 13 ++ arch/csky/kernel/power.c | 30 arch/csky/lib/delay.c| 39 + 19 files changed, 1420 insertions(+) create mode 100644 arch/csky/abiv1/bswapdi.c create mode 100644 arch/csky/abiv1/bswapsi.c create mode 100644 arch/csky/abiv1/inc/abi/string.h create mode 100644 arch/csky/abiv1/memcpy.S create mode 100644 arch/csky/abiv1/memset.c create mode 100644 arch/csky/abiv1/strksyms.c create mode 100644 arch/csky/abiv2/inc/abi/string.h create mode 100644 arch/csky/abiv2/memcmp.S create mode 100644 arch/csky/abiv2/memcpy.S create mode 100644 arch/csky/abiv2/memmove.S create mode 100644 arch/csky/abiv2/memset.S create mode 100644 arch/csky/abiv2/strcmp.S create mode 100644 arch/csky/abiv2/strcpy.S create mode 100644 arch/csky/abiv2/strksyms.c create mode 100644 arch/csky/abiv2/strlen.S create mode 100644 arch/csky/abiv2/sysdep.h create mode 100644 arch/csky/include/asm/string.h create mode 100644 arch/csky/kernel/power.c create mode 100644 arch/csky/lib/delay.c diff --git a/arch/csky/abiv1/bswapdi.c b/arch/csky/abiv1/bswapdi.c new file mode 100644 index 000..f50a1d6 --- /dev/null +++ b/arch/csky/abiv1/bswapdi.c @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. + +#include +#include +#include + +unsigned long long notrace __bswapdi2(unsigned long long u) +{ + return ___constant_swab64(u); +} +EXPORT_SYMBOL(__bswapdi2); diff --git a/arch/csky/abiv1/bswapsi.c b/arch/csky/abiv1/bswapsi.c new file mode 100644 index 000..0f79182 --- /dev/null +++ b/arch/csky/abiv1/bswapsi.c @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. + +#include +#include +#include + +unsigned int notrace __bswapsi2(unsigned int u) +{ + return ___constant_swab32(u); +} +EXPORT_SYMBOL(__bswapsi2); diff --git a/arch/csky/abiv1/inc/abi/string.h b/arch/csky/abiv1/inc/abi/string.h new file mode 100644 index 000..5abe80b --- /dev/null +++ b/arch/csky/abiv1/inc/abi/string.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. + +#ifndef __ABI_CSKY_STRING_H +#define __ABI_CSKY_STRING_H + +#define __HAVE_ARCH_MEMCPY +extern void *memcpy(void *, const void *, __kernel_size_t); + +#define __HAVE_ARCH_MEMSET +extern void *memset(void *, int, __kernel_size_t); + +#endif /* __ABI_CSKY_STRING_H */ diff --git a/arch/csky/abiv1/memcpy.S b/arch/csky/abiv1/memcpy.S new file mode 100644 index 000..5078eb5 --- /dev/null +++ b/arch/csky/abiv1/memcpy.S @@ -0,0 +1,347 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. + +#include + +.macro GET_FRONT_BITS rx y +#ifdef __cskyLE__ + lsri\rx, \y +#else + lsli\rx, \y +#endif +.endm + +.macro GET_AFTER_BITS rx y +#ifdef __cskyLE__ + lsli\rx, \y +#else + lsri\rx, \y +#endif +.endm + +/* void *memcpy(void *dest, const void *src, size_t n); */ +ENTRY(memcpy) + mov r7, r2 + cmplti r4, 4 + bt .L_copy_by_byte + mov r6, r2 + andir6, 3 + cmpnei r6, 0 + jbt .L_dest_not_aligned + mov r6, r3 + andir6, 3 + cmpnei r6, 0 + jbt .L_dest_aligned_but_src_not_aligned +.L0: + cmplti r4, 16 + jbt .L_aligned_and_len_less_16bytes + subisp, 8 + stw r8, (sp, 0) +.L_aligned_and_len_larger_16bytes: + ldw r1, (r3, 0) + ldw r5, (r3, 4) + ldw r8, (r3, 8) + stw r1, (r7, 0) + ldw r1, (r3, 12) + stw r5, (r7, 4) + stw r8, (r7, 8) + stw r1, (r7, 12) + subir4, 16 + addir3, 16 + addir7, 16 + cmplti r4, 16 + jbf .L_aligned_and_len_larger_16bytes + ldw
[PATCH V7 14/20] csky: User access
This patch adds "user access from kernel" codes. Signed-off-by: Guo Ren --- arch/csky/include/asm/uaccess.h | 416 arch/csky/lib/usercopy.c| 262 + 2 files changed, 678 insertions(+) create mode 100644 arch/csky/include/asm/uaccess.h create mode 100644 arch/csky/lib/usercopy.c diff --git a/arch/csky/include/asm/uaccess.h b/arch/csky/include/asm/uaccess.h new file mode 100644 index 000..acaf0e210 --- /dev/null +++ b/arch/csky/include/asm/uaccess.h @@ -0,0 +1,416 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. + +#ifndef __ASM_CSKY_UACCESS_H +#define __ASM_CSKY_UACCESS_H + +/* + * User space memory access functions + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#define VERIFY_READ0 +#define VERIFY_WRITE 1 + +static inline int access_ok(int type, const void *addr, unsigned long size) +{ + unsigned long limit = current_thread_info()->addr_limit.seg; + + return (((unsigned long)addr < limit) && + ((unsigned long)(addr + size) < limit)); +} + +static inline int verify_area(int type, const void *addr, unsigned long size) +{ + return access_ok(type, addr, size) ? 0 : -EFAULT; +} + +#define __addr_ok(addr) (access_ok(VERIFY_READ, addr, 0)) + +extern int __put_user_bad(void); + +/* + * Tell gcc we read from memory instead of writing: this is because + * we do not write to any memory gcc knows about, so there are no + * aliasing issues. + */ + +/* + * These are the main single-value transfer routines. They automatically + * use the right size if we just have the right pointer type. + * + * This gets kind of ugly. We want to return _two_ values in "get_user()" + * and yet we don't want to do any pointers, because that is too much + * of a performance impact. Thus we have a few rather ugly macros here, + * and hide all the ugliness from the user. + * + * The "__xxx" versions of the user access functions are versions that + * do not verify the address space, that must have been done previously + * with a separate "access_ok()" call (this is used when we do multiple + * accesses to the same area of user memory). + * + * As we use the same address space for kernel and user data on + * Ckcore, we can just do these as direct assignments. (Of course, the + * exception handling means that it's no longer "just"...) + */ + +#define put_user(x, ptr) \ + __put_user_check((x), (ptr), sizeof(*(ptr))) + +#define __put_user(x, ptr) \ + __put_user_nocheck((x), (ptr), sizeof(*(ptr))) + +#define __ptr(x) ((unsigned long *)(x)) + +#define get_user(x, ptr) \ + __get_user_check((x), (ptr), sizeof(*(ptr))) + +#define __get_user(x, ptr) \ + __get_user_nocheck((x), (ptr), sizeof(*(ptr))) + +#define __put_user_nocheck(x, ptr, size) \ +({ \ + long __pu_err = 0; \ + typeof(*(ptr)) *__pu_addr = (ptr); \ + typeof(*(ptr)) __pu_val = (typeof(*(ptr)))(x); \ + if (__pu_addr) \ + __put_user_size(__pu_val, (__pu_addr), (size), \ + __pu_err); \ + __pu_err; \ +}) + +#define __put_user_check(x, ptr, size) \ +({ \ + long __pu_err = -EFAULT;\ + typeof(*(ptr)) *__pu_addr = (ptr); \ + typeof(*(ptr)) __pu_val = (typeof(*(ptr)))(x); \ + if (access_ok(VERIFY_WRITE, __pu_addr, size) && __pu_addr) \ + __put_user_size(__pu_val, __pu_addr, (size), __pu_err); \ + __pu_err; \ +}) + +#define __put_user_size(x, ptr, size, retval) \ +do { \ + retval = 0; \ + switch (size) { \ + case 1: \ + __put_user_asm_b(x, ptr, retval); \ + break; \ + case 2: \ + __put_user_asm_h(x, ptr, retval); \ + break; \ + case 4: \ + __put_user_asm_w(x, ptr, retval); \ + break; \ + case 8: \ + __put_user_asm_64(x, ptr, retval); \ +
[PATCH V7 09/20] csky: VDSO and rt_sigreturn
This patch adds files related to VDSO and our VDSO only support rt_sigreturn. Signed-off-by: Guo Ren --- arch/csky/abiv1/inc/abi/vdso.h | 17 + arch/csky/abiv2/inc/abi/vdso.h | 23 +++ arch/csky/include/asm/vdso.h | 12 ++ arch/csky/kernel/vdso.c| 86 ++ 4 files changed, 138 insertions(+) create mode 100644 arch/csky/abiv1/inc/abi/vdso.h create mode 100644 arch/csky/abiv2/inc/abi/vdso.h create mode 100644 arch/csky/include/asm/vdso.h create mode 100644 arch/csky/kernel/vdso.c diff --git a/arch/csky/abiv1/inc/abi/vdso.h b/arch/csky/abiv1/inc/abi/vdso.h new file mode 100644 index 000..14352f5 --- /dev/null +++ b/arch/csky/abiv1/inc/abi/vdso.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#include + +static inline int setup_vdso_page(unsigned short *ptr) +{ + int err = 0; + + /* movi r1, 127 */ + err |= __put_user(0x67f1, ptr + 0); + /* addi r1, (139 - 127) */ + err |= __put_user(0x20b1, ptr + 1); + /* trap 0 */ + err |= __put_user(0x0008, ptr + 2); + + return err; +} diff --git a/arch/csky/abiv2/inc/abi/vdso.h b/arch/csky/abiv2/inc/abi/vdso.h new file mode 100644 index 000..b60d4a0 --- /dev/null +++ b/arch/csky/abiv2/inc/abi/vdso.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef __ABI_CSKY_VDSO_H +#define __ABI_CSKY_VDSO_H + +#include + +static inline int setup_vdso_page(unsigned short *ptr) +{ + int err = 0; + + /* movi r7, 173 */ + err |= __put_user(0xea07, ptr); + err |= __put_user(0x008b, ptr+1); + + /* trap 0 */ + err |= __put_user(0xc000, ptr+2); + err |= __put_user(0x2020, ptr+3); + + return err; +} + +#endif /* __ABI_CSKY_STRING_H */ diff --git a/arch/csky/include/asm/vdso.h b/arch/csky/include/asm/vdso.h new file mode 100644 index 000..d963d69 --- /dev/null +++ b/arch/csky/include/asm/vdso.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef __ASM_CSKY_VDSO_H +#define __ASM_CSKY_VDSO_H + +#include + +struct csky_vdso { + unsigned short rt_signal_retcode[4]; +}; + +#endif /* __ASM_CSKY_VDSO_H */ diff --git a/arch/csky/kernel/vdso.c b/arch/csky/kernel/vdso.c new file mode 100644 index 000..60ff7ad --- /dev/null +++ b/arch/csky/kernel/vdso.c @@ -0,0 +1,86 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +static struct page *vdso_page; + +static int __init init_vdso(void) +{ + struct csky_vdso *vdso; + int err = 0; + + vdso_page = alloc_page(GFP_KERNEL); + if (!vdso_page) + panic("Cannot allocate vdso"); + + vdso = vmap(_page, 1, 0, PAGE_KERNEL); + if (!vdso) + panic("Cannot map vdso"); + + clear_page(vdso); + + err = setup_vdso_page(vdso->rt_signal_retcode); + if (err) + panic("Cannot set signal return code, err: %x.", err); + + dcache_wb_range((unsigned long)vdso, (unsigned long)vdso + 16); + + vunmap(vdso); + + return 0; +} +subsys_initcall(init_vdso); + +int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) +{ + int ret; + unsigned long addr; + struct mm_struct *mm = current->mm; + + down_write(>mmap_sem); + + addr = get_unmapped_area(NULL, STACK_TOP, PAGE_SIZE, 0, 0); + if (IS_ERR_VALUE(addr)) { + ret = addr; + goto up_fail; + } + + ret = install_special_mapping( + mm, + addr, + PAGE_SIZE, + VM_READ|VM_EXEC|VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC, + _page); + if (ret) + goto up_fail; + + mm->context.vdso = (void *)addr; + +up_fail: + up_write(>mmap_sem); + return ret; +} + +const char *arch_vma_name(struct vm_area_struct *vma) +{ + if (vma->vm_mm == NULL) + return NULL; + + if (vma->vm_start == (long)vma->vm_mm->context.vdso) + return "[vdso]"; + else + return NULL; +} -- 2.7.4
[PATCH V7 09/20] csky: VDSO and rt_sigreturn
This patch adds files related to VDSO and our VDSO only support rt_sigreturn. Signed-off-by: Guo Ren --- arch/csky/abiv1/inc/abi/vdso.h | 17 + arch/csky/abiv2/inc/abi/vdso.h | 23 +++ arch/csky/include/asm/vdso.h | 12 ++ arch/csky/kernel/vdso.c| 86 ++ 4 files changed, 138 insertions(+) create mode 100644 arch/csky/abiv1/inc/abi/vdso.h create mode 100644 arch/csky/abiv2/inc/abi/vdso.h create mode 100644 arch/csky/include/asm/vdso.h create mode 100644 arch/csky/kernel/vdso.c diff --git a/arch/csky/abiv1/inc/abi/vdso.h b/arch/csky/abiv1/inc/abi/vdso.h new file mode 100644 index 000..14352f5 --- /dev/null +++ b/arch/csky/abiv1/inc/abi/vdso.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#include + +static inline int setup_vdso_page(unsigned short *ptr) +{ + int err = 0; + + /* movi r1, 127 */ + err |= __put_user(0x67f1, ptr + 0); + /* addi r1, (139 - 127) */ + err |= __put_user(0x20b1, ptr + 1); + /* trap 0 */ + err |= __put_user(0x0008, ptr + 2); + + return err; +} diff --git a/arch/csky/abiv2/inc/abi/vdso.h b/arch/csky/abiv2/inc/abi/vdso.h new file mode 100644 index 000..b60d4a0 --- /dev/null +++ b/arch/csky/abiv2/inc/abi/vdso.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef __ABI_CSKY_VDSO_H +#define __ABI_CSKY_VDSO_H + +#include + +static inline int setup_vdso_page(unsigned short *ptr) +{ + int err = 0; + + /* movi r7, 173 */ + err |= __put_user(0xea07, ptr); + err |= __put_user(0x008b, ptr+1); + + /* trap 0 */ + err |= __put_user(0xc000, ptr+2); + err |= __put_user(0x2020, ptr+3); + + return err; +} + +#endif /* __ABI_CSKY_STRING_H */ diff --git a/arch/csky/include/asm/vdso.h b/arch/csky/include/asm/vdso.h new file mode 100644 index 000..d963d69 --- /dev/null +++ b/arch/csky/include/asm/vdso.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef __ASM_CSKY_VDSO_H +#define __ASM_CSKY_VDSO_H + +#include + +struct csky_vdso { + unsigned short rt_signal_retcode[4]; +}; + +#endif /* __ASM_CSKY_VDSO_H */ diff --git a/arch/csky/kernel/vdso.c b/arch/csky/kernel/vdso.c new file mode 100644 index 000..60ff7ad --- /dev/null +++ b/arch/csky/kernel/vdso.c @@ -0,0 +1,86 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +static struct page *vdso_page; + +static int __init init_vdso(void) +{ + struct csky_vdso *vdso; + int err = 0; + + vdso_page = alloc_page(GFP_KERNEL); + if (!vdso_page) + panic("Cannot allocate vdso"); + + vdso = vmap(_page, 1, 0, PAGE_KERNEL); + if (!vdso) + panic("Cannot map vdso"); + + clear_page(vdso); + + err = setup_vdso_page(vdso->rt_signal_retcode); + if (err) + panic("Cannot set signal return code, err: %x.", err); + + dcache_wb_range((unsigned long)vdso, (unsigned long)vdso + 16); + + vunmap(vdso); + + return 0; +} +subsys_initcall(init_vdso); + +int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) +{ + int ret; + unsigned long addr; + struct mm_struct *mm = current->mm; + + down_write(>mmap_sem); + + addr = get_unmapped_area(NULL, STACK_TOP, PAGE_SIZE, 0, 0); + if (IS_ERR_VALUE(addr)) { + ret = addr; + goto up_fail; + } + + ret = install_special_mapping( + mm, + addr, + PAGE_SIZE, + VM_READ|VM_EXEC|VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC, + _page); + if (ret) + goto up_fail; + + mm->context.vdso = (void *)addr; + +up_fail: + up_write(>mmap_sem); + return ret; +} + +const char *arch_vma_name(struct vm_area_struct *vma) +{ + if (vma->vm_mm == NULL) + return NULL; + + if (vma->vm_start == (long)vma->vm_mm->context.vdso) + return "[vdso]"; + else + return NULL; +} -- 2.7.4
[PATCH V7 11/20] csky: Atomic operations
This patch adds atomic, cmpxchg, spinlock files. Changlog: - SMP supported - ticklock supported - queue-rwlock supported Signed-off-by: Guo Ren --- arch/csky/include/asm/atomic.h | 212 + arch/csky/include/asm/cmpxchg.h| 73 + arch/csky/include/asm/spinlock.h | 274 + arch/csky/include/asm/spinlock_types.h | 37 + arch/csky/kernel/atomic.S | 87 +++ 5 files changed, 683 insertions(+) create mode 100644 arch/csky/include/asm/atomic.h create mode 100644 arch/csky/include/asm/cmpxchg.h create mode 100644 arch/csky/include/asm/spinlock.h create mode 100644 arch/csky/include/asm/spinlock_types.h create mode 100644 arch/csky/kernel/atomic.S diff --git a/arch/csky/include/asm/atomic.h b/arch/csky/include/asm/atomic.h new file mode 100644 index 000..e369d73 --- /dev/null +++ b/arch/csky/include/asm/atomic.h @@ -0,0 +1,212 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef __ASM_CSKY_ATOMIC_H +#define __ASM_CSKY_ATOMIC_H + +#include +#include +#include + +#ifdef CONFIG_CPU_HAS_LDSTEX + +#define __atomic_add_unless __atomic_add_unless +static inline int __atomic_add_unless(atomic_t *v, int a, int u) +{ + unsigned long tmp, ret; + + smp_mb(); + + asm volatile ( + "1: ldex.w %0, (%3) \n" + " mov %1, %0 \n" + " cmpne %0, %4 \n" + " bf 2f \n" + " add %0, %2 \n" + " stex.w %0, (%3) \n" + " bez %0, 1b \n" + "2: \n" + : "=" (tmp), "=" (ret) + : "r" (a), "r"(>counter), "r"(u) + : "memory"); + + if (ret != u) + smp_mb(); + + return ret; +} + +#define ATOMIC_OP(op, c_op)\ +static inline void atomic_##op(int i, atomic_t *v) \ +{ \ + unsigned long tmp; \ + \ + asm volatile ( \ + "1: ldex.w %0, (%2) \n"\ + " " #op " %0, %1 \n"\ + " stex.w %0, (%2) \n"\ + " bez %0, 1b \n"\ + : "=" (tmp) \ + : "r" (i), "r"(>counter) \ + : "memory");\ +} + +#define ATOMIC_OP_RETURN(op, c_op) \ +static inline int atomic_##op##_return(int i, atomic_t *v) \ +{ \ + unsigned long tmp, ret; \ + \ + smp_mb(); \ + asm volatile ( \ + "1: ldex.w %0, (%3) \n"\ + " " #op " %0, %2 \n"\ + " mov %1, %0 \n"\ + " stex.w %0, (%3) \n"\ + " bez %0, 1b \n"\ + : "=" (tmp), "=" (ret) \ + : "r" (i), "r"(>counter) \ + : "memory");\ + smp_mb(); \ + \ + return ret; \ +} + +#define ATOMIC_FETCH_OP(op, c_op) \ +static inline int atomic_fetch_##op(int i, atomic_t *v) \ +{ \ + unsigned long tmp, ret; \ + \ + smp_mb(); \ + asm volatile ( \ + "1: ldex.w %0, (%3) \n"\ + " mov %1, %0 \n"\ + " " #op " %0, %2 \n"\ + " stex.w %0, (%3) \n"\ +
[PATCH] writeback: fix range_cyclic writeback vs writepages deadlock
From: Dave Chinner We've recently seen a workload on XFS filesystems with a repeatable deadlock between background writeback and a multi-process application doing concurrent writes and fsyncs to a small range of a file. range_cyclic writeback Process 1 Process 2 xfs_vm_writepages write_cache_pages writeback_index = 2 cycled = 0 find page 2 dirty lock Page 2 ->writepage page 2 writeback page 2 clean page 2 added to bio no more pages write() locks page 1 dirties page 1 locks page 2 dirties page 1 fsync() xfs_vm_writepages write_cache_pages start index 0 find page 1 towrite lock Page 1 ->writepage page 1 writeback page 1 clean page 1 added to bio find page 2 towrite lock Page 2 page 2 is writeback write() locks page 1 dirties page 1 fsync() xfs_vm_writepages write_cache_pages start index 0 !done && !cycled sets index to 0, restarts lookup find page 1 dirty find page 1 towrite lock Page 1 page 1 is writeback lock Page 1 DEADLOCK because: - process 1 needs page 2 writeback to complete to make enough progress to issue IO pending for page 1 - writeback needs page 1 writeback to complete so process 2 can progress and unlock the page it is blocked on, then it can issue the IO pending for page 2 - process 2 can't make progress until process 1 issues IO for page 1 The underlying cause of the problem here is that range_cyclic writeback is processing pages in descending index order as we hold higher index pages in a structure controlled from above write_cache_pages(). The write_cache_pages() caller needs to be able to submit these pages for IO before write_cache_pages restarts writeback at mapping index 0 to avoid wcp inverting the page lock/writeback wait order. generic_writepages() is not susceptible to this bug as it has no private context held across write_cache_pages() - filesystems using this infrastructure always submit pages in ->writepage immediately and so there is no problem with range_cyclic going back to mapping index 0. However: mpage_writepages() has a private bio context, exofs_writepages() has page_collect fuse_writepages() has fuse_fill_wb_data nfs_writepages() has nfs_pageio_descriptor xfs_vm_writepages() has xfs_writepage_ctx All of these ->writepages implementations can hold pages under writeback in their private structures until write_cache_pages() returns, and hence they are all susceptible to this deadlock. Also worth noting is that ext4 has it's own bastardised version of write_cache_pages() and so it /may/ have an equivalent deadlock. I looked at the code long enough to understand that it has a similar retry loop for range_cyclic writeback reaching the end of the file and then promptly ran away before my eyes bled too much. I'll leave it for the ext4 developers to determine if their code is actually has this deadlock and how to fix it if it has. There's a few ways I can see avoid this deadlock. There's probably more, but these are the first I've though of: 1. get rid of range_cyclic altogether 2. range_cyclic always stops at EOF, and we start again from writeback index 0 on the next call into write_cache_pages() 2a. wcp also returns EAGAIN to ->writepages implementations to indicate range cyclic has hit EOF. writepages implementations can then flush the current context and call wpc again to continue. i.e. lift the retry into the ->writepages implementation 3. range_cyclic uses trylock_page() rather than lock_page(), and it skips pages it can't lock without blocking. It will already do this for pages under writeback, so this seems like a no-brainer 3a. all non-WB_SYNC_ALL writeback uses trylock_page() to avoid blocking as per pages under writeback. I don't think #1 is an option -
[PATCH V7 11/20] csky: Atomic operations
This patch adds atomic, cmpxchg, spinlock files. Changlog: - SMP supported - ticklock supported - queue-rwlock supported Signed-off-by: Guo Ren --- arch/csky/include/asm/atomic.h | 212 + arch/csky/include/asm/cmpxchg.h| 73 + arch/csky/include/asm/spinlock.h | 274 + arch/csky/include/asm/spinlock_types.h | 37 + arch/csky/kernel/atomic.S | 87 +++ 5 files changed, 683 insertions(+) create mode 100644 arch/csky/include/asm/atomic.h create mode 100644 arch/csky/include/asm/cmpxchg.h create mode 100644 arch/csky/include/asm/spinlock.h create mode 100644 arch/csky/include/asm/spinlock_types.h create mode 100644 arch/csky/kernel/atomic.S diff --git a/arch/csky/include/asm/atomic.h b/arch/csky/include/asm/atomic.h new file mode 100644 index 000..e369d73 --- /dev/null +++ b/arch/csky/include/asm/atomic.h @@ -0,0 +1,212 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef __ASM_CSKY_ATOMIC_H +#define __ASM_CSKY_ATOMIC_H + +#include +#include +#include + +#ifdef CONFIG_CPU_HAS_LDSTEX + +#define __atomic_add_unless __atomic_add_unless +static inline int __atomic_add_unless(atomic_t *v, int a, int u) +{ + unsigned long tmp, ret; + + smp_mb(); + + asm volatile ( + "1: ldex.w %0, (%3) \n" + " mov %1, %0 \n" + " cmpne %0, %4 \n" + " bf 2f \n" + " add %0, %2 \n" + " stex.w %0, (%3) \n" + " bez %0, 1b \n" + "2: \n" + : "=" (tmp), "=" (ret) + : "r" (a), "r"(>counter), "r"(u) + : "memory"); + + if (ret != u) + smp_mb(); + + return ret; +} + +#define ATOMIC_OP(op, c_op)\ +static inline void atomic_##op(int i, atomic_t *v) \ +{ \ + unsigned long tmp; \ + \ + asm volatile ( \ + "1: ldex.w %0, (%2) \n"\ + " " #op " %0, %1 \n"\ + " stex.w %0, (%2) \n"\ + " bez %0, 1b \n"\ + : "=" (tmp) \ + : "r" (i), "r"(>counter) \ + : "memory");\ +} + +#define ATOMIC_OP_RETURN(op, c_op) \ +static inline int atomic_##op##_return(int i, atomic_t *v) \ +{ \ + unsigned long tmp, ret; \ + \ + smp_mb(); \ + asm volatile ( \ + "1: ldex.w %0, (%3) \n"\ + " " #op " %0, %2 \n"\ + " mov %1, %0 \n"\ + " stex.w %0, (%3) \n"\ + " bez %0, 1b \n"\ + : "=" (tmp), "=" (ret) \ + : "r" (i), "r"(>counter) \ + : "memory");\ + smp_mb(); \ + \ + return ret; \ +} + +#define ATOMIC_FETCH_OP(op, c_op) \ +static inline int atomic_fetch_##op(int i, atomic_t *v) \ +{ \ + unsigned long tmp, ret; \ + \ + smp_mb(); \ + asm volatile ( \ + "1: ldex.w %0, (%3) \n"\ + " mov %1, %0 \n"\ + " " #op " %0, %2 \n"\ + " stex.w %0, (%3) \n"\ +
[PATCH] writeback: fix range_cyclic writeback vs writepages deadlock
From: Dave Chinner We've recently seen a workload on XFS filesystems with a repeatable deadlock between background writeback and a multi-process application doing concurrent writes and fsyncs to a small range of a file. range_cyclic writeback Process 1 Process 2 xfs_vm_writepages write_cache_pages writeback_index = 2 cycled = 0 find page 2 dirty lock Page 2 ->writepage page 2 writeback page 2 clean page 2 added to bio no more pages write() locks page 1 dirties page 1 locks page 2 dirties page 1 fsync() xfs_vm_writepages write_cache_pages start index 0 find page 1 towrite lock Page 1 ->writepage page 1 writeback page 1 clean page 1 added to bio find page 2 towrite lock Page 2 page 2 is writeback write() locks page 1 dirties page 1 fsync() xfs_vm_writepages write_cache_pages start index 0 !done && !cycled sets index to 0, restarts lookup find page 1 dirty find page 1 towrite lock Page 1 page 1 is writeback lock Page 1 DEADLOCK because: - process 1 needs page 2 writeback to complete to make enough progress to issue IO pending for page 1 - writeback needs page 1 writeback to complete so process 2 can progress and unlock the page it is blocked on, then it can issue the IO pending for page 2 - process 2 can't make progress until process 1 issues IO for page 1 The underlying cause of the problem here is that range_cyclic writeback is processing pages in descending index order as we hold higher index pages in a structure controlled from above write_cache_pages(). The write_cache_pages() caller needs to be able to submit these pages for IO before write_cache_pages restarts writeback at mapping index 0 to avoid wcp inverting the page lock/writeback wait order. generic_writepages() is not susceptible to this bug as it has no private context held across write_cache_pages() - filesystems using this infrastructure always submit pages in ->writepage immediately and so there is no problem with range_cyclic going back to mapping index 0. However: mpage_writepages() has a private bio context, exofs_writepages() has page_collect fuse_writepages() has fuse_fill_wb_data nfs_writepages() has nfs_pageio_descriptor xfs_vm_writepages() has xfs_writepage_ctx All of these ->writepages implementations can hold pages under writeback in their private structures until write_cache_pages() returns, and hence they are all susceptible to this deadlock. Also worth noting is that ext4 has it's own bastardised version of write_cache_pages() and so it /may/ have an equivalent deadlock. I looked at the code long enough to understand that it has a similar retry loop for range_cyclic writeback reaching the end of the file and then promptly ran away before my eyes bled too much. I'll leave it for the ext4 developers to determine if their code is actually has this deadlock and how to fix it if it has. There's a few ways I can see avoid this deadlock. There's probably more, but these are the first I've though of: 1. get rid of range_cyclic altogether 2. range_cyclic always stops at EOF, and we start again from writeback index 0 on the next call into write_cache_pages() 2a. wcp also returns EAGAIN to ->writepages implementations to indicate range cyclic has hit EOF. writepages implementations can then flush the current context and call wpc again to continue. i.e. lift the retry into the ->writepages implementation 3. range_cyclic uses trylock_page() rather than lock_page(), and it skips pages it can't lock without blocking. It will already do this for pages under writeback, so this seems like a no-brainer 3a. all non-WB_SYNC_ALL writeback uses trylock_page() to avoid blocking as per pages under writeback. I don't think #1 is an option -
[PATCH V7 04/20] csky: Exception handling and mm-fault
This patch adds exception handling code, cpuinfo and mm-fault code. Signed-off-by: Guo Ren --- arch/csky/abiv1/alignment.c | 323 arch/csky/abiv1/inc/abi/entry.h | 160 arch/csky/abiv2/inc/abi/entry.h | 156 arch/csky/include/asm/traps.h | 44 + arch/csky/include/asm/unistd.h | 4 + arch/csky/kernel/cpu-probe.c| 79 arch/csky/kernel/entry.S| 396 arch/csky/kernel/traps.c| 172 + arch/csky/mm/fault.c| 220 ++ 9 files changed, 1554 insertions(+) create mode 100644 arch/csky/abiv1/alignment.c create mode 100644 arch/csky/abiv1/inc/abi/entry.h create mode 100644 arch/csky/abiv2/inc/abi/entry.h create mode 100644 arch/csky/include/asm/traps.h create mode 100644 arch/csky/include/asm/unistd.h create mode 100644 arch/csky/kernel/cpu-probe.c create mode 100644 arch/csky/kernel/entry.S create mode 100644 arch/csky/kernel/traps.c create mode 100644 arch/csky/mm/fault.c diff --git a/arch/csky/abiv1/alignment.c b/arch/csky/abiv1/alignment.c new file mode 100644 index 000..8ec7400 --- /dev/null +++ b/arch/csky/abiv1/alignment.c @@ -0,0 +1,323 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. + +#include +#include +#include + +static int align_enable = 1; +static int align_count; + +static inline uint32_t get_ptreg(struct pt_regs *regs, uint32_t rx) +{ + return *((int *)&(regs->a0) - 2 + rx); +} + +static inline void put_ptreg(struct pt_regs *regs, uint32_t rx, uint32_t val) +{ + *((int *)&(regs->a0) - 2 + rx) = val; +} + +/* + * Get byte-value from addr and set it to *valp. + * + * Success: return 0 + * Failure: return 1 + */ +static int ldb_asm(uint32_t addr, uint32_t *valp) +{ + uint32_t val; + int err; + + if (!access_ok(VERIFY_READ, (void *)addr, 1)) + return 1; + + asm volatile ( + "movi %0, 0\n" + "1:\n" + "ldb%1, (%2)\n" + "br 3f\n" + "2:\n" + "movi %0, 1\n" + "br 3f\n" + ".section __ex_table,\"a\"\n" + ".align 2\n" + ".long 1b, 2b\n" + ".previous\n" + "3:\n" + : "="(err), "=r"(val) + : "r" (addr) + ); + + *valp = val; + + return err; +} + +/* + * Put byte-value to addr. + * + * Success: return 0 + * Failure: return 1 + */ +static int stb_asm(uint32_t addr, uint32_t val) +{ + int err; + + if (!access_ok(VERIFY_WRITE, (void *)addr, 1)) + return 1; + + asm volatile ( + "movi %0, 0\n" + "1:\n" + "stb%1, (%2)\n" + "br 3f\n" + "2:\n" + "movi %0, 1\n" + "br 3f\n" + ".section __ex_table,\"a\"\n" + ".align 2\n" + ".long 1b, 2b\n" + ".previous\n" + "3:\n" + : "="(err) + : "r"(val), "r" (addr) + ); + + return err; +} + +/* + * Get half-word from [rx + imm] + * + * Success: return 0 + * Failure: return 1 + */ +static int ldh_c(struct pt_regs *regs, uint32_t rz, uint32_t addr) +{ + uint32_t byte0, byte1; + + if (ldb_asm(addr, )) + return 1; + addr += 1; + if (ldb_asm(addr, )) + return 1; + + byte0 |= byte1 << 8; + put_ptreg(regs, rz, byte0); + + return 0; +} + +/* + * Store half-word to [rx + imm] + * + * Success: return 0 + * Failure: return 1 + */ +static int sth_c(struct pt_regs *regs, uint32_t rz, uint32_t addr) +{ + uint32_t byte0, byte1; + + byte0 = byte1 = get_ptreg(regs, rz); + + byte0 &= 0xff; + + if (stb_asm(addr, byte0)) + return 1; + + addr += 1; + byte1 = (byte1 >> 8) & 0xff; + if (stb_asm(addr, byte1)) + return 1; + + return 0; +} + +/* + * Get word from [rx + imm] + * + * Success: return 0 + * Failure: return 1 + */ +static int ldw_c(struct pt_regs *regs, uint32_t rz, uint32_t addr) +{ + uint32_t byte0, byte1, byte2, byte3; + + if (ldb_asm(addr, )) + return 1; + + addr += 1; + if (ldb_asm(addr, )) + return 1; + + addr += 1; + if (ldb_asm(addr, )) + return 1; + + addr += 1; + if (ldb_asm(addr, )) + return 1; + + byte0 |= byte1 << 8; + byte0 |= byte2 << 16; + byte0 |= byte3 << 24; + + put_ptreg(regs, rz, byte0); + + return 0; +} + +/* + * Store word to [rx + imm] + * + * Success: return 0 + * Failure: return 1 + */ +static int stw_c(struct pt_regs *regs, uint32_t rz, uint32_t addr) +{ + uint32_t byte0, byte1, byte2, byte3; + +
[PATCH V7 04/20] csky: Exception handling and mm-fault
This patch adds exception handling code, cpuinfo and mm-fault code. Signed-off-by: Guo Ren --- arch/csky/abiv1/alignment.c | 323 arch/csky/abiv1/inc/abi/entry.h | 160 arch/csky/abiv2/inc/abi/entry.h | 156 arch/csky/include/asm/traps.h | 44 + arch/csky/include/asm/unistd.h | 4 + arch/csky/kernel/cpu-probe.c| 79 arch/csky/kernel/entry.S| 396 arch/csky/kernel/traps.c| 172 + arch/csky/mm/fault.c| 220 ++ 9 files changed, 1554 insertions(+) create mode 100644 arch/csky/abiv1/alignment.c create mode 100644 arch/csky/abiv1/inc/abi/entry.h create mode 100644 arch/csky/abiv2/inc/abi/entry.h create mode 100644 arch/csky/include/asm/traps.h create mode 100644 arch/csky/include/asm/unistd.h create mode 100644 arch/csky/kernel/cpu-probe.c create mode 100644 arch/csky/kernel/entry.S create mode 100644 arch/csky/kernel/traps.c create mode 100644 arch/csky/mm/fault.c diff --git a/arch/csky/abiv1/alignment.c b/arch/csky/abiv1/alignment.c new file mode 100644 index 000..8ec7400 --- /dev/null +++ b/arch/csky/abiv1/alignment.c @@ -0,0 +1,323 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. + +#include +#include +#include + +static int align_enable = 1; +static int align_count; + +static inline uint32_t get_ptreg(struct pt_regs *regs, uint32_t rx) +{ + return *((int *)&(regs->a0) - 2 + rx); +} + +static inline void put_ptreg(struct pt_regs *regs, uint32_t rx, uint32_t val) +{ + *((int *)&(regs->a0) - 2 + rx) = val; +} + +/* + * Get byte-value from addr and set it to *valp. + * + * Success: return 0 + * Failure: return 1 + */ +static int ldb_asm(uint32_t addr, uint32_t *valp) +{ + uint32_t val; + int err; + + if (!access_ok(VERIFY_READ, (void *)addr, 1)) + return 1; + + asm volatile ( + "movi %0, 0\n" + "1:\n" + "ldb%1, (%2)\n" + "br 3f\n" + "2:\n" + "movi %0, 1\n" + "br 3f\n" + ".section __ex_table,\"a\"\n" + ".align 2\n" + ".long 1b, 2b\n" + ".previous\n" + "3:\n" + : "="(err), "=r"(val) + : "r" (addr) + ); + + *valp = val; + + return err; +} + +/* + * Put byte-value to addr. + * + * Success: return 0 + * Failure: return 1 + */ +static int stb_asm(uint32_t addr, uint32_t val) +{ + int err; + + if (!access_ok(VERIFY_WRITE, (void *)addr, 1)) + return 1; + + asm volatile ( + "movi %0, 0\n" + "1:\n" + "stb%1, (%2)\n" + "br 3f\n" + "2:\n" + "movi %0, 1\n" + "br 3f\n" + ".section __ex_table,\"a\"\n" + ".align 2\n" + ".long 1b, 2b\n" + ".previous\n" + "3:\n" + : "="(err) + : "r"(val), "r" (addr) + ); + + return err; +} + +/* + * Get half-word from [rx + imm] + * + * Success: return 0 + * Failure: return 1 + */ +static int ldh_c(struct pt_regs *regs, uint32_t rz, uint32_t addr) +{ + uint32_t byte0, byte1; + + if (ldb_asm(addr, )) + return 1; + addr += 1; + if (ldb_asm(addr, )) + return 1; + + byte0 |= byte1 << 8; + put_ptreg(regs, rz, byte0); + + return 0; +} + +/* + * Store half-word to [rx + imm] + * + * Success: return 0 + * Failure: return 1 + */ +static int sth_c(struct pt_regs *regs, uint32_t rz, uint32_t addr) +{ + uint32_t byte0, byte1; + + byte0 = byte1 = get_ptreg(regs, rz); + + byte0 &= 0xff; + + if (stb_asm(addr, byte0)) + return 1; + + addr += 1; + byte1 = (byte1 >> 8) & 0xff; + if (stb_asm(addr, byte1)) + return 1; + + return 0; +} + +/* + * Get word from [rx + imm] + * + * Success: return 0 + * Failure: return 1 + */ +static int ldw_c(struct pt_regs *regs, uint32_t rz, uint32_t addr) +{ + uint32_t byte0, byte1, byte2, byte3; + + if (ldb_asm(addr, )) + return 1; + + addr += 1; + if (ldb_asm(addr, )) + return 1; + + addr += 1; + if (ldb_asm(addr, )) + return 1; + + addr += 1; + if (ldb_asm(addr, )) + return 1; + + byte0 |= byte1 << 8; + byte0 |= byte2 << 16; + byte0 |= byte3 << 24; + + put_ptreg(regs, rz, byte0); + + return 0; +} + +/* + * Store word to [rx + imm] + * + * Success: return 0 + * Failure: return 1 + */ +static int stw_c(struct pt_regs *regs, uint32_t rz, uint32_t addr) +{ + uint32_t byte0, byte1, byte2, byte3; + +
[PATCH V7 07/20] csky: MMU and page table management
This patch adds files related to memory management and here is our memory-layout: Fixmap : 0xffc02000 – 0xf000 (4 MB - 12KB) Pkmap: 0xff80 – 0xffc0 (4 MB) Vmalloc : 0xf020 – 0xff00 (238 MB) Lowmem : 0x8000 – 0xc000 (1GB) abiv1 CPU (CK610) is VIPT cache and it doesn't support highmem. abiv2 CPUs are all PIPT cache and they could support highmem. Lowmem is directly mapped by msa0 & msa1 reg, and we needn't setup memory page table for it. Changelog: - dma-mapping: fix up dma_mapping error The arch_sync_dma_for_cpu()/arch_sync_dma_for_device() implementation is broken for some combinations that end up in a BUG() instead of performing the necessary flushes. - Fixup arch_sync_dma() broken when size is larger than PAGE_SIZE. Ignore the DMA_ATTR_NON_CONSISTENT, remove the BUG() and use return NULL instead. The implementation of arch should follow the following rules: map for_cpu for_device unmap TO_DEV writeback nonewriteback none TO_CPU invalidate invalidate* invalidate invalidate* BIDIR writeback invalidate writeback invalidate Link:https://lore.kernel.org/lkml/20180518215548.gh17...@n2100.armlinux.org.uk/ Signed-off-by: Guo Ren --- arch/csky/abiv1/inc/abi/ckmmu.h| 75 arch/csky/abiv1/inc/abi/page.h | 27 +++ arch/csky/abiv1/inc/abi/pgtable-bits.h | 37 arch/csky/abiv1/mmap.c | 66 +++ arch/csky/abiv2/inc/abi/ckmmu.h| 87 ++ arch/csky/abiv2/inc/abi/page.h | 14 ++ arch/csky/abiv2/inc/abi/pgtable-bits.h | 37 arch/csky/include/asm/addrspace.h | 10 ++ arch/csky/include/asm/fixmap.h | 27 +++ arch/csky/include/asm/highmem.h| 51 ++ arch/csky/include/asm/mmu.h| 12 ++ arch/csky/include/asm/page.h | 105 +++ arch/csky/include/asm/pgalloc.h| 115 + arch/csky/include/asm/pgtable.h| 306 + arch/csky/include/asm/segment.h| 19 ++ arch/csky/include/asm/shmparam.h | 11 ++ arch/csky/mm/dma-mapping.c | 254 +++ arch/csky/mm/highmem.c | 196 + arch/csky/mm/init.c| 121 + arch/csky/mm/ioremap.c | 48 ++ 20 files changed, 1618 insertions(+) create mode 100644 arch/csky/abiv1/inc/abi/ckmmu.h create mode 100644 arch/csky/abiv1/inc/abi/page.h create mode 100644 arch/csky/abiv1/inc/abi/pgtable-bits.h create mode 100644 arch/csky/abiv1/mmap.c create mode 100644 arch/csky/abiv2/inc/abi/ckmmu.h create mode 100644 arch/csky/abiv2/inc/abi/page.h create mode 100644 arch/csky/abiv2/inc/abi/pgtable-bits.h create mode 100644 arch/csky/include/asm/addrspace.h create mode 100644 arch/csky/include/asm/fixmap.h create mode 100644 arch/csky/include/asm/highmem.h create mode 100644 arch/csky/include/asm/mmu.h create mode 100644 arch/csky/include/asm/page.h create mode 100644 arch/csky/include/asm/pgalloc.h create mode 100644 arch/csky/include/asm/pgtable.h create mode 100644 arch/csky/include/asm/segment.h create mode 100644 arch/csky/include/asm/shmparam.h create mode 100644 arch/csky/mm/dma-mapping.c create mode 100644 arch/csky/mm/highmem.c create mode 100644 arch/csky/mm/init.c create mode 100644 arch/csky/mm/ioremap.c diff --git a/arch/csky/abiv1/inc/abi/ckmmu.h b/arch/csky/abiv1/inc/abi/ckmmu.h new file mode 100644 index 000..3a00201 --- /dev/null +++ b/arch/csky/abiv1/inc/abi/ckmmu.h @@ -0,0 +1,75 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. + +#ifndef __ASM_CSKY_CKMMUV1_H +#define __ASM_CSKY_CKMMUV1_H +#include + +static inline int read_mmu_index(void) +{ + return cprcr("cpcr0"); +} + +static inline void write_mmu_index(int value) +{ + cpwcr("cpcr0", value); +} + +static inline int read_mmu_entrylo0(void) +{ + return cprcr("cpcr2") << 6; +} + +static inline int read_mmu_entrylo1(void) +{ + return cprcr("cpcr3") << 6; +} + +static inline void write_mmu_pagemask(int value) +{ + cpwcr("cpcr6", value); +} + +static inline int read_mmu_entryhi(void) +{ + return cprcr("cpcr4"); +} + +static inline void write_mmu_entryhi(int value) +{ + cpwcr("cpcr4", value); +} + +/* + * TLB operations. + */ +static inline void tlb_probe(void) +{ + cpwcr("cpcr8", 0x8000); +} + +static inline void tlb_read(void) +{ + cpwcr("cpcr8", 0x4000); +} + +static inline void tlb_invalid_all(void) +{ + cpwcr("cpcr8", 0x0400); +} + +static inline void tlb_invalid_indexed(void) +{ + cpwcr("cpcr8", 0x0200); +} + +static inline void setup_pgd(unsigned long pgd, bool kernel) +{ + cpwcr("cpcr29", pgd); +} + +static inline unsigned long get_pgd(void)
[PATCH V7 08/20] csky: Process management and Signal
This patch adds files related to task_switch, sigcontext, signal. Changelog: - abiv2/fpu.c: Userspace should never be sent NSIGXXX as a si_code. Use FPE_FLTUNK instead. - abiv2/fpu.c: Use force_sig_fault instead. Signed-off-by: Guo Ren --- arch/csky/abiv2/fpu.c | 275 + arch/csky/abiv2/inc/abi/fpu.h | 66 ++ arch/csky/include/asm/mmu_context.h | 150 ++ arch/csky/include/asm/processor.h | 121 +++ arch/csky/include/asm/switch_to.h | 36 arch/csky/include/asm/thread_info.h | 75 +++ arch/csky/include/uapi/asm/sigcontext.h | 14 ++ arch/csky/kernel/process.c | 136 arch/csky/kernel/signal.c | 355 arch/csky/kernel/time.c | 11 + 10 files changed, 1239 insertions(+) create mode 100644 arch/csky/abiv2/fpu.c create mode 100644 arch/csky/abiv2/inc/abi/fpu.h create mode 100644 arch/csky/include/asm/mmu_context.h create mode 100644 arch/csky/include/asm/processor.h create mode 100644 arch/csky/include/asm/switch_to.h create mode 100644 arch/csky/include/asm/thread_info.h create mode 100644 arch/csky/include/uapi/asm/sigcontext.h create mode 100644 arch/csky/kernel/process.c create mode 100644 arch/csky/kernel/signal.c create mode 100644 arch/csky/kernel/time.c diff --git a/arch/csky/abiv2/fpu.c b/arch/csky/abiv2/fpu.c new file mode 100644 index 000..e7e1134 --- /dev/null +++ b/arch/csky/abiv2/fpu.c @@ -0,0 +1,275 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. + +#include +#include +#include + +#define MTCR_MASK 0xFC00FFE0 +#define MFCR_MASK 0xFC00FFE0 +#define MTCR_DIST 0xC0006420 +#define MFCR_DIST 0xC0006020 + +void __init init_fpu(void) +{ + mtcr("cr<1, 2>", 0); +} + +/* + * fpu_libc_helper() is to help libc to excute: + * - mfcr %a, cr<1, 2> + * - mfcr %a, cr<2, 2> + * - mtcr %a, cr<1, 2> + * - mtcr %a, cr<2, 2> + */ +int fpu_libc_helper(struct pt_regs *regs) +{ + int fault; + unsigned long instrptr, regx = 0; + unsigned long index = 0, tmp = 0; + unsigned long tinstr = 0; + u16 instr_hi, instr_low; + + instrptr = instruction_pointer(regs); + if (instrptr & 1) + return 0; + + fault = __get_user(instr_low, (u16 *)instrptr); + if (fault) + return 0; + + fault = __get_user(instr_hi, (u16 *)(instrptr + 2)); + if (fault) + return 0; + + tinstr = instr_hi | ((unsigned long)instr_low << 16); + + if (((tinstr >> 21) & 0x1F) != 2) + return 0; + + if ((tinstr & MTCR_MASK) == MTCR_DIST) { + index = (tinstr >> 16) & 0x1F; + if (index > 13) + return 0; + + tmp = tinstr & 0x1F; + if (tmp > 2) + return 0; + + regx = *(>a0 + index); + + if (tmp == 1) + mtcr("cr<1, 2>", regx); + else if (tmp == 2) + mtcr("cr<2, 2>", regx); + else + return 0; + + regs->pc += 4; + return 1; + } + + if ((tinstr & MFCR_MASK) == MFCR_DIST) { + index = tinstr & 0x1F; + if (index > 13) + return 0; + + tmp = ((tinstr >> 16) & 0x1F); + if (tmp > 2) + return 0; + + if (tmp == 1) + regx = mfcr("cr<1, 2>"); + else if (tmp == 2) + regx = mfcr("cr<2, 2>"); + else + return 0; + + *(>a0 + index) = regx; + + regs->pc += 4; + return 1; + } + + return 0; +} + +void fpu_fpe(struct pt_regs *regs) +{ + int sig, code; + unsigned int fesr; + + fesr = mfcr("cr<2, 2>"); + + sig = SIGFPE; + code = FPE_FLTUNK; + + if (fesr & FPE_ILLE) { + sig = SIGILL; + code = ILL_ILLOPC; + } else if (fesr & FPE_IDC) { + sig = SIGILL; + code = ILL_ILLOPN; + } else if (fesr & FPE_FEC) { + sig = SIGFPE; + if (fesr & FPE_IOC) + code = FPE_FLTINV; + else if (fesr & FPE_DZC) + code = FPE_FLTDIV; + else if (fesr & FPE_UFC) + code = FPE_FLTUND; + else if (fesr & FPE_OFC) + code = FPE_FLTOVF; + else if (fesr & FPE_IXC) + code = FPE_FLTRES; + } + + force_sig_fault(sig, code, (void __user *)regs->pc, current); +} + +#define FMFVR_FPU_REGS(vrx, vry) \ + "fmfvrl %0, "#vrx"\n" \ + "fmfvrh %1, "#vrx"\n"
[PATCH V7 01/20] csky: Build infrastructure
This patch adds Makefile, Kconfig for build infrastructure. Changelog: - Add compat.h in asm/Kbuild. - Add select DMA_DIRECT_OPS in Kconfig. - remove kernel/platform.c in Makefile. Signed-off-by: Guo Ren --- arch/csky/Kconfig | 205 + arch/csky/Kconfig.debug| 13 +++ arch/csky/Makefile | 92 +++ arch/csky/abiv1/Makefile | 8 ++ arch/csky/abiv2/Makefile | 10 ++ arch/csky/boot/Makefile| 24 arch/csky/boot/dts/Makefile| 13 +++ arch/csky/boot/dts/include/dt-bindings | 1 + arch/csky/include/asm/Kbuild | 71 arch/csky/include/uapi/asm/Kbuild | 33 ++ arch/csky/kernel/Makefile | 8 ++ arch/csky/lib/Makefile | 1 + arch/csky/mm/Makefile | 13 +++ 13 files changed, 492 insertions(+) create mode 100644 arch/csky/Kconfig create mode 100644 arch/csky/Kconfig.debug create mode 100644 arch/csky/Makefile create mode 100644 arch/csky/abiv1/Makefile create mode 100644 arch/csky/abiv2/Makefile create mode 100644 arch/csky/boot/Makefile create mode 100644 arch/csky/boot/dts/Makefile create mode 12 arch/csky/boot/dts/include/dt-bindings create mode 100644 arch/csky/include/asm/Kbuild create mode 100644 arch/csky/include/uapi/asm/Kbuild create mode 100644 arch/csky/kernel/Makefile create mode 100644 arch/csky/lib/Makefile create mode 100644 arch/csky/mm/Makefile diff --git a/arch/csky/Kconfig b/arch/csky/Kconfig new file mode 100644 index 000..89b726a --- /dev/null +++ b/arch/csky/Kconfig @@ -0,0 +1,205 @@ +config CSKY + def_bool y + select ARCH_HAS_SYNC_DMA_FOR_CPU + select ARCH_HAS_SYNC_DMA_FOR_DEVICE + select ARCH_USE_BUILTIN_BSWAP + select ARCH_USE_QUEUED_RWLOCKS if NR_CPUS>2 + select COMMON_CLK + select CLKSRC_MMIO + select CLKSRC_OF + select DMA_DIRECT_OPS + select DMA_NONCOHERENT_OPS + select IRQ_DOMAIN + select HANDLE_DOMAIN_IRQ + select DW_APB_TIMER_OF + select GENERIC_LIB_ASHLDI3 + select GENERIC_LIB_ASHRDI3 + select GENERIC_LIB_LSHRDI3 + select GENERIC_LIB_MULDI3 + select GENERIC_LIB_CMPDI2 + select GENERIC_LIB_UCMPDI2 + select GENERIC_ALLOCATOR + select GENERIC_ATOMIC64 + select GENERIC_CLOCKEVENTS + select GENERIC_CPU_DEVICES + select GENERIC_IRQ_CHIP + select GENERIC_IRQ_PROBE + select GENERIC_IRQ_SHOW + select GENERIC_IRQ_MULTI_HANDLER + select GENERIC_SCHED_CLOCK + select GENERIC_SMP_IDLE_THREAD + select HAVE_ARCH_TRACEHOOK + select HAVE_GENERIC_DMA_COHERENT + select HAVE_KERNEL_GZIP + select HAVE_KERNEL_LZO + select HAVE_KERNEL_LZMA + select HAVE_C_RECORDMCOUNT + select HAVE_DMA_API_DEBUG + select HAVE_DMA_CONTIGUOUS + select HAVE_MEMBLOCK + select MAY_HAVE_SPARSE_IRQ + select MODULES_USE_ELF_RELA if MODULES + select NO_BOOTMEM + select OF + select OF_EARLY_FLATTREE + select OF_RESERVED_MEM + select PERF_USE_VMALLOC + select RTC_LIB + select TIMER_OF + select USB_ARCH_HAS_EHCI + select USB_ARCH_HAS_OHCI + +config CPU_HAS_CACHEV2 + bool + +config CPU_HAS_FPUV2 + bool + +config CPU_HAS_HILO + bool + +config CPU_HAS_TLBI + bool + +config CPU_HAS_LDSTEX + bool + help + For SMP, CPU needs "ldex" instrcutions to atomic operations. + +config CPU_NEED_TLBSYNC + bool + +config CPU_NEED_SOFTALIGN + bool + +config CPU_NO_USER_BKPT + bool + help + For abiv2 we couldn't use "trap 1" as user space bkpt in gdbserver, because + abiv2 is 16/32bit instruction set and "trap 1" is 32bit. + So we need a 16bit instruction as user space bkpt, and it will cause an illegal + instruction exception. + In kernel we parse the *regs->pc to determine whether to send SIGTRAP or not. + +config GENERIC_CALIBRATE_DELAY + def_bool y + +config GENERIC_CSUM + def_bool y + +config GENERIC_HWEIGHT + def_bool y + +config MMU + def_bool y + +config RWSEM_GENERIC_SPINLOCK + def_bool y + +config TIME_LOW_RES + def_bool y + +config TRACE_IRQFLAGS_SUPPORT + def_bool y + +config CPU_TLB_SIZE + int + default "128" if (CPU_CK610 || CPU_CK807 || CPU_CK810) + default "1024" if (CPU_CK860) + +config CPU_ASID_BITS + int + default "8" if (CPU_CK610 || CPU_CK807 || CPU_CK810) + default "12"if (CPU_CK860) + +config L1_CACHE_SHIFT + int + default "4" if (CPU_CK610) + default "5" if (CPU_CK807 || CPU_CK810) + default "6" if (CPU_CK860) + +menu "Processor type and features" + +choice + prompt "CPU MODEL" + default CPU_CK860 + +config CPU_CK610 +
[PATCH V7 07/20] csky: MMU and page table management
This patch adds files related to memory management and here is our memory-layout: Fixmap : 0xffc02000 – 0xf000 (4 MB - 12KB) Pkmap: 0xff80 – 0xffc0 (4 MB) Vmalloc : 0xf020 – 0xff00 (238 MB) Lowmem : 0x8000 – 0xc000 (1GB) abiv1 CPU (CK610) is VIPT cache and it doesn't support highmem. abiv2 CPUs are all PIPT cache and they could support highmem. Lowmem is directly mapped by msa0 & msa1 reg, and we needn't setup memory page table for it. Changelog: - dma-mapping: fix up dma_mapping error The arch_sync_dma_for_cpu()/arch_sync_dma_for_device() implementation is broken for some combinations that end up in a BUG() instead of performing the necessary flushes. - Fixup arch_sync_dma() broken when size is larger than PAGE_SIZE. Ignore the DMA_ATTR_NON_CONSISTENT, remove the BUG() and use return NULL instead. The implementation of arch should follow the following rules: map for_cpu for_device unmap TO_DEV writeback nonewriteback none TO_CPU invalidate invalidate* invalidate invalidate* BIDIR writeback invalidate writeback invalidate Link:https://lore.kernel.org/lkml/20180518215548.gh17...@n2100.armlinux.org.uk/ Signed-off-by: Guo Ren --- arch/csky/abiv1/inc/abi/ckmmu.h| 75 arch/csky/abiv1/inc/abi/page.h | 27 +++ arch/csky/abiv1/inc/abi/pgtable-bits.h | 37 arch/csky/abiv1/mmap.c | 66 +++ arch/csky/abiv2/inc/abi/ckmmu.h| 87 ++ arch/csky/abiv2/inc/abi/page.h | 14 ++ arch/csky/abiv2/inc/abi/pgtable-bits.h | 37 arch/csky/include/asm/addrspace.h | 10 ++ arch/csky/include/asm/fixmap.h | 27 +++ arch/csky/include/asm/highmem.h| 51 ++ arch/csky/include/asm/mmu.h| 12 ++ arch/csky/include/asm/page.h | 105 +++ arch/csky/include/asm/pgalloc.h| 115 + arch/csky/include/asm/pgtable.h| 306 + arch/csky/include/asm/segment.h| 19 ++ arch/csky/include/asm/shmparam.h | 11 ++ arch/csky/mm/dma-mapping.c | 254 +++ arch/csky/mm/highmem.c | 196 + arch/csky/mm/init.c| 121 + arch/csky/mm/ioremap.c | 48 ++ 20 files changed, 1618 insertions(+) create mode 100644 arch/csky/abiv1/inc/abi/ckmmu.h create mode 100644 arch/csky/abiv1/inc/abi/page.h create mode 100644 arch/csky/abiv1/inc/abi/pgtable-bits.h create mode 100644 arch/csky/abiv1/mmap.c create mode 100644 arch/csky/abiv2/inc/abi/ckmmu.h create mode 100644 arch/csky/abiv2/inc/abi/page.h create mode 100644 arch/csky/abiv2/inc/abi/pgtable-bits.h create mode 100644 arch/csky/include/asm/addrspace.h create mode 100644 arch/csky/include/asm/fixmap.h create mode 100644 arch/csky/include/asm/highmem.h create mode 100644 arch/csky/include/asm/mmu.h create mode 100644 arch/csky/include/asm/page.h create mode 100644 arch/csky/include/asm/pgalloc.h create mode 100644 arch/csky/include/asm/pgtable.h create mode 100644 arch/csky/include/asm/segment.h create mode 100644 arch/csky/include/asm/shmparam.h create mode 100644 arch/csky/mm/dma-mapping.c create mode 100644 arch/csky/mm/highmem.c create mode 100644 arch/csky/mm/init.c create mode 100644 arch/csky/mm/ioremap.c diff --git a/arch/csky/abiv1/inc/abi/ckmmu.h b/arch/csky/abiv1/inc/abi/ckmmu.h new file mode 100644 index 000..3a00201 --- /dev/null +++ b/arch/csky/abiv1/inc/abi/ckmmu.h @@ -0,0 +1,75 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. + +#ifndef __ASM_CSKY_CKMMUV1_H +#define __ASM_CSKY_CKMMUV1_H +#include + +static inline int read_mmu_index(void) +{ + return cprcr("cpcr0"); +} + +static inline void write_mmu_index(int value) +{ + cpwcr("cpcr0", value); +} + +static inline int read_mmu_entrylo0(void) +{ + return cprcr("cpcr2") << 6; +} + +static inline int read_mmu_entrylo1(void) +{ + return cprcr("cpcr3") << 6; +} + +static inline void write_mmu_pagemask(int value) +{ + cpwcr("cpcr6", value); +} + +static inline int read_mmu_entryhi(void) +{ + return cprcr("cpcr4"); +} + +static inline void write_mmu_entryhi(int value) +{ + cpwcr("cpcr4", value); +} + +/* + * TLB operations. + */ +static inline void tlb_probe(void) +{ + cpwcr("cpcr8", 0x8000); +} + +static inline void tlb_read(void) +{ + cpwcr("cpcr8", 0x4000); +} + +static inline void tlb_invalid_all(void) +{ + cpwcr("cpcr8", 0x0400); +} + +static inline void tlb_invalid_indexed(void) +{ + cpwcr("cpcr8", 0x0200); +} + +static inline void setup_pgd(unsigned long pgd, bool kernel) +{ + cpwcr("cpcr29", pgd); +} + +static inline unsigned long get_pgd(void)
[PATCH V7 08/20] csky: Process management and Signal
This patch adds files related to task_switch, sigcontext, signal. Changelog: - abiv2/fpu.c: Userspace should never be sent NSIGXXX as a si_code. Use FPE_FLTUNK instead. - abiv2/fpu.c: Use force_sig_fault instead. Signed-off-by: Guo Ren --- arch/csky/abiv2/fpu.c | 275 + arch/csky/abiv2/inc/abi/fpu.h | 66 ++ arch/csky/include/asm/mmu_context.h | 150 ++ arch/csky/include/asm/processor.h | 121 +++ arch/csky/include/asm/switch_to.h | 36 arch/csky/include/asm/thread_info.h | 75 +++ arch/csky/include/uapi/asm/sigcontext.h | 14 ++ arch/csky/kernel/process.c | 136 arch/csky/kernel/signal.c | 355 arch/csky/kernel/time.c | 11 + 10 files changed, 1239 insertions(+) create mode 100644 arch/csky/abiv2/fpu.c create mode 100644 arch/csky/abiv2/inc/abi/fpu.h create mode 100644 arch/csky/include/asm/mmu_context.h create mode 100644 arch/csky/include/asm/processor.h create mode 100644 arch/csky/include/asm/switch_to.h create mode 100644 arch/csky/include/asm/thread_info.h create mode 100644 arch/csky/include/uapi/asm/sigcontext.h create mode 100644 arch/csky/kernel/process.c create mode 100644 arch/csky/kernel/signal.c create mode 100644 arch/csky/kernel/time.c diff --git a/arch/csky/abiv2/fpu.c b/arch/csky/abiv2/fpu.c new file mode 100644 index 000..e7e1134 --- /dev/null +++ b/arch/csky/abiv2/fpu.c @@ -0,0 +1,275 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. + +#include +#include +#include + +#define MTCR_MASK 0xFC00FFE0 +#define MFCR_MASK 0xFC00FFE0 +#define MTCR_DIST 0xC0006420 +#define MFCR_DIST 0xC0006020 + +void __init init_fpu(void) +{ + mtcr("cr<1, 2>", 0); +} + +/* + * fpu_libc_helper() is to help libc to excute: + * - mfcr %a, cr<1, 2> + * - mfcr %a, cr<2, 2> + * - mtcr %a, cr<1, 2> + * - mtcr %a, cr<2, 2> + */ +int fpu_libc_helper(struct pt_regs *regs) +{ + int fault; + unsigned long instrptr, regx = 0; + unsigned long index = 0, tmp = 0; + unsigned long tinstr = 0; + u16 instr_hi, instr_low; + + instrptr = instruction_pointer(regs); + if (instrptr & 1) + return 0; + + fault = __get_user(instr_low, (u16 *)instrptr); + if (fault) + return 0; + + fault = __get_user(instr_hi, (u16 *)(instrptr + 2)); + if (fault) + return 0; + + tinstr = instr_hi | ((unsigned long)instr_low << 16); + + if (((tinstr >> 21) & 0x1F) != 2) + return 0; + + if ((tinstr & MTCR_MASK) == MTCR_DIST) { + index = (tinstr >> 16) & 0x1F; + if (index > 13) + return 0; + + tmp = tinstr & 0x1F; + if (tmp > 2) + return 0; + + regx = *(>a0 + index); + + if (tmp == 1) + mtcr("cr<1, 2>", regx); + else if (tmp == 2) + mtcr("cr<2, 2>", regx); + else + return 0; + + regs->pc += 4; + return 1; + } + + if ((tinstr & MFCR_MASK) == MFCR_DIST) { + index = tinstr & 0x1F; + if (index > 13) + return 0; + + tmp = ((tinstr >> 16) & 0x1F); + if (tmp > 2) + return 0; + + if (tmp == 1) + regx = mfcr("cr<1, 2>"); + else if (tmp == 2) + regx = mfcr("cr<2, 2>"); + else + return 0; + + *(>a0 + index) = regx; + + regs->pc += 4; + return 1; + } + + return 0; +} + +void fpu_fpe(struct pt_regs *regs) +{ + int sig, code; + unsigned int fesr; + + fesr = mfcr("cr<2, 2>"); + + sig = SIGFPE; + code = FPE_FLTUNK; + + if (fesr & FPE_ILLE) { + sig = SIGILL; + code = ILL_ILLOPC; + } else if (fesr & FPE_IDC) { + sig = SIGILL; + code = ILL_ILLOPN; + } else if (fesr & FPE_FEC) { + sig = SIGFPE; + if (fesr & FPE_IOC) + code = FPE_FLTINV; + else if (fesr & FPE_DZC) + code = FPE_FLTDIV; + else if (fesr & FPE_UFC) + code = FPE_FLTUND; + else if (fesr & FPE_OFC) + code = FPE_FLTOVF; + else if (fesr & FPE_IXC) + code = FPE_FLTRES; + } + + force_sig_fault(sig, code, (void __user *)regs->pc, current); +} + +#define FMFVR_FPU_REGS(vrx, vry) \ + "fmfvrl %0, "#vrx"\n" \ + "fmfvrh %1, "#vrx"\n"
[PATCH V7 01/20] csky: Build infrastructure
This patch adds Makefile, Kconfig for build infrastructure. Changelog: - Add compat.h in asm/Kbuild. - Add select DMA_DIRECT_OPS in Kconfig. - remove kernel/platform.c in Makefile. Signed-off-by: Guo Ren --- arch/csky/Kconfig | 205 + arch/csky/Kconfig.debug| 13 +++ arch/csky/Makefile | 92 +++ arch/csky/abiv1/Makefile | 8 ++ arch/csky/abiv2/Makefile | 10 ++ arch/csky/boot/Makefile| 24 arch/csky/boot/dts/Makefile| 13 +++ arch/csky/boot/dts/include/dt-bindings | 1 + arch/csky/include/asm/Kbuild | 71 arch/csky/include/uapi/asm/Kbuild | 33 ++ arch/csky/kernel/Makefile | 8 ++ arch/csky/lib/Makefile | 1 + arch/csky/mm/Makefile | 13 +++ 13 files changed, 492 insertions(+) create mode 100644 arch/csky/Kconfig create mode 100644 arch/csky/Kconfig.debug create mode 100644 arch/csky/Makefile create mode 100644 arch/csky/abiv1/Makefile create mode 100644 arch/csky/abiv2/Makefile create mode 100644 arch/csky/boot/Makefile create mode 100644 arch/csky/boot/dts/Makefile create mode 12 arch/csky/boot/dts/include/dt-bindings create mode 100644 arch/csky/include/asm/Kbuild create mode 100644 arch/csky/include/uapi/asm/Kbuild create mode 100644 arch/csky/kernel/Makefile create mode 100644 arch/csky/lib/Makefile create mode 100644 arch/csky/mm/Makefile diff --git a/arch/csky/Kconfig b/arch/csky/Kconfig new file mode 100644 index 000..89b726a --- /dev/null +++ b/arch/csky/Kconfig @@ -0,0 +1,205 @@ +config CSKY + def_bool y + select ARCH_HAS_SYNC_DMA_FOR_CPU + select ARCH_HAS_SYNC_DMA_FOR_DEVICE + select ARCH_USE_BUILTIN_BSWAP + select ARCH_USE_QUEUED_RWLOCKS if NR_CPUS>2 + select COMMON_CLK + select CLKSRC_MMIO + select CLKSRC_OF + select DMA_DIRECT_OPS + select DMA_NONCOHERENT_OPS + select IRQ_DOMAIN + select HANDLE_DOMAIN_IRQ + select DW_APB_TIMER_OF + select GENERIC_LIB_ASHLDI3 + select GENERIC_LIB_ASHRDI3 + select GENERIC_LIB_LSHRDI3 + select GENERIC_LIB_MULDI3 + select GENERIC_LIB_CMPDI2 + select GENERIC_LIB_UCMPDI2 + select GENERIC_ALLOCATOR + select GENERIC_ATOMIC64 + select GENERIC_CLOCKEVENTS + select GENERIC_CPU_DEVICES + select GENERIC_IRQ_CHIP + select GENERIC_IRQ_PROBE + select GENERIC_IRQ_SHOW + select GENERIC_IRQ_MULTI_HANDLER + select GENERIC_SCHED_CLOCK + select GENERIC_SMP_IDLE_THREAD + select HAVE_ARCH_TRACEHOOK + select HAVE_GENERIC_DMA_COHERENT + select HAVE_KERNEL_GZIP + select HAVE_KERNEL_LZO + select HAVE_KERNEL_LZMA + select HAVE_C_RECORDMCOUNT + select HAVE_DMA_API_DEBUG + select HAVE_DMA_CONTIGUOUS + select HAVE_MEMBLOCK + select MAY_HAVE_SPARSE_IRQ + select MODULES_USE_ELF_RELA if MODULES + select NO_BOOTMEM + select OF + select OF_EARLY_FLATTREE + select OF_RESERVED_MEM + select PERF_USE_VMALLOC + select RTC_LIB + select TIMER_OF + select USB_ARCH_HAS_EHCI + select USB_ARCH_HAS_OHCI + +config CPU_HAS_CACHEV2 + bool + +config CPU_HAS_FPUV2 + bool + +config CPU_HAS_HILO + bool + +config CPU_HAS_TLBI + bool + +config CPU_HAS_LDSTEX + bool + help + For SMP, CPU needs "ldex" instrcutions to atomic operations. + +config CPU_NEED_TLBSYNC + bool + +config CPU_NEED_SOFTALIGN + bool + +config CPU_NO_USER_BKPT + bool + help + For abiv2 we couldn't use "trap 1" as user space bkpt in gdbserver, because + abiv2 is 16/32bit instruction set and "trap 1" is 32bit. + So we need a 16bit instruction as user space bkpt, and it will cause an illegal + instruction exception. + In kernel we parse the *regs->pc to determine whether to send SIGTRAP or not. + +config GENERIC_CALIBRATE_DELAY + def_bool y + +config GENERIC_CSUM + def_bool y + +config GENERIC_HWEIGHT + def_bool y + +config MMU + def_bool y + +config RWSEM_GENERIC_SPINLOCK + def_bool y + +config TIME_LOW_RES + def_bool y + +config TRACE_IRQFLAGS_SUPPORT + def_bool y + +config CPU_TLB_SIZE + int + default "128" if (CPU_CK610 || CPU_CK807 || CPU_CK810) + default "1024" if (CPU_CK860) + +config CPU_ASID_BITS + int + default "8" if (CPU_CK610 || CPU_CK807 || CPU_CK810) + default "12"if (CPU_CK860) + +config L1_CACHE_SHIFT + int + default "4" if (CPU_CK610) + default "5" if (CPU_CK807 || CPU_CK810) + default "6" if (CPU_CK860) + +menu "Processor type and features" + +choice + prompt "CPU MODEL" + default CPU_CK860 + +config CPU_CK610 +
[PATCH V7 00/20] C-SKY(csky) Linux Kernel Port
This is the 7th version patchset to add the Linux kernel port for C-SKY(csky) based on linux-4.19-rc3. In this patchset some fixup patches are folded into original patch in order to make review clearly and reduce the patches' number for upstream patchset. The changelog is added in the every patch's commit-msg. Here is the LTP test report for this patchset: (and add "V10 C-SKY(csky) Linux Kernel Driver" patchset) --- Total Tests: 1298 Total Skipped Tests: 280 Total Failures: 11 Kernel Version: 4.19.0-rc3+ Machine Architecture: csky Hostname: buildroot --- This patchset adds architecture support to Linux for C-SKY's 32-bit embedded There are two ABI versions with several CPU cores in this patchset: ABIv1: ck610 (16-bit instruction, 32-bit data path, VIPT Cache ...) ABIv2: ck807 ck810 ck860 (16/32-bit variable length instruction, PIPT Cache, SMP ...) More information: http://en.c-sky.com The development repo: https://gitlab.com/c-sky/csky-linux Here is the pre-built cross compiler for fast test from our CI: https://gitlab.com/c-sky/buildroot/-/jobs/101608095/artifacts/file/output/images/csky_toolchain_qemu_csky_ck807f_4.18_glibc_defconfig_482b221e52908be1c9b2ccb444255e1562bb7025.tar.xz We use buildroot as our CI-test enviornment. "LTP, Lmbench ..." will be tested for every commit. See here for more details: https://gitlab.com/c-sky/buildroot/pipelines Any feedback is welcome. Changes in v7: - Use checkpatch.pl to check all patches and fixup as possible. - Remove github.com/c-sky print in bootup. - Give a return in DMA_ATTR_NON_CONSISTENT in csky_dma_alloc_atomic(). - Remove the NSIGXXX in fpu.c and use force_sig_fault() in fpu.c. - Remove irq.h and add it in asm/Kbuild. - Use byteswap helpers in abiv1/bswapXi.c. - Fixup arch_sync_dma() only with one page problem. Changes in v6: - use asm-generic/bitops/atomic.h for all in asm/bitops.h - fix flush_cache_range and tlb_start_vma - fix compile error with include linux/bug.h in cmpxchg.h - improve the comment Changes in v5: - remove redundant smp_mb operations in spinlock.h - add commit message for dt-bindings docs - add CPUHP_AP_CSKY_TIMER_STARTING in hotplug.h for csky_mptimer - add COMPILE_TEST for timer-gx6605s Kconfig - seperate csky two interrupt controllers with 2 patches - add MAINTAINERS patch for csky - move IPI_IRQ into csky_mptimer, fixup irq_mapping problem - coding convension Changes in v4: - cleanup defconfig - use ksys_ in syscall.c - remove wrong comment in vdso.c - Use GENERIC_IRQ_MULTI_HANDLER - optimize the memset.c - fixup dts warnings - remove big-endian in byteorder.h Changes in v3: dc560f1 csky: change to EM_CSKY 252 for elf.h 2ac3ddf csky: remove gx6605s.dts af00b8c csky: add defconfig and qemu.dts 6c87efb csky: remove the deprecate name. f6dda39 csky: add dt-bindings doc. d9f02a8 csky: remove KERNEL_VERSION in upstream branch 7bd663c csky: Use kernel/dma/noncoherent.c 1544c09 csky: bugfix emmc hang up LINS-976 e963271 csky: cleanup include/asm/Kbuild cd267ba csky: remove CSKY_DEBUG_INFO 78950da csky: remove dcache invalid. 13fe51d csky: remove csum_ipv6_magic(), use generic one. a7372db csky: bugfix CK810 access twice error. 1bb7c69 csky: bugfix add gcc asm memory for barrier. 5ea3257 csky: add -msoft-float instead of -mfloat-abi=soft. 38b037d csky: bugfix losing cache flush range. ab5e8c4 csky: Add ticket-spinlock and qrwlock support. c9aaec5 csky: rename cskyksyms.c to libgcc_ksyms.c 28c5e48 csky: avoid the MB on failure: trylock f929c97 csky: bugfix idly4 may cause exception. 09dc496 csky: Use GENERIC_ASHLDI3/ASHRDI3 etc 6ecc99d csky: optimize smp boot code. 16f50df csky: asm/bug.h simple implement. 0ba532a csky: csky asm/atomic.h added. df66947 csky: asm/compat.h added 275a06f csky: String operations optimization 4c021dd csky: ck860 SMP memory barrier optimize fc39c66 csky: Add wait/doze/stop d005144 csky: add GENERIC_ALLOCATOR 4a10074 csky: bugfix cma failed for highmem. 9f2ca70 csky: CMA supported :) 53791f4 csky: optimize csky_dma_alloc_nonatomic 974676e csky: optimize the cpuinfo printf. 2538669 csky: bugfix make headers_install error. 1158d0c csky: prevent hard-float and vdsp instructions. dc3c856 csky: increase Normal Memory to 1GB 6ee5932 csky: bugfix qemu mmu couldn't support 0xe000 1d7dfb8 csky: csky_dma_alloc_atomic added. caf6610 csky: restruct the fixmap memory layout. 5a17eaa csky: use -Wa,-mcpu=ckxxxfv to the as. 4d51829 csky: use Kconfig.hz. f3f88fa csky: BUGFIX add -mcpu=ck860f support 6192fd1 csky: support ck860 fpu. 7aa5e01 csky: BUGFIX add smp_mb before ldex. 15758e2 csky: BUGFIX tlbi couldn't handle ASID in another CPU core. d69640d csky: enable tlbi.vas to flush one tlb entry Changes in v2: a29bfc8 csky: add pre_mmu_init, move misc mmu setup to mm/init.c 4eab702 csky: no need kmap for !VM_EXEC. 6770eec csky: Use TEE as the name of CPU Trusted Execution Enviornment.
[PATCH V7 00/20] C-SKY(csky) Linux Kernel Port
This is the 7th version patchset to add the Linux kernel port for C-SKY(csky) based on linux-4.19-rc3. In this patchset some fixup patches are folded into original patch in order to make review clearly and reduce the patches' number for upstream patchset. The changelog is added in the every patch's commit-msg. Here is the LTP test report for this patchset: (and add "V10 C-SKY(csky) Linux Kernel Driver" patchset) --- Total Tests: 1298 Total Skipped Tests: 280 Total Failures: 11 Kernel Version: 4.19.0-rc3+ Machine Architecture: csky Hostname: buildroot --- This patchset adds architecture support to Linux for C-SKY's 32-bit embedded There are two ABI versions with several CPU cores in this patchset: ABIv1: ck610 (16-bit instruction, 32-bit data path, VIPT Cache ...) ABIv2: ck807 ck810 ck860 (16/32-bit variable length instruction, PIPT Cache, SMP ...) More information: http://en.c-sky.com The development repo: https://gitlab.com/c-sky/csky-linux Here is the pre-built cross compiler for fast test from our CI: https://gitlab.com/c-sky/buildroot/-/jobs/101608095/artifacts/file/output/images/csky_toolchain_qemu_csky_ck807f_4.18_glibc_defconfig_482b221e52908be1c9b2ccb444255e1562bb7025.tar.xz We use buildroot as our CI-test enviornment. "LTP, Lmbench ..." will be tested for every commit. See here for more details: https://gitlab.com/c-sky/buildroot/pipelines Any feedback is welcome. Changes in v7: - Use checkpatch.pl to check all patches and fixup as possible. - Remove github.com/c-sky print in bootup. - Give a return in DMA_ATTR_NON_CONSISTENT in csky_dma_alloc_atomic(). - Remove the NSIGXXX in fpu.c and use force_sig_fault() in fpu.c. - Remove irq.h and add it in asm/Kbuild. - Use byteswap helpers in abiv1/bswapXi.c. - Fixup arch_sync_dma() only with one page problem. Changes in v6: - use asm-generic/bitops/atomic.h for all in asm/bitops.h - fix flush_cache_range and tlb_start_vma - fix compile error with include linux/bug.h in cmpxchg.h - improve the comment Changes in v5: - remove redundant smp_mb operations in spinlock.h - add commit message for dt-bindings docs - add CPUHP_AP_CSKY_TIMER_STARTING in hotplug.h for csky_mptimer - add COMPILE_TEST for timer-gx6605s Kconfig - seperate csky two interrupt controllers with 2 patches - add MAINTAINERS patch for csky - move IPI_IRQ into csky_mptimer, fixup irq_mapping problem - coding convension Changes in v4: - cleanup defconfig - use ksys_ in syscall.c - remove wrong comment in vdso.c - Use GENERIC_IRQ_MULTI_HANDLER - optimize the memset.c - fixup dts warnings - remove big-endian in byteorder.h Changes in v3: dc560f1 csky: change to EM_CSKY 252 for elf.h 2ac3ddf csky: remove gx6605s.dts af00b8c csky: add defconfig and qemu.dts 6c87efb csky: remove the deprecate name. f6dda39 csky: add dt-bindings doc. d9f02a8 csky: remove KERNEL_VERSION in upstream branch 7bd663c csky: Use kernel/dma/noncoherent.c 1544c09 csky: bugfix emmc hang up LINS-976 e963271 csky: cleanup include/asm/Kbuild cd267ba csky: remove CSKY_DEBUG_INFO 78950da csky: remove dcache invalid. 13fe51d csky: remove csum_ipv6_magic(), use generic one. a7372db csky: bugfix CK810 access twice error. 1bb7c69 csky: bugfix add gcc asm memory for barrier. 5ea3257 csky: add -msoft-float instead of -mfloat-abi=soft. 38b037d csky: bugfix losing cache flush range. ab5e8c4 csky: Add ticket-spinlock and qrwlock support. c9aaec5 csky: rename cskyksyms.c to libgcc_ksyms.c 28c5e48 csky: avoid the MB on failure: trylock f929c97 csky: bugfix idly4 may cause exception. 09dc496 csky: Use GENERIC_ASHLDI3/ASHRDI3 etc 6ecc99d csky: optimize smp boot code. 16f50df csky: asm/bug.h simple implement. 0ba532a csky: csky asm/atomic.h added. df66947 csky: asm/compat.h added 275a06f csky: String operations optimization 4c021dd csky: ck860 SMP memory barrier optimize fc39c66 csky: Add wait/doze/stop d005144 csky: add GENERIC_ALLOCATOR 4a10074 csky: bugfix cma failed for highmem. 9f2ca70 csky: CMA supported :) 53791f4 csky: optimize csky_dma_alloc_nonatomic 974676e csky: optimize the cpuinfo printf. 2538669 csky: bugfix make headers_install error. 1158d0c csky: prevent hard-float and vdsp instructions. dc3c856 csky: increase Normal Memory to 1GB 6ee5932 csky: bugfix qemu mmu couldn't support 0xe000 1d7dfb8 csky: csky_dma_alloc_atomic added. caf6610 csky: restruct the fixmap memory layout. 5a17eaa csky: use -Wa,-mcpu=ckxxxfv to the as. 4d51829 csky: use Kconfig.hz. f3f88fa csky: BUGFIX add -mcpu=ck860f support 6192fd1 csky: support ck860 fpu. 7aa5e01 csky: BUGFIX add smp_mb before ldex. 15758e2 csky: BUGFIX tlbi couldn't handle ASID in another CPU core. d69640d csky: enable tlbi.vas to flush one tlb entry Changes in v2: a29bfc8 csky: add pre_mmu_init, move misc mmu setup to mm/init.c 4eab702 csky: no need kmap for !VM_EXEC. 6770eec csky: Use TEE as the name of CPU Trusted Execution Enviornment.
[PATCH V7 05/20] csky: System Call
This patch adds files related to syscall. Signed-off-by: Guo Ren --- arch/csky/include/asm/syscall.h | 71 + arch/csky/include/asm/syscalls.h| 15 arch/csky/include/uapi/asm/unistd.h | 10 ++ arch/csky/kernel/syscall.c | 43 ++ arch/csky/kernel/syscall_table.c| 14 5 files changed, 153 insertions(+) create mode 100644 arch/csky/include/asm/syscall.h create mode 100644 arch/csky/include/asm/syscalls.h create mode 100644 arch/csky/include/uapi/asm/unistd.h create mode 100644 arch/csky/kernel/syscall.c create mode 100644 arch/csky/kernel/syscall_table.c diff --git a/arch/csky/include/asm/syscall.h b/arch/csky/include/asm/syscall.h new file mode 100644 index 000..926a64a --- /dev/null +++ b/arch/csky/include/asm/syscall.h @@ -0,0 +1,71 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef __ASM_SYSCALL_H +#define __ASM_SYSCALL_H + +#include +#include +#include + +static inline int +syscall_get_nr(struct task_struct *task, struct pt_regs *regs) +{ + return regs_syscallid(regs); +} + +static inline void +syscall_rollback(struct task_struct *task, struct pt_regs *regs) +{ + regs->a0 = regs->orig_a0; +} + +static inline long +syscall_get_error(struct task_struct *task, struct pt_regs *regs) +{ + unsigned long error = regs->a0; + + return IS_ERR_VALUE(error) ? error : 0; +} + +static inline long +syscall_get_return_value(struct task_struct *task, struct pt_regs *regs) +{ + return regs->a0; +} + +static inline void +syscall_set_return_value(struct task_struct *task, struct pt_regs *regs, + int error, long val) +{ + regs->a0 = (long) error ?: val; +} + +static inline void +syscall_get_arguments(struct task_struct *task, struct pt_regs *regs, + unsigned int i, unsigned int n, unsigned long *args) +{ + BUG_ON(i + n > 6); + if (i == 0) { + args[0] = regs->orig_a0; + args++; + i++; + n--; + } + memcpy(args, >a1 + i * sizeof(regs->a1), n * sizeof(args[0])); +} + +static inline void +syscall_set_arguments(struct task_struct *task, struct pt_regs *regs, + unsigned int i, unsigned int n, const unsigned long *args) +{ + BUG_ON(i + n > 6); + if (i == 0) { + regs->orig_a0 = args[0]; + args++; + i++; + n--; + } + memcpy(>a1 + i * sizeof(regs->a1), args, n * sizeof(regs->a0)); +} + +#endif /* __ASM_SYSCALL_H */ diff --git a/arch/csky/include/asm/syscalls.h b/arch/csky/include/asm/syscalls.h new file mode 100644 index 000..5d48e5e --- /dev/null +++ b/arch/csky/include/asm/syscalls.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. + +#ifndef __ASM_CSKY_SYSCALLS_H +#define __ASM_CSKY_SYSCALLS_H + +#include + +long sys_cacheflush(void __user *, unsigned long, int); + +long sys_set_thread_area(unsigned long addr); + +long sys_csky_fadvise64_64(int fd, int advice, loff_t offset, loff_t len); + +#endif /* __ASM_CSKY_SYSCALLS_H */ diff --git a/arch/csky/include/uapi/asm/unistd.h b/arch/csky/include/uapi/asm/unistd.h new file mode 100644 index 000..16ed71e --- /dev/null +++ b/arch/csky/include/uapi/asm/unistd.h @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. + +#define __ARCH_WANT_SYS_CLONE +#include + +#define __NR_set_thread_area (__NR_arch_specific_syscall + 0) +__SYSCALL(__NR_set_thread_area, sys_set_thread_area) +#define __NR_cacheflush(__NR_arch_specific_syscall + 4) +__SYSCALL(__NR_cacheflush, sys_cacheflush) diff --git a/arch/csky/kernel/syscall.c b/arch/csky/kernel/syscall.c new file mode 100644 index 000..3d30e58 --- /dev/null +++ b/arch/csky/kernel/syscall.c @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. + +#include + +SYSCALL_DEFINE1(set_thread_area, unsigned long, addr) +{ + struct thread_info *ti = task_thread_info(current); + struct pt_regs *reg = current_pt_regs(); + + reg->tls = addr; + ti->tp_value = addr; + + return 0; +} + +SYSCALL_DEFINE6(mmap2, + unsigned long, addr, + unsigned long, len, + unsigned long, prot, + unsigned long, flags, + unsigned long, fd, + off_t, offset) +{ + if (unlikely(offset & (~PAGE_MASK >> 12))) + return -EINVAL; + + return ksys_mmap_pgoff(addr, len, prot, flags, fd, + offset >> (PAGE_SHIFT - 12)); +} + +/* + * for abiv1 the 64bits args should be even th, So we need mov the advice + * forward. + */ +SYSCALL_DEFINE4(csky_fadvise64_64, + int, fd, + int, advice, + loff_t, offset, + loff_t, len) +{ + return ksys_fadvise64_64(fd, offset, len, advice); +}
[PATCH V7 06/20] csky: Cache and TLB routines
This patch adds cache and tlb sync codes for abiv1 & abiv2. Changelog: - tlb.h & cacheflush.h: fix flush_cache_range and tlb_start_vma of abiv1 in flush_cache_range(vma, ...). cache_wbinv_range() couldn't deal with vma->mm's asid for cache_flush_line and we use cache_wbinv_all() first. Wwe'll improve with cache_flush(vma, start, end) in future. For tlb_start_vma, we make it the same as other arch. - remove the abi/tlb.h Signed-off-by: Guo Ren --- arch/csky/abiv1/cacheflush.c | 52 arch/csky/abiv1/inc/abi/cacheflush.h | 49 arch/csky/abiv2/cacheflush.c | 60 ++ arch/csky/abiv2/inc/abi/cacheflush.h | 46 +++ arch/csky/include/asm/barrier.h | 49 arch/csky/include/asm/cache.h | 30 + arch/csky/include/asm/cacheflush.h| 9 ++ arch/csky/include/asm/io.h| 24 arch/csky/include/asm/tlb.h | 25 arch/csky/include/asm/tlbflush.h | 25 arch/csky/include/uapi/asm/cachectl.h | 13 ++ arch/csky/mm/cachev1.c| 125 +++ arch/csky/mm/cachev2.c| 78 arch/csky/mm/syscache.c | 32 + arch/csky/mm/tlb.c| 219 ++ 15 files changed, 836 insertions(+) create mode 100644 arch/csky/abiv1/cacheflush.c create mode 100644 arch/csky/abiv1/inc/abi/cacheflush.h create mode 100644 arch/csky/abiv2/cacheflush.c create mode 100644 arch/csky/abiv2/inc/abi/cacheflush.h create mode 100644 arch/csky/include/asm/barrier.h create mode 100644 arch/csky/include/asm/cache.h create mode 100644 arch/csky/include/asm/cacheflush.h create mode 100644 arch/csky/include/asm/io.h create mode 100644 arch/csky/include/asm/tlb.h create mode 100644 arch/csky/include/asm/tlbflush.h create mode 100644 arch/csky/include/uapi/asm/cachectl.h create mode 100644 arch/csky/mm/cachev1.c create mode 100644 arch/csky/mm/cachev2.c create mode 100644 arch/csky/mm/syscache.c create mode 100644 arch/csky/mm/tlb.c diff --git a/arch/csky/abiv1/cacheflush.c b/arch/csky/abiv1/cacheflush.c new file mode 100644 index 000..10af8b6 --- /dev/null +++ b/arch/csky/abiv1/cacheflush.c @@ -0,0 +1,52 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void flush_dcache_page(struct page *page) +{ + struct address_space *mapping = page_mapping(page); + unsigned long addr; + + if (mapping && !mapping_mapped(mapping)) { + set_bit(PG_arch_1, &(page)->flags); + return; + } + + /* +* We could delay the flush for the !page_mapping case too. But that +* case is for exec env/arg pages and those are %99 certainly going to +* get faulted into the tlb (and thus flushed) anyways. +*/ + addr = (unsigned long) page_address(page); + dcache_wb_range(addr, addr + PAGE_SIZE); +} + +void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, + pte_t *pte) +{ + unsigned long addr; + struct page *page; + unsigned long pfn; + + pfn = pte_pfn(*pte); + if (unlikely(!pfn_valid(pfn))) + return; + + page = pfn_to_page(pfn); + addr = (unsigned long) page_address(page); + + if (vma->vm_flags & VM_EXEC || + pages_do_alias(addr, address & PAGE_MASK)) + cache_wbinv_all(); + + clear_bit(PG_arch_1, &(page)->flags); +} diff --git a/arch/csky/abiv1/inc/abi/cacheflush.h b/arch/csky/abiv1/inc/abi/cacheflush.h new file mode 100644 index 000..5f663ae --- /dev/null +++ b/arch/csky/abiv1/inc/abi/cacheflush.h @@ -0,0 +1,49 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. + +#ifndef __ABI_CSKY_CACHEFLUSH_H +#define __ABI_CSKY_CACHEFLUSH_H + +#include +#include +#include + +#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1 +extern void flush_dcache_page(struct page *); + +#define flush_cache_mm(mm) cache_wbinv_all() +#define flush_cache_page(vma, page, pfn) cache_wbinv_all() +#define flush_cache_dup_mm(mm) cache_wbinv_all() + +/* + * if (current_mm != vma->mm) cache_wbinv_range(start, end) will be broken. + * Use cache_wbinv_all() here and need to be improved in future. + */ +#define flush_cache_range(vma, start, end) cache_wbinv_all() +#define flush_cache_vmap(start, end) cache_wbinv_range(start, end) +#define flush_cache_vunmap(start, end) cache_wbinv_range(start, end) + +#define flush_icache_page(vma, page) cache_wbinv_all() +#define flush_icache_range(start, end) cache_wbinv_range(start, end) + +#define flush_icache_user_range(vma, pg, adr, len) \ + cache_wbinv_range(adr, adr + len) + +#define
[PATCH V7 03/20] csky: Kernel booting
This patch add boot code. Thx boot params is all in dtb and it's the only way to let kernel get bootloader param information. Signed-off-by: Guo Ren --- arch/csky/kernel/head.S| 77 + arch/csky/kernel/setup.c | 151 + arch/csky/kernel/vmlinux.lds.S | 66 ++ 3 files changed, 294 insertions(+) create mode 100644 arch/csky/kernel/head.S create mode 100644 arch/csky/kernel/setup.c create mode 100644 arch/csky/kernel/vmlinux.lds.S diff --git a/arch/csky/kernel/head.S b/arch/csky/kernel/head.S new file mode 100644 index 000..9c4ec47 --- /dev/null +++ b/arch/csky/kernel/head.S @@ -0,0 +1,77 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#include +#include +#include +#include + +__HEAD +ENTRY(_start) + /* set super user mode */ + lrw a3, DEFAULT_PSR_VALUE + mtcra3, psr + psrset ee + + SETUP_MMU a3 + + /* set stack point */ + lrw a3, init_thread_union + THREAD_SIZE + mov sp, a3 + + jmpicsky_start +END(_start) + +#ifdef CONFIG_SMP +.align 10 +ENTRY(_start_smp_secondary) + /* Invalid I/Dcache BTB BHT */ + movia3, 7 + lslia3, 16 + addia3, (1<<4) | 3 + mtcra3, cr17 + + tlbi.alls + + /* setup PAGEMASK */ + movia3, 0 + mtcra3, cr<6, 15> + + /* setup MEL0/MEL1 */ + grs a0, _start_smp_pc +_start_smp_pc: + bmaski a1, 13 + andna0, a1 + movia1, 0x0006 + movia2, 0x1006 + or a1, a0 + or a2, a0 + mtcra1, cr<2, 15> + mtcra2, cr<3, 15> + + /* setup MEH */ + mtcra0, cr<4, 15> + + /* write TLB */ + bgeni a3, 28 + mtcra3, cr<8, 15> + + SETUP_MMU a3 + + /* enable MMU */ + movia3, 1 + mtcra3, cr18 + + jmpi_goto_mmu_on +_goto_mmu_on: + lrw a3, DEFAULT_PSR_VALUE + mtcra3, psr + psrset ee + + /* set stack point */ + lrw a3, secondary_stack + ld.wa3, (a3, 0) + mov sp, a3 + + jmpicsky_start_secondary +END(_start_smp_secondary) +#endif diff --git a/arch/csky/kernel/setup.c b/arch/csky/kernel/setup.c new file mode 100644 index 000..33f4114 --- /dev/null +++ b/arch/csky/kernel/setup.c @@ -0,0 +1,151 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +phys_addr_t __init_memblock memblock_end_of_REG0(void) +{ + return (memblock.memory.regions[0].base + + memblock.memory.regions[0].size); +} + +phys_addr_t __init_memblock memblock_start_of_REG1(void) +{ + return memblock.memory.regions[1].base; +} + +size_t __init_memblock memblock_size_of_REG1(void) +{ + return memblock.memory.regions[1].size; +} + +static void __init csky_memblock_init(void) +{ + unsigned long zone_size[MAX_NR_ZONES]; + unsigned long zhole_size[MAX_NR_ZONES]; + signed long size; + + memblock_reserve(__pa(_stext), _end - _stext); +#ifdef CONFIG_BLK_DEV_INITRD + memblock_reserve(__pa(initrd_start), initrd_end - initrd_start); +#endif + + early_init_fdt_reserve_self(); + early_init_fdt_scan_reserved_mem(); + + memblock_dump_all(); + + memset(zone_size, 0, sizeof(zone_size)); + memset(zhole_size, 0, sizeof(zhole_size)); + + min_low_pfn = PFN_UP(memblock_start_of_DRAM()); + max_pfn = PFN_DOWN(memblock_end_of_DRAM()); + + max_low_pfn = PFN_UP(memblock_end_of_REG0()); + if (max_low_pfn == 0) + max_low_pfn = max_pfn; + + size = max_pfn - min_low_pfn; + + if (memblock.memory.cnt > 1) { + zone_size[ZONE_NORMAL] = + PFN_DOWN(memblock_start_of_REG1()) - min_low_pfn; + zhole_size[ZONE_NORMAL] = + PFN_DOWN(memblock_start_of_REG1()) - max_low_pfn; + } else { + if (size <= PFN_DOWN(LOWMEM_LIMIT - PHYS_OFFSET_OFFSET)) + zone_size[ZONE_NORMAL] = max_pfn - min_low_pfn; + else { + zone_size[ZONE_NORMAL] = + PFN_DOWN(LOWMEM_LIMIT - PHYS_OFFSET_OFFSET); + max_low_pfn = min_low_pfn + zone_size[ZONE_NORMAL]; + } + } + +#ifdef CONFIG_HIGHMEM + size = 0; + if (memblock.memory.cnt > 1) { + size = PFN_DOWN(memblock_size_of_REG1()); + highstart_pfn = PFN_DOWN(memblock_start_of_REG1()); + } else { + size = max_pfn - min_low_pfn - + PFN_DOWN(LOWMEM_LIMIT - PHYS_OFFSET_OFFSET); + highstart_pfn = min_low_pfn + + PFN_DOWN(LOWMEM_LIMIT -
[PATCH V7 03/20] csky: Kernel booting
This patch add boot code. Thx boot params is all in dtb and it's the only way to let kernel get bootloader param information. Signed-off-by: Guo Ren --- arch/csky/kernel/head.S| 77 + arch/csky/kernel/setup.c | 151 + arch/csky/kernel/vmlinux.lds.S | 66 ++ 3 files changed, 294 insertions(+) create mode 100644 arch/csky/kernel/head.S create mode 100644 arch/csky/kernel/setup.c create mode 100644 arch/csky/kernel/vmlinux.lds.S diff --git a/arch/csky/kernel/head.S b/arch/csky/kernel/head.S new file mode 100644 index 000..9c4ec47 --- /dev/null +++ b/arch/csky/kernel/head.S @@ -0,0 +1,77 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#include +#include +#include +#include + +__HEAD +ENTRY(_start) + /* set super user mode */ + lrw a3, DEFAULT_PSR_VALUE + mtcra3, psr + psrset ee + + SETUP_MMU a3 + + /* set stack point */ + lrw a3, init_thread_union + THREAD_SIZE + mov sp, a3 + + jmpicsky_start +END(_start) + +#ifdef CONFIG_SMP +.align 10 +ENTRY(_start_smp_secondary) + /* Invalid I/Dcache BTB BHT */ + movia3, 7 + lslia3, 16 + addia3, (1<<4) | 3 + mtcra3, cr17 + + tlbi.alls + + /* setup PAGEMASK */ + movia3, 0 + mtcra3, cr<6, 15> + + /* setup MEL0/MEL1 */ + grs a0, _start_smp_pc +_start_smp_pc: + bmaski a1, 13 + andna0, a1 + movia1, 0x0006 + movia2, 0x1006 + or a1, a0 + or a2, a0 + mtcra1, cr<2, 15> + mtcra2, cr<3, 15> + + /* setup MEH */ + mtcra0, cr<4, 15> + + /* write TLB */ + bgeni a3, 28 + mtcra3, cr<8, 15> + + SETUP_MMU a3 + + /* enable MMU */ + movia3, 1 + mtcra3, cr18 + + jmpi_goto_mmu_on +_goto_mmu_on: + lrw a3, DEFAULT_PSR_VALUE + mtcra3, psr + psrset ee + + /* set stack point */ + lrw a3, secondary_stack + ld.wa3, (a3, 0) + mov sp, a3 + + jmpicsky_start_secondary +END(_start_smp_secondary) +#endif diff --git a/arch/csky/kernel/setup.c b/arch/csky/kernel/setup.c new file mode 100644 index 000..33f4114 --- /dev/null +++ b/arch/csky/kernel/setup.c @@ -0,0 +1,151 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +phys_addr_t __init_memblock memblock_end_of_REG0(void) +{ + return (memblock.memory.regions[0].base + + memblock.memory.regions[0].size); +} + +phys_addr_t __init_memblock memblock_start_of_REG1(void) +{ + return memblock.memory.regions[1].base; +} + +size_t __init_memblock memblock_size_of_REG1(void) +{ + return memblock.memory.regions[1].size; +} + +static void __init csky_memblock_init(void) +{ + unsigned long zone_size[MAX_NR_ZONES]; + unsigned long zhole_size[MAX_NR_ZONES]; + signed long size; + + memblock_reserve(__pa(_stext), _end - _stext); +#ifdef CONFIG_BLK_DEV_INITRD + memblock_reserve(__pa(initrd_start), initrd_end - initrd_start); +#endif + + early_init_fdt_reserve_self(); + early_init_fdt_scan_reserved_mem(); + + memblock_dump_all(); + + memset(zone_size, 0, sizeof(zone_size)); + memset(zhole_size, 0, sizeof(zhole_size)); + + min_low_pfn = PFN_UP(memblock_start_of_DRAM()); + max_pfn = PFN_DOWN(memblock_end_of_DRAM()); + + max_low_pfn = PFN_UP(memblock_end_of_REG0()); + if (max_low_pfn == 0) + max_low_pfn = max_pfn; + + size = max_pfn - min_low_pfn; + + if (memblock.memory.cnt > 1) { + zone_size[ZONE_NORMAL] = + PFN_DOWN(memblock_start_of_REG1()) - min_low_pfn; + zhole_size[ZONE_NORMAL] = + PFN_DOWN(memblock_start_of_REG1()) - max_low_pfn; + } else { + if (size <= PFN_DOWN(LOWMEM_LIMIT - PHYS_OFFSET_OFFSET)) + zone_size[ZONE_NORMAL] = max_pfn - min_low_pfn; + else { + zone_size[ZONE_NORMAL] = + PFN_DOWN(LOWMEM_LIMIT - PHYS_OFFSET_OFFSET); + max_low_pfn = min_low_pfn + zone_size[ZONE_NORMAL]; + } + } + +#ifdef CONFIG_HIGHMEM + size = 0; + if (memblock.memory.cnt > 1) { + size = PFN_DOWN(memblock_size_of_REG1()); + highstart_pfn = PFN_DOWN(memblock_start_of_REG1()); + } else { + size = max_pfn - min_low_pfn - + PFN_DOWN(LOWMEM_LIMIT - PHYS_OFFSET_OFFSET); + highstart_pfn = min_low_pfn + + PFN_DOWN(LOWMEM_LIMIT -
[PATCH V7 05/20] csky: System Call
This patch adds files related to syscall. Signed-off-by: Guo Ren --- arch/csky/include/asm/syscall.h | 71 + arch/csky/include/asm/syscalls.h| 15 arch/csky/include/uapi/asm/unistd.h | 10 ++ arch/csky/kernel/syscall.c | 43 ++ arch/csky/kernel/syscall_table.c| 14 5 files changed, 153 insertions(+) create mode 100644 arch/csky/include/asm/syscall.h create mode 100644 arch/csky/include/asm/syscalls.h create mode 100644 arch/csky/include/uapi/asm/unistd.h create mode 100644 arch/csky/kernel/syscall.c create mode 100644 arch/csky/kernel/syscall_table.c diff --git a/arch/csky/include/asm/syscall.h b/arch/csky/include/asm/syscall.h new file mode 100644 index 000..926a64a --- /dev/null +++ b/arch/csky/include/asm/syscall.h @@ -0,0 +1,71 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef __ASM_SYSCALL_H +#define __ASM_SYSCALL_H + +#include +#include +#include + +static inline int +syscall_get_nr(struct task_struct *task, struct pt_regs *regs) +{ + return regs_syscallid(regs); +} + +static inline void +syscall_rollback(struct task_struct *task, struct pt_regs *regs) +{ + regs->a0 = regs->orig_a0; +} + +static inline long +syscall_get_error(struct task_struct *task, struct pt_regs *regs) +{ + unsigned long error = regs->a0; + + return IS_ERR_VALUE(error) ? error : 0; +} + +static inline long +syscall_get_return_value(struct task_struct *task, struct pt_regs *regs) +{ + return regs->a0; +} + +static inline void +syscall_set_return_value(struct task_struct *task, struct pt_regs *regs, + int error, long val) +{ + regs->a0 = (long) error ?: val; +} + +static inline void +syscall_get_arguments(struct task_struct *task, struct pt_regs *regs, + unsigned int i, unsigned int n, unsigned long *args) +{ + BUG_ON(i + n > 6); + if (i == 0) { + args[0] = regs->orig_a0; + args++; + i++; + n--; + } + memcpy(args, >a1 + i * sizeof(regs->a1), n * sizeof(args[0])); +} + +static inline void +syscall_set_arguments(struct task_struct *task, struct pt_regs *regs, + unsigned int i, unsigned int n, const unsigned long *args) +{ + BUG_ON(i + n > 6); + if (i == 0) { + regs->orig_a0 = args[0]; + args++; + i++; + n--; + } + memcpy(>a1 + i * sizeof(regs->a1), args, n * sizeof(regs->a0)); +} + +#endif /* __ASM_SYSCALL_H */ diff --git a/arch/csky/include/asm/syscalls.h b/arch/csky/include/asm/syscalls.h new file mode 100644 index 000..5d48e5e --- /dev/null +++ b/arch/csky/include/asm/syscalls.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. + +#ifndef __ASM_CSKY_SYSCALLS_H +#define __ASM_CSKY_SYSCALLS_H + +#include + +long sys_cacheflush(void __user *, unsigned long, int); + +long sys_set_thread_area(unsigned long addr); + +long sys_csky_fadvise64_64(int fd, int advice, loff_t offset, loff_t len); + +#endif /* __ASM_CSKY_SYSCALLS_H */ diff --git a/arch/csky/include/uapi/asm/unistd.h b/arch/csky/include/uapi/asm/unistd.h new file mode 100644 index 000..16ed71e --- /dev/null +++ b/arch/csky/include/uapi/asm/unistd.h @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. + +#define __ARCH_WANT_SYS_CLONE +#include + +#define __NR_set_thread_area (__NR_arch_specific_syscall + 0) +__SYSCALL(__NR_set_thread_area, sys_set_thread_area) +#define __NR_cacheflush(__NR_arch_specific_syscall + 4) +__SYSCALL(__NR_cacheflush, sys_cacheflush) diff --git a/arch/csky/kernel/syscall.c b/arch/csky/kernel/syscall.c new file mode 100644 index 000..3d30e58 --- /dev/null +++ b/arch/csky/kernel/syscall.c @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. + +#include + +SYSCALL_DEFINE1(set_thread_area, unsigned long, addr) +{ + struct thread_info *ti = task_thread_info(current); + struct pt_regs *reg = current_pt_regs(); + + reg->tls = addr; + ti->tp_value = addr; + + return 0; +} + +SYSCALL_DEFINE6(mmap2, + unsigned long, addr, + unsigned long, len, + unsigned long, prot, + unsigned long, flags, + unsigned long, fd, + off_t, offset) +{ + if (unlikely(offset & (~PAGE_MASK >> 12))) + return -EINVAL; + + return ksys_mmap_pgoff(addr, len, prot, flags, fd, + offset >> (PAGE_SHIFT - 12)); +} + +/* + * for abiv1 the 64bits args should be even th, So we need mov the advice + * forward. + */ +SYSCALL_DEFINE4(csky_fadvise64_64, + int, fd, + int, advice, + loff_t, offset, + loff_t, len) +{ + return ksys_fadvise64_64(fd, offset, len, advice); +}
[PATCH V7 06/20] csky: Cache and TLB routines
This patch adds cache and tlb sync codes for abiv1 & abiv2. Changelog: - tlb.h & cacheflush.h: fix flush_cache_range and tlb_start_vma of abiv1 in flush_cache_range(vma, ...). cache_wbinv_range() couldn't deal with vma->mm's asid for cache_flush_line and we use cache_wbinv_all() first. Wwe'll improve with cache_flush(vma, start, end) in future. For tlb_start_vma, we make it the same as other arch. - remove the abi/tlb.h Signed-off-by: Guo Ren --- arch/csky/abiv1/cacheflush.c | 52 arch/csky/abiv1/inc/abi/cacheflush.h | 49 arch/csky/abiv2/cacheflush.c | 60 ++ arch/csky/abiv2/inc/abi/cacheflush.h | 46 +++ arch/csky/include/asm/barrier.h | 49 arch/csky/include/asm/cache.h | 30 + arch/csky/include/asm/cacheflush.h| 9 ++ arch/csky/include/asm/io.h| 24 arch/csky/include/asm/tlb.h | 25 arch/csky/include/asm/tlbflush.h | 25 arch/csky/include/uapi/asm/cachectl.h | 13 ++ arch/csky/mm/cachev1.c| 125 +++ arch/csky/mm/cachev2.c| 78 arch/csky/mm/syscache.c | 32 + arch/csky/mm/tlb.c| 219 ++ 15 files changed, 836 insertions(+) create mode 100644 arch/csky/abiv1/cacheflush.c create mode 100644 arch/csky/abiv1/inc/abi/cacheflush.h create mode 100644 arch/csky/abiv2/cacheflush.c create mode 100644 arch/csky/abiv2/inc/abi/cacheflush.h create mode 100644 arch/csky/include/asm/barrier.h create mode 100644 arch/csky/include/asm/cache.h create mode 100644 arch/csky/include/asm/cacheflush.h create mode 100644 arch/csky/include/asm/io.h create mode 100644 arch/csky/include/asm/tlb.h create mode 100644 arch/csky/include/asm/tlbflush.h create mode 100644 arch/csky/include/uapi/asm/cachectl.h create mode 100644 arch/csky/mm/cachev1.c create mode 100644 arch/csky/mm/cachev2.c create mode 100644 arch/csky/mm/syscache.c create mode 100644 arch/csky/mm/tlb.c diff --git a/arch/csky/abiv1/cacheflush.c b/arch/csky/abiv1/cacheflush.c new file mode 100644 index 000..10af8b6 --- /dev/null +++ b/arch/csky/abiv1/cacheflush.c @@ -0,0 +1,52 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void flush_dcache_page(struct page *page) +{ + struct address_space *mapping = page_mapping(page); + unsigned long addr; + + if (mapping && !mapping_mapped(mapping)) { + set_bit(PG_arch_1, &(page)->flags); + return; + } + + /* +* We could delay the flush for the !page_mapping case too. But that +* case is for exec env/arg pages and those are %99 certainly going to +* get faulted into the tlb (and thus flushed) anyways. +*/ + addr = (unsigned long) page_address(page); + dcache_wb_range(addr, addr + PAGE_SIZE); +} + +void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, + pte_t *pte) +{ + unsigned long addr; + struct page *page; + unsigned long pfn; + + pfn = pte_pfn(*pte); + if (unlikely(!pfn_valid(pfn))) + return; + + page = pfn_to_page(pfn); + addr = (unsigned long) page_address(page); + + if (vma->vm_flags & VM_EXEC || + pages_do_alias(addr, address & PAGE_MASK)) + cache_wbinv_all(); + + clear_bit(PG_arch_1, &(page)->flags); +} diff --git a/arch/csky/abiv1/inc/abi/cacheflush.h b/arch/csky/abiv1/inc/abi/cacheflush.h new file mode 100644 index 000..5f663ae --- /dev/null +++ b/arch/csky/abiv1/inc/abi/cacheflush.h @@ -0,0 +1,49 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. + +#ifndef __ABI_CSKY_CACHEFLUSH_H +#define __ABI_CSKY_CACHEFLUSH_H + +#include +#include +#include + +#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1 +extern void flush_dcache_page(struct page *); + +#define flush_cache_mm(mm) cache_wbinv_all() +#define flush_cache_page(vma, page, pfn) cache_wbinv_all() +#define flush_cache_dup_mm(mm) cache_wbinv_all() + +/* + * if (current_mm != vma->mm) cache_wbinv_range(start, end) will be broken. + * Use cache_wbinv_all() here and need to be improved in future. + */ +#define flush_cache_range(vma, start, end) cache_wbinv_all() +#define flush_cache_vmap(start, end) cache_wbinv_range(start, end) +#define flush_cache_vunmap(start, end) cache_wbinv_range(start, end) + +#define flush_icache_page(vma, page) cache_wbinv_all() +#define flush_icache_range(start, end) cache_wbinv_range(start, end) + +#define flush_icache_user_range(vma, pg, adr, len) \ + cache_wbinv_range(adr, adr + len) + +#define
[PATCH V7 02/20] csky: defconfig
This patch adds csky defconfig. Signed-off-by: Guo Ren --- arch/csky/configs/defconfig | 61 + 1 file changed, 61 insertions(+) create mode 100644 arch/csky/configs/defconfig diff --git a/arch/csky/configs/defconfig b/arch/csky/configs/defconfig new file mode 100644 index 000..7ef4289 --- /dev/null +++ b/arch/csky/configs/defconfig @@ -0,0 +1,61 @@ +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_DEFAULT_HOSTNAME="csky" +# CONFIG_SWAP is not set +CONFIG_SYSVIPC=y +CONFIG_POSIX_MQUEUE=y +CONFIG_AUDIT=y +CONFIG_NO_HZ_IDLE=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_BSD_PROCESS_ACCT_V3=y +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +CONFIG_DEFAULT_DEADLINE=y +CONFIG_CPU_CK807=y +CONFIG_CPU_HAS_FPU=y +CONFIG_NET=y +CONFIG_PACKET=y +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=65536 +CONFIG_VT_HW_CONSOLE_BINDING=y +CONFIG_SERIAL_NONSTANDARD=y +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_OF_PLATFORM=y +CONFIG_TTY_PRINTK=y +# CONFIG_VGA_CONSOLE is not set +CONFIG_CSKY_MPTIMER=y +CONFIG_GX6605S_TIMER=y +CONFIG_PM_DEVFREQ=y +CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=y +CONFIG_DEVFREQ_GOV_PERFORMANCE=y +CONFIG_DEVFREQ_GOV_POWERSAVE=y +CONFIG_DEVFREQ_GOV_USERSPACE=y +CONFIG_GENERIC_PHY=y +CONFIG_EXT4_FS=y +CONFIG_FANOTIFY=y +CONFIG_QUOTA=y +CONFIG_FSCACHE=m +CONFIG_FSCACHE_STATS=y +CONFIG_CACHEFILES=m +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_UTF8=y +CONFIG_NTFS_FS=y +CONFIG_PROC_KCORE=y +CONFIG_PROC_CHILDREN=y +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +CONFIG_CONFIGFS_FS=y +CONFIG_CRAMFS=y +CONFIG_ROMFS_FS=y +CONFIG_NFS_FS=y +CONFIG_PRINTK_TIME=y +CONFIG_DEBUG_INFO=y +CONFIG_DEBUG_FS=y +CONFIG_MAGIC_SYSRQ=y -- 2.7.4
[PATCH V7 02/20] csky: defconfig
This patch adds csky defconfig. Signed-off-by: Guo Ren --- arch/csky/configs/defconfig | 61 + 1 file changed, 61 insertions(+) create mode 100644 arch/csky/configs/defconfig diff --git a/arch/csky/configs/defconfig b/arch/csky/configs/defconfig new file mode 100644 index 000..7ef4289 --- /dev/null +++ b/arch/csky/configs/defconfig @@ -0,0 +1,61 @@ +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_DEFAULT_HOSTNAME="csky" +# CONFIG_SWAP is not set +CONFIG_SYSVIPC=y +CONFIG_POSIX_MQUEUE=y +CONFIG_AUDIT=y +CONFIG_NO_HZ_IDLE=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_BSD_PROCESS_ACCT_V3=y +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +CONFIG_DEFAULT_DEADLINE=y +CONFIG_CPU_CK807=y +CONFIG_CPU_HAS_FPU=y +CONFIG_NET=y +CONFIG_PACKET=y +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=65536 +CONFIG_VT_HW_CONSOLE_BINDING=y +CONFIG_SERIAL_NONSTANDARD=y +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_OF_PLATFORM=y +CONFIG_TTY_PRINTK=y +# CONFIG_VGA_CONSOLE is not set +CONFIG_CSKY_MPTIMER=y +CONFIG_GX6605S_TIMER=y +CONFIG_PM_DEVFREQ=y +CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=y +CONFIG_DEVFREQ_GOV_PERFORMANCE=y +CONFIG_DEVFREQ_GOV_POWERSAVE=y +CONFIG_DEVFREQ_GOV_USERSPACE=y +CONFIG_GENERIC_PHY=y +CONFIG_EXT4_FS=y +CONFIG_FANOTIFY=y +CONFIG_QUOTA=y +CONFIG_FSCACHE=m +CONFIG_FSCACHE_STATS=y +CONFIG_CACHEFILES=m +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_UTF8=y +CONFIG_NTFS_FS=y +CONFIG_PROC_KCORE=y +CONFIG_PROC_CHILDREN=y +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +CONFIG_CONFIGFS_FS=y +CONFIG_CRAMFS=y +CONFIG_ROMFS_FS=y +CONFIG_NFS_FS=y +CONFIG_PRINTK_TIME=y +CONFIG_DEBUG_INFO=y +CONFIG_DEBUG_FS=y +CONFIG_MAGIC_SYSRQ=y -- 2.7.4
linux-next: build warning after merge of the crypto tree
Hi Herbert, After merging the crypto tree, today's linux-next build (powerpc allyesconfig) produced this warning: drivers/crypto/cavium/nitrox/nitrox_debugfs.c: In function 'stats_show': drivers/crypto/cavium/nitrox/nitrox_debugfs.c:62:30: warning: format '%lld' expects argument of type 'long long int', but argument 3 has type 'long int' [-Wformat=] seq_printf(s, " Posted: %lld\n", atomic64_read(>stats.posted)); ~~~^ ~~ %ld drivers/crypto/cavium/nitrox/nitrox_debugfs.c:63:33: warning: format '%lld' expects argument of type 'long long int', but argument 3 has type 'long int' [-Wformat=] seq_printf(s, " Completed: %lld\n", ~~~^ %ld atomic64_read(>stats.completed)); ~ drivers/crypto/cavium/nitrox/nitrox_debugfs.c:65:31: warning: format '%lld' expects argument of type 'long long int', but argument 3 has type 'long int' [-Wformat=] seq_printf(s, " Dropped: %lld\n", atomic64_read(>stats.dropped)); ~~~^ ~~~ %ld Introduced by commit 2a8780be9c26 ("crypto: cavium/nitrox - updated debugfs information.") -- Cheers, Stephen Rothwell pgpWq5TyA7n7S.pgp Description: OpenPGP digital signature
linux-next: build warning after merge of the crypto tree
Hi Herbert, After merging the crypto tree, today's linux-next build (powerpc allyesconfig) produced this warning: drivers/crypto/cavium/nitrox/nitrox_debugfs.c: In function 'stats_show': drivers/crypto/cavium/nitrox/nitrox_debugfs.c:62:30: warning: format '%lld' expects argument of type 'long long int', but argument 3 has type 'long int' [-Wformat=] seq_printf(s, " Posted: %lld\n", atomic64_read(>stats.posted)); ~~~^ ~~ %ld drivers/crypto/cavium/nitrox/nitrox_debugfs.c:63:33: warning: format '%lld' expects argument of type 'long long int', but argument 3 has type 'long int' [-Wformat=] seq_printf(s, " Completed: %lld\n", ~~~^ %ld atomic64_read(>stats.completed)); ~ drivers/crypto/cavium/nitrox/nitrox_debugfs.c:65:31: warning: format '%lld' expects argument of type 'long long int', but argument 3 has type 'long int' [-Wformat=] seq_printf(s, " Dropped: %lld\n", atomic64_read(>stats.dropped)); ~~~^ ~~~ %ld Introduced by commit 2a8780be9c26 ("crypto: cavium/nitrox - updated debugfs information.") -- Cheers, Stephen Rothwell pgpWq5TyA7n7S.pgp Description: OpenPGP digital signature
Re: [PATCH 0/5] ti_am335x_tsc: Enable wakeup capability
On Friday 28 September 2018 11:42 AM, Vignesh R wrote: > Hi Lee, > > On Wednesday 25 July 2018 10:56 AM, Lee Jones wrote: > [...] Vignesh R (5): mfd: ti_am335x_tscadc: Don't mark TSCADC MFD as wakeup capable Input: ti_am335x_tsc: Mark TSC device as wakeup source mfd: ti_am335x_tscadc: Keep ADC interface on if child is wakeup capable iio: adc: ti_am335x_adc: Disable ADC during suspend unconditionally Input: ti_am335x_tsc: Mark IRQ as wakeup capable drivers/iio/adc/ti_am335x_adc.c | 12 drivers/input/touchscreen/ti_am335x_tsc.c | 22 +- drivers/mfd/ti_am335x_tscadc.c| 14 +- 3 files changed, 34 insertions(+), 14 deletions(-) >>> >>> Gentle ping... Could you review/pick this series? MFD amd IIO bits are >>> already ACKed >> >> MFD patches are reviewed "for my own reference" meaning that we >> haven't yet agreed on a merge plan yet. > > I think this series makes sense to be pushed through a single tree as > opposed to being spread between 3, even if it could technically be > possible. It looks like Jonathan is fine with going it through either > his or some other tree, I am fine with it going through MFD. I'm happy either way. >>> Thanks Dmitry, Jonathan and Lee Jones! >>> >>> Could this be applied to one of the trees now? MFD perhaps? >> >> It'll be applied, when it's applied. ;) > > I see that this series was not picked up for v4.19. Could you consider > this series for v4.20? Patches apply cleanly against linux-next. > > Gentle ping... -- Regards Vignesh
Re: [PATCH 0/5] ti_am335x_tsc: Enable wakeup capability
On Friday 28 September 2018 11:42 AM, Vignesh R wrote: > Hi Lee, > > On Wednesday 25 July 2018 10:56 AM, Lee Jones wrote: > [...] Vignesh R (5): mfd: ti_am335x_tscadc: Don't mark TSCADC MFD as wakeup capable Input: ti_am335x_tsc: Mark TSC device as wakeup source mfd: ti_am335x_tscadc: Keep ADC interface on if child is wakeup capable iio: adc: ti_am335x_adc: Disable ADC during suspend unconditionally Input: ti_am335x_tsc: Mark IRQ as wakeup capable drivers/iio/adc/ti_am335x_adc.c | 12 drivers/input/touchscreen/ti_am335x_tsc.c | 22 +- drivers/mfd/ti_am335x_tscadc.c| 14 +- 3 files changed, 34 insertions(+), 14 deletions(-) >>> >>> Gentle ping... Could you review/pick this series? MFD amd IIO bits are >>> already ACKed >> >> MFD patches are reviewed "for my own reference" meaning that we >> haven't yet agreed on a merge plan yet. > > I think this series makes sense to be pushed through a single tree as > opposed to being spread between 3, even if it could technically be > possible. It looks like Jonathan is fine with going it through either > his or some other tree, I am fine with it going through MFD. I'm happy either way. >>> Thanks Dmitry, Jonathan and Lee Jones! >>> >>> Could this be applied to one of the trees now? MFD perhaps? >> >> It'll be applied, when it's applied. ;) > > I see that this series was not picked up for v4.19. Could you consider > this series for v4.20? Patches apply cleanly against linux-next. > > Gentle ping... -- Regards Vignesh
[PATCH v2] HID: i2c-hid: Add a small delay after sleep command for Raydium touchpanel
Raydium touchpanel (2386:4B33) sometimes does not work in desktop session although it works in display manager. During user logging, the display manager exits, close the HID device, then the device gets runtime suspended and powered off. The desktop session begins shortly after, opens the HID device, then the device gets runtime resumed and powered on. If the trasition from display manager to desktop sesesion is fast, the touchpanel cannot switch from powered off to powered on in short timeframe. So add a small delay to workaround the issue. Signed-off-by: Kai-Heng Feng --- v2: - Use quirk to only match affected touchpanel - Only delay the next power on if the time hasn't elapsed drivers/hid/hid-ids.h | 3 +++ drivers/hid/i2c-hid/i2c-hid-core.c | 19 +++ 2 files changed, 22 insertions(+) diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 16342188df19..c1b5f03eb630 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -926,6 +926,9 @@ #define USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_30030x3003 #define USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_30080x3008 +#define I2C_VENDOR_ID_RAYDIUM 0x2386 +#define I2C_PRODUCT_ID_RAYDIUM_4B330x4b33 + #define USB_VENDOR_ID_RAZER0x1532 #define USB_DEVICE_ID_RAZER_BLADE_14 0x011D diff --git a/drivers/hid/i2c-hid/i2c-hid-core.c b/drivers/hid/i2c-hid/i2c-hid-core.c index 4aab96cf0818..3cde7c1b9c33 100644 --- a/drivers/hid/i2c-hid/i2c-hid-core.c +++ b/drivers/hid/i2c-hid/i2c-hid-core.c @@ -49,6 +49,7 @@ #define I2C_HID_QUIRK_SET_PWR_WAKEUP_DEV BIT(0) #define I2C_HID_QUIRK_NO_IRQ_AFTER_RESET BIT(1) #define I2C_HID_QUIRK_NO_RUNTIME_PMBIT(2) +#define I2C_HID_QUIRK_DELAY_AFTER_SLEEPBIT(3) /* flags */ #define I2C_HID_STARTED0 @@ -158,6 +159,8 @@ struct i2c_hid { boolirq_wake_enabled; struct mutexreset_lock; + + unsigned long sleep_delay; }; static const struct i2c_hid_quirks { @@ -172,6 +175,8 @@ static const struct i2c_hid_quirks { { I2C_VENDOR_ID_HANTICK, I2C_PRODUCT_ID_HANTICK_5288, I2C_HID_QUIRK_NO_IRQ_AFTER_RESET | I2C_HID_QUIRK_NO_RUNTIME_PM }, + { I2C_VENDOR_ID_RAYDIUM, I2C_PRODUCT_ID_RAYDIUM_4B33, + I2C_HID_QUIRK_DELAY_AFTER_SLEEP }, { 0, 0 } }; @@ -387,6 +392,7 @@ static int i2c_hid_set_power(struct i2c_client *client, int power_state) { struct i2c_hid *ihid = i2c_get_clientdata(client); int ret; + unsigned long now, delay; i2c_hid_dbg(ihid, "%s\n", __func__); @@ -404,9 +410,22 @@ static int i2c_hid_set_power(struct i2c_client *client, int power_state) goto set_pwr_exit; } + if (ihid->quirks & I2C_HID_QUIRK_DELAY_AFTER_SLEEP && + power_state == I2C_HID_PWR_ON) { + now = jiffies; + if (time_after(ihid->sleep_delay, now)) { + delay = jiffies_to_usecs(ihid->sleep_delay - now); + usleep_range(delay, delay + 1); + } + } + ret = __i2c_hid_command(client, _set_power_cmd, power_state, 0, NULL, 0, NULL, 0); + if (ihid->quirks & I2C_HID_QUIRK_DELAY_AFTER_SLEEP && + power_state == I2C_HID_PWR_SLEEP) + ihid->sleep_delay = jiffies + msecs_to_jiffies(20); + if (ret) dev_err(>dev, "failed to change power setting.\n"); -- 2.17.1
[PATCH v2] HID: i2c-hid: Add a small delay after sleep command for Raydium touchpanel
Raydium touchpanel (2386:4B33) sometimes does not work in desktop session although it works in display manager. During user logging, the display manager exits, close the HID device, then the device gets runtime suspended and powered off. The desktop session begins shortly after, opens the HID device, then the device gets runtime resumed and powered on. If the trasition from display manager to desktop sesesion is fast, the touchpanel cannot switch from powered off to powered on in short timeframe. So add a small delay to workaround the issue. Signed-off-by: Kai-Heng Feng --- v2: - Use quirk to only match affected touchpanel - Only delay the next power on if the time hasn't elapsed drivers/hid/hid-ids.h | 3 +++ drivers/hid/i2c-hid/i2c-hid-core.c | 19 +++ 2 files changed, 22 insertions(+) diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 16342188df19..c1b5f03eb630 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -926,6 +926,9 @@ #define USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_30030x3003 #define USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_30080x3008 +#define I2C_VENDOR_ID_RAYDIUM 0x2386 +#define I2C_PRODUCT_ID_RAYDIUM_4B330x4b33 + #define USB_VENDOR_ID_RAZER0x1532 #define USB_DEVICE_ID_RAZER_BLADE_14 0x011D diff --git a/drivers/hid/i2c-hid/i2c-hid-core.c b/drivers/hid/i2c-hid/i2c-hid-core.c index 4aab96cf0818..3cde7c1b9c33 100644 --- a/drivers/hid/i2c-hid/i2c-hid-core.c +++ b/drivers/hid/i2c-hid/i2c-hid-core.c @@ -49,6 +49,7 @@ #define I2C_HID_QUIRK_SET_PWR_WAKEUP_DEV BIT(0) #define I2C_HID_QUIRK_NO_IRQ_AFTER_RESET BIT(1) #define I2C_HID_QUIRK_NO_RUNTIME_PMBIT(2) +#define I2C_HID_QUIRK_DELAY_AFTER_SLEEPBIT(3) /* flags */ #define I2C_HID_STARTED0 @@ -158,6 +159,8 @@ struct i2c_hid { boolirq_wake_enabled; struct mutexreset_lock; + + unsigned long sleep_delay; }; static const struct i2c_hid_quirks { @@ -172,6 +175,8 @@ static const struct i2c_hid_quirks { { I2C_VENDOR_ID_HANTICK, I2C_PRODUCT_ID_HANTICK_5288, I2C_HID_QUIRK_NO_IRQ_AFTER_RESET | I2C_HID_QUIRK_NO_RUNTIME_PM }, + { I2C_VENDOR_ID_RAYDIUM, I2C_PRODUCT_ID_RAYDIUM_4B33, + I2C_HID_QUIRK_DELAY_AFTER_SLEEP }, { 0, 0 } }; @@ -387,6 +392,7 @@ static int i2c_hid_set_power(struct i2c_client *client, int power_state) { struct i2c_hid *ihid = i2c_get_clientdata(client); int ret; + unsigned long now, delay; i2c_hid_dbg(ihid, "%s\n", __func__); @@ -404,9 +410,22 @@ static int i2c_hid_set_power(struct i2c_client *client, int power_state) goto set_pwr_exit; } + if (ihid->quirks & I2C_HID_QUIRK_DELAY_AFTER_SLEEP && + power_state == I2C_HID_PWR_ON) { + now = jiffies; + if (time_after(ihid->sleep_delay, now)) { + delay = jiffies_to_usecs(ihid->sleep_delay - now); + usleep_range(delay, delay + 1); + } + } + ret = __i2c_hid_command(client, _set_power_cmd, power_state, 0, NULL, 0, NULL, 0); + if (ihid->quirks & I2C_HID_QUIRK_DELAY_AFTER_SLEEP && + power_state == I2C_HID_PWR_SLEEP) + ihid->sleep_delay = jiffies + msecs_to_jiffies(20); + if (ret) dev_err(>dev, "failed to change power setting.\n"); -- 2.17.1
[PATCH] traps:Recover undefined user instruction on ARM
From: Rohit Thapliyal During user undefined instruction exception, the arm exception handler currently results in application crash through SIGILL. The bad instruction can be due to ddr/hardware issue. For such cases, exception trap handler could try to recover the corrupted text by clearing pagetable entry of undefined instruction pc and trying to fetch the instruction opcode by generating major page fault. Resulting in loading the page with correct instruction from mapped file. If there is no error in root filesystem i.e. the opcode is intact in file, then filemap fault shall be able to recover the instruction and continue execution normally instead of crashing. Signed-off-by: Rohit Thapliyal Signed-off-by: Manjeet Pawar --- arch/arm/kernel/traps.c | 100 +++- 1 file changed, 90 insertions(+), 10 deletions(-) diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index badf02c..d971834 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -51,6 +52,9 @@ }; void *vectors_page; +#define MAX_UNDEF_RECOVERY_ATTEMPT NR_CPUS +static DEFINE_RATELIMIT_STATE(undef_recov_rs, 10 * HZ, NR_CPUS); +static int undef_recovery_attempt; #ifdef CONFIG_DEBUG_USER unsigned int user_debug; @@ -435,14 +439,9 @@ int call_undef_hook(struct pt_regs *regs, unsigned int instr) return fn ? fn(regs, instr) : 1; } -asmlinkage void do_undefinstr(struct pt_regs *regs) +static unsigned int getInstr(void __user *pc, struct pt_regs *regs) { - unsigned int instr; - siginfo_t info; - void __user *pc; - - clear_siginfo(); - pc = (void __user *)instruction_pointer(regs); + unsigned int instr = 0; if (processor_mode(regs) == SVC_MODE) { #ifdef CONFIG_THUMB2_KERNEL @@ -472,11 +471,32 @@ asmlinkage void do_undefinstr(struct pt_regs *regs) goto die_sig; instr = __mem_to_opcode_arm(instr); } +die_sig: + return instr; +} + +asmlinkage void __exception do_undefinstr(struct pt_regs *regs) +{ + unsigned int instr, instr2; + siginfo_t info; + void __user *pc; + unsigned long addr; + struct mm_struct *mm; + struct vm_area_struct *vma; + pgd_t *pgd; + pud_t *pud; + pmd_t *pmd; + pte_t *pte; + spinlock_t *ptl; + clear_siginfo(); - if (call_undef_hook(regs, instr) == 0) + pc = (void __user *)instruction_pointer(regs); + + instr = getInstr(pc, regs); + + if (instr && call_undef_hook(regs, instr) == 0) return; -die_sig: #ifdef CONFIG_DEBUG_USER if (user_debug & UDBG_UNDEFINED) { pr_info("%s (%d): undefined instruction: pc=%p\n", @@ -485,7 +505,67 @@ asmlinkage void do_undefinstr(struct pt_regs *regs) dump_instr(KERN_INFO, regs); } #endif - + /* Trying to recover an invalid userspace instruction from here */ + if ((undef_recovery_attempt < MAX_UNDEF_RECOVERY_ATTEMPT) && __ratelimit(_recov_rs)) { + addr = (unsigned long) pc; + if (processor_mode(regs) == USR_MODE) { + struct page *page = NULL; + + mm = current->mm; + vma = find_vma(mm, (unsigned long)pc); + if (!vma) + goto fail_recovery; + + if (!vma->vm_file) + goto fail_recovery; + + dump_instr(KERN_ALERT, regs); + down_write(>mmap_sem); + /* Check first, just in case, recovery already done by some other thread simultaneously */ + flush_cache_range(vma, vma->vm_start, vma->vm_end); + instr2 = getInstr(pc, regs); + if (instr != instr2) { + up_write(>mmap_sem); + return; + } + pgd = pgd_offset(vma->vm_mm, addr); + pud = pud_offset(pgd, addr); + if (!pud_present(*pud)) { + up_write(>mmap_sem); + goto fail_recovery; + } + pmd = pmd_offset(pud, addr); + if (!pmd_present(*pmd)) { + up_write(>mmap_sem); + goto fail_recovery; + } + pte = pte_offset_map_lock(mm, pmd, addr, ); + if (!pte_present(*pte)) { + pte_unmap_unlock(pte, ptl); + up_write(>mmap_sem); + goto fail_recovery; + } + page = pte_page(*pte); + +
[PATCH] traps:Recover undefined user instruction on ARM
From: Rohit Thapliyal During user undefined instruction exception, the arm exception handler currently results in application crash through SIGILL. The bad instruction can be due to ddr/hardware issue. For such cases, exception trap handler could try to recover the corrupted text by clearing pagetable entry of undefined instruction pc and trying to fetch the instruction opcode by generating major page fault. Resulting in loading the page with correct instruction from mapped file. If there is no error in root filesystem i.e. the opcode is intact in file, then filemap fault shall be able to recover the instruction and continue execution normally instead of crashing. Signed-off-by: Rohit Thapliyal Signed-off-by: Manjeet Pawar --- arch/arm/kernel/traps.c | 100 +++- 1 file changed, 90 insertions(+), 10 deletions(-) diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index badf02c..d971834 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -51,6 +52,9 @@ }; void *vectors_page; +#define MAX_UNDEF_RECOVERY_ATTEMPT NR_CPUS +static DEFINE_RATELIMIT_STATE(undef_recov_rs, 10 * HZ, NR_CPUS); +static int undef_recovery_attempt; #ifdef CONFIG_DEBUG_USER unsigned int user_debug; @@ -435,14 +439,9 @@ int call_undef_hook(struct pt_regs *regs, unsigned int instr) return fn ? fn(regs, instr) : 1; } -asmlinkage void do_undefinstr(struct pt_regs *regs) +static unsigned int getInstr(void __user *pc, struct pt_regs *regs) { - unsigned int instr; - siginfo_t info; - void __user *pc; - - clear_siginfo(); - pc = (void __user *)instruction_pointer(regs); + unsigned int instr = 0; if (processor_mode(regs) == SVC_MODE) { #ifdef CONFIG_THUMB2_KERNEL @@ -472,11 +471,32 @@ asmlinkage void do_undefinstr(struct pt_regs *regs) goto die_sig; instr = __mem_to_opcode_arm(instr); } +die_sig: + return instr; +} + +asmlinkage void __exception do_undefinstr(struct pt_regs *regs) +{ + unsigned int instr, instr2; + siginfo_t info; + void __user *pc; + unsigned long addr; + struct mm_struct *mm; + struct vm_area_struct *vma; + pgd_t *pgd; + pud_t *pud; + pmd_t *pmd; + pte_t *pte; + spinlock_t *ptl; + clear_siginfo(); - if (call_undef_hook(regs, instr) == 0) + pc = (void __user *)instruction_pointer(regs); + + instr = getInstr(pc, regs); + + if (instr && call_undef_hook(regs, instr) == 0) return; -die_sig: #ifdef CONFIG_DEBUG_USER if (user_debug & UDBG_UNDEFINED) { pr_info("%s (%d): undefined instruction: pc=%p\n", @@ -485,7 +505,67 @@ asmlinkage void do_undefinstr(struct pt_regs *regs) dump_instr(KERN_INFO, regs); } #endif - + /* Trying to recover an invalid userspace instruction from here */ + if ((undef_recovery_attempt < MAX_UNDEF_RECOVERY_ATTEMPT) && __ratelimit(_recov_rs)) { + addr = (unsigned long) pc; + if (processor_mode(regs) == USR_MODE) { + struct page *page = NULL; + + mm = current->mm; + vma = find_vma(mm, (unsigned long)pc); + if (!vma) + goto fail_recovery; + + if (!vma->vm_file) + goto fail_recovery; + + dump_instr(KERN_ALERT, regs); + down_write(>mmap_sem); + /* Check first, just in case, recovery already done by some other thread simultaneously */ + flush_cache_range(vma, vma->vm_start, vma->vm_end); + instr2 = getInstr(pc, regs); + if (instr != instr2) { + up_write(>mmap_sem); + return; + } + pgd = pgd_offset(vma->vm_mm, addr); + pud = pud_offset(pgd, addr); + if (!pud_present(*pud)) { + up_write(>mmap_sem); + goto fail_recovery; + } + pmd = pmd_offset(pud, addr); + if (!pmd_present(*pmd)) { + up_write(>mmap_sem); + goto fail_recovery; + } + pte = pte_offset_map_lock(mm, pmd, addr, ); + if (!pte_present(*pte)) { + pte_unmap_unlock(pte, ptl); + up_write(>mmap_sem); + goto fail_recovery; + } + page = pte_page(*pte); + +
Re: [PATCH v3 3/7] drivers: parisc: Avoids building driver if CONFIG_PARISC is disabled
On Thu, 4 Oct 2018, Leonardo Bras wrote: > ... > But, why these chosen Makefiles, and not all of them? I think that inconsistency is untenable. If nothing else, it means your changes will get broken by other people who also apply constraints inconsistently. I think you need to consider what happens when you apply this regime tree-wide. Either that or explain why it would make sense to build e.g. drivers/s390 but not drivers/s390/net. --
Re: [PATCH v3 3/7] drivers: parisc: Avoids building driver if CONFIG_PARISC is disabled
On Thu, 4 Oct 2018, Leonardo Bras wrote: > ... > But, why these chosen Makefiles, and not all of them? I think that inconsistency is untenable. If nothing else, it means your changes will get broken by other people who also apply constraints inconsistently. I think you need to consider what happens when you apply this regime tree-wide. Either that or explain why it would make sense to build e.g. drivers/s390 but not drivers/s390/net. --
Re: [PATCH] Input: uinput - add a schedule point in uinput_inject_events()
On Thu, Oct 04, 2018 at 05:54:32PM -0700, Dmitry Torokhov wrote: > Large writes to uinput interface may cause rcu stalls. Let's add > cond_resched() to the loop to avoid this. > > Signed-off-by: Dmitry Torokhov Reviewed-by: Paul E. McKenney > --- > drivers/input/misc/uinput.c | 1 + > 1 file changed, 1 insertion(+) > > diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c > index eb14ddf69346..8ec483e8688b 100644 > --- a/drivers/input/misc/uinput.c > +++ b/drivers/input/misc/uinput.c > @@ -598,6 +598,7 @@ static ssize_t uinput_inject_events(struct uinput_device > *udev, > > input_event(udev->dev, ev.type, ev.code, ev.value); > bytes += input_event_size(); > + cond_resched(); > } > > return bytes; > -- > 2.19.0.605.g01d371f741-goog > > > -- > Dmitry >
Re: [PATCH] Input: uinput - add a schedule point in uinput_inject_events()
On Thu, Oct 04, 2018 at 05:54:32PM -0700, Dmitry Torokhov wrote: > Large writes to uinput interface may cause rcu stalls. Let's add > cond_resched() to the loop to avoid this. > > Signed-off-by: Dmitry Torokhov Reviewed-by: Paul E. McKenney > --- > drivers/input/misc/uinput.c | 1 + > 1 file changed, 1 insertion(+) > > diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c > index eb14ddf69346..8ec483e8688b 100644 > --- a/drivers/input/misc/uinput.c > +++ b/drivers/input/misc/uinput.c > @@ -598,6 +598,7 @@ static ssize_t uinput_inject_events(struct uinput_device > *udev, > > input_event(udev->dev, ev.type, ev.code, ev.value); > bytes += input_event_size(); > + cond_resched(); > } > > return bytes; > -- > 2.19.0.605.g01d371f741-goog > > > -- > Dmitry >
Re: [PATCH] Input: evdev - add a schedule point in evdev_write()
On Thu, Oct 04, 2018 at 05:53:59PM -0700, Dmitry Torokhov wrote: > Large writes to evdev interface may cause rcu stalls. Let's add > cond_resched() to the loop to avoid this. > > Signed-off-by: Dmitry Torokhov Reviewed-by: Paul E. McKenney > --- > drivers/input/evdev.c | 1 + > 1 file changed, 1 insertion(+) > > diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c > index 370206f987f9..f48369d6f3a0 100644 > --- a/drivers/input/evdev.c > +++ b/drivers/input/evdev.c > @@ -564,6 +564,7 @@ static ssize_t evdev_write(struct file *file, const char > __user *buffer, > > input_inject_event(>handle, > event.type, event.code, event.value); > + cond_resched(); > } > > out: > -- > 2.19.0.605.g01d371f741-goog > > > -- > Dmitry >
Re: [PATCH] Input: evdev - add a schedule point in evdev_write()
On Thu, Oct 04, 2018 at 05:53:59PM -0700, Dmitry Torokhov wrote: > Large writes to evdev interface may cause rcu stalls. Let's add > cond_resched() to the loop to avoid this. > > Signed-off-by: Dmitry Torokhov Reviewed-by: Paul E. McKenney > --- > drivers/input/evdev.c | 1 + > 1 file changed, 1 insertion(+) > > diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c > index 370206f987f9..f48369d6f3a0 100644 > --- a/drivers/input/evdev.c > +++ b/drivers/input/evdev.c > @@ -564,6 +564,7 @@ static ssize_t evdev_write(struct file *file, const char > __user *buffer, > > input_inject_event(>handle, > event.type, event.code, event.value); > + cond_resched(); > } > > out: > -- > 2.19.0.605.g01d371f741-goog > > > -- > Dmitry >
Re: [PATCH - resend] VFS: use synchronize_rcu_expedited() in namespace_unlock()
On Fri, Oct 05, 2018 at 02:40:02AM +0100, Al Viro wrote: > On Fri, Oct 05, 2018 at 11:27:37AM +1000, NeilBrown wrote: > > > > The synchronize_rcu() in namespace_unlock() is called every time > > a filesystem is unmounted. If a great many filesystems are mounted, > > this can cause a noticable slow-down in, for example, system shutdown. > > > > The sequence: > > mkdir -p /tmp/Mtest/{0..5000} > > time for i in /tmp/Mtest/*; do mount -t tmpfs tmpfs $i ; done > > time umount /tmp/Mtest/* > > > > on a 4-cpu VM can report 8 seconds to mount the tmpfs filesystems, and > > 100 seconds to unmount them. > > > > Boot the same VM with 1 CPU and it takes 18 seconds to mount the > > tmpfs filesystems, but only 36 to unmount. > > > > If we change the synchronize_rcu() to synchronize_rcu_expedited() > > the umount time on a 4-cpu VM drop to 0.6 seconds > > > > I think this 200-fold speed up is worth the slightly high system > > impact of using synchronize_rcu_expedited(). > > > > Acked-by: Paul E. McKenney (from general rcu > > perspective) > > Signed-off-by: NeilBrown > > --- > > > > I posted this last October, then again last November (cc:ing Linus) > > Paul is happy enough with it, but no other response. > > I'm hoping it can get applied this time > > Umm... IIRC, the last one got sidetracked on the other thing in the series... > that was s_anon stuff. I can live with this one; FWIW, what kind > of load would trigger the impact of the change? Paul? You lost me with "what kind of load would trigger the impact of the change?", but if you are asking about the downside, that would be IPIs sent from each call to synchronize_rcu_expedited(). But people with things like real-time workloads that therefore don't like those IPIs have a number of options: 1. Boot with rcupdate.rcu_normal=1, which converts all calls to synchronize_rcu_expedited() to synchronize_rcu(). This of course loses the performance gain, but this can be a good tradeoff for real-time workloads. 2. Build with CONFIG_NO_HZ_FULL=y and boot with nohz_full= to cover the CPUs running your real-time workload. Then as long as there is only one runnable usermode task per nohz_full CPU, synchronize_rcu_expedited() will avoid sending IPIs to any of the nohz_full CPUs. 3. Don't do unmounts while your real-time application is running. Probably other options as well, but those are the ones that come immediately to mind. If I missed the point of your question, please help me understand what you are asking for. Thanx, Paul
Re: [PATCH - resend] VFS: use synchronize_rcu_expedited() in namespace_unlock()
On Fri, Oct 05, 2018 at 02:40:02AM +0100, Al Viro wrote: > On Fri, Oct 05, 2018 at 11:27:37AM +1000, NeilBrown wrote: > > > > The synchronize_rcu() in namespace_unlock() is called every time > > a filesystem is unmounted. If a great many filesystems are mounted, > > this can cause a noticable slow-down in, for example, system shutdown. > > > > The sequence: > > mkdir -p /tmp/Mtest/{0..5000} > > time for i in /tmp/Mtest/*; do mount -t tmpfs tmpfs $i ; done > > time umount /tmp/Mtest/* > > > > on a 4-cpu VM can report 8 seconds to mount the tmpfs filesystems, and > > 100 seconds to unmount them. > > > > Boot the same VM with 1 CPU and it takes 18 seconds to mount the > > tmpfs filesystems, but only 36 to unmount. > > > > If we change the synchronize_rcu() to synchronize_rcu_expedited() > > the umount time on a 4-cpu VM drop to 0.6 seconds > > > > I think this 200-fold speed up is worth the slightly high system > > impact of using synchronize_rcu_expedited(). > > > > Acked-by: Paul E. McKenney (from general rcu > > perspective) > > Signed-off-by: NeilBrown > > --- > > > > I posted this last October, then again last November (cc:ing Linus) > > Paul is happy enough with it, but no other response. > > I'm hoping it can get applied this time > > Umm... IIRC, the last one got sidetracked on the other thing in the series... > that was s_anon stuff. I can live with this one; FWIW, what kind > of load would trigger the impact of the change? Paul? You lost me with "what kind of load would trigger the impact of the change?", but if you are asking about the downside, that would be IPIs sent from each call to synchronize_rcu_expedited(). But people with things like real-time workloads that therefore don't like those IPIs have a number of options: 1. Boot with rcupdate.rcu_normal=1, which converts all calls to synchronize_rcu_expedited() to synchronize_rcu(). This of course loses the performance gain, but this can be a good tradeoff for real-time workloads. 2. Build with CONFIG_NO_HZ_FULL=y and boot with nohz_full= to cover the CPUs running your real-time workload. Then as long as there is only one runnable usermode task per nohz_full CPU, synchronize_rcu_expedited() will avoid sending IPIs to any of the nohz_full CPUs. 3. Don't do unmounts while your real-time application is running. Probably other options as well, but those are the ones that come immediately to mind. If I missed the point of your question, please help me understand what you are asking for. Thanx, Paul
[PATCH v2 2/3] mm: introduce put_user_page[s](), placeholder versions
From: John Hubbard Introduces put_user_page(), which simply calls put_page(). This provides a way to update all get_user_pages*() callers, so that they call put_user_page(), instead of put_page(). Also introduces put_user_pages(), and a few dirty/locked variations, as a replacement for release_pages(), for the same reasons. These may be used for subsequent performance improvements, via batching of pages to be released. This prepares for eventually fixing the problem described in [1], and is following a plan listed in [2], [3], [4]. [1] https://lwn.net/Articles/753027/ : "The Trouble with get_user_pages()" [2] https://lkml.kernel.org/r/20180709080554.21931-1-jhubb...@nvidia.com Proposed steps for fixing get_user_pages() + DMA problems. [3]https://lkml.kernel.org/r/20180710082100.mkdwngdv5kkrc...@quack2.suse.cz Bounce buffers (otherwise [2] is not really viable). [4] https://lkml.kernel.org/r/20181003162115.gg24...@quack2.suse.cz Follow-up discussions. CC: Matthew Wilcox CC: Michal Hocko CC: Christopher Lameter CC: Jason Gunthorpe CC: Dan Williams CC: Jan Kara CC: Al Viro CC: Jerome Glisse CC: Christoph Hellwig Signed-off-by: John Hubbard --- include/linux/mm.h | 42 -- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/include/linux/mm.h b/include/linux/mm.h index a61ebe8ad4ca..1a9aae7c659f 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -137,6 +137,8 @@ extern int overcommit_ratio_handler(struct ctl_table *, int, void __user *, size_t *, loff_t *); extern int overcommit_kbytes_handler(struct ctl_table *, int, void __user *, size_t *, loff_t *); +int set_page_dirty(struct page *page); +int set_page_dirty_lock(struct page *page); #define nth_page(page,n) pfn_to_page(page_to_pfn((page)) + (n)) @@ -943,6 +945,44 @@ static inline void put_page(struct page *page) __put_page(page); } +/* Placeholder version, until all get_user_pages*() callers are updated. */ +static inline void put_user_page(struct page *page) +{ + put_page(page); +} + +/* For get_user_pages*()-pinned pages, use these variants instead of + * release_pages(): + */ +static inline void put_user_pages_dirty(struct page **pages, + unsigned long npages) +{ + while (npages) { + set_page_dirty(pages[npages]); + put_user_page(pages[npages]); + --npages; + } +} + +static inline void put_user_pages_dirty_lock(struct page **pages, +unsigned long npages) +{ + while (npages) { + set_page_dirty_lock(pages[npages]); + put_user_page(pages[npages]); + --npages; + } +} + +static inline void put_user_pages(struct page **pages, + unsigned long npages) +{ + while (npages) { + put_user_page(pages[npages]); + --npages; + } +} + #if defined(CONFIG_SPARSEMEM) && !defined(CONFIG_SPARSEMEM_VMEMMAP) #define SECTION_IN_PAGE_FLAGS #endif @@ -1534,8 +1574,6 @@ int redirty_page_for_writepage(struct writeback_control *wbc, void account_page_dirtied(struct page *page, struct address_space *mapping); void account_page_cleaned(struct page *page, struct address_space *mapping, struct bdi_writeback *wb); -int set_page_dirty(struct page *page); -int set_page_dirty_lock(struct page *page); void __cancel_dirty_page(struct page *page); static inline void cancel_dirty_page(struct page *page) { -- 2.19.0
[PATCH v2 2/3] mm: introduce put_user_page[s](), placeholder versions
From: John Hubbard Introduces put_user_page(), which simply calls put_page(). This provides a way to update all get_user_pages*() callers, so that they call put_user_page(), instead of put_page(). Also introduces put_user_pages(), and a few dirty/locked variations, as a replacement for release_pages(), for the same reasons. These may be used for subsequent performance improvements, via batching of pages to be released. This prepares for eventually fixing the problem described in [1], and is following a plan listed in [2], [3], [4]. [1] https://lwn.net/Articles/753027/ : "The Trouble with get_user_pages()" [2] https://lkml.kernel.org/r/20180709080554.21931-1-jhubb...@nvidia.com Proposed steps for fixing get_user_pages() + DMA problems. [3]https://lkml.kernel.org/r/20180710082100.mkdwngdv5kkrc...@quack2.suse.cz Bounce buffers (otherwise [2] is not really viable). [4] https://lkml.kernel.org/r/20181003162115.gg24...@quack2.suse.cz Follow-up discussions. CC: Matthew Wilcox CC: Michal Hocko CC: Christopher Lameter CC: Jason Gunthorpe CC: Dan Williams CC: Jan Kara CC: Al Viro CC: Jerome Glisse CC: Christoph Hellwig Signed-off-by: John Hubbard --- include/linux/mm.h | 42 -- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/include/linux/mm.h b/include/linux/mm.h index a61ebe8ad4ca..1a9aae7c659f 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -137,6 +137,8 @@ extern int overcommit_ratio_handler(struct ctl_table *, int, void __user *, size_t *, loff_t *); extern int overcommit_kbytes_handler(struct ctl_table *, int, void __user *, size_t *, loff_t *); +int set_page_dirty(struct page *page); +int set_page_dirty_lock(struct page *page); #define nth_page(page,n) pfn_to_page(page_to_pfn((page)) + (n)) @@ -943,6 +945,44 @@ static inline void put_page(struct page *page) __put_page(page); } +/* Placeholder version, until all get_user_pages*() callers are updated. */ +static inline void put_user_page(struct page *page) +{ + put_page(page); +} + +/* For get_user_pages*()-pinned pages, use these variants instead of + * release_pages(): + */ +static inline void put_user_pages_dirty(struct page **pages, + unsigned long npages) +{ + while (npages) { + set_page_dirty(pages[npages]); + put_user_page(pages[npages]); + --npages; + } +} + +static inline void put_user_pages_dirty_lock(struct page **pages, +unsigned long npages) +{ + while (npages) { + set_page_dirty_lock(pages[npages]); + put_user_page(pages[npages]); + --npages; + } +} + +static inline void put_user_pages(struct page **pages, + unsigned long npages) +{ + while (npages) { + put_user_page(pages[npages]); + --npages; + } +} + #if defined(CONFIG_SPARSEMEM) && !defined(CONFIG_SPARSEMEM_VMEMMAP) #define SECTION_IN_PAGE_FLAGS #endif @@ -1534,8 +1574,6 @@ int redirty_page_for_writepage(struct writeback_control *wbc, void account_page_dirtied(struct page *page, struct address_space *mapping); void account_page_cleaned(struct page *page, struct address_space *mapping, struct bdi_writeback *wb); -int set_page_dirty(struct page *page); -int set_page_dirty_lock(struct page *page); void __cancel_dirty_page(struct page *page); static inline void cancel_dirty_page(struct page *page) { -- 2.19.0
[PATCH v2 3/3] infiniband/mm: convert to the new put_user_page[s]() calls
From: John Hubbard For code that retains pages via get_user_pages*(), release those pages via the new put_user_page(), instead of put_page(). This prepares for eventually fixing the problem described in [1], and is following a plan listed in [2], [3], [4]. [1] https://lwn.net/Articles/753027/ : "The Trouble with get_user_pages()" [2] https://lkml.kernel.org/r/20180709080554.21931-1-jhubb...@nvidia.com Proposed steps for fixing get_user_pages() + DMA problems. [3]https://lkml.kernel.org/r/20180710082100.mkdwngdv5kkrc...@quack2.suse.cz Bounce buffers (otherwise [2] is not really viable). [4] https://lkml.kernel.org/r/20181003162115.gg24...@quack2.suse.cz Follow-up discussions. CC: Doug Ledford CC: Jason Gunthorpe CC: Mike Marciniszyn CC: Dennis Dalessandro CC: Christian Benvenuti CC: linux-r...@vger.kernel.org CC: linux-kernel@vger.kernel.org CC: linux...@kvack.org Signed-off-by: John Hubbard --- drivers/infiniband/core/umem.c | 2 +- drivers/infiniband/core/umem_odp.c | 2 +- drivers/infiniband/hw/hfi1/user_pages.c | 11 --- drivers/infiniband/hw/mthca/mthca_memfree.c | 6 +++--- drivers/infiniband/hw/qib/qib_user_pages.c | 11 --- drivers/infiniband/hw/qib/qib_user_sdma.c | 8 drivers/infiniband/hw/usnic/usnic_uiom.c| 2 +- 7 files changed, 18 insertions(+), 24 deletions(-) diff --git a/drivers/infiniband/core/umem.c b/drivers/infiniband/core/umem.c index a41792dbae1f..9430d697cb9f 100644 --- a/drivers/infiniband/core/umem.c +++ b/drivers/infiniband/core/umem.c @@ -60,7 +60,7 @@ static void __ib_umem_release(struct ib_device *dev, struct ib_umem *umem, int d page = sg_page(sg); if (!PageDirty(page) && umem->writable && dirty) set_page_dirty_lock(page); - put_page(page); + put_user_page(page); } sg_free_table(>sg_head); diff --git a/drivers/infiniband/core/umem_odp.c b/drivers/infiniband/core/umem_odp.c index 6ec748eccff7..6227b89cf05c 100644 --- a/drivers/infiniband/core/umem_odp.c +++ b/drivers/infiniband/core/umem_odp.c @@ -717,7 +717,7 @@ int ib_umem_odp_map_dma_pages(struct ib_umem *umem, u64 user_virt, u64 bcnt, ret = -EFAULT; break; } - put_page(local_page_list[j]); + put_user_page(local_page_list[j]); continue; } diff --git a/drivers/infiniband/hw/hfi1/user_pages.c b/drivers/infiniband/hw/hfi1/user_pages.c index e341e6dcc388..99ccc0483711 100644 --- a/drivers/infiniband/hw/hfi1/user_pages.c +++ b/drivers/infiniband/hw/hfi1/user_pages.c @@ -121,13 +121,10 @@ int hfi1_acquire_user_pages(struct mm_struct *mm, unsigned long vaddr, size_t np void hfi1_release_user_pages(struct mm_struct *mm, struct page **p, size_t npages, bool dirty) { - size_t i; - - for (i = 0; i < npages; i++) { - if (dirty) - set_page_dirty_lock(p[i]); - put_page(p[i]); - } + if (dirty) + put_user_pages_dirty_lock(p, npages); + else + put_user_pages(p, npages); if (mm) { /* during close after signal, mm can be NULL */ down_write(>mmap_sem); diff --git a/drivers/infiniband/hw/mthca/mthca_memfree.c b/drivers/infiniband/hw/mthca/mthca_memfree.c index cc9c0c8ccba3..b8b12effd009 100644 --- a/drivers/infiniband/hw/mthca/mthca_memfree.c +++ b/drivers/infiniband/hw/mthca/mthca_memfree.c @@ -481,7 +481,7 @@ int mthca_map_user_db(struct mthca_dev *dev, struct mthca_uar *uar, ret = pci_map_sg(dev->pdev, _tab->page[i].mem, 1, PCI_DMA_TODEVICE); if (ret < 0) { - put_page(pages[0]); + put_user_page(pages[0]); goto out; } @@ -489,7 +489,7 @@ int mthca_map_user_db(struct mthca_dev *dev, struct mthca_uar *uar, mthca_uarc_virt(dev, uar, i)); if (ret) { pci_unmap_sg(dev->pdev, _tab->page[i].mem, 1, PCI_DMA_TODEVICE); - put_page(sg_page(_tab->page[i].mem)); + put_user_page(sg_page(_tab->page[i].mem)); goto out; } @@ -555,7 +555,7 @@ void mthca_cleanup_user_db_tab(struct mthca_dev *dev, struct mthca_uar *uar, if (db_tab->page[i].uvirt) { mthca_UNMAP_ICM(dev, mthca_uarc_virt(dev, uar, i), 1); pci_unmap_sg(dev->pdev, _tab->page[i].mem, 1, PCI_DMA_TODEVICE); - put_page(sg_page(_tab->page[i].mem)); + put_user_page(sg_page(_tab->page[i].mem)); } } diff --git a/drivers/infiniband/hw/qib/qib_user_pages.c b/drivers/infiniband/hw/qib/qib_user_pages.c index
[PATCH v2 3/3] infiniband/mm: convert to the new put_user_page[s]() calls
From: John Hubbard For code that retains pages via get_user_pages*(), release those pages via the new put_user_page(), instead of put_page(). This prepares for eventually fixing the problem described in [1], and is following a plan listed in [2], [3], [4]. [1] https://lwn.net/Articles/753027/ : "The Trouble with get_user_pages()" [2] https://lkml.kernel.org/r/20180709080554.21931-1-jhubb...@nvidia.com Proposed steps for fixing get_user_pages() + DMA problems. [3]https://lkml.kernel.org/r/20180710082100.mkdwngdv5kkrc...@quack2.suse.cz Bounce buffers (otherwise [2] is not really viable). [4] https://lkml.kernel.org/r/20181003162115.gg24...@quack2.suse.cz Follow-up discussions. CC: Doug Ledford CC: Jason Gunthorpe CC: Mike Marciniszyn CC: Dennis Dalessandro CC: Christian Benvenuti CC: linux-r...@vger.kernel.org CC: linux-kernel@vger.kernel.org CC: linux...@kvack.org Signed-off-by: John Hubbard --- drivers/infiniband/core/umem.c | 2 +- drivers/infiniband/core/umem_odp.c | 2 +- drivers/infiniband/hw/hfi1/user_pages.c | 11 --- drivers/infiniband/hw/mthca/mthca_memfree.c | 6 +++--- drivers/infiniband/hw/qib/qib_user_pages.c | 11 --- drivers/infiniband/hw/qib/qib_user_sdma.c | 8 drivers/infiniband/hw/usnic/usnic_uiom.c| 2 +- 7 files changed, 18 insertions(+), 24 deletions(-) diff --git a/drivers/infiniband/core/umem.c b/drivers/infiniband/core/umem.c index a41792dbae1f..9430d697cb9f 100644 --- a/drivers/infiniband/core/umem.c +++ b/drivers/infiniband/core/umem.c @@ -60,7 +60,7 @@ static void __ib_umem_release(struct ib_device *dev, struct ib_umem *umem, int d page = sg_page(sg); if (!PageDirty(page) && umem->writable && dirty) set_page_dirty_lock(page); - put_page(page); + put_user_page(page); } sg_free_table(>sg_head); diff --git a/drivers/infiniband/core/umem_odp.c b/drivers/infiniband/core/umem_odp.c index 6ec748eccff7..6227b89cf05c 100644 --- a/drivers/infiniband/core/umem_odp.c +++ b/drivers/infiniband/core/umem_odp.c @@ -717,7 +717,7 @@ int ib_umem_odp_map_dma_pages(struct ib_umem *umem, u64 user_virt, u64 bcnt, ret = -EFAULT; break; } - put_page(local_page_list[j]); + put_user_page(local_page_list[j]); continue; } diff --git a/drivers/infiniband/hw/hfi1/user_pages.c b/drivers/infiniband/hw/hfi1/user_pages.c index e341e6dcc388..99ccc0483711 100644 --- a/drivers/infiniband/hw/hfi1/user_pages.c +++ b/drivers/infiniband/hw/hfi1/user_pages.c @@ -121,13 +121,10 @@ int hfi1_acquire_user_pages(struct mm_struct *mm, unsigned long vaddr, size_t np void hfi1_release_user_pages(struct mm_struct *mm, struct page **p, size_t npages, bool dirty) { - size_t i; - - for (i = 0; i < npages; i++) { - if (dirty) - set_page_dirty_lock(p[i]); - put_page(p[i]); - } + if (dirty) + put_user_pages_dirty_lock(p, npages); + else + put_user_pages(p, npages); if (mm) { /* during close after signal, mm can be NULL */ down_write(>mmap_sem); diff --git a/drivers/infiniband/hw/mthca/mthca_memfree.c b/drivers/infiniband/hw/mthca/mthca_memfree.c index cc9c0c8ccba3..b8b12effd009 100644 --- a/drivers/infiniband/hw/mthca/mthca_memfree.c +++ b/drivers/infiniband/hw/mthca/mthca_memfree.c @@ -481,7 +481,7 @@ int mthca_map_user_db(struct mthca_dev *dev, struct mthca_uar *uar, ret = pci_map_sg(dev->pdev, _tab->page[i].mem, 1, PCI_DMA_TODEVICE); if (ret < 0) { - put_page(pages[0]); + put_user_page(pages[0]); goto out; } @@ -489,7 +489,7 @@ int mthca_map_user_db(struct mthca_dev *dev, struct mthca_uar *uar, mthca_uarc_virt(dev, uar, i)); if (ret) { pci_unmap_sg(dev->pdev, _tab->page[i].mem, 1, PCI_DMA_TODEVICE); - put_page(sg_page(_tab->page[i].mem)); + put_user_page(sg_page(_tab->page[i].mem)); goto out; } @@ -555,7 +555,7 @@ void mthca_cleanup_user_db_tab(struct mthca_dev *dev, struct mthca_uar *uar, if (db_tab->page[i].uvirt) { mthca_UNMAP_ICM(dev, mthca_uarc_virt(dev, uar, i), 1); pci_unmap_sg(dev->pdev, _tab->page[i].mem, 1, PCI_DMA_TODEVICE); - put_page(sg_page(_tab->page[i].mem)); + put_user_page(sg_page(_tab->page[i].mem)); } } diff --git a/drivers/infiniband/hw/qib/qib_user_pages.c b/drivers/infiniband/hw/qib/qib_user_pages.c index
[PATCH v2 1/3] mm: get_user_pages: consolidate error handling
From: John Hubbard An upcoming patch requires a way to operate on each page that any of the get_user_pages_*() variants returns. In preparation for that, consolidate the error handling for __get_user_pages(). This provides a single location (the "out:" label) for operating on the collected set of pages that are about to be returned. As long every use of the "ret" variable is being edited, rename "ret" --> "err", so that its name matches its true role. This also gets rid of two shadowed variable declarations, as a tiny beneficial a side effect. Reviewed-by: Jan Kara Signed-off-by: John Hubbard --- mm/gup.c | 37 ++--- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/mm/gup.c b/mm/gup.c index 1abc8b4afff6..05ee7c18e59a 100644 --- a/mm/gup.c +++ b/mm/gup.c @@ -660,6 +660,7 @@ static long __get_user_pages(struct task_struct *tsk, struct mm_struct *mm, struct vm_area_struct **vmas, int *nonblocking) { long i = 0; + int err = 0; unsigned int page_mask; struct vm_area_struct *vma = NULL; @@ -685,18 +686,19 @@ static long __get_user_pages(struct task_struct *tsk, struct mm_struct *mm, if (!vma || start >= vma->vm_end) { vma = find_extend_vma(mm, start); if (!vma && in_gate_area(mm, start)) { - int ret; - ret = get_gate_page(mm, start & PAGE_MASK, + err = get_gate_page(mm, start & PAGE_MASK, gup_flags, , pages ? [i] : NULL); - if (ret) - return i ? : ret; + if (err) + goto out; page_mask = 0; goto next_page; } - if (!vma || check_vma_flags(vma, gup_flags)) - return i ? : -EFAULT; + if (!vma || check_vma_flags(vma, gup_flags)) { + err = -EFAULT; + goto out; + } if (is_vm_hugetlb_page(vma)) { i = follow_hugetlb_page(mm, vma, pages, vmas, , _pages, i, @@ -709,23 +711,25 @@ static long __get_user_pages(struct task_struct *tsk, struct mm_struct *mm, * If we have a pending SIGKILL, don't keep faulting pages and * potentially allocating memory. */ - if (unlikely(fatal_signal_pending(current))) - return i ? i : -ERESTARTSYS; + if (unlikely(fatal_signal_pending(current))) { + err = -ERESTARTSYS; + goto out; + } cond_resched(); page = follow_page_mask(vma, start, foll_flags, _mask); if (!page) { - int ret; - ret = faultin_page(tsk, vma, start, _flags, + err = faultin_page(tsk, vma, start, _flags, nonblocking); - switch (ret) { + switch (err) { case 0: goto retry; case -EFAULT: case -ENOMEM: case -EHWPOISON: - return i ? i : ret; + goto out; case -EBUSY: - return i; + err = 0; + goto out; case -ENOENT: goto next_page; } @@ -737,7 +741,8 @@ static long __get_user_pages(struct task_struct *tsk, struct mm_struct *mm, */ goto next_page; } else if (IS_ERR(page)) { - return i ? i : PTR_ERR(page); + err = PTR_ERR(page); + goto out; } if (pages) { pages[i] = page; @@ -757,7 +762,9 @@ static long __get_user_pages(struct task_struct *tsk, struct mm_struct *mm, start += page_increm * PAGE_SIZE; nr_pages -= page_increm; } while (nr_pages); - return i; + +out: + return i ? i : err; } static bool vma_permits_fault(struct vm_area_struct *vma, -- 2.19.0
[PATCH v2 0/3] get_user_pages*() and RDMA: first steps
From: John Hubbard Changes since v1: -- Renamed release_user_pages*() to put_user_pages*(), from Jan's feedback. -- Removed the goldfish.c changes, and instead, only included a single user (infiniband) of the new functions. That is because goldfish.c no longer has a name collision (it has a release_user_pages() routine), and also because infiniband exercises both the put_user_page() and put_user_pages*() paths. -- Updated links to discussions and plans, so as to be sure to include bounce buffers, thanks to Jerome's feedback. Also: -- Dennis, thanks for your earlier review, and I have not yet added your Reviewed-by tag, because this revision changes the things that you had previously reviewed, thus potentially requiring another look. This short series prepares for eventually fixing the problem described in [1], and is following a plan listed in [2], [3], [4]. I'd like to get the first two patches into the -mm tree. Patch 1, although not technically critical to do now, is still nice to have, because it's already been reviewed by Jan, and it's just one more thing on the long TODO list here, that is ready to be checked off. Patch 2 is required in order to allow me (and others, if I'm lucky) to start submitting changes to convert all of the callsites of get_user_pages*() and put_page(). I think this will work a lot better than trying to maintain a massive patchset and submitting all at once. Patch 3 converts infiniband drivers: put_page() --> put_user_page(), and also exercises put_user_pages_dirty_locked(). Once these are all in, then the floodgates can open up to convert the large number of get_user_pages*() callsites. [1] https://lwn.net/Articles/753027/ : "The Trouble with get_user_pages()" [2] https://lkml.kernel.org/r/20180709080554.21931-1-jhubb...@nvidia.com Proposed steps for fixing get_user_pages() + DMA problems. [3]https://lkml.kernel.org/r/20180710082100.mkdwngdv5kkrc...@quack2.suse.cz Bounce buffers (otherwise [2] is not really viable). [4] https://lkml.kernel.org/r/20181003162115.gg24...@quack2.suse.cz Follow-up discussions. CC: Matthew Wilcox CC: Michal Hocko CC: Christopher Lameter CC: Jason Gunthorpe CC: Dan Williams CC: Jan Kara CC: Al Viro CC: Jerome Glisse CC: Christoph Hellwig John Hubbard (3): mm: get_user_pages: consolidate error handling mm: introduce put_user_page[s](), placeholder versions infiniband/mm: convert to the new put_user_page[s]() calls drivers/infiniband/core/umem.c | 2 +- drivers/infiniband/core/umem_odp.c | 2 +- drivers/infiniband/hw/hfi1/user_pages.c | 11 ++ drivers/infiniband/hw/mthca/mthca_memfree.c | 6 +-- drivers/infiniband/hw/qib/qib_user_pages.c | 11 ++ drivers/infiniband/hw/qib/qib_user_sdma.c | 8 ++-- drivers/infiniband/hw/usnic/usnic_uiom.c| 2 +- include/linux/mm.h | 42 - mm/gup.c| 37 ++ 9 files changed, 80 insertions(+), 41 deletions(-) -- 2.19.0
[PATCH v2 1/3] mm: get_user_pages: consolidate error handling
From: John Hubbard An upcoming patch requires a way to operate on each page that any of the get_user_pages_*() variants returns. In preparation for that, consolidate the error handling for __get_user_pages(). This provides a single location (the "out:" label) for operating on the collected set of pages that are about to be returned. As long every use of the "ret" variable is being edited, rename "ret" --> "err", so that its name matches its true role. This also gets rid of two shadowed variable declarations, as a tiny beneficial a side effect. Reviewed-by: Jan Kara Signed-off-by: John Hubbard --- mm/gup.c | 37 ++--- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/mm/gup.c b/mm/gup.c index 1abc8b4afff6..05ee7c18e59a 100644 --- a/mm/gup.c +++ b/mm/gup.c @@ -660,6 +660,7 @@ static long __get_user_pages(struct task_struct *tsk, struct mm_struct *mm, struct vm_area_struct **vmas, int *nonblocking) { long i = 0; + int err = 0; unsigned int page_mask; struct vm_area_struct *vma = NULL; @@ -685,18 +686,19 @@ static long __get_user_pages(struct task_struct *tsk, struct mm_struct *mm, if (!vma || start >= vma->vm_end) { vma = find_extend_vma(mm, start); if (!vma && in_gate_area(mm, start)) { - int ret; - ret = get_gate_page(mm, start & PAGE_MASK, + err = get_gate_page(mm, start & PAGE_MASK, gup_flags, , pages ? [i] : NULL); - if (ret) - return i ? : ret; + if (err) + goto out; page_mask = 0; goto next_page; } - if (!vma || check_vma_flags(vma, gup_flags)) - return i ? : -EFAULT; + if (!vma || check_vma_flags(vma, gup_flags)) { + err = -EFAULT; + goto out; + } if (is_vm_hugetlb_page(vma)) { i = follow_hugetlb_page(mm, vma, pages, vmas, , _pages, i, @@ -709,23 +711,25 @@ static long __get_user_pages(struct task_struct *tsk, struct mm_struct *mm, * If we have a pending SIGKILL, don't keep faulting pages and * potentially allocating memory. */ - if (unlikely(fatal_signal_pending(current))) - return i ? i : -ERESTARTSYS; + if (unlikely(fatal_signal_pending(current))) { + err = -ERESTARTSYS; + goto out; + } cond_resched(); page = follow_page_mask(vma, start, foll_flags, _mask); if (!page) { - int ret; - ret = faultin_page(tsk, vma, start, _flags, + err = faultin_page(tsk, vma, start, _flags, nonblocking); - switch (ret) { + switch (err) { case 0: goto retry; case -EFAULT: case -ENOMEM: case -EHWPOISON: - return i ? i : ret; + goto out; case -EBUSY: - return i; + err = 0; + goto out; case -ENOENT: goto next_page; } @@ -737,7 +741,8 @@ static long __get_user_pages(struct task_struct *tsk, struct mm_struct *mm, */ goto next_page; } else if (IS_ERR(page)) { - return i ? i : PTR_ERR(page); + err = PTR_ERR(page); + goto out; } if (pages) { pages[i] = page; @@ -757,7 +762,9 @@ static long __get_user_pages(struct task_struct *tsk, struct mm_struct *mm, start += page_increm * PAGE_SIZE; nr_pages -= page_increm; } while (nr_pages); - return i; + +out: + return i ? i : err; } static bool vma_permits_fault(struct vm_area_struct *vma, -- 2.19.0
[PATCH v2 0/3] get_user_pages*() and RDMA: first steps
From: John Hubbard Changes since v1: -- Renamed release_user_pages*() to put_user_pages*(), from Jan's feedback. -- Removed the goldfish.c changes, and instead, only included a single user (infiniband) of the new functions. That is because goldfish.c no longer has a name collision (it has a release_user_pages() routine), and also because infiniband exercises both the put_user_page() and put_user_pages*() paths. -- Updated links to discussions and plans, so as to be sure to include bounce buffers, thanks to Jerome's feedback. Also: -- Dennis, thanks for your earlier review, and I have not yet added your Reviewed-by tag, because this revision changes the things that you had previously reviewed, thus potentially requiring another look. This short series prepares for eventually fixing the problem described in [1], and is following a plan listed in [2], [3], [4]. I'd like to get the first two patches into the -mm tree. Patch 1, although not technically critical to do now, is still nice to have, because it's already been reviewed by Jan, and it's just one more thing on the long TODO list here, that is ready to be checked off. Patch 2 is required in order to allow me (and others, if I'm lucky) to start submitting changes to convert all of the callsites of get_user_pages*() and put_page(). I think this will work a lot better than trying to maintain a massive patchset and submitting all at once. Patch 3 converts infiniband drivers: put_page() --> put_user_page(), and also exercises put_user_pages_dirty_locked(). Once these are all in, then the floodgates can open up to convert the large number of get_user_pages*() callsites. [1] https://lwn.net/Articles/753027/ : "The Trouble with get_user_pages()" [2] https://lkml.kernel.org/r/20180709080554.21931-1-jhubb...@nvidia.com Proposed steps for fixing get_user_pages() + DMA problems. [3]https://lkml.kernel.org/r/20180710082100.mkdwngdv5kkrc...@quack2.suse.cz Bounce buffers (otherwise [2] is not really viable). [4] https://lkml.kernel.org/r/20181003162115.gg24...@quack2.suse.cz Follow-up discussions. CC: Matthew Wilcox CC: Michal Hocko CC: Christopher Lameter CC: Jason Gunthorpe CC: Dan Williams CC: Jan Kara CC: Al Viro CC: Jerome Glisse CC: Christoph Hellwig John Hubbard (3): mm: get_user_pages: consolidate error handling mm: introduce put_user_page[s](), placeholder versions infiniband/mm: convert to the new put_user_page[s]() calls drivers/infiniband/core/umem.c | 2 +- drivers/infiniband/core/umem_odp.c | 2 +- drivers/infiniband/hw/hfi1/user_pages.c | 11 ++ drivers/infiniband/hw/mthca/mthca_memfree.c | 6 +-- drivers/infiniband/hw/qib/qib_user_pages.c | 11 ++ drivers/infiniband/hw/qib/qib_user_sdma.c | 8 ++-- drivers/infiniband/hw/usnic/usnic_uiom.c| 2 +- include/linux/mm.h | 42 - mm/gup.c| 37 ++ 9 files changed, 80 insertions(+), 41 deletions(-) -- 2.19.0
Re: [PATCH - resend] VFS: use synchronize_rcu_expedited() in namespace_unlock()
On Fri, Oct 05 2018, Al Viro wrote: > On Fri, Oct 05, 2018 at 11:27:37AM +1000, NeilBrown wrote: >> >> The synchronize_rcu() in namespace_unlock() is called every time >> a filesystem is unmounted. If a great many filesystems are mounted, >> this can cause a noticable slow-down in, for example, system shutdown. >> >> The sequence: >> mkdir -p /tmp/Mtest/{0..5000} >> time for i in /tmp/Mtest/*; do mount -t tmpfs tmpfs $i ; done >> time umount /tmp/Mtest/* >> >> on a 4-cpu VM can report 8 seconds to mount the tmpfs filesystems, and >> 100 seconds to unmount them. >> >> Boot the same VM with 1 CPU and it takes 18 seconds to mount the >> tmpfs filesystems, but only 36 to unmount. >> >> If we change the synchronize_rcu() to synchronize_rcu_expedited() >> the umount time on a 4-cpu VM drop to 0.6 seconds >> >> I think this 200-fold speed up is worth the slightly high system >> impact of using synchronize_rcu_expedited(). >> >> Acked-by: Paul E. McKenney (from general rcu >> perspective) >> Signed-off-by: NeilBrown >> --- >> >> I posted this last October, then again last November (cc:ing Linus) >> Paul is happy enough with it, but no other response. >> I'm hoping it can get applied this time > > Umm... IIRC, the last one got sidetracked on the other thing in the series... > that was s_anon stuff. I can live with this one; FWIW, what kind > of load would trigger the impact of the change? Paul? I think you would need a long sequence of umounts to notice anything. What you would notice is substantially reduced wall-clock time, but slightly increased CPU time. The original bug report that lead to this patch was a system with "HUGE direct automount maps (>23k at this point)". Stopping autofs (during shutdown) took more minutes than seemed reasonable. I noticed it again just recently when working on a systemd issue. If you mount thousands of filesystems in quick succession (ClearCase can do this), systemd processes /proc/self/mountinfo constantly and slows down the whole process. When I unmount my test filesystems (mount --bind /etc /MNT/$1) it takes a similar amount of time, but now it isn't systemd slowing things down (which is odd actually, I wonder why systemd didn't notice..) but rather the synchronize_rcu() delays. Thanks, NeilBrown signature.asc Description: PGP signature
Re: [PATCH - resend] VFS: use synchronize_rcu_expedited() in namespace_unlock()
On Fri, Oct 05 2018, Al Viro wrote: > On Fri, Oct 05, 2018 at 11:27:37AM +1000, NeilBrown wrote: >> >> The synchronize_rcu() in namespace_unlock() is called every time >> a filesystem is unmounted. If a great many filesystems are mounted, >> this can cause a noticable slow-down in, for example, system shutdown. >> >> The sequence: >> mkdir -p /tmp/Mtest/{0..5000} >> time for i in /tmp/Mtest/*; do mount -t tmpfs tmpfs $i ; done >> time umount /tmp/Mtest/* >> >> on a 4-cpu VM can report 8 seconds to mount the tmpfs filesystems, and >> 100 seconds to unmount them. >> >> Boot the same VM with 1 CPU and it takes 18 seconds to mount the >> tmpfs filesystems, but only 36 to unmount. >> >> If we change the synchronize_rcu() to synchronize_rcu_expedited() >> the umount time on a 4-cpu VM drop to 0.6 seconds >> >> I think this 200-fold speed up is worth the slightly high system >> impact of using synchronize_rcu_expedited(). >> >> Acked-by: Paul E. McKenney (from general rcu >> perspective) >> Signed-off-by: NeilBrown >> --- >> >> I posted this last October, then again last November (cc:ing Linus) >> Paul is happy enough with it, but no other response. >> I'm hoping it can get applied this time > > Umm... IIRC, the last one got sidetracked on the other thing in the series... > that was s_anon stuff. I can live with this one; FWIW, what kind > of load would trigger the impact of the change? Paul? I think you would need a long sequence of umounts to notice anything. What you would notice is substantially reduced wall-clock time, but slightly increased CPU time. The original bug report that lead to this patch was a system with "HUGE direct automount maps (>23k at this point)". Stopping autofs (during shutdown) took more minutes than seemed reasonable. I noticed it again just recently when working on a systemd issue. If you mount thousands of filesystems in quick succession (ClearCase can do this), systemd processes /proc/self/mountinfo constantly and slows down the whole process. When I unmount my test filesystems (mount --bind /etc /MNT/$1) it takes a similar amount of time, but now it isn't systemd slowing things down (which is odd actually, I wonder why systemd didn't notice..) but rather the synchronize_rcu() delays. Thanks, NeilBrown signature.asc Description: PGP signature
Re: [PATCH 1/1] kbuild: Optimize tests and remove shadowed local variable.
Hello David, My name is Leonardo and I am new to kernel development. Is this patch acceptable? Do it need some rework? The change makes sense? Is there a way to better follow the workflow for this patch? Please let me know if it needs anything. Best regards, Leonardo Bras On Wed, Sep 19, 2018 at 4:11 AM Masahiro Yamada wrote: > > FW: David Howells > > > 2018-09-19 8:00 GMT+09:00 Leonardo Brás : > > Removes an unnecessary shadowed local variable (start). > > Optimize test of isdigit: > > - If isalpha returns true, isdigit will return false, so no need to test. > > > > Signed-off-by: Leonardo Brás > > > This patch was sent to me, but maybe belong to David's field. > > David, will you take care of this patch? > > https://lore.kernel.org/patchwork/patch/988171/ > > I think the commit subject should be changed kbuild: -> ASN.1: > > > Anyway, this patch looks trivial, > FWIW > > Reviewed-by: Masahiro Yamada > > > > > > > --- > > scripts/asn1_compiler.c | 8 > > 1 file changed, 4 insertions(+), 4 deletions(-) > > > > diff --git a/scripts/asn1_compiler.c b/scripts/asn1_compiler.c > > index c146020fc783..a0056df4e358 100644 > > --- a/scripts/asn1_compiler.c > > +++ b/scripts/asn1_compiler.c > > @@ -413,7 +413,7 @@ static void tokenise(char *buffer, char *end) > > > > /* Handle string tokens */ > > if (isalpha(*p)) { > > - const char **dir, *start = p; > > + const char **dir; > > > > /* Can be a directive, type name or element > > * name. Find the end of the name. > > @@ -454,10 +454,10 @@ static void tokenise(char *buffer, char *end) > > > > tokens[tix++].token_type = TOKEN_TYPE_NAME; > > continue; > > - } > > > > - /* Handle numbers */ > > - if (isdigit(*p)) { > > + } else if (isdigit(*p)) { > > + /* Handle numbers */ > > + > > /* Find the end of the number */ > > q = p + 1; > > while (q < nl && (isdigit(*q))) > > -- > > 2.19.0 > > > > > > -- > Best Regards > Masahiro Yamada
Re: [PATCH 1/1] kbuild: Optimize tests and remove shadowed local variable.
Hello David, My name is Leonardo and I am new to kernel development. Is this patch acceptable? Do it need some rework? The change makes sense? Is there a way to better follow the workflow for this patch? Please let me know if it needs anything. Best regards, Leonardo Bras On Wed, Sep 19, 2018 at 4:11 AM Masahiro Yamada wrote: > > FW: David Howells > > > 2018-09-19 8:00 GMT+09:00 Leonardo Brás : > > Removes an unnecessary shadowed local variable (start). > > Optimize test of isdigit: > > - If isalpha returns true, isdigit will return false, so no need to test. > > > > Signed-off-by: Leonardo Brás > > > This patch was sent to me, but maybe belong to David's field. > > David, will you take care of this patch? > > https://lore.kernel.org/patchwork/patch/988171/ > > I think the commit subject should be changed kbuild: -> ASN.1: > > > Anyway, this patch looks trivial, > FWIW > > Reviewed-by: Masahiro Yamada > > > > > > > --- > > scripts/asn1_compiler.c | 8 > > 1 file changed, 4 insertions(+), 4 deletions(-) > > > > diff --git a/scripts/asn1_compiler.c b/scripts/asn1_compiler.c > > index c146020fc783..a0056df4e358 100644 > > --- a/scripts/asn1_compiler.c > > +++ b/scripts/asn1_compiler.c > > @@ -413,7 +413,7 @@ static void tokenise(char *buffer, char *end) > > > > /* Handle string tokens */ > > if (isalpha(*p)) { > > - const char **dir, *start = p; > > + const char **dir; > > > > /* Can be a directive, type name or element > > * name. Find the end of the name. > > @@ -454,10 +454,10 @@ static void tokenise(char *buffer, char *end) > > > > tokens[tix++].token_type = TOKEN_TYPE_NAME; > > continue; > > - } > > > > - /* Handle numbers */ > > - if (isdigit(*p)) { > > + } else if (isdigit(*p)) { > > + /* Handle numbers */ > > + > > /* Find the end of the number */ > > q = p + 1; > > while (q < nl && (isdigit(*q))) > > -- > > 2.19.0 > > > > > > -- > Best Regards > Masahiro Yamada
Re: [PATCH v3 3/7] drivers: parisc: Avoids building driver if CONFIG_PARISC is disabled
> Well it's not really that persuasive. Most people simply let the build > run to completion, but if you have a problem with a job control 3h > timelimit, then create a job that kills itself at 2:59 and then > resubmits itself. That will produce a complete build in 3h chunks > without any need to call sub Makefiles. > Humm, I probably should have explained better how GitlabCI works. It works creating a docker container that have a limited lifespan of 3h max. After that the time is over, this container ceases to exist, leaving no build objects, only the console log. So there is no way of 'resuming' the building from where it stopped. I used the 'job' term because it's how they call it, and I understand it's easily confused with bash jobs. > All of our Makefiles are coded assuming the upper level can prevent > descent into the lower ones. You're proposing to change that > assumption, requiring a fairly large patch set, which doesn't really > seem to provide a huge benefit. > > James I understand your viewpoint. But what I propose is not to change that assumption, but instead give some Makefiles the aditional ability to be called directly and still not build stuff if they were not enabled in .config. But, why these chosen Makefiles, and not all of them? Granularity. What I am trying to achieve with this patchset is the ability of building smaller sets of drivers without accidentally building what is not enabled on .config. And, in my viewpoint, building a single drivers/DRIVERNAME is small enough to be fast in most situations. This change is not supposed to bother the usual way of building the kernel, and it is not even supposed to add overhead to kernel compilation. And it would, at least, solve my problem with the 3h limit, and enable the tool I am building on GiltabCI to help other developers. Thanks for reading, Leonardo Bras
Re: [PATCH v3 3/7] drivers: parisc: Avoids building driver if CONFIG_PARISC is disabled
> Well it's not really that persuasive. Most people simply let the build > run to completion, but if you have a problem with a job control 3h > timelimit, then create a job that kills itself at 2:59 and then > resubmits itself. That will produce a complete build in 3h chunks > without any need to call sub Makefiles. > Humm, I probably should have explained better how GitlabCI works. It works creating a docker container that have a limited lifespan of 3h max. After that the time is over, this container ceases to exist, leaving no build objects, only the console log. So there is no way of 'resuming' the building from where it stopped. I used the 'job' term because it's how they call it, and I understand it's easily confused with bash jobs. > All of our Makefiles are coded assuming the upper level can prevent > descent into the lower ones. You're proposing to change that > assumption, requiring a fairly large patch set, which doesn't really > seem to provide a huge benefit. > > James I understand your viewpoint. But what I propose is not to change that assumption, but instead give some Makefiles the aditional ability to be called directly and still not build stuff if they were not enabled in .config. But, why these chosen Makefiles, and not all of them? Granularity. What I am trying to achieve with this patchset is the ability of building smaller sets of drivers without accidentally building what is not enabled on .config. And, in my viewpoint, building a single drivers/DRIVERNAME is small enough to be fast in most situations. This change is not supposed to bother the usual way of building the kernel, and it is not even supposed to add overhead to kernel compilation. And it would, at least, solve my problem with the 3h limit, and enable the tool I am building on GiltabCI to help other developers. Thanks for reading, Leonardo Bras
[PATCH] arm64: dts: qcom: sdm845: Add qspi (quad SPI) node
This adds the Quad SPI controller to the main sdm845 device tree file. Boards will be expected to assign the proper pinctrl depending on how many chip selects they have hooked up and how many data lines. This depends on commit 48735597f7bd ("clk: qcom: Add qspi (Quad SPI) clock defines for sdm845 to header") to add the needed defines. It also shouldn't land until the patch ("dt-bindings: spi: Qualcomm Quad SPI(QSPI) documentation") [1] lands. [1] https://lkml.kernel.org/r/20181002214709.162330-1-ryandc...@chromium.org Signed-off-by: Douglas Anderson --- arch/arm64/boot/dts/qcom/sdm845.dtsi | 47 1 file changed, 47 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi b/arch/arm64/boot/dts/qcom/sdm845.dtsi index b72bdb0a31a5..cfc96262e8dd 100644 --- a/arch/arm64/boot/dts/qcom/sdm845.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi @@ -822,6 +822,41 @@ interrupt-controller; #interrupt-cells = <2>; + qspi_clk: qspi-clk { + pinmux { + pins = "gpio95"; + function = "qspi_clk"; + }; + }; + + qspi_cs0: qspi-cs0 { + pinmux { + pins = "gpio90"; + function = "qspi_cs"; + }; + }; + + qspi_cs1: qspi-cs1 { + pinmux { + pins = "gpio89"; + function = "qspi_cs"; + }; + }; + + qspi_data01: qspi-data01 { + pinmux-data { + pins = "gpio91", "gpio92"; + function = "qspi_data"; + }; + }; + + qspi_data12: qspi-data12 { + pinmux-data { + pins = "gpio93", "gpio94"; + function = "qspi_data"; + }; + }; + qup_i2c0_default: qup-i2c0-default { pinmux { pins = "gpio0", "gpio1"; @@ -1070,6 +1105,18 @@ }; }; + qspi: qspi@88df000 { + compatible = "qcom,sdm845-qspi", "qcom,qspi-v1"; + reg = <0x88df000 0x600>; + #address-cells = <1>; + #size-cells = <0>; + interrupts = ; + clocks = < GCC_QSPI_CNOC_PERIPH_AHB_CLK>, +< GCC_QSPI_CORE_CLK>; + clock-names = "iface", "core"; + status = "disabled"; + }; + usb_1_hsphy: phy@88e2000 { compatible = "qcom,sdm845-qusb2-phy"; reg = <0x88e2000 0x400>; -- 2.19.0.605.g01d371f741-goog
[PATCH] arm64: dts: qcom: sdm845: Add qspi (quad SPI) node
This adds the Quad SPI controller to the main sdm845 device tree file. Boards will be expected to assign the proper pinctrl depending on how many chip selects they have hooked up and how many data lines. This depends on commit 48735597f7bd ("clk: qcom: Add qspi (Quad SPI) clock defines for sdm845 to header") to add the needed defines. It also shouldn't land until the patch ("dt-bindings: spi: Qualcomm Quad SPI(QSPI) documentation") [1] lands. [1] https://lkml.kernel.org/r/20181002214709.162330-1-ryandc...@chromium.org Signed-off-by: Douglas Anderson --- arch/arm64/boot/dts/qcom/sdm845.dtsi | 47 1 file changed, 47 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi b/arch/arm64/boot/dts/qcom/sdm845.dtsi index b72bdb0a31a5..cfc96262e8dd 100644 --- a/arch/arm64/boot/dts/qcom/sdm845.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi @@ -822,6 +822,41 @@ interrupt-controller; #interrupt-cells = <2>; + qspi_clk: qspi-clk { + pinmux { + pins = "gpio95"; + function = "qspi_clk"; + }; + }; + + qspi_cs0: qspi-cs0 { + pinmux { + pins = "gpio90"; + function = "qspi_cs"; + }; + }; + + qspi_cs1: qspi-cs1 { + pinmux { + pins = "gpio89"; + function = "qspi_cs"; + }; + }; + + qspi_data01: qspi-data01 { + pinmux-data { + pins = "gpio91", "gpio92"; + function = "qspi_data"; + }; + }; + + qspi_data12: qspi-data12 { + pinmux-data { + pins = "gpio93", "gpio94"; + function = "qspi_data"; + }; + }; + qup_i2c0_default: qup-i2c0-default { pinmux { pins = "gpio0", "gpio1"; @@ -1070,6 +1105,18 @@ }; }; + qspi: qspi@88df000 { + compatible = "qcom,sdm845-qspi", "qcom,qspi-v1"; + reg = <0x88df000 0x600>; + #address-cells = <1>; + #size-cells = <0>; + interrupts = ; + clocks = < GCC_QSPI_CNOC_PERIPH_AHB_CLK>, +< GCC_QSPI_CORE_CLK>; + clock-names = "iface", "core"; + status = "disabled"; + }; + usb_1_hsphy: phy@88e2000 { compatible = "qcom,sdm845-qusb2-phy"; reg = <0x88e2000 0x400>; -- 2.19.0.605.g01d371f741-goog
[PATCH] power: supply: olpc_battery: correct the temperature units
According to [1] and [2], the temperature values are in tenths of degree Celsius. Exposing the Celsius value makes the battery appear on fire: $ upower -i /org/freedesktop/UPower/devices/battery_olpc_battery ... temperature: 236.9 degrees C Tested on OLPC XO-1 and OLPC XO-1.75 laptops. [1] include/linux/power_supply.h [2] Documentation/power/power_supply_class.txt Cc: sta...@vger.kernel.org Signed-off-by: Lubomir Rintel --- drivers/power/supply/olpc_battery.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/power/supply/olpc_battery.c b/drivers/power/supply/olpc_battery.c index 6da79ae14860..5a97e42a3547 100644 --- a/drivers/power/supply/olpc_battery.c +++ b/drivers/power/supply/olpc_battery.c @@ -428,14 +428,14 @@ static int olpc_bat_get_property(struct power_supply *psy, if (ret) return ret; - val->intval = (s16)be16_to_cpu(ec_word) * 100 / 256; + val->intval = (s16)be16_to_cpu(ec_word) * 10 / 256; break; case POWER_SUPPLY_PROP_TEMP_AMBIENT: ret = olpc_ec_cmd(EC_AMB_TEMP, NULL, 0, (void *)_word, 2); if (ret) return ret; - val->intval = (int)be16_to_cpu(ec_word) * 100 / 256; + val->intval = (int)be16_to_cpu(ec_word) * 10 / 256; break; case POWER_SUPPLY_PROP_CHARGE_COUNTER: ret = olpc_ec_cmd(EC_BAT_ACR, NULL, 0, (void *)_word, 2); -- 2.19.0
[PATCH] power: supply: olpc_battery: correct the temperature units
According to [1] and [2], the temperature values are in tenths of degree Celsius. Exposing the Celsius value makes the battery appear on fire: $ upower -i /org/freedesktop/UPower/devices/battery_olpc_battery ... temperature: 236.9 degrees C Tested on OLPC XO-1 and OLPC XO-1.75 laptops. [1] include/linux/power_supply.h [2] Documentation/power/power_supply_class.txt Cc: sta...@vger.kernel.org Signed-off-by: Lubomir Rintel --- drivers/power/supply/olpc_battery.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/power/supply/olpc_battery.c b/drivers/power/supply/olpc_battery.c index 6da79ae14860..5a97e42a3547 100644 --- a/drivers/power/supply/olpc_battery.c +++ b/drivers/power/supply/olpc_battery.c @@ -428,14 +428,14 @@ static int olpc_bat_get_property(struct power_supply *psy, if (ret) return ret; - val->intval = (s16)be16_to_cpu(ec_word) * 100 / 256; + val->intval = (s16)be16_to_cpu(ec_word) * 10 / 256; break; case POWER_SUPPLY_PROP_TEMP_AMBIENT: ret = olpc_ec_cmd(EC_AMB_TEMP, NULL, 0, (void *)_word, 2); if (ret) return ret; - val->intval = (int)be16_to_cpu(ec_word) * 100 / 256; + val->intval = (int)be16_to_cpu(ec_word) * 10 / 256; break; case POWER_SUPPLY_PROP_CHARGE_COUNTER: ret = olpc_ec_cmd(EC_BAT_ACR, NULL, 0, (void *)_word, 2); -- 2.19.0
[PATCH] MAINTAINERS: Add me to Android drivers
I am one of the main engineers working on ashmem. I have been fixing bugs in the driver and have been involved in the memfd conversion discussions and sending patches about that. I also have an understanding of the binder driver and was involved with some of the development on finer grained locking. So I would like to be added to the MAINTAINERS file for android drivers for review and maintenance of ashmem and other Android drivers. Cc: tk...@google.com Cc: gre...@linuxfoundation.org Signed-off-by: Joel Fernandes (Google) --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS index 544cac829cf4..d639c4d04438 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -894,6 +894,7 @@ M: Greg Kroah-Hartman M: Arve Hjønnevåg M: Todd Kjos M: Martijn Coenen +M: Joel Fernandes T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging.git L: de...@driverdev.osuosl.org S: Supported -- 2.19.0.605.g01d371f741-goog
[PATCH] MAINTAINERS: Add me to Android drivers
I am one of the main engineers working on ashmem. I have been fixing bugs in the driver and have been involved in the memfd conversion discussions and sending patches about that. I also have an understanding of the binder driver and was involved with some of the development on finer grained locking. So I would like to be added to the MAINTAINERS file for android drivers for review and maintenance of ashmem and other Android drivers. Cc: tk...@google.com Cc: gre...@linuxfoundation.org Signed-off-by: Joel Fernandes (Google) --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS index 544cac829cf4..d639c4d04438 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -894,6 +894,7 @@ M: Greg Kroah-Hartman M: Arve Hjønnevåg M: Todd Kjos M: Martijn Coenen +M: Joel Fernandes T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging.git L: de...@driverdev.osuosl.org S: Supported -- 2.19.0.605.g01d371f741-goog
Re: [PATCH] Allow hwrng to initialize crng.
On Wed, Sep 26, 2018 at 6:35 PM Jarkko Sakkinen wrote: > > On Wed, Sep 26, 2018 at 11:24:55AM +0800, Louis Collard wrote: > > Some systems, for example embedded systems, do not generate > > enough entropy on boot through interrupts, and boot may be blocked for > > several minutes waiting for a call to getrandom to complete. > > > > Currently, random data is read from a hwrng when it is registered, > > and is loaded into primary_crng. This data is treated in the same > > way as data that is device-specific but otherwise unchanging, and > > so primary_crng cannot become initialized with the data from the > > hwrng. > > > > This change causes the data initially read from the hwrng to be > > treated the same as subsequent data that is read from the hwrng if > > it's quality score is non-zero. > > > > The implications of this are: > > > > The data read from hwrng can cause primary_crng to become > > initialized, therefore avoiding problems of getrandom blocking > > on boot. > > > > Calls to getrandom (with GRND_RANDOM) may be using entropy > > exclusively (or in practise, almost exclusively) from the hwrng. > > > > Regarding the latter point; this behavior is the same as if a > > user specified a quality score of 1 (bit of entropy per 1024 bits) > > so hopefully this is not too scary a change to make. > > > > This change is the result of the discussion here: > > https://patchwork.kernel.org/patch/10453893/ > > > > Signed-off-by: Louis Collard > > Acked-by: Jarkko Sakkinen > > /Jarkko Thanks! Adding a few people I think I should have included previously - I'm new to this process so apologies for any missteps; please let me know if there is anything else I can / should be doing!
Re: [PATCH] Allow hwrng to initialize crng.
On Wed, Sep 26, 2018 at 6:35 PM Jarkko Sakkinen wrote: > > On Wed, Sep 26, 2018 at 11:24:55AM +0800, Louis Collard wrote: > > Some systems, for example embedded systems, do not generate > > enough entropy on boot through interrupts, and boot may be blocked for > > several minutes waiting for a call to getrandom to complete. > > > > Currently, random data is read from a hwrng when it is registered, > > and is loaded into primary_crng. This data is treated in the same > > way as data that is device-specific but otherwise unchanging, and > > so primary_crng cannot become initialized with the data from the > > hwrng. > > > > This change causes the data initially read from the hwrng to be > > treated the same as subsequent data that is read from the hwrng if > > it's quality score is non-zero. > > > > The implications of this are: > > > > The data read from hwrng can cause primary_crng to become > > initialized, therefore avoiding problems of getrandom blocking > > on boot. > > > > Calls to getrandom (with GRND_RANDOM) may be using entropy > > exclusively (or in practise, almost exclusively) from the hwrng. > > > > Regarding the latter point; this behavior is the same as if a > > user specified a quality score of 1 (bit of entropy per 1024 bits) > > so hopefully this is not too scary a change to make. > > > > This change is the result of the discussion here: > > https://patchwork.kernel.org/patch/10453893/ > > > > Signed-off-by: Louis Collard > > Acked-by: Jarkko Sakkinen > > /Jarkko Thanks! Adding a few people I think I should have included previously - I'm new to this process so apologies for any missteps; please let me know if there is anything else I can / should be doing!
Re: [PATCH - resend] VFS: use synchronize_rcu_expedited() in namespace_unlock()
On Fri, Oct 05, 2018 at 11:27:37AM +1000, NeilBrown wrote: > > The synchronize_rcu() in namespace_unlock() is called every time > a filesystem is unmounted. If a great many filesystems are mounted, > this can cause a noticable slow-down in, for example, system shutdown. > > The sequence: > mkdir -p /tmp/Mtest/{0..5000} > time for i in /tmp/Mtest/*; do mount -t tmpfs tmpfs $i ; done > time umount /tmp/Mtest/* > > on a 4-cpu VM can report 8 seconds to mount the tmpfs filesystems, and > 100 seconds to unmount them. > > Boot the same VM with 1 CPU and it takes 18 seconds to mount the > tmpfs filesystems, but only 36 to unmount. > > If we change the synchronize_rcu() to synchronize_rcu_expedited() > the umount time on a 4-cpu VM drop to 0.6 seconds > > I think this 200-fold speed up is worth the slightly high system > impact of using synchronize_rcu_expedited(). > > Acked-by: Paul E. McKenney (from general rcu > perspective) > Signed-off-by: NeilBrown > --- > > I posted this last October, then again last November (cc:ing Linus) > Paul is happy enough with it, but no other response. > I'm hoping it can get applied this time Umm... IIRC, the last one got sidetracked on the other thing in the series... that was s_anon stuff. I can live with this one; FWIW, what kind of load would trigger the impact of the change? Paul?
Re: [PATCH - resend] VFS: use synchronize_rcu_expedited() in namespace_unlock()
On Fri, Oct 05, 2018 at 11:27:37AM +1000, NeilBrown wrote: > > The synchronize_rcu() in namespace_unlock() is called every time > a filesystem is unmounted. If a great many filesystems are mounted, > this can cause a noticable slow-down in, for example, system shutdown. > > The sequence: > mkdir -p /tmp/Mtest/{0..5000} > time for i in /tmp/Mtest/*; do mount -t tmpfs tmpfs $i ; done > time umount /tmp/Mtest/* > > on a 4-cpu VM can report 8 seconds to mount the tmpfs filesystems, and > 100 seconds to unmount them. > > Boot the same VM with 1 CPU and it takes 18 seconds to mount the > tmpfs filesystems, but only 36 to unmount. > > If we change the synchronize_rcu() to synchronize_rcu_expedited() > the umount time on a 4-cpu VM drop to 0.6 seconds > > I think this 200-fold speed up is worth the slightly high system > impact of using synchronize_rcu_expedited(). > > Acked-by: Paul E. McKenney (from general rcu > perspective) > Signed-off-by: NeilBrown > --- > > I posted this last October, then again last November (cc:ing Linus) > Paul is happy enough with it, but no other response. > I'm hoping it can get applied this time Umm... IIRC, the last one got sidetracked on the other thing in the series... that was s_anon stuff. I can live with this one; FWIW, what kind of load would trigger the impact of the change? Paul?
linux-next: build failure after merge of the drm-msm tree
Hi Rob, After merging the drm-msm tree, today's linux-next build (arm multi_v7_defconfig) failed like this: arm-linux-gnueabi-ld: drivers/gpu/drm/msm/adreno/a6xx_gpu.o: in function `a6xx_gpu_busy': a6xx_gpu.c:(.text+0x70): undefined reference to `__aeabi_uldivmod' Caused by commit a2c3c0a54d4c ("drm/msm/a6xx: Add devfreq support for a6xx") I have used the drm-msm tree from next-20181004 for today. -- Cheers, Stephen Rothwell pgpTe4jFg2sAC.pgp Description: OpenPGP digital signature
linux-next: build failure after merge of the drm-msm tree
Hi Rob, After merging the drm-msm tree, today's linux-next build (arm multi_v7_defconfig) failed like this: arm-linux-gnueabi-ld: drivers/gpu/drm/msm/adreno/a6xx_gpu.o: in function `a6xx_gpu_busy': a6xx_gpu.c:(.text+0x70): undefined reference to `__aeabi_uldivmod' Caused by commit a2c3c0a54d4c ("drm/msm/a6xx: Add devfreq support for a6xx") I have used the drm-msm tree from next-20181004 for today. -- Cheers, Stephen Rothwell pgpTe4jFg2sAC.pgp Description: OpenPGP digital signature
Re: linux-next: Tree for Oct 4
On 10/04/2018 04:44 PM, Stephen Rothwell wrote: Hi Geert, On Thu, 4 Oct 2018 16:21:42 +0200 Geert Uytterhoeven wrote: On Thu, Oct 4, 2018 at 3:47 PM Guenter Roeck wrote: Time for a status report. Build results: total: 135 pass: 121 fail: 14 Failed builds: arm:allmodconfig i386:allyesconfig i386:allmodconfig m68k:defconfig m68k:allmodconfig m68k:sun3_defconfig mips:allmodconfig parisc:allmodconfig powerpc:ppc6xx_defconfig s390:defconfig s390:allmodconfig s390:allnoconfig sparc32:allmodconfig xtensa:allmodconfig Most (all?) 32-bit builds are broken due to commit 571ed1fd2390f74e ("SUNRPC: Replace krb5_seq_lock with a lockless scheme"), presumably fixed by Arnd's "SUNRPC: use cmpxchg64() in gss_seq_send64_fetch_and_inc" (https://lore.kernel.org/patchwork/patch/994909/). I have added that patch to the nfs tree merge in linux-next today. Most of the boot failures are hopefully fixed with https://lore.kernel.org/patchwork/patch/995254/ Guenter
Re: linux-next: Tree for Oct 4
On 10/04/2018 04:44 PM, Stephen Rothwell wrote: Hi Geert, On Thu, 4 Oct 2018 16:21:42 +0200 Geert Uytterhoeven wrote: On Thu, Oct 4, 2018 at 3:47 PM Guenter Roeck wrote: Time for a status report. Build results: total: 135 pass: 121 fail: 14 Failed builds: arm:allmodconfig i386:allyesconfig i386:allmodconfig m68k:defconfig m68k:allmodconfig m68k:sun3_defconfig mips:allmodconfig parisc:allmodconfig powerpc:ppc6xx_defconfig s390:defconfig s390:allmodconfig s390:allnoconfig sparc32:allmodconfig xtensa:allmodconfig Most (all?) 32-bit builds are broken due to commit 571ed1fd2390f74e ("SUNRPC: Replace krb5_seq_lock with a lockless scheme"), presumably fixed by Arnd's "SUNRPC: use cmpxchg64() in gss_seq_send64_fetch_and_inc" (https://lore.kernel.org/patchwork/patch/994909/). I have added that patch to the nfs tree merge in linux-next today. Most of the boot failures are hopefully fixed with https://lore.kernel.org/patchwork/patch/995254/ Guenter
[PATCH - resend] VFS: use synchronize_rcu_expedited() in namespace_unlock()
The synchronize_rcu() in namespace_unlock() is called every time a filesystem is unmounted. If a great many filesystems are mounted, this can cause a noticable slow-down in, for example, system shutdown. The sequence: mkdir -p /tmp/Mtest/{0..5000} time for i in /tmp/Mtest/*; do mount -t tmpfs tmpfs $i ; done time umount /tmp/Mtest/* on a 4-cpu VM can report 8 seconds to mount the tmpfs filesystems, and 100 seconds to unmount them. Boot the same VM with 1 CPU and it takes 18 seconds to mount the tmpfs filesystems, but only 36 to unmount. If we change the synchronize_rcu() to synchronize_rcu_expedited() the umount time on a 4-cpu VM drop to 0.6 seconds I think this 200-fold speed up is worth the slightly high system impact of using synchronize_rcu_expedited(). Acked-by: Paul E. McKenney (from general rcu perspective) Signed-off-by: NeilBrown --- I posted this last October, then again last November (cc:ing Linus) Paul is happy enough with it, but no other response. I'm hoping it can get applied this time Thanks, NeilBrown fs/namespace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/namespace.c b/fs/namespace.c index 99186556f8d3..02e978b22294 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -1360,7 +1360,7 @@ static void namespace_unlock(void) if (likely(hlist_empty())) return; - synchronize_rcu(); + synchronize_rcu_expedited(); group_pin_kill(); } -- 2.14.0.rc0.dirty signature.asc Description: PGP signature
[PATCH - resend] VFS: use synchronize_rcu_expedited() in namespace_unlock()
The synchronize_rcu() in namespace_unlock() is called every time a filesystem is unmounted. If a great many filesystems are mounted, this can cause a noticable slow-down in, for example, system shutdown. The sequence: mkdir -p /tmp/Mtest/{0..5000} time for i in /tmp/Mtest/*; do mount -t tmpfs tmpfs $i ; done time umount /tmp/Mtest/* on a 4-cpu VM can report 8 seconds to mount the tmpfs filesystems, and 100 seconds to unmount them. Boot the same VM with 1 CPU and it takes 18 seconds to mount the tmpfs filesystems, but only 36 to unmount. If we change the synchronize_rcu() to synchronize_rcu_expedited() the umount time on a 4-cpu VM drop to 0.6 seconds I think this 200-fold speed up is worth the slightly high system impact of using synchronize_rcu_expedited(). Acked-by: Paul E. McKenney (from general rcu perspective) Signed-off-by: NeilBrown --- I posted this last October, then again last November (cc:ing Linus) Paul is happy enough with it, but no other response. I'm hoping it can get applied this time Thanks, NeilBrown fs/namespace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/namespace.c b/fs/namespace.c index 99186556f8d3..02e978b22294 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -1360,7 +1360,7 @@ static void namespace_unlock(void) if (likely(hlist_empty())) return; - synchronize_rcu(); + synchronize_rcu_expedited(); group_pin_kill(); } -- 2.14.0.rc0.dirty signature.asc Description: PGP signature
[PATCH] Input: uinput - add a schedule point in uinput_inject_events()
Large writes to uinput interface may cause rcu stalls. Let's add cond_resched() to the loop to avoid this. Signed-off-by: Dmitry Torokhov --- drivers/input/misc/uinput.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c index eb14ddf69346..8ec483e8688b 100644 --- a/drivers/input/misc/uinput.c +++ b/drivers/input/misc/uinput.c @@ -598,6 +598,7 @@ static ssize_t uinput_inject_events(struct uinput_device *udev, input_event(udev->dev, ev.type, ev.code, ev.value); bytes += input_event_size(); + cond_resched(); } return bytes; -- 2.19.0.605.g01d371f741-goog -- Dmitry
[PATCH] Input: uinput - add a schedule point in uinput_inject_events()
Large writes to uinput interface may cause rcu stalls. Let's add cond_resched() to the loop to avoid this. Signed-off-by: Dmitry Torokhov --- drivers/input/misc/uinput.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c index eb14ddf69346..8ec483e8688b 100644 --- a/drivers/input/misc/uinput.c +++ b/drivers/input/misc/uinput.c @@ -598,6 +598,7 @@ static ssize_t uinput_inject_events(struct uinput_device *udev, input_event(udev->dev, ev.type, ev.code, ev.value); bytes += input_event_size(); + cond_resched(); } return bytes; -- 2.19.0.605.g01d371f741-goog -- Dmitry
[PATCH] Input: evdev - add a schedule point in evdev_write()
Large writes to evdev interface may cause rcu stalls. Let's add cond_resched() to the loop to avoid this. Signed-off-by: Dmitry Torokhov --- drivers/input/evdev.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index 370206f987f9..f48369d6f3a0 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c @@ -564,6 +564,7 @@ static ssize_t evdev_write(struct file *file, const char __user *buffer, input_inject_event(>handle, event.type, event.code, event.value); + cond_resched(); } out: -- 2.19.0.605.g01d371f741-goog -- Dmitry
[PATCH] Input: evdev - add a schedule point in evdev_write()
Large writes to evdev interface may cause rcu stalls. Let's add cond_resched() to the loop to avoid this. Signed-off-by: Dmitry Torokhov --- drivers/input/evdev.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index 370206f987f9..f48369d6f3a0 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c @@ -564,6 +564,7 @@ static ssize_t evdev_write(struct file *file, const char __user *buffer, input_inject_event(>handle, event.type, event.code, event.value); + cond_resched(); } out: -- 2.19.0.605.g01d371f741-goog -- Dmitry
Re: [PATCH v2 5/5] ASoC: qdsp6: q6asm-dai: Add support to compress offload
On 26-09-18, 11:23, Srinivas Kandagatla wrote: > This patch adds MP3 playback support in q6asm dais, adding other codec > support should be pretty trivial. > > Signed-off-by: Srinivas Kandagatla > --- > sound/soc/qcom/Kconfig | 1 + > sound/soc/qcom/qdsp6/q6asm-dai.c | 377 ++- > 2 files changed, 377 insertions(+), 1 deletion(-) > > diff --git a/sound/soc/qcom/Kconfig b/sound/soc/qcom/Kconfig > index 2a4c912d1e48..ebf991bb546c 100644 > --- a/sound/soc/qcom/Kconfig > +++ b/sound/soc/qcom/Kconfig > @@ -66,6 +66,7 @@ config SND_SOC_QDSP6_ASM > tristate > > config SND_SOC_QDSP6_ASM_DAI > + select SND_SOC_COMPRESS > tristate > > config SND_SOC_QDSP6 > diff --git a/sound/soc/qcom/qdsp6/q6asm-dai.c > b/sound/soc/qcom/qdsp6/q6asm-dai.c > index 9db9a2944ef2..57b8abcbebcd 100644 > --- a/sound/soc/qcom/qdsp6/q6asm-dai.c > +++ b/sound/soc/qcom/qdsp6/q6asm-dai.c > @@ -11,6 +11,8 @@ > #include > #include > #include > +#include > +#include > #include > #include > #include > @@ -31,6 +33,16 @@ > #define CAPTURE_MIN_PERIOD_SIZE 320 > #define SID_MASK_DEFAULT 0xF > > +/* Default values used if user space does not set */ > +#define COMPR_PLAYBACK_MIN_FRAGMENT_SIZE (8 * 1024) > +#define COMPR_PLAYBACK_MAX_FRAGMENT_SIZE (128 * 1024) > +#define COMPR_PLAYBACK_MIN_NUM_FRAGMENTS (4) > +#define COMPR_PLAYBACK_MAX_NUM_FRAGMENTS (16 * 4) > +#define Q6ASM_DAI_TX_RX 0 > +#define Q6ASM_DAI_TX 1 > +#define Q6ASM_DAI_RX 2 > + > + Unnecessary double space > enum stream_state { > Q6ASM_STREAM_IDLE = 0, > Q6ASM_STREAM_STOPPED, > @@ -39,11 +51,22 @@ enum stream_state { > > struct q6asm_dai_rtd { > struct snd_pcm_substream *substream; > + struct snd_compr_stream *cstream; > + struct snd_compr_params codec_param; > + struct snd_dma_buffer dma_buffer; > + > phys_addr_t phys; > + spinlock_t lock; why would we need a lock for compress case? -- ~Vinod
Re: [PATCH v2 5/5] ASoC: qdsp6: q6asm-dai: Add support to compress offload
On 26-09-18, 11:23, Srinivas Kandagatla wrote: > This patch adds MP3 playback support in q6asm dais, adding other codec > support should be pretty trivial. > > Signed-off-by: Srinivas Kandagatla > --- > sound/soc/qcom/Kconfig | 1 + > sound/soc/qcom/qdsp6/q6asm-dai.c | 377 ++- > 2 files changed, 377 insertions(+), 1 deletion(-) > > diff --git a/sound/soc/qcom/Kconfig b/sound/soc/qcom/Kconfig > index 2a4c912d1e48..ebf991bb546c 100644 > --- a/sound/soc/qcom/Kconfig > +++ b/sound/soc/qcom/Kconfig > @@ -66,6 +66,7 @@ config SND_SOC_QDSP6_ASM > tristate > > config SND_SOC_QDSP6_ASM_DAI > + select SND_SOC_COMPRESS > tristate > > config SND_SOC_QDSP6 > diff --git a/sound/soc/qcom/qdsp6/q6asm-dai.c > b/sound/soc/qcom/qdsp6/q6asm-dai.c > index 9db9a2944ef2..57b8abcbebcd 100644 > --- a/sound/soc/qcom/qdsp6/q6asm-dai.c > +++ b/sound/soc/qcom/qdsp6/q6asm-dai.c > @@ -11,6 +11,8 @@ > #include > #include > #include > +#include > +#include > #include > #include > #include > @@ -31,6 +33,16 @@ > #define CAPTURE_MIN_PERIOD_SIZE 320 > #define SID_MASK_DEFAULT 0xF > > +/* Default values used if user space does not set */ > +#define COMPR_PLAYBACK_MIN_FRAGMENT_SIZE (8 * 1024) > +#define COMPR_PLAYBACK_MAX_FRAGMENT_SIZE (128 * 1024) > +#define COMPR_PLAYBACK_MIN_NUM_FRAGMENTS (4) > +#define COMPR_PLAYBACK_MAX_NUM_FRAGMENTS (16 * 4) > +#define Q6ASM_DAI_TX_RX 0 > +#define Q6ASM_DAI_TX 1 > +#define Q6ASM_DAI_RX 2 > + > + Unnecessary double space > enum stream_state { > Q6ASM_STREAM_IDLE = 0, > Q6ASM_STREAM_STOPPED, > @@ -39,11 +51,22 @@ enum stream_state { > > struct q6asm_dai_rtd { > struct snd_pcm_substream *substream; > + struct snd_compr_stream *cstream; > + struct snd_compr_params codec_param; > + struct snd_dma_buffer dma_buffer; > + > phys_addr_t phys; > + spinlock_t lock; why would we need a lock for compress case? -- ~Vinod
Re: [PATCH v2 1/5] ALSA: soc-compress: add support to snd_compr_set_runtime_buffer()
On 26-09-18, 11:23, Srinivas Kandagatla wrote: > This patch adds support to set runtime dma buffer on compressed stream. The change is fine as is, but I feel we need to document the motivation in the changelog. The core changes need a bit more explanation on why we should add this.. > > Signed-off-by: Srinivas Kandagatla > --- > include/sound/compress_driver.h | 19 +++ > 1 file changed, 19 insertions(+) > > diff --git a/include/sound/compress_driver.h b/include/sound/compress_driver.h > index ea8c93bbb0e0..0cdc3999ecfa 100644 > --- a/include/sound/compress_driver.h > +++ b/include/sound/compress_driver.h > @@ -23,6 +23,7 @@ struct snd_compr_ops; > * struct snd_compr_runtime: runtime stream description > * @state: stream state > * @ops: pointer to DSP callbacks > + * @dma_buffer_p: runtime dma buffer pointer > * @buffer: pointer to kernel buffer, valid only when not in mmap mode or > * DSP doesn't implement copy > * @buffer_size: size of the above buffer > @@ -37,6 +38,7 @@ struct snd_compr_ops; > struct snd_compr_runtime { > snd_pcm_state_t state; > struct snd_compr_ops *ops; > + struct snd_dma_buffer *dma_buffer_p; > void *buffer; > u64 buffer_size; > u32 fragment_size; > @@ -175,6 +177,23 @@ static inline void snd_compr_drain_notify(struct > snd_compr_stream *stream) > wake_up(>runtime->sleep); > } > > +/** > + * snd_compr_set_runtime_buffer - Set the Compress runtime buffer > + * @substream: compress substream to set > + * @bufp: the buffer information, NULL to clear > + * > + * Copy the buffer information to runtime buffer when @bufp is non-NULL. > + * Otherwise it clears the current buffer information. > + */ > +static inline void snd_compr_set_runtime_buffer( > + struct snd_compr_stream *substream, > + struct snd_dma_buffer *bufp) > +{ > + struct snd_compr_runtime *runtime = substream->runtime; > + > + runtime->dma_buffer_p = bufp; > +} > + > int snd_compr_stop_error(struct snd_compr_stream *stream, >snd_pcm_state_t state); > > -- > 2.19.0 -- ~Vinod
Re: [PATCH v2 1/5] ALSA: soc-compress: add support to snd_compr_set_runtime_buffer()
On 26-09-18, 11:23, Srinivas Kandagatla wrote: > This patch adds support to set runtime dma buffer on compressed stream. The change is fine as is, but I feel we need to document the motivation in the changelog. The core changes need a bit more explanation on why we should add this.. > > Signed-off-by: Srinivas Kandagatla > --- > include/sound/compress_driver.h | 19 +++ > 1 file changed, 19 insertions(+) > > diff --git a/include/sound/compress_driver.h b/include/sound/compress_driver.h > index ea8c93bbb0e0..0cdc3999ecfa 100644 > --- a/include/sound/compress_driver.h > +++ b/include/sound/compress_driver.h > @@ -23,6 +23,7 @@ struct snd_compr_ops; > * struct snd_compr_runtime: runtime stream description > * @state: stream state > * @ops: pointer to DSP callbacks > + * @dma_buffer_p: runtime dma buffer pointer > * @buffer: pointer to kernel buffer, valid only when not in mmap mode or > * DSP doesn't implement copy > * @buffer_size: size of the above buffer > @@ -37,6 +38,7 @@ struct snd_compr_ops; > struct snd_compr_runtime { > snd_pcm_state_t state; > struct snd_compr_ops *ops; > + struct snd_dma_buffer *dma_buffer_p; > void *buffer; > u64 buffer_size; > u32 fragment_size; > @@ -175,6 +177,23 @@ static inline void snd_compr_drain_notify(struct > snd_compr_stream *stream) > wake_up(>runtime->sleep); > } > > +/** > + * snd_compr_set_runtime_buffer - Set the Compress runtime buffer > + * @substream: compress substream to set > + * @bufp: the buffer information, NULL to clear > + * > + * Copy the buffer information to runtime buffer when @bufp is non-NULL. > + * Otherwise it clears the current buffer information. > + */ > +static inline void snd_compr_set_runtime_buffer( > + struct snd_compr_stream *substream, > + struct snd_dma_buffer *bufp) > +{ > + struct snd_compr_runtime *runtime = substream->runtime; > + > + runtime->dma_buffer_p = bufp; > +} > + > int snd_compr_stop_error(struct snd_compr_stream *stream, >snd_pcm_state_t state); > > -- > 2.19.0 -- ~Vinod
Re: [ANN] init-kconfig - easy way to embrace Linux's kconfig
On 10/4/18 1:02 PM, Luis Chamberlain wrote: > Every now and then a project is born, and they decide to use Linux's > kconfig to enable configuration of their project. As it stands we *know* > kconfig is now used in at least over 12 different projects [0]. I myself > added kconfig to one as well years ago. Even research reveals that > kconfig has become one of the leading industrial variability modeling > languages [1] [2]. > > What is often difficult to do though is to start off using kconfig and > integrating it into a project. Or updating / syncing to the latest > kconfig from upstream Linux. > > I had yet another need to use kconfig for another small project so > decided to make a clean template others can use and help keep it in sync. > This is a passive fork which aims to keep in sync with the Linux > kernel's latest kconfig to make it easier to keep up to date and to > enable new projects to use and embrace kconfig on their own. The goal > is *not* to fork kconfig and evolve it separately, but rather keep in > sync with the evolution of kconfig on Linux to make it easier for > projects to use kconfig and also update their own kconfig when needed. > > This may also be useful if folks want to test R code on a smaller > compartamentalized codebase. > > If you find this useful and you'd like to help keep it in sync, send > patches my way as the kernel's kconfig evolves. The code is up on > gitlab [3]. > > Do we want to document this option on Linux in case folks want to try > and embrace kconfig on their own for other projects? > > [0] http://www.eng.uwaterloo.ca/~shshe/kconfig_semantics.pdf > [1] http://gsd.uwaterloo.ca/sites/default/files/vm-2013-berger.pdf > [2] http://gsd.uwaterloo.ca/sites/default/files/ase241-berger_0.pdf > [3] https://gitlab.com/mcgrof/init-kconfig > > Luis > Hi Luis, Any crossover with Ulf's recent announcement? https://lore.kernel.org/lkml/CAFkk2KQ-sC=bad9fckovpnmzn8m+ezfpztire+j5vpvw120...@mail.gmail.com/ thanx, -- ~Randy
Re: [ANN] init-kconfig - easy way to embrace Linux's kconfig
On 10/4/18 1:02 PM, Luis Chamberlain wrote: > Every now and then a project is born, and they decide to use Linux's > kconfig to enable configuration of their project. As it stands we *know* > kconfig is now used in at least over 12 different projects [0]. I myself > added kconfig to one as well years ago. Even research reveals that > kconfig has become one of the leading industrial variability modeling > languages [1] [2]. > > What is often difficult to do though is to start off using kconfig and > integrating it into a project. Or updating / syncing to the latest > kconfig from upstream Linux. > > I had yet another need to use kconfig for another small project so > decided to make a clean template others can use and help keep it in sync. > This is a passive fork which aims to keep in sync with the Linux > kernel's latest kconfig to make it easier to keep up to date and to > enable new projects to use and embrace kconfig on their own. The goal > is *not* to fork kconfig and evolve it separately, but rather keep in > sync with the evolution of kconfig on Linux to make it easier for > projects to use kconfig and also update their own kconfig when needed. > > This may also be useful if folks want to test R code on a smaller > compartamentalized codebase. > > If you find this useful and you'd like to help keep it in sync, send > patches my way as the kernel's kconfig evolves. The code is up on > gitlab [3]. > > Do we want to document this option on Linux in case folks want to try > and embrace kconfig on their own for other projects? > > [0] http://www.eng.uwaterloo.ca/~shshe/kconfig_semantics.pdf > [1] http://gsd.uwaterloo.ca/sites/default/files/vm-2013-berger.pdf > [2] http://gsd.uwaterloo.ca/sites/default/files/ase241-berger_0.pdf > [3] https://gitlab.com/mcgrof/init-kconfig > > Luis > Hi Luis, Any crossover with Ulf's recent announcement? https://lore.kernel.org/lkml/CAFkk2KQ-sC=bad9fckovpnmzn8m+ezfpztire+j5vpvw120...@mail.gmail.com/ thanx, -- ~Randy
linux-next: build failure after merge of the nfsd tree
Hi all, After merging the nfsd tree, today's linux-next build (x86_64 allmodconfig) failed like this: fs/nfs/dns_resolve.c: In function 'nfs_dns_ent_put': fs/nfs/dns_resolve.c:119:11: error: passing argument 1 of 'call_rcu_sched' from incompatible pointer type [-Werror=incompatible-pointer-types] call_rcu(item, nfs_dns_ent_free_rcu); ^~~~ In file included from include/linux/srcu.h:33, from include/linux/notifier.h:16, from include/linux/memory_hotplug.h:7, from include/linux/mmzone.h:758, from include/linux/gfp.h:6, from include/linux/umh.h:4, from include/linux/kmod.h:22, from include/linux/module.h:13, from fs/nfs/dns_resolve.c:36: include/linux/rcupdate.h:59:38: note: expected 'struct callback_head *' but argument is of type 'struct nfs_dns_ent *' void call_rcu_sched(struct rcu_head *head, rcu_callback_t func); ~^~~~ Caused by commit fd497f1e40d9 ("NFS: Lockless DNS lookups") I have used the nfsd tree from next-20181004 for today. -- Cheers, Stephen Rothwell pgpkwXakKkEXX.pgp Description: OpenPGP digital signature
linux-next: build failure after merge of the nfsd tree
Hi all, After merging the nfsd tree, today's linux-next build (x86_64 allmodconfig) failed like this: fs/nfs/dns_resolve.c: In function 'nfs_dns_ent_put': fs/nfs/dns_resolve.c:119:11: error: passing argument 1 of 'call_rcu_sched' from incompatible pointer type [-Werror=incompatible-pointer-types] call_rcu(item, nfs_dns_ent_free_rcu); ^~~~ In file included from include/linux/srcu.h:33, from include/linux/notifier.h:16, from include/linux/memory_hotplug.h:7, from include/linux/mmzone.h:758, from include/linux/gfp.h:6, from include/linux/umh.h:4, from include/linux/kmod.h:22, from include/linux/module.h:13, from fs/nfs/dns_resolve.c:36: include/linux/rcupdate.h:59:38: note: expected 'struct callback_head *' but argument is of type 'struct nfs_dns_ent *' void call_rcu_sched(struct rcu_head *head, rcu_callback_t func); ~^~~~ Caused by commit fd497f1e40d9 ("NFS: Lockless DNS lookups") I have used the nfsd tree from next-20181004 for today. -- Cheers, Stephen Rothwell pgpkwXakKkEXX.pgp Description: OpenPGP digital signature
linux-next: build failure after merge of the nfsd tree
Hi all, After merging the nfsd tree, today's linux-next build (powerpc ppc64_defconfig) failed like this: net/sunrpc/xprtrdma/svc_rdma_backchannel.c: In function 'svc_rdma_handle_bc_reply': net/sunrpc/xprtrdma/svc_rdma_backchannel.c:67:21: error: 'struct rpc_xprt' has no member named 'recv_lock'; did you mean 'reserve_lock'? spin_unlock(>recv_lock); ^ reserve_lock net/sunrpc/xprtrdma/svc_rdma_backchannel.c:79:19: error: 'struct rpc_xprt' has no member named 'recv_lock'; did you mean 'reserve_lock'? spin_lock(>recv_lock); ^ reserve_lock Caused by commit cf4f6fd48dac ("svcrdma: Remove ->release_rqst call in bc reply handler") interacting with commit 75c84151a9dc ("SUNRPC: Rename xprt->recv_lock to xprt->queue_lock") from the nfs tree. I have added the following merge fix patch for today: From b249a74ca8c4f992e2530f95218ea4f2ed72e0b9 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Fri, 5 Oct 2018 09:51:30 +1000 Subject: [PATCH] svcrdma: fix up for recv_lock rename Signed-off-by: Stephen Rothwell --- net/sunrpc/xprtrdma/svc_rdma_backchannel.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/sunrpc/xprtrdma/svc_rdma_backchannel.c b/net/sunrpc/xprtrdma/svc_rdma_backchannel.c index 19e34a6aa583..2d176a48543a 100644 --- a/net/sunrpc/xprtrdma/svc_rdma_backchannel.c +++ b/net/sunrpc/xprtrdma/svc_rdma_backchannel.c @@ -64,7 +64,7 @@ int svc_rdma_handle_bc_reply(struct rpc_xprt *xprt, __be32 *rdma_resp, goto out_unlock; memcpy(dst->iov_base, p, len); xprt_pin_rqst(req); - spin_unlock(>recv_lock); + spin_unlock(>queue_lock); credits = be32_to_cpup(rdma_resp + 2); if (credits == 0) @@ -76,7 +76,7 @@ int svc_rdma_handle_bc_reply(struct rpc_xprt *xprt, __be32 *rdma_resp, xprt->cwnd = credits << RPC_CWNDSHIFT; spin_unlock_bh(>transport_lock); - spin_lock(>recv_lock); + spin_lock(>queue_lock); ret = 0; xprt_complete_rqst(req->rq_task, rcvbuf->len); xprt_unpin_rqst(req); -- 2.18.0 -- Cheers, Stephen Rothwell pgpYHk5mFRdcl.pgp Description: OpenPGP digital signature
linux-next: build failure after merge of the nfsd tree
Hi all, After merging the nfsd tree, today's linux-next build (powerpc ppc64_defconfig) failed like this: net/sunrpc/xprtrdma/svc_rdma_backchannel.c: In function 'svc_rdma_handle_bc_reply': net/sunrpc/xprtrdma/svc_rdma_backchannel.c:67:21: error: 'struct rpc_xprt' has no member named 'recv_lock'; did you mean 'reserve_lock'? spin_unlock(>recv_lock); ^ reserve_lock net/sunrpc/xprtrdma/svc_rdma_backchannel.c:79:19: error: 'struct rpc_xprt' has no member named 'recv_lock'; did you mean 'reserve_lock'? spin_lock(>recv_lock); ^ reserve_lock Caused by commit cf4f6fd48dac ("svcrdma: Remove ->release_rqst call in bc reply handler") interacting with commit 75c84151a9dc ("SUNRPC: Rename xprt->recv_lock to xprt->queue_lock") from the nfs tree. I have added the following merge fix patch for today: From b249a74ca8c4f992e2530f95218ea4f2ed72e0b9 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Fri, 5 Oct 2018 09:51:30 +1000 Subject: [PATCH] svcrdma: fix up for recv_lock rename Signed-off-by: Stephen Rothwell --- net/sunrpc/xprtrdma/svc_rdma_backchannel.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/sunrpc/xprtrdma/svc_rdma_backchannel.c b/net/sunrpc/xprtrdma/svc_rdma_backchannel.c index 19e34a6aa583..2d176a48543a 100644 --- a/net/sunrpc/xprtrdma/svc_rdma_backchannel.c +++ b/net/sunrpc/xprtrdma/svc_rdma_backchannel.c @@ -64,7 +64,7 @@ int svc_rdma_handle_bc_reply(struct rpc_xprt *xprt, __be32 *rdma_resp, goto out_unlock; memcpy(dst->iov_base, p, len); xprt_pin_rqst(req); - spin_unlock(>recv_lock); + spin_unlock(>queue_lock); credits = be32_to_cpup(rdma_resp + 2); if (credits == 0) @@ -76,7 +76,7 @@ int svc_rdma_handle_bc_reply(struct rpc_xprt *xprt, __be32 *rdma_resp, xprt->cwnd = credits << RPC_CWNDSHIFT; spin_unlock_bh(>transport_lock); - spin_lock(>recv_lock); + spin_lock(>queue_lock); ret = 0; xprt_complete_rqst(req->rq_task, rcvbuf->len); xprt_unpin_rqst(req); -- 2.18.0 -- Cheers, Stephen Rothwell pgpYHk5mFRdcl.pgp Description: OpenPGP digital signature