From db4c4426daedffefcfd890d04a6ec9ed93268878 Mon Sep 17 00:00:00 2001 From: Vineet Gupta Date: Thu, 28 Jan 2016 12:52:33 +0530 Subject: ARC: [intc-compact] setup TIMER as percpu_dev This removes the quirk from arc_request_percpu_irq() and paves way for future simplifications Signed-off-by: Vineet Gupta --- arch/arc/kernel/intc-compact.c | 3 ++- arch/arc/kernel/irq.c | 12 ------------ 2 files changed, 2 insertions(+), 13 deletions(-) (limited to 'arch/arc/kernel') diff --git a/arch/arc/kernel/intc-compact.c b/arch/arc/kernel/intc-compact.c index 224d1c3aa9c4..4195eedeb6d1 100644 --- a/arch/arc/kernel/intc-compact.c +++ b/arch/arc/kernel/intc-compact.c @@ -79,8 +79,9 @@ static struct irq_chip onchip_intc = { static int arc_intc_domain_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw) { - switch (irq) { + switch (hw) { case TIMER0_IRQ: + irq_set_percpu_devid(irq); irq_set_chip_and_handler(irq, &onchip_intc, handle_percpu_irq); break; default: diff --git a/arch/arc/kernel/irq.c b/arch/arc/kernel/irq.c index ba17f85285cf..88074b50456b 100644 --- a/arch/arc/kernel/irq.c +++ b/arch/arc/kernel/irq.c @@ -72,18 +72,6 @@ void arc_request_percpu_irq(int irq, int cpu, if (!cpu) { int rc; -#ifdef CONFIG_ISA_ARCOMPACT - /* - * A subsequent request_percpu_irq() fails if percpu_devid is - * not set. That in turns sets NOAUTOEN, meaning each core needs - * to call enable_percpu_irq() - * - * For ARCv2, this is done in irq map function since we know - * which irqs are strictly per cpu - */ - irq_set_percpu_devid(irq); -#endif - rc = request_percpu_irq(irq, isr, irq_nm, percpu_dev); if (rc) panic("Percpu IRQ request failed for %d\n", irq); -- cgit v1.2.3 From 569579401ae1c9b9f317f38261e32135b153e9b3 Mon Sep 17 00:00:00 2001 From: Vineet Gupta Date: Thu, 28 Jan 2016 12:56:03 +0530 Subject: ARC: opencode arc_request_percpu_irq - The idea is to remove the API usage since it has a subltle design flaw - relies on being called on cpu0 first. This is true for some early per cpu irqs such as TIMER/IPI, but not for late probed per cpu peripherals such a perf. And it's usage in perf has already bitten us once: see c6317bc7c5ab ("ARCv2: perf: Ensure perf intr gets enabled on all cores") where we ended up open coding it anyways - The seeming duplication will go away once we start using cpu notifier for timer setup Signed-off-by: Vineet Gupta --- arch/arc/include/asm/irq.h | 3 --- arch/arc/kernel/irq.c | 29 ----------------------------- arch/arc/kernel/smp.c | 15 ++++++++++++++- arch/arc/kernel/time.c | 14 +++++++++++--- 4 files changed, 25 insertions(+), 36 deletions(-) (limited to 'arch/arc/kernel') diff --git a/arch/arc/include/asm/irq.h b/arch/arc/include/asm/irq.h index 49014f0ef36d..f9c735ede4fc 100644 --- a/arch/arc/include/asm/irq.h +++ b/arch/arc/include/asm/irq.h @@ -26,8 +26,5 @@ extern void arc_init_IRQ(void); void arc_local_timer_setup(void); -void arc_request_percpu_irq(int irq, int cpu, - irqreturn_t (*isr)(int irq, void *dev), - const char *irq_nm, void *percpu_dev); #endif diff --git a/arch/arc/kernel/irq.c b/arch/arc/kernel/irq.c index 88074b50456b..fb6dede9d05f 100644 --- a/arch/arc/kernel/irq.c +++ b/arch/arc/kernel/irq.c @@ -50,32 +50,3 @@ void arch_do_IRQ(unsigned int irq, struct pt_regs *regs) irq_exit(); set_irq_regs(old_regs); } - -/* - * API called for requesting percpu interrupts - called by each CPU - * - For boot CPU, actually request the IRQ with genirq core + enables - * - For subsequent callers only enable called locally - * - * Relies on being called by boot cpu first (i.e. request called ahead) of - * any enable as expected by genirq. Hence Suitable only for TIMER, IPI - * which are guaranteed to be setup on boot core first. - * Late probed peripherals such as perf can't use this as there no guarantee - * of being called on boot CPU first. - */ - -void arc_request_percpu_irq(int irq, int cpu, - irqreturn_t (*isr)(int irq, void *dev), - const char *irq_nm, - void *percpu_dev) -{ - /* Boot cpu calls request, all call enable */ - if (!cpu) { - int rc; - - rc = request_percpu_irq(irq, isr, irq_nm, percpu_dev); - if (rc) - panic("Percpu IRQ request failed for %d\n", irq); - } - - enable_percpu_irq(irq, 0); -} diff --git a/arch/arc/kernel/smp.c b/arch/arc/kernel/smp.c index 4cb3add77c75..ca83ebe15a64 100644 --- a/arch/arc/kernel/smp.c +++ b/arch/arc/kernel/smp.c @@ -346,6 +346,10 @@ irqreturn_t do_IPI(int irq, void *dev_id) /* * API called by platform code to hookup arch-common ISR to their IPI IRQ + * + * Note: If IPI is provided by platform (vs. say ARC MCIP), their intc setup/map + * function needs to call call irq_set_percpu_devid() for IPI IRQ, otherwise + * request_percpu_irq() below will fail */ static DEFINE_PER_CPU(int, ipi_dev); @@ -353,7 +357,16 @@ int smp_ipi_irq_setup(int cpu, int irq) { int *dev = per_cpu_ptr(&ipi_dev, cpu); - arc_request_percpu_irq(irq, cpu, do_IPI, "IPI Interrupt", dev); + /* Boot cpu calls request, all call enable */ + if (!cpu) { + int rc; + + rc = request_percpu_irq(irq, do_IPI, "IPI Interrupt", dev); + if (rc) + panic("Percpu IRQ request failed for %d\n", irq); + } + + enable_percpu_irq(irq, 0); return 0; } diff --git a/arch/arc/kernel/time.c b/arch/arc/kernel/time.c index 7d9a736fc7e5..146da3cbcc99 100644 --- a/arch/arc/kernel/time.c +++ b/arch/arc/kernel/time.c @@ -251,14 +251,22 @@ void arc_local_timer_setup() { struct clock_event_device *evt = this_cpu_ptr(&arc_clockevent_device); int cpu = smp_processor_id(); + int irq = TIMER0_IRQ; evt->cpumask = cpumask_of(cpu); clockevents_config_and_register(evt, arc_get_core_freq(), 0, ARC_TIMER_MAX); - /* setup the per-cpu timer IRQ handler - for all cpus */ - arc_request_percpu_irq(TIMER0_IRQ, cpu, timer_irq_handler, - "Timer0 (per-cpu-tick)", evt); + if (!cpu) { + int rc; + + rc = request_percpu_irq(irq, timer_irq_handler, + "Timer0 (per-cpu-tick)", evt); + if (rc) + panic("Percpu IRQ request failed for TIMER\n"); + } + + enable_percpu_irq(irq, 0); } /* -- cgit v1.2.3 From eec3c58efa271d7dfa30c978dda2c88280212634 Mon Sep 17 00:00:00 2001 From: Noam Camus Date: Fri, 1 Jan 2016 15:48:49 +0530 Subject: ARC: clockevent: switch to cpu notifier for clockevent setup ARC Timers so far have been handled as "legacy" w/o explicit description in DT. This poses challenge for newer platforms wanting to use them. This series will eventually help move timers over to DT. This patch does a small change of using a CPU notifier to set clockevent on non-boot CPUs. So explicit setup is done only on boot CPU (which will later be done by DT) Signed-off-by: Noam Camus [vgupta: broken off from a bigger patch] Signed-off-by: Vineet Gupta --- arch/arc/include/asm/irq.h | 1 - arch/arc/kernel/smp.c | 2 -- arch/arc/kernel/time.c | 62 ++++++++++++++++++++++++++++++---------------- 3 files changed, 41 insertions(+), 24 deletions(-) (limited to 'arch/arc/kernel') diff --git a/arch/arc/include/asm/irq.h b/arch/arc/include/asm/irq.h index f9c735ede4fc..5c0b5abda67a 100644 --- a/arch/arc/include/asm/irq.h +++ b/arch/arc/include/asm/irq.h @@ -25,6 +25,5 @@ #include extern void arc_init_IRQ(void); -void arc_local_timer_setup(void); #endif diff --git a/arch/arc/kernel/smp.c b/arch/arc/kernel/smp.c index ca83ebe15a64..6b1813456336 100644 --- a/arch/arc/kernel/smp.c +++ b/arch/arc/kernel/smp.c @@ -138,8 +138,6 @@ void start_kernel_secondary(void) if (machine_desc->init_per_cpu) machine_desc->init_per_cpu(cpu); - arc_local_timer_setup(); - local_irq_enable(); preempt_disable(); cpu_startup_entry(CPUHP_AP_ONLINE_IDLE); diff --git a/arch/arc/kernel/time.c b/arch/arc/kernel/time.c index 146da3cbcc99..e97be743d47b 100644 --- a/arch/arc/kernel/time.c +++ b/arch/arc/kernel/time.c @@ -29,17 +29,14 @@ * which however is currently broken */ -#include #include #include -#include #include #include #include -#include -#include #include #include +#include #include #include #include @@ -183,6 +180,8 @@ static struct clocksource arc_counter = { /********** Clock Event Device *********/ +static int arc_timer_irq = TIMER0_IRQ; + /* * Arm the timer to interrupt after @cycles * The distinction for oneshot/periodic is done in arc_event_timer_ack() below @@ -218,7 +217,6 @@ static DEFINE_PER_CPU(struct clock_event_device, arc_clockevent_device) = { .features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_PERIODIC, .rating = 300, - .irq = TIMER0_IRQ, /* hardwired, no need for resources */ .set_next_event = arc_clkevent_set_next_event, .set_state_periodic = arc_clkevent_set_periodic, }; @@ -244,29 +242,52 @@ static irqreturn_t timer_irq_handler(int irq, void *dev_id) return IRQ_HANDLED; } +static int arc_timer_cpu_notify(struct notifier_block *self, + unsigned long action, void *hcpu) +{ + struct clock_event_device *evt = this_cpu_ptr(&arc_clockevent_device); + + evt->cpumask = cpumask_of(smp_processor_id()); + + switch (action & ~CPU_TASKS_FROZEN) { + case CPU_STARTING: + clockevents_config_and_register(evt, arc_get_core_freq(), + 0, ULONG_MAX); + enable_percpu_irq(arc_timer_irq, 0); + break; + case CPU_DYING: + disable_percpu_irq(arc_timer_irq); + break; + } + + return NOTIFY_OK; +} + +static struct notifier_block arc_timer_cpu_nb = { + .notifier_call = arc_timer_cpu_notify, +}; + /* - * Setup the local event timer for @cpu + * clockevent setup for boot CPU */ -void arc_local_timer_setup() +static void __init arc_clockevent_setup(void) { struct clock_event_device *evt = this_cpu_ptr(&arc_clockevent_device); - int cpu = smp_processor_id(); - int irq = TIMER0_IRQ; + int ret; - evt->cpumask = cpumask_of(cpu); + register_cpu_notifier(&arc_timer_cpu_nb); + + evt->cpumask = cpumask_of(smp_processor_id()); clockevents_config_and_register(evt, arc_get_core_freq(), 0, ARC_TIMER_MAX); - if (!cpu) { - int rc; - - rc = request_percpu_irq(irq, timer_irq_handler, - "Timer0 (per-cpu-tick)", evt); - if (rc) - panic("Percpu IRQ request failed for TIMER\n"); - } + /* Needs apriori irq_set_percpu_devid() done in intc map function */ + ret = request_percpu_irq(arc_timer_irq, timer_irq_handler, + "Timer0 (per-cpu-tick)", evt); + if (ret) + pr_err("Unable to register interrupt\n"); - enable_percpu_irq(irq, 0); + enable_percpu_irq(arc_timer_irq, 0); } /* @@ -291,6 +312,5 @@ void __init time_init(void) */ clocksource_register_hz(&arc_counter, arc_get_core_freq()); - /* sets up the periodic event timer */ - arc_local_timer_setup(); + arc_clockevent_setup(); } -- cgit v1.2.3 From 69fbd09874ded099d445271d05681529dac4d00a Mon Sep 17 00:00:00 2001 From: Noam Camus Date: Thu, 14 Jan 2016 12:20:08 +0530 Subject: ARC: clockevent: Prepare for DT based probe - call clocksource_probe() - This in turns needs of_clk_init() to be called earlier Cc: Daniel Lezcano Signed-off-by: Noam Camus [vgupta: broken off from a bigger patch] Signed-off-by: Vineet Gupta --- arch/arc/Kconfig | 3 ++- arch/arc/kernel/setup.c | 2 -- arch/arc/kernel/time.c | 5 +++++ 3 files changed, 7 insertions(+), 3 deletions(-) (limited to 'arch/arc/kernel') diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig index a8767430df7d..ae3943435abf 100644 --- a/arch/arc/Kconfig +++ b/arch/arc/Kconfig @@ -10,8 +10,9 @@ config ARC def_bool y select ARCH_SUPPORTS_ATOMIC_RMW if ARC_HAS_LLSC select BUILDTIME_EXTABLE_SORT - select COMMON_CLK + select CLKSRC_OF select CLONE_BACKWARDS + select COMMON_CLK select GENERIC_ATOMIC64 select GENERIC_CLOCKEVENTS select GENERIC_FIND_FIRST_BIT diff --git a/arch/arc/kernel/setup.c b/arch/arc/kernel/setup.c index 151acf0c9383..507ec523112a 100644 --- a/arch/arc/kernel/setup.c +++ b/arch/arc/kernel/setup.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include @@ -444,7 +443,6 @@ void __init setup_arch(char **cmdline_p) static int __init customize_machine(void) { - of_clk_init(NULL); /* * Traverses flattened DeviceTree - registering platform devices * (if any) complete with their resources diff --git a/arch/arc/kernel/time.c b/arch/arc/kernel/time.c index e97be743d47b..848353a27ac8 100644 --- a/arch/arc/kernel/time.c +++ b/arch/arc/kernel/time.c @@ -34,6 +34,8 @@ #include #include #include +#include +#include #include #include #include @@ -301,6 +303,9 @@ static void __init arc_clockevent_setup(void) */ void __init time_init(void) { + of_clk_init(NULL); + clocksource_probe(); + /* * sets up the timekeeping free-flowing counter which also returns * whether the counter is usable as clocksource -- cgit v1.2.3 From 77c8d0d6b3f4ea0989b9ca42fb368cc2aac02495 Mon Sep 17 00:00:00 2001 From: Vineet Gupta Date: Fri, 1 Jan 2016 17:58:45 +0530 Subject: ARC: clockevent: DT based probe - timer frequency is derived from DT (no longer rely on top level DT "clock-frequency" probed early and exported by asm/clk.h) - TIMER0_IRQ need not be exported across arch code, confined to intc as it is property of same - Any failures in clockevent setup are considered pedantic and system panic()'s as there is no generic fallback (unlike clocksource where a jiffies based soft clocksource always exists) Acked-by: Daniel Lezcano Signed-off-by: Vineet Gupta --- arch/arc/include/asm/irq.h | 9 ------- arch/arc/kernel/intc-compact.c | 2 ++ arch/arc/kernel/time.c | 59 ++++++++++++++++++++++++++++++------------ 3 files changed, 45 insertions(+), 25 deletions(-) (limited to 'arch/arc/kernel') diff --git a/arch/arc/include/asm/irq.h b/arch/arc/include/asm/irq.h index 5c0b5abda67a..a6ac89dc228f 100644 --- a/arch/arc/include/asm/irq.h +++ b/arch/arc/include/asm/irq.h @@ -12,15 +12,6 @@ #define NR_CPU_IRQS 32 /* number of interrupt lines of ARC770 CPU */ #define NR_IRQS 128 /* allow some CPU external IRQ handling */ -/* Platform Independent IRQs */ -#ifdef CONFIG_ISA_ARCOMPACT -#define TIMER0_IRQ 3 -#define TIMER1_IRQ 4 -#else -#define TIMER0_IRQ 16 -#define TIMER1_IRQ 17 -#endif - #include #include diff --git a/arch/arc/kernel/intc-compact.c b/arch/arc/kernel/intc-compact.c index 4195eedeb6d1..d31bc647146d 100644 --- a/arch/arc/kernel/intc-compact.c +++ b/arch/arc/kernel/intc-compact.c @@ -14,6 +14,8 @@ #include #include +#define TIMER0_IRQ 3 /* Fixed by ISA */ + /* * Early Hardware specific Interrupt setup * -Platform independent, needed for each CPU (not foldable into init_IRQ) diff --git a/arch/arc/kernel/time.c b/arch/arc/kernel/time.c index 848353a27ac8..01ec30d83590 100644 --- a/arch/arc/kernel/time.c +++ b/arch/arc/kernel/time.c @@ -30,19 +30,15 @@ */ #include -#include -#include -#include -#include #include #include #include #include #include +#include +#include #include #include -#include -#include #include @@ -59,6 +55,30 @@ #define ARC_TIMER_MAX 0xFFFFFFFF +static unsigned long arc_timer_freq; + +static int noinline arc_get_timer_clk(struct device_node *node) +{ + struct clk *clk; + int ret; + + clk = of_clk_get(node, 0); + if (IS_ERR(clk)) { + pr_err("timer missing clk"); + return PTR_ERR(clk); + } + + ret = clk_prepare_enable(clk); + if (ret) { + pr_err("Couldn't enable parent clk\n"); + return ret; + } + + arc_timer_freq = clk_get_rate(clk); + + return 0; +} + /********** Clock Source Device *********/ #ifdef CONFIG_ARC_HAS_GFRC @@ -182,7 +202,7 @@ static struct clocksource arc_counter = { /********** Clock Event Device *********/ -static int arc_timer_irq = TIMER0_IRQ; +static int arc_timer_irq; /* * Arm the timer to interrupt after @cycles @@ -210,7 +230,7 @@ static int arc_clkevent_set_periodic(struct clock_event_device *dev) * At X Hz, 1 sec = 1000ms -> X cycles; * 10ms -> X / 100 cycles */ - arc_timer_event_setup(arc_get_core_freq() / HZ); + arc_timer_event_setup(arc_timer_freq / HZ); return 0; } @@ -253,7 +273,7 @@ static int arc_timer_cpu_notify(struct notifier_block *self, switch (action & ~CPU_TASKS_FROZEN) { case CPU_STARTING: - clockevents_config_and_register(evt, arc_get_core_freq(), + clockevents_config_and_register(evt, arc_timer_freq, 0, ULONG_MAX); enable_percpu_irq(arc_timer_irq, 0); break; @@ -272,25 +292,35 @@ static struct notifier_block arc_timer_cpu_nb = { /* * clockevent setup for boot CPU */ -static void __init arc_clockevent_setup(void) +static void __init arc_clockevent_setup(struct device_node *node) { struct clock_event_device *evt = this_cpu_ptr(&arc_clockevent_device); int ret; register_cpu_notifier(&arc_timer_cpu_nb); + arc_timer_irq = irq_of_parse_and_map(node, 0); + if (arc_timer_irq <= 0) + panic("clockevent: missing irq"); + + ret = arc_get_timer_clk(node); + if (ret) + panic("clockevent: missing clk"); + + evt->irq = arc_timer_irq; evt->cpumask = cpumask_of(smp_processor_id()); - clockevents_config_and_register(evt, arc_get_core_freq(), + clockevents_config_and_register(evt, arc_timer_freq, 0, ARC_TIMER_MAX); /* Needs apriori irq_set_percpu_devid() done in intc map function */ ret = request_percpu_irq(arc_timer_irq, timer_irq_handler, "Timer0 (per-cpu-tick)", evt); if (ret) - pr_err("Unable to register interrupt\n"); + panic("clockevent: unable to request irq\n"); enable_percpu_irq(arc_timer_irq, 0); } +CLOCKSOURCE_OF_DECLARE(arc_clkevt, "snps,arc-timer", arc_clockevent_setup); /* * Called from start_kernel() - boot CPU only @@ -299,7 +329,6 @@ static void __init arc_clockevent_setup(void) * -Also sets up any global state needed for timer subsystem: * - for "counting" timer, registers a clocksource, usable across CPUs * (provided that underlying counter h/w is synchronized across cores) - * - for "event" timer, sets up TIMER0 IRQ (as that is platform agnostic) */ void __init time_init(void) { @@ -315,7 +344,5 @@ void __init time_init(void) * CLK upto 4.29 GHz can be safely represented in 32 bits * because Max 32 bit number is 4,294,967,295 */ - clocksource_register_hz(&arc_counter, arc_get_core_freq()); - - arc_clockevent_setup(); + clocksource_register_hz(&arc_counter, arc_timer_freq); } -- cgit v1.2.3 From e608b53ea863a92eb458cb1ec7c2fcf3ca2b043a Mon Sep 17 00:00:00 2001 From: Vineet Gupta Date: Fri, 1 Jan 2016 18:05:48 +0530 Subject: ARC: clocksource: DT based probe - Remove explicit clocksource setup and let it be done by OF framework by defining CLOCKSOURCE_OF_DECLARE() for various timers - This allows multiple clocksources to be potentially registered simultaneouly: previously we could only do one - as all of them had same arc_counter_setup() routine for registration - Setup routines also ensure that the underlying timer actually exists. - Remove some of the panic() calls if underlying timer is NOT detected as fallback clocksource might still be available 1. If GRFC doesn't exist, jiffies clocksource gets registered anyways 2. if RTC doesn't exist, TIMER1 can take over (as it is always present) Cc: Daniel Lezcano Signed-off-by: Vineet Gupta --- arch/arc/kernel/mcip.c | 4 +- arch/arc/kernel/setup.c | 3 -- arch/arc/kernel/time.c | 134 +++++++++++++++++++++++++++++------------------- 3 files changed, 82 insertions(+), 59 deletions(-) (limited to 'arch/arc/kernel') diff --git a/arch/arc/kernel/mcip.c b/arch/arc/kernel/mcip.c index c41c364b926c..262d9c3771e6 100644 --- a/arch/arc/kernel/mcip.c +++ b/arch/arc/kernel/mcip.c @@ -116,15 +116,13 @@ static void mcip_probe_n_setup(void) IS_AVAIL1(mp.dbg, "DEBUG "), IS_AVAIL1(mp.gfrc, "GFRC")); + cpuinfo_arc700[0].extn.gfrc = mp.gfrc; idu_detected = mp.idu; if (mp.dbg) { __mcip_cmd_data(CMD_DEBUG_SET_SELECT, 0, 0xf); __mcip_cmd_data(CMD_DEBUG_SET_MASK, 0xf, 0xf); } - - if (IS_ENABLED(CONFIG_ARC_HAS_GFRC) && !mp.gfrc) - panic("kernel trying to use non-existent GFRC\n"); } struct plat_smp_ops plat_smp_ops = { diff --git a/arch/arc/kernel/setup.c b/arch/arc/kernel/setup.c index 507ec523112a..91f79fa447bc 100644 --- a/arch/arc/kernel/setup.c +++ b/arch/arc/kernel/setup.c @@ -313,9 +313,6 @@ static void arc_chk_core_config(void) if (!cpu->extn.timer1) panic("Timer1 is not present!\n"); - if (IS_ENABLED(CONFIG_ARC_HAS_RTC) && !cpu->extn.rtc) - panic("RTC is not present\n"); - #ifdef CONFIG_ARC_HAS_DCCM /* * DCCM can be arbit placed in hardware. diff --git a/arch/arc/kernel/time.c b/arch/arc/kernel/time.c index 01ec30d83590..4549ab255dd1 100644 --- a/arch/arc/kernel/time.c +++ b/arch/arc/kernel/time.c @@ -83,12 +83,7 @@ static int noinline arc_get_timer_clk(struct device_node *node) #ifdef CONFIG_ARC_HAS_GFRC -static int arc_counter_setup(void) -{ - return 1; -} - -static cycle_t arc_counter_read(struct clocksource *cs) +static cycle_t arc_read_gfrc(struct clocksource *cs) { unsigned long flags; union { @@ -113,15 +108,31 @@ static cycle_t arc_counter_read(struct clocksource *cs) return stamp.full; } -static struct clocksource arc_counter = { +static struct clocksource arc_counter_gfrc = { .name = "ARConnect GFRC", .rating = 400, - .read = arc_counter_read, + .read = arc_read_gfrc, .mask = CLOCKSOURCE_MASK(64), .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; -#else +static void __init arc_cs_setup_gfrc(struct device_node *node) +{ + int exists = cpuinfo_arc700[0].extn.gfrc; + int ret; + + if (WARN(!exists, "Global-64-bit-Ctr clocksource not detected")) + return; + + ret = arc_get_timer_clk(node); + if (ret) + return; + + clocksource_register_hz(&arc_counter_gfrc, arc_timer_freq); +} +CLOCKSOURCE_OF_DECLARE(arc_gfrc, "snps,archs-timer-gfrc", arc_cs_setup_gfrc); + +#endif #ifdef CONFIG_ARC_HAS_RTC @@ -129,15 +140,7 @@ static struct clocksource arc_counter = { #define AUX_RTC_LOW 0x104 #define AUX_RTC_HIGH 0x105 -int arc_counter_setup(void) -{ - write_aux_reg(AUX_RTC_CTRL, 1); - - /* Not usable in SMP */ - return !IS_ENABLED(CONFIG_SMP); -} - -static cycle_t arc_counter_read(struct clocksource *cs) +static cycle_t arc_read_rtc(struct clocksource *cs) { unsigned long status; union { @@ -161,44 +164,73 @@ static cycle_t arc_counter_read(struct clocksource *cs) return stamp.full; } -static struct clocksource arc_counter = { +static struct clocksource arc_counter_rtc = { .name = "ARCv2 RTC", .rating = 350, - .read = arc_counter_read, + .read = arc_read_rtc, .mask = CLOCKSOURCE_MASK(64), .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; -#else /* !CONFIG_ARC_HAS_RTC */ - -/* - * set 32bit TIMER1 to keep counting monotonically and wraparound - */ -int arc_counter_setup(void) +static void __init arc_cs_setup_rtc(struct device_node *node) { - write_aux_reg(ARC_REG_TIMER1_LIMIT, ARC_TIMER_MAX); - write_aux_reg(ARC_REG_TIMER1_CNT, 0); - write_aux_reg(ARC_REG_TIMER1_CTRL, TIMER_CTRL_NH); + int exists = cpuinfo_arc700[smp_processor_id()].extn.rtc; + int ret; + + if (WARN(!exists, "Local-64-bit-Ctr clocksource not detected")) + return; + + /* Local to CPU hence not usable in SMP */ + if (WARN(IS_ENABLED(CONFIG_SMP), "Local-64-bit-Ctr not usable in SMP")) + return; + + ret = arc_get_timer_clk(node); + if (ret) + return; - /* Not usable in SMP */ - return !IS_ENABLED(CONFIG_SMP); + write_aux_reg(AUX_RTC_CTRL, 1); + + clocksource_register_hz(&arc_counter_rtc, arc_timer_freq); } +CLOCKSOURCE_OF_DECLARE(arc_rtc, "snps,archs-timer-rtc", arc_cs_setup_rtc); + +#endif -static cycle_t arc_counter_read(struct clocksource *cs) +/* + * 32bit TIMER1 to keep counting monotonically and wraparound + */ + +static cycle_t arc_read_timer1(struct clocksource *cs) { return (cycle_t) read_aux_reg(ARC_REG_TIMER1_CNT); } -static struct clocksource arc_counter = { +static struct clocksource arc_counter_timer1 = { .name = "ARC Timer1", .rating = 300, - .read = arc_counter_read, + .read = arc_read_timer1, .mask = CLOCKSOURCE_MASK(32), .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; -#endif -#endif +static void __init arc_cs_setup_timer1(struct device_node *node) +{ + int ret; + + /* Local to CPU hence not usable in SMP */ + if (IS_ENABLED(CONFIG_SMP)) + return; + + ret = arc_get_timer_clk(node); + if (ret) + return; + + write_aux_reg(ARC_REG_TIMER1_LIMIT, ARC_TIMER_MAX); + write_aux_reg(ARC_REG_TIMER1_CNT, 0); + write_aux_reg(ARC_REG_TIMER1_CTRL, TIMER_CTRL_NH); + + clocksource_register_hz(&arc_counter_timer1, arc_timer_freq); +} /********** Clock Event Device *********/ @@ -320,29 +352,25 @@ static void __init arc_clockevent_setup(struct device_node *node) enable_percpu_irq(arc_timer_irq, 0); } -CLOCKSOURCE_OF_DECLARE(arc_clkevt, "snps,arc-timer", arc_clockevent_setup); + +static void __init arc_of_timer_init(struct device_node *np) +{ + static int init_count = 0; + + if (!init_count) { + init_count = 1; + arc_clockevent_setup(np); + } else { + arc_cs_setup_timer1(np); + } +} +CLOCKSOURCE_OF_DECLARE(arc_clkevt, "snps,arc-timer", arc_of_timer_init); /* * Called from start_kernel() - boot CPU only - * - * -Sets up h/w timers as applicable on boot cpu - * -Also sets up any global state needed for timer subsystem: - * - for "counting" timer, registers a clocksource, usable across CPUs - * (provided that underlying counter h/w is synchronized across cores) */ void __init time_init(void) { of_clk_init(NULL); clocksource_probe(); - - /* - * sets up the timekeeping free-flowing counter which also returns - * whether the counter is usable as clocksource - */ - if (arc_counter_setup()) - /* - * CLK upto 4.29 GHz can be safely represented in 32 bits - * because Max 32 bit number is 4,294,967,295 - */ - clocksource_register_hz(&arc_counter, arc_timer_freq); } -- cgit v1.2.3 From 88555cc584d93e658722f090d3f8fb84d5fa15a5 Mon Sep 17 00:00:00 2001 From: Vineet Gupta Date: Wed, 30 Mar 2016 18:35:28 +0530 Subject: ARC: irq: export some IRQs again This will be needed for switching to linear irq domain as irq_create_mapping() called by intr code needs the IRQ numbers in addition to existing usage in mcip.c for requesting the irq Signed-off-by: Vineet Gupta --- arch/arc/include/asm/irq.h | 6 ++++++ arch/arc/kernel/mcip.c | 3 --- 2 files changed, 6 insertions(+), 3 deletions(-) (limited to 'arch/arc/kernel') diff --git a/arch/arc/include/asm/irq.h b/arch/arc/include/asm/irq.h index a6ac89dc228f..c0fa0d2de400 100644 --- a/arch/arc/include/asm/irq.h +++ b/arch/arc/include/asm/irq.h @@ -12,6 +12,12 @@ #define NR_CPU_IRQS 32 /* number of interrupt lines of ARC770 CPU */ #define NR_IRQS 128 /* allow some CPU external IRQ handling */ +/* Platform Independent IRQs */ +#ifdef CONFIG_ISA_ARCV2 +#define IPI_IRQ 19 +#define SOFTIRQ_IRQ 21 +#endif + #include #include diff --git a/arch/arc/kernel/mcip.c b/arch/arc/kernel/mcip.c index 262d9c3771e6..72f9179b1a24 100644 --- a/arch/arc/kernel/mcip.c +++ b/arch/arc/kernel/mcip.c @@ -15,9 +15,6 @@ #include #include -#define IPI_IRQ 19 -#define SOFTIRQ_IRQ 21 - static char smp_cpuinfo_buf[128]; static int idu_detected; -- cgit v1.2.3 From 1b0ccb8a4eee2d8c14adc996e07335cb7aa9e2ac Mon Sep 17 00:00:00 2001 From: Vineet Gupta Date: Fri, 1 Jan 2016 15:12:54 +0530 Subject: ARC: [intc-*] Do a domain lookup in primary handler for hwirq -> linux virq The primary interrupt handler arch_do_IRQ() was passing hwirq as linux virq to core code. This was fragile and worked so far as we only had legacy/linear domains. This came out of a rant by Marc Zyngier. http://lists.infradead.org/pipermail/linux-snps-arc/2015-December/000298.html Cc: Marc Zyngier Cc: Thomas Gleixner Cc: Noam Camus Signed-off-by: Vineet Gupta --- arch/arc/Kconfig | 1 + arch/arc/kernel/intc-arcv2.c | 9 ++++++--- arch/arc/kernel/intc-compact.c | 10 ++++++---- arch/arc/kernel/irq.c | 9 ++------- 4 files changed, 15 insertions(+), 14 deletions(-) (limited to 'arch/arc/kernel') diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig index ae3943435abf..4f1482aa8823 100644 --- a/arch/arc/Kconfig +++ b/arch/arc/Kconfig @@ -31,6 +31,7 @@ config ARC select HAVE_MOD_ARCH_SPECIFIC if ARC_DW2_UNWIND select HAVE_OPROFILE select HAVE_PERF_EVENTS + select HANDLE_DOMAIN_IRQ select IRQ_DOMAIN select MODULES_USE_ELF_RELA select NO_BOOTMEM diff --git a/arch/arc/kernel/intc-arcv2.c b/arch/arc/kernel/intc-arcv2.c index 942526322ae7..592cc977151e 100644 --- a/arch/arc/kernel/intc-arcv2.c +++ b/arch/arc/kernel/intc-arcv2.c @@ -137,21 +137,24 @@ static const struct irq_domain_ops arcv2_irq_ops = { .map = arcv2_irq_map, }; -static struct irq_domain *root_domain; static int __init init_onchip_IRQ(struct device_node *intc, struct device_node *parent) { + struct irq_domain *root_domain; + if (parent) panic("DeviceTree incore intc not a root irq controller\n"); root_domain = irq_domain_add_legacy(intc, NR_CPU_IRQS, 0, 0, &arcv2_irq_ops, NULL); - if (!root_domain) panic("root irq domain not avail\n"); - /* with this we don't need to export root_domain */ + /* + * Needed for primary domain lookup to succeed + * This is a primary irqchip, and can never have a parent + */ irq_set_default_host(root_domain); return 0; diff --git a/arch/arc/kernel/intc-compact.c b/arch/arc/kernel/intc-compact.c index d31bc647146d..48a8b24de23e 100644 --- a/arch/arc/kernel/intc-compact.c +++ b/arch/arc/kernel/intc-compact.c @@ -97,21 +97,23 @@ static const struct irq_domain_ops arc_intc_domain_ops = { .map = arc_intc_domain_map, }; -static struct irq_domain *root_domain; - static int __init init_onchip_IRQ(struct device_node *intc, struct device_node *parent) { + struct irq_domain *root_domain; + if (parent) panic("DeviceTree incore intc not a root irq controller\n"); root_domain = irq_domain_add_legacy(intc, NR_CPU_IRQS, 0, 0, &arc_intc_domain_ops, NULL); - if (!root_domain) panic("root irq domain not avail\n"); - /* with this we don't need to export root_domain */ + /* + * Needed for primary domain lookup to succeed + * This is a primary irqchip, and can never have a parent + */ irq_set_default_host(root_domain); return 0; diff --git a/arch/arc/kernel/irq.c b/arch/arc/kernel/irq.c index fb6dede9d05f..538b36afe89e 100644 --- a/arch/arc/kernel/irq.c +++ b/arch/arc/kernel/irq.c @@ -41,12 +41,7 @@ void __init init_IRQ(void) * "C" Entry point for any ARC ISR, called from low level vector handler * @irq is the vector number read from ICAUSE reg of on-chip intc */ -void arch_do_IRQ(unsigned int irq, struct pt_regs *regs) +void arch_do_IRQ(unsigned int hwirq, struct pt_regs *regs) { - struct pt_regs *old_regs = set_irq_regs(regs); - - irq_enter(); - generic_handle_irq(irq); - irq_exit(); - set_irq_regs(old_regs); + handle_domain_irq(NULL, hwirq, regs); } -- cgit v1.2.3 From d21beffb0b9181c8823f71a5a7fabce6a0d4cf29 Mon Sep 17 00:00:00 2001 From: Vineet Gupta Date: Thu, 28 Jan 2016 09:40:10 +0530 Subject: ARC: [intc-*] switch to linear domain Now that we have Timers probed from DT, don't need legacy domain This however requires mapping to be called explicitly for the IRQ which still can't (and probably never) be probed from DT such as IPI and SOFTIRQ Acked-by: Marc Zyngier Signed-off-by: Vineet Gupta --- arch/arc/kernel/intc-arcv2.c | 8 ++++++-- arch/arc/kernel/intc-compact.c | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) (limited to 'arch/arc/kernel') diff --git a/arch/arc/kernel/intc-arcv2.c b/arch/arc/kernel/intc-arcv2.c index 592cc977151e..6c24faf48b16 100644 --- a/arch/arc/kernel/intc-arcv2.c +++ b/arch/arc/kernel/intc-arcv2.c @@ -146,8 +146,7 @@ init_onchip_IRQ(struct device_node *intc, struct device_node *parent) if (parent) panic("DeviceTree incore intc not a root irq controller\n"); - root_domain = irq_domain_add_legacy(intc, NR_CPU_IRQS, 0, 0, - &arcv2_irq_ops, NULL); + root_domain = irq_domain_add_linear(intc, NR_CPU_IRQS, &arcv2_irq_ops, NULL); if (!root_domain) panic("root irq domain not avail\n"); @@ -157,6 +156,11 @@ init_onchip_IRQ(struct device_node *intc, struct device_node *parent) */ irq_set_default_host(root_domain); +#ifdef CONFIG_SMP + irq_create_mapping(root_domain, IPI_IRQ); +#endif + irq_create_mapping(root_domain, SOFTIRQ_IRQ); + return 0; } diff --git a/arch/arc/kernel/intc-compact.c b/arch/arc/kernel/intc-compact.c index 48a8b24de23e..c5cceca36118 100644 --- a/arch/arc/kernel/intc-compact.c +++ b/arch/arc/kernel/intc-compact.c @@ -105,7 +105,7 @@ init_onchip_IRQ(struct device_node *intc, struct device_node *parent) if (parent) panic("DeviceTree incore intc not a root irq controller\n"); - root_domain = irq_domain_add_legacy(intc, NR_CPU_IRQS, 0, 0, + root_domain = irq_domain_add_linear(intc, NR_CPU_IRQS, &arc_intc_domain_ops, NULL); if (!root_domain) panic("root irq domain not avail\n"); -- cgit v1.2.3 From 0e6e9b648d802fe6641fe543b6dc4828baded159 Mon Sep 17 00:00:00 2001 From: Alexey Brodkin Date: Mon, 1 Feb 2016 16:31:14 +0300 Subject: ARC: use fixed frequencies in arc_set_early_base_baud() UARTs usually have fixed clock so we're switching to use of constant values instead of something derived from core clock frequency. Among other things this will allow us to get rid of arc_{get|set}_core_freq() and switch to generic clock framework later on. Acked-by: Christian Ruppert Signed-off-by: Alexey Brodkin Signed-off-by: Vineet Gupta --- arch/arc/kernel/devtree.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'arch/arc/kernel') diff --git a/arch/arc/kernel/devtree.c b/arch/arc/kernel/devtree.c index 7e844fd8213f..fecbc96df828 100644 --- a/arch/arc/kernel/devtree.c +++ b/arch/arc/kernel/devtree.c @@ -28,14 +28,12 @@ unsigned int __init arc_early_base_baud(void) static void __init arc_set_early_base_baud(unsigned long dt_root) { - unsigned int core_clk = arc_get_core_freq(); - if (of_flat_dt_is_compatible(dt_root, "abilis,arc-tb10x")) - arc_base_baud = core_clk/3; + arc_base_baud = 166666666; /* Fixed 166.6MHz clk (TB10x) */ else if (of_flat_dt_is_compatible(dt_root, "snps,arc-sdp")) arc_base_baud = 33333333; /* Fixed 33MHz clk (AXS10x) */ else - arc_base_baud = core_clk; + arc_base_baud = 50000000; /* Fixed default 50MHz */ } #else #define arc_set_early_base_baud(dt_root) -- cgit v1.2.3 From 20c7dbbdbe12db75f9e9ac3fd0d713ab95549623 Mon Sep 17 00:00:00 2001 From: Alexey Brodkin Date: Mon, 1 Feb 2016 17:30:17 +0300 Subject: ARC: Don't try to use value of top level clock-frequency in DT We no longer use it and instead a real clk device such as fixed-clk instance is fed to timers etc. Signed-off-by: Alexey Brodkin [vgupta: broken out of a bigger patch, rewrote changelog] Signed-off-by: Vineet Gupta --- arch/arc/kernel/setup.c | 12 +++++++----- arch/arc/plat-axs10x/axs10x.c | 2 -- 2 files changed, 7 insertions(+), 7 deletions(-) (limited to 'arch/arc/kernel') diff --git a/arch/arc/kernel/setup.c b/arch/arc/kernel/setup.c index 91f79fa447bc..f63b8bfefb0c 100644 --- a/arch/arc/kernel/setup.c +++ b/arch/arc/kernel/setup.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include @@ -219,10 +218,6 @@ static char *arc_cpu_mumbojumbo(int cpu_id, char *buf, int len) if (tbl->info.id == 0) n += scnprintf(buf + n, len - n, "UNKNOWN ARC Processor\n"); - n += scnprintf(buf + n, len - n, "CPU speed\t: %u.%02u Mhz\n", - (unsigned int)(arc_get_core_freq() / 1000000), - (unsigned int)(arc_get_core_freq() / 10000) % 100); - n += scnprintf(buf + n, len - n, "Timers\t\t: %s%s%s%s\nISA Extn\t: ", IS_AVAIL1(cpu->extn.timer0, "Timer0 "), IS_AVAIL1(cpu->extn.timer1, "Timer1 "), @@ -472,6 +467,8 @@ static int show_cpuinfo(struct seq_file *m, void *v) { char *str; int cpu_id = ptr_to_cpu(v); + struct device_node *core_clk = of_find_node_by_name(NULL, "core_clk"); + u32 freq = 0; if (!cpu_online(cpu_id)) { seq_printf(m, "processor [%d]\t: Offline\n", cpu_id); @@ -484,6 +481,11 @@ static int show_cpuinfo(struct seq_file *m, void *v) seq_printf(m, arc_cpu_mumbojumbo(cpu_id, str, PAGE_SIZE)); + of_property_read_u32(core_clk, "clock-frequency", &freq); + if (freq) + seq_printf(m, "CPU speed\t: %u.%02u Mhz\n", + freq / 1000000, (freq / 10000) % 100); + seq_printf(m, "Bogo MIPS\t: %lu.%02lu\n", loops_per_jiffy / (500000 / HZ), (loops_per_jiffy / (5000 / HZ)) % 100); diff --git a/arch/arc/plat-axs10x/axs10x.c b/arch/arc/plat-axs10x/axs10x.c index f90fac271d16..9701c93f315d 100644 --- a/arch/arc/plat-axs10x/axs10x.c +++ b/arch/arc/plat-axs10x/axs10x.c @@ -19,7 +19,6 @@ #include #include -#include #include #include #include @@ -448,7 +447,6 @@ static void __init axs103_early_init(void) /* Patching .dtb in-place with new core clock value */ if (freq != orig ) { - arc_set_core_freq(freq * 1000000); freq = cpu_to_be32(freq * 1000000); fdt_setprop_inplace(initial_boot_params, offset, "clock-frequency", &freq, sizeof(freq)); -- cgit v1.2.3 From 6e9318d1be83714e004a0ac795a936df4d2bed3e Mon Sep 17 00:00:00 2001 From: Alexey Brodkin Date: Mon, 1 Feb 2016 17:30:17 +0300 Subject: ARC: RIP arc_{get|set}_core_freq() clk API There are no more users of this - so RIP! Signed-off-by: Alexey Brodkin [vgupta: update changelog] Signed-off-by: Vineet Gupta --- arch/arc/include/asm/clk.h | 22 ---------------------- arch/arc/kernel/Makefile | 2 +- arch/arc/kernel/clk.c | 21 --------------------- arch/arc/kernel/devtree.c | 7 ------- 4 files changed, 1 insertion(+), 51 deletions(-) delete mode 100644 arch/arc/include/asm/clk.h delete mode 100644 arch/arc/kernel/clk.c (limited to 'arch/arc/kernel') diff --git a/arch/arc/include/asm/clk.h b/arch/arc/include/asm/clk.h deleted file mode 100644 index bf9d29f5bd53..000000000000 --- a/arch/arc/include/asm/clk.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (C) 2012 Synopsys, Inc. (www.synopsys.com) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef _ASM_ARC_CLK_H -#define _ASM_ARC_CLK_H - -/* Although we can't really hide core_freq, the accessor is still better way */ -extern unsigned long core_freq; - -static inline unsigned long arc_get_core_freq(void) -{ - return core_freq; -} - -extern int arc_set_core_freq(unsigned long); - -#endif diff --git a/arch/arc/kernel/Makefile b/arch/arc/kernel/Makefile index 1bc2036b19d7..cfcdedf52ff8 100644 --- a/arch/arc/kernel/Makefile +++ b/arch/arc/kernel/Makefile @@ -9,7 +9,7 @@ CFLAGS_ptrace.o += -DUTS_MACHINE='"$(UTS_MACHINE)"' obj-y := arcksyms.o setup.o irq.o time.o reset.o ptrace.o process.o devtree.o -obj-y += signal.o traps.o sys.o troubleshoot.o stacktrace.o disasm.o clk.o +obj-y += signal.o traps.o sys.o troubleshoot.o stacktrace.o disasm.o obj-$(CONFIG_ISA_ARCOMPACT) += entry-compact.o intc-compact.o obj-$(CONFIG_ISA_ARCV2) += entry-arcv2.o intc-arcv2.o obj-$(CONFIG_PCI) += pcibios.o diff --git a/arch/arc/kernel/clk.c b/arch/arc/kernel/clk.c deleted file mode 100644 index 10c7b0b5a079..000000000000 --- a/arch/arc/kernel/clk.c +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (C) 2012 Synopsys, Inc. (www.synopsys.com) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include - -unsigned long core_freq = 80000000; - -/* - * As of now we default to device-tree provided clock - * In future we can determine this in early boot - */ -int arc_set_core_freq(unsigned long freq) -{ - core_freq = freq; - return 0; -} diff --git a/arch/arc/kernel/devtree.c b/arch/arc/kernel/devtree.c index fecbc96df828..f1e07c2344f8 100644 --- a/arch/arc/kernel/devtree.c +++ b/arch/arc/kernel/devtree.c @@ -14,7 +14,6 @@ #include #include #include -#include #include #ifdef CONFIG_SERIAL_EARLYCON @@ -63,8 +62,6 @@ const struct machine_desc * __init setup_machine_fdt(void *dt) { const struct machine_desc *mdesc; unsigned long dt_root; - const void *clk; - int len; if (!early_init_dt_scan(dt)) return NULL; @@ -74,10 +71,6 @@ const struct machine_desc * __init setup_machine_fdt(void *dt) machine_halt(); dt_root = of_get_flat_dt_root(); - clk = of_get_flat_dt_prop(dt_root, "clock-frequency", &len); - if (clk) - arc_set_core_freq(of_read_ulong(clk, len/4)); - arc_set_early_base_baud(dt_root); return mdesc; -- cgit v1.2.3 From 71f9cf8fdd72e5f5c3a60f632bd1534fc7996b81 Mon Sep 17 00:00:00 2001 From: Noam Camus Date: Sat, 7 Nov 2015 09:16:19 +0200 Subject: ARC: Mark secondary cpu online only after all HW setup is done In SMP setup, master loops for each_present_cpu calling cpu_up(). For ARC it returns as soon as new cpu's status becomes online, However secondary may still do HW initializing, machine or platform hook level. So turn secondary online only after all HW setup is done. Signed-off-by: Noam Camus Acked-by: Vineet Gupta --- arch/arc/kernel/smp.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'arch/arc/kernel') diff --git a/arch/arc/kernel/smp.c b/arch/arc/kernel/smp.c index 6b1813456336..f183cc648851 100644 --- a/arch/arc/kernel/smp.c +++ b/arch/arc/kernel/smp.c @@ -126,11 +126,6 @@ void start_kernel_secondary(void) current->active_mm = mm; cpumask_set_cpu(cpu, mm_cpumask(mm)); - notify_cpu_starting(cpu); - set_cpu_online(cpu, true); - - pr_info("## CPU%u LIVE ##: Executing Code...\n", cpu); - /* Some SMP H/w setup - for each cpu */ if (plat_smp_ops.init_per_cpu) plat_smp_ops.init_per_cpu(cpu); @@ -138,6 +133,11 @@ void start_kernel_secondary(void) if (machine_desc->init_per_cpu) machine_desc->init_per_cpu(cpu); + notify_cpu_starting(cpu); + set_cpu_online(cpu, true); + + pr_info("## CPU%u LIVE ##: Executing Code...\n", cpu); + local_irq_enable(); preempt_disable(); cpu_startup_entry(CPUHP_AP_ONLINE_IDLE); -- cgit v1.2.3 From 86c25466f7414d6396f1aaa13e4b34f36ec272d5 Mon Sep 17 00:00:00 2001 From: Noam Camus Date: Mon, 3 Jun 2013 15:17:25 +0300 Subject: ARC: [plat-eznps] Use dedicated identity auxiliary register. With generic "identity" num of CPUs is limited to 256 (8 bit). We use our alternative AUX register GLOBAL_ID (12 bit). Now we can support up to 4096 CPUs. Signed-off-by: Noam Camus --- arch/arc/include/asm/entry-compact.h | 6 ++++++ arch/arc/kernel/ctx_sw.c | 13 +++++++++++++ arch/arc/plat-eznps/include/plat/ctop.h | 9 +++++++++ 3 files changed, 28 insertions(+) (limited to 'arch/arc/kernel') diff --git a/arch/arc/include/asm/entry-compact.h b/arch/arc/include/asm/entry-compact.h index 1d8f57cd6057..e0e1faf03c50 100644 --- a/arch/arc/include/asm/entry-compact.h +++ b/arch/arc/include/asm/entry-compact.h @@ -36,6 +36,10 @@ #include #include /* For THREAD_SIZE */ +#ifdef CONFIG_ARC_PLAT_EZNPS +#include +#endif + /*-------------------------------------------------------------- * Switch to Kernel Mode stack if SP points to User Mode stack * @@ -296,11 +300,13 @@ bic \reg, sp, (THREAD_SIZE - 1) .endm +#ifndef CONFIG_ARC_PLAT_EZNPS /* Get CPU-ID of this core */ .macro GET_CPU_ID reg lr \reg, [identity] lsr \reg, \reg, 8 bmsk \reg, \reg, 7 .endm +#endif #endif /* __ASM_ARC_ENTRY_COMPACT_H */ diff --git a/arch/arc/kernel/ctx_sw.c b/arch/arc/kernel/ctx_sw.c index 5d446df2c413..6f4cb0dab1b9 100644 --- a/arch/arc/kernel/ctx_sw.c +++ b/arch/arc/kernel/ctx_sw.c @@ -16,6 +16,9 @@ #include #include +#ifdef CONFIG_ARC_PLAT_EZNPS +#include +#endif #define KSP_WORD_OFF ((TASK_THREAD + THREAD_KSP) / 4) @@ -66,10 +69,17 @@ __switch_to(struct task_struct *prev_task, struct task_struct *next_task) */ #ifndef CONFIG_SMP "st %2, [@_current_task] \n\t" +#else +#ifdef CONFIG_ARC_PLAT_EZNPS + "lr r24, [%4] \n\t" +#ifndef CONFIG_EZNPS_MTM_EXT + "lsr r24, r24, 4 \n\t" +#endif #else "lr r24, [identity] \n\t" "lsr r24, r24, 8 \n\t" "bmsk r24, r24, 7 \n\t" +#endif "add2 r24, @_current_task, r24 \n\t" "st %2, [r24] \n\t" #endif @@ -107,6 +117,9 @@ __switch_to(struct task_struct *prev_task, struct task_struct *next_task) : "=r"(tmp) : "n"(KSP_WORD_OFF), "r"(next), "r"(prev) +#ifdef CONFIG_ARC_PLAT_EZNPS + , "i"(CTOP_AUX_LOGIC_GLOBAL_ID) +#endif : "blink" ); diff --git a/arch/arc/plat-eznps/include/plat/ctop.h b/arch/arc/plat-eznps/include/plat/ctop.h index 91b25f3dd39a..9d6718c1a199 100644 --- a/arch/arc/plat-eznps/include/plat/ctop.h +++ b/arch/arc/plat-eznps/include/plat/ctop.h @@ -195,6 +195,15 @@ struct nps_host_reg_aux_lpc { #define REG_GIM_P_INT_DST_25 nps_host_reg_non_cl(NPS_GIM_BLKID, 0x149) #define REG_GIM_P_INT_DST_26 nps_host_reg_non_cl(NPS_GIM_BLKID, 0x14A) +#else + +.macro GET_CPU_ID reg + lr \reg, [CTOP_AUX_LOGIC_GLOBAL_ID] +#ifndef CONFIG_EZNPS_MTM_EXT + lsr \reg, \reg, 4 +#endif +.endm + #endif /* __ASSEMBLY__ */ #endif /* _PLAT_EZNPS_CTOP_H */ -- cgit v1.2.3 From cfbcf468454ab4b20f0b4b62da51920b99fdb19e Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Thu, 28 Apr 2016 12:30:53 -0300 Subject: perf core: Pass max stack as a perf_callchain_entry context This makes perf_callchain_{user,kernel}() receive the max stack as context for the perf_callchain_entry, instead of accessing the global sysctl_perf_event_max_stack. Cc: Adrian Hunter Cc: Alexander Shishkin Cc: Alexei Starovoitov Cc: Brendan Gregg Cc: David Ahern Cc: Frederic Weisbecker Cc: He Kuang Cc: Jiri Olsa Cc: Linus Torvalds Cc: Masami Hiramatsu Cc: Milian Wolff Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Stephane Eranian Cc: Thomas Gleixner Cc: Vince Weaver Cc: Wang Nan Cc: Zefan Li Link: http://lkml.kernel.org/n/tip-kolmn1yo40p7jhswxwrc7rrd@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- arch/arc/kernel/perf_event.c | 6 +++--- arch/arm/kernel/perf_callchain.c | 10 +++++----- arch/arm64/kernel/perf_callchain.c | 14 +++++++------- arch/metag/kernel/perf_callchain.c | 10 +++++----- arch/mips/kernel/perf_event.c | 12 ++++++------ arch/powerpc/perf/callchain.c | 14 +++++++------- arch/s390/kernel/perf_event.c | 4 ++-- arch/sh/kernel/perf_callchain.c | 4 ++-- arch/sparc/kernel/perf_event.c | 14 +++++++------- arch/tile/kernel/perf_event.c | 6 +++--- arch/x86/events/core.c | 14 +++++++------- arch/xtensa/kernel/perf_event.c | 10 +++++----- include/linux/perf_event.h | 16 +++++++++++----- kernel/bpf/stackmap.c | 3 ++- kernel/events/callchain.c | 20 ++++++++++++-------- 15 files changed, 84 insertions(+), 73 deletions(-) (limited to 'arch/arc/kernel') diff --git a/arch/arc/kernel/perf_event.c b/arch/arc/kernel/perf_event.c index 8b134cfe5e1f..6fd48021324b 100644 --- a/arch/arc/kernel/perf_event.c +++ b/arch/arc/kernel/perf_event.c @@ -48,7 +48,7 @@ struct arc_callchain_trace { static int callchain_trace(unsigned int addr, void *data) { struct arc_callchain_trace *ctrl = data; - struct perf_callchain_entry *entry = ctrl->perf_stuff; + struct perf_callchain_entry_ctx *entry = ctrl->perf_stuff; perf_callchain_store(entry, addr); if (ctrl->depth++ < 3) @@ -58,7 +58,7 @@ static int callchain_trace(unsigned int addr, void *data) } void -perf_callchain_kernel(struct perf_callchain_entry *entry, struct pt_regs *regs) +perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs) { struct arc_callchain_trace ctrl = { .depth = 0, @@ -69,7 +69,7 @@ perf_callchain_kernel(struct perf_callchain_entry *entry, struct pt_regs *regs) } void -perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs) +perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs) { /* * User stack can't be unwound trivially with kernel dwarf unwinder diff --git a/arch/arm/kernel/perf_callchain.c b/arch/arm/kernel/perf_callchain.c index 27563befa8a2..bc552e813e7b 100644 --- a/arch/arm/kernel/perf_callchain.c +++ b/arch/arm/kernel/perf_callchain.c @@ -31,7 +31,7 @@ struct frame_tail { */ static struct frame_tail __user * user_backtrace(struct frame_tail __user *tail, - struct perf_callchain_entry *entry) + struct perf_callchain_entry_ctx *entry) { struct frame_tail buftail; unsigned long err; @@ -59,7 +59,7 @@ user_backtrace(struct frame_tail __user *tail, } void -perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs) +perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs) { struct frame_tail __user *tail; @@ -75,7 +75,7 @@ perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs) tail = (struct frame_tail __user *)regs->ARM_fp - 1; - while ((entry->nr < sysctl_perf_event_max_stack) && + while ((entry->entry->nr < entry->max_stack) && tail && !((unsigned long)tail & 0x3)) tail = user_backtrace(tail, entry); } @@ -89,13 +89,13 @@ static int callchain_trace(struct stackframe *fr, void *data) { - struct perf_callchain_entry *entry = data; + struct perf_callchain_entry_ctx *entry = data; perf_callchain_store(entry, fr->pc); return 0; } void -perf_callchain_kernel(struct perf_callchain_entry *entry, struct pt_regs *regs) +perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs) { struct stackframe fr; diff --git a/arch/arm64/kernel/perf_callchain.c b/arch/arm64/kernel/perf_callchain.c index 32c3c6e70119..0d60150057cf 100644 --- a/arch/arm64/kernel/perf_callchain.c +++ b/arch/arm64/kernel/perf_callchain.c @@ -31,7 +31,7 @@ struct frame_tail { */ static struct frame_tail __user * user_backtrace(struct frame_tail __user *tail, - struct perf_callchain_entry *entry) + struct perf_callchain_entry_ctx *entry) { struct frame_tail buftail; unsigned long err; @@ -76,7 +76,7 @@ struct compat_frame_tail { static struct compat_frame_tail __user * compat_user_backtrace(struct compat_frame_tail __user *tail, - struct perf_callchain_entry *entry) + struct perf_callchain_entry_ctx *entry) { struct compat_frame_tail buftail; unsigned long err; @@ -106,7 +106,7 @@ compat_user_backtrace(struct compat_frame_tail __user *tail, } #endif /* CONFIG_COMPAT */ -void perf_callchain_user(struct perf_callchain_entry *entry, +void perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs) { if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) { @@ -122,7 +122,7 @@ void perf_callchain_user(struct perf_callchain_entry *entry, tail = (struct frame_tail __user *)regs->regs[29]; - while (entry->nr < sysctl_perf_event_max_stack && + while (entry->entry->nr < entry->max_stack && tail && !((unsigned long)tail & 0xf)) tail = user_backtrace(tail, entry); } else { @@ -132,7 +132,7 @@ void perf_callchain_user(struct perf_callchain_entry *entry, tail = (struct compat_frame_tail __user *)regs->compat_fp - 1; - while ((entry->nr < sysctl_perf_event_max_stack) && + while ((entry->entry->nr < entry->max_stack) && tail && !((unsigned long)tail & 0x3)) tail = compat_user_backtrace(tail, entry); #endif @@ -146,12 +146,12 @@ void perf_callchain_user(struct perf_callchain_entry *entry, */ static int callchain_trace(struct stackframe *frame, void *data) { - struct perf_callchain_entry *entry = data; + struct perf_callchain_entry_ctx *entry = data; perf_callchain_store(entry, frame->pc); return 0; } -void perf_callchain_kernel(struct perf_callchain_entry *entry, +void perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs) { struct stackframe frame; diff --git a/arch/metag/kernel/perf_callchain.c b/arch/metag/kernel/perf_callchain.c index 252abc12a5a3..b3261a98b15b 100644 --- a/arch/metag/kernel/perf_callchain.c +++ b/arch/metag/kernel/perf_callchain.c @@ -29,7 +29,7 @@ static bool is_valid_call(unsigned long calladdr) static struct metag_frame __user * user_backtrace(struct metag_frame __user *user_frame, - struct perf_callchain_entry *entry) + struct perf_callchain_entry_ctx *entry) { struct metag_frame frame; unsigned long calladdr; @@ -56,7 +56,7 @@ user_backtrace(struct metag_frame __user *user_frame, } void -perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs) +perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs) { unsigned long sp = regs->ctx.AX[0].U0; struct metag_frame __user *frame; @@ -65,7 +65,7 @@ perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs) --frame; - while ((entry->nr < sysctl_perf_event_max_stack) && frame) + while ((entry->entry->nr < entry->max_stack) && frame) frame = user_backtrace(frame, entry); } @@ -78,13 +78,13 @@ static int callchain_trace(struct stackframe *fr, void *data) { - struct perf_callchain_entry *entry = data; + struct perf_callchain_entry_ctx *entry = data; perf_callchain_store(entry, fr->pc); return 0; } void -perf_callchain_kernel(struct perf_callchain_entry *entry, struct pt_regs *regs) +perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs) { struct stackframe fr; diff --git a/arch/mips/kernel/perf_event.c b/arch/mips/kernel/perf_event.c index 5021c546ad07..22395c7d7030 100644 --- a/arch/mips/kernel/perf_event.c +++ b/arch/mips/kernel/perf_event.c @@ -25,8 +25,8 @@ * the user stack callchains, we will add it here. */ -static void save_raw_perf_callchain(struct perf_callchain_entry *entry, - unsigned long reg29) +static void save_raw_perf_callchain(struct perf_callchain_entry_ctx *entry, + unsigned long reg29) { unsigned long *sp = (unsigned long *)reg29; unsigned long addr; @@ -35,14 +35,14 @@ static void save_raw_perf_callchain(struct perf_callchain_entry *entry, addr = *sp++; if (__kernel_text_address(addr)) { perf_callchain_store(entry, addr); - if (entry->nr >= sysctl_perf_event_max_stack) + if (entry->entry->nr >= entry->max_stack) break; } } } -void perf_callchain_kernel(struct perf_callchain_entry *entry, - struct pt_regs *regs) +void perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, + struct pt_regs *regs) { unsigned long sp = regs->regs[29]; #ifdef CONFIG_KALLSYMS @@ -59,7 +59,7 @@ void perf_callchain_kernel(struct perf_callchain_entry *entry, } do { perf_callchain_store(entry, pc); - if (entry->nr >= sysctl_perf_event_max_stack) + if (entry->entry->nr >= entry->max_stack) break; pc = unwind_stack(current, &sp, pc, &ra); } while (pc); diff --git a/arch/powerpc/perf/callchain.c b/arch/powerpc/perf/callchain.c index 22d9015c1acc..c9260c1dfdbc 100644 --- a/arch/powerpc/perf/callchain.c +++ b/arch/powerpc/perf/callchain.c @@ -47,7 +47,7 @@ static int valid_next_sp(unsigned long sp, unsigned long prev_sp) } void -perf_callchain_kernel(struct perf_callchain_entry *entry, struct pt_regs *regs) +perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs) { unsigned long sp, next_sp; unsigned long next_ip; @@ -232,7 +232,7 @@ static int sane_signal_64_frame(unsigned long sp) puc == (unsigned long) &sf->uc; } -static void perf_callchain_user_64(struct perf_callchain_entry *entry, +static void perf_callchain_user_64(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs) { unsigned long sp, next_sp; @@ -247,7 +247,7 @@ static void perf_callchain_user_64(struct perf_callchain_entry *entry, sp = regs->gpr[1]; perf_callchain_store(entry, next_ip); - while (entry->nr < sysctl_perf_event_max_stack) { + while (entry->entry->nr < entry->max_stack) { fp = (unsigned long __user *) sp; if (!valid_user_sp(sp, 1) || read_user_stack_64(fp, &next_sp)) return; @@ -319,7 +319,7 @@ static int read_user_stack_32(unsigned int __user *ptr, unsigned int *ret) return rc; } -static inline void perf_callchain_user_64(struct perf_callchain_entry *entry, +static inline void perf_callchain_user_64(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs) { } @@ -439,7 +439,7 @@ static unsigned int __user *signal_frame_32_regs(unsigned int sp, return mctx->mc_gregs; } -static void perf_callchain_user_32(struct perf_callchain_entry *entry, +static void perf_callchain_user_32(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs) { unsigned int sp, next_sp; @@ -453,7 +453,7 @@ static void perf_callchain_user_32(struct perf_callchain_entry *entry, sp = regs->gpr[1]; perf_callchain_store(entry, next_ip); - while (entry->nr < sysctl_perf_event_max_stack) { + while (entry->entry->nr < entry->max_stack) { fp = (unsigned int __user *) (unsigned long) sp; if (!valid_user_sp(sp, 0) || read_user_stack_32(fp, &next_sp)) return; @@ -487,7 +487,7 @@ static void perf_callchain_user_32(struct perf_callchain_entry *entry, } void -perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs) +perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs) { if (current_is_64bit()) perf_callchain_user_64(entry, regs); diff --git a/arch/s390/kernel/perf_event.c b/arch/s390/kernel/perf_event.c index c3e4099b60a5..87035fa58bbe 100644 --- a/arch/s390/kernel/perf_event.c +++ b/arch/s390/kernel/perf_event.c @@ -224,13 +224,13 @@ arch_initcall(service_level_perf_register); static int __perf_callchain_kernel(void *data, unsigned long address) { - struct perf_callchain_entry *entry = data; + struct perf_callchain_entry_ctx *entry = data; perf_callchain_store(entry, address); return 0; } -void perf_callchain_kernel(struct perf_callchain_entry *entry, +void perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs) { if (user_mode(regs)) diff --git a/arch/sh/kernel/perf_callchain.c b/arch/sh/kernel/perf_callchain.c index cc80b614b5fa..fa2c0cd23eaa 100644 --- a/arch/sh/kernel/perf_callchain.c +++ b/arch/sh/kernel/perf_callchain.c @@ -21,7 +21,7 @@ static int callchain_stack(void *data, char *name) static void callchain_address(void *data, unsigned long addr, int reliable) { - struct perf_callchain_entry *entry = data; + struct perf_callchain_entry_ctx *entry = data; if (reliable) perf_callchain_store(entry, addr); @@ -33,7 +33,7 @@ static const struct stacktrace_ops callchain_ops = { }; void -perf_callchain_kernel(struct perf_callchain_entry *entry, struct pt_regs *regs) +perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs) { perf_callchain_store(entry, regs->pc); diff --git a/arch/sparc/kernel/perf_event.c b/arch/sparc/kernel/perf_event.c index a4b8b5aed21c..bcc5376db74b 100644 --- a/arch/sparc/kernel/perf_event.c +++ b/arch/sparc/kernel/perf_event.c @@ -1711,7 +1711,7 @@ static int __init init_hw_perf_events(void) } pure_initcall(init_hw_perf_events); -void perf_callchain_kernel(struct perf_callchain_entry *entry, +void perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs) { unsigned long ksp, fp; @@ -1756,7 +1756,7 @@ void perf_callchain_kernel(struct perf_callchain_entry *entry, } } #endif - } while (entry->nr < sysctl_perf_event_max_stack); + } while (entry->entry->nr < entry->max_stack); } static inline int @@ -1769,7 +1769,7 @@ valid_user_frame(const void __user *fp, unsigned long size) return (__range_not_ok(fp, size, TASK_SIZE) == 0); } -static void perf_callchain_user_64(struct perf_callchain_entry *entry, +static void perf_callchain_user_64(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs) { unsigned long ufp; @@ -1790,10 +1790,10 @@ static void perf_callchain_user_64(struct perf_callchain_entry *entry, pc = sf.callers_pc; ufp = (unsigned long)sf.fp + STACK_BIAS; perf_callchain_store(entry, pc); - } while (entry->nr < sysctl_perf_event_max_stack); + } while (entry->entry->nr < entry->max_stack); } -static void perf_callchain_user_32(struct perf_callchain_entry *entry, +static void perf_callchain_user_32(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs) { unsigned long ufp; @@ -1822,11 +1822,11 @@ static void perf_callchain_user_32(struct perf_callchain_entry *entry, ufp = (unsigned long)sf.fp; } perf_callchain_store(entry, pc); - } while (entry->nr < sysctl_perf_event_max_stack); + } while (entry->entry->nr < entry->max_stack); } void -perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs) +perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs) { u64 saved_fault_address = current_thread_info()->fault_address; u8 saved_fault_code = get_thread_fault_code(); diff --git a/arch/tile/kernel/perf_event.c b/arch/tile/kernel/perf_event.c index 8767060d70fb..6394c1ccb68e 100644 --- a/arch/tile/kernel/perf_event.c +++ b/arch/tile/kernel/perf_event.c @@ -941,7 +941,7 @@ arch_initcall(init_hw_perf_events); /* * Tile specific backtracing code for perf_events. */ -static inline void perf_callchain(struct perf_callchain_entry *entry, +static inline void perf_callchain(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs) { struct KBacktraceIterator kbt; @@ -992,13 +992,13 @@ static inline void perf_callchain(struct perf_callchain_entry *entry, } } -void perf_callchain_user(struct perf_callchain_entry *entry, +void perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs) { perf_callchain(entry, regs); } -void perf_callchain_kernel(struct perf_callchain_entry *entry, +void perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs) { perf_callchain(entry, regs); diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c index 5e5e76a52f58..07f2b01cfb72 100644 --- a/arch/x86/events/core.c +++ b/arch/x86/events/core.c @@ -2202,7 +2202,7 @@ static int backtrace_stack(void *data, char *name) static int backtrace_address(void *data, unsigned long addr, int reliable) { - struct perf_callchain_entry *entry = data; + struct perf_callchain_entry_ctx *entry = data; return perf_callchain_store(entry, addr); } @@ -2214,7 +2214,7 @@ static const struct stacktrace_ops backtrace_ops = { }; void -perf_callchain_kernel(struct perf_callchain_entry *entry, struct pt_regs *regs) +perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs) { if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) { /* TODO: We don't support guest os callchain now */ @@ -2268,7 +2268,7 @@ static unsigned long get_segment_base(unsigned int segment) #include static inline int -perf_callchain_user32(struct pt_regs *regs, struct perf_callchain_entry *entry) +perf_callchain_user32(struct pt_regs *regs, struct perf_callchain_entry_ctx *entry) { /* 32-bit process in 64-bit kernel. */ unsigned long ss_base, cs_base; @@ -2283,7 +2283,7 @@ perf_callchain_user32(struct pt_regs *regs, struct perf_callchain_entry *entry) fp = compat_ptr(ss_base + regs->bp); pagefault_disable(); - while (entry->nr < sysctl_perf_event_max_stack) { + while (entry->entry->nr < entry->max_stack) { unsigned long bytes; frame.next_frame = 0; frame.return_address = 0; @@ -2309,14 +2309,14 @@ perf_callchain_user32(struct pt_regs *regs, struct perf_callchain_entry *entry) } #else static inline int -perf_callchain_user32(struct pt_regs *regs, struct perf_callchain_entry *entry) +perf_callchain_user32(struct pt_regs *regs, struct perf_callchain_entry_ctx *entry) { return 0; } #endif void -perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs) +perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs) { struct stack_frame frame; const void __user *fp; @@ -2343,7 +2343,7 @@ perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs) return; pagefault_disable(); - while (entry->nr < sysctl_perf_event_max_stack) { + while (entry->entry->nr < entry->max_stack) { unsigned long bytes; frame.next_frame = NULL; frame.return_address = 0; diff --git a/arch/xtensa/kernel/perf_event.c b/arch/xtensa/kernel/perf_event.c index a6b00b3af429..ef90479e0397 100644 --- a/arch/xtensa/kernel/perf_event.c +++ b/arch/xtensa/kernel/perf_event.c @@ -323,23 +323,23 @@ static void xtensa_pmu_read(struct perf_event *event) static int callchain_trace(struct stackframe *frame, void *data) { - struct perf_callchain_entry *entry = data; + struct perf_callchain_entry_ctx *entry = data; perf_callchain_store(entry, frame->pc); return 0; } -void perf_callchain_kernel(struct perf_callchain_entry *entry, +void perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs) { - xtensa_backtrace_kernel(regs, sysctl_perf_event_max_stack, + xtensa_backtrace_kernel(regs, entry->max_stack, callchain_trace, NULL, entry); } -void perf_callchain_user(struct perf_callchain_entry *entry, +void perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs) { - xtensa_backtrace_user(regs, sysctl_perf_event_max_stack, + xtensa_backtrace_user(regs, entry->max_stack, callchain_trace, entry); } diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index 9e1c3ada91c4..dbd18246b36e 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h @@ -61,6 +61,11 @@ struct perf_callchain_entry { __u64 ip[0]; /* /proc/sys/kernel/perf_event_max_stack */ }; +struct perf_callchain_entry_ctx { + struct perf_callchain_entry *entry; + u32 max_stack; +}; + struct perf_raw_record { u32 size; void *data; @@ -1063,19 +1068,20 @@ extern void perf_event_fork(struct task_struct *tsk); /* Callchains */ DECLARE_PER_CPU(struct perf_callchain_entry, perf_callchain_entry); -extern void perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs); -extern void perf_callchain_kernel(struct perf_callchain_entry *entry, struct pt_regs *regs); +extern void perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs); +extern void perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs); extern struct perf_callchain_entry * get_perf_callchain(struct pt_regs *regs, u32 init_nr, bool kernel, bool user, - bool crosstask, bool add_mark); + u32 max_stack, bool crosstask, bool add_mark); extern int get_callchain_buffers(void); extern void put_callchain_buffers(void); extern int sysctl_perf_event_max_stack; -static inline int perf_callchain_store(struct perf_callchain_entry *entry, u64 ip) +static inline int perf_callchain_store(struct perf_callchain_entry_ctx *ctx, u64 ip) { - if (entry->nr < sysctl_perf_event_max_stack) { + struct perf_callchain_entry *entry = ctx->entry; + if (entry->nr < ctx->max_stack) { entry->ip[entry->nr++] = ip; return 0; } else { diff --git a/kernel/bpf/stackmap.c b/kernel/bpf/stackmap.c index f5a19548be12..a82d7605db3f 100644 --- a/kernel/bpf/stackmap.c +++ b/kernel/bpf/stackmap.c @@ -136,7 +136,8 @@ static u64 bpf_get_stackid(u64 r1, u64 r2, u64 flags, u64 r4, u64 r5) BPF_F_FAST_STACK_CMP | BPF_F_REUSE_STACKID))) return -EINVAL; - trace = get_perf_callchain(regs, init_nr, kernel, user, false, false); + trace = get_perf_callchain(regs, init_nr, kernel, user, + sysctl_perf_event_max_stack, false, false); if (unlikely(!trace)) /* couldn't fetch the stack trace */ diff --git a/kernel/events/callchain.c b/kernel/events/callchain.c index 7fc89939ede9..af95ad92893a 100644 --- a/kernel/events/callchain.c +++ b/kernel/events/callchain.c @@ -32,12 +32,12 @@ static DEFINE_MUTEX(callchain_mutex); static struct callchain_cpus_entries *callchain_cpus_entries; -__weak void perf_callchain_kernel(struct perf_callchain_entry *entry, +__weak void perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs) { } -__weak void perf_callchain_user(struct perf_callchain_entry *entry, +__weak void perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs) { } @@ -176,14 +176,15 @@ perf_callchain(struct perf_event *event, struct pt_regs *regs) if (!kernel && !user) return NULL; - return get_perf_callchain(regs, 0, kernel, user, crosstask, true); + return get_perf_callchain(regs, 0, kernel, user, sysctl_perf_event_max_stack, crosstask, true); } struct perf_callchain_entry * get_perf_callchain(struct pt_regs *regs, u32 init_nr, bool kernel, bool user, - bool crosstask, bool add_mark) + u32 max_stack, bool crosstask, bool add_mark) { struct perf_callchain_entry *entry; + struct perf_callchain_entry_ctx ctx; int rctx; entry = get_callchain_entry(&rctx); @@ -193,12 +194,15 @@ get_perf_callchain(struct pt_regs *regs, u32 init_nr, bool kernel, bool user, if (!entry) goto exit_put; + ctx.entry = entry; + ctx.max_stack = max_stack; + entry->nr = init_nr; if (kernel && !user_mode(regs)) { if (add_mark) - perf_callchain_store(entry, PERF_CONTEXT_KERNEL); - perf_callchain_kernel(entry, regs); + perf_callchain_store(&ctx, PERF_CONTEXT_KERNEL); + perf_callchain_kernel(&ctx, regs); } if (user) { @@ -214,8 +218,8 @@ get_perf_callchain(struct pt_regs *regs, u32 init_nr, bool kernel, bool user, goto exit_put; if (add_mark) - perf_callchain_store(entry, PERF_CONTEXT_USER); - perf_callchain_user(entry, regs); + perf_callchain_store(&ctx, PERF_CONTEXT_USER); + perf_callchain_user(&ctx, regs); } } -- cgit v1.2.3 From 5f56a5dfdb9bcb3bca03df59980d4d2f012cbb53 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 20 May 2016 17:00:16 -0700 Subject: exit_thread: remove empty bodies Define HAVE_EXIT_THREAD for archs which want to do something in exit_thread. For others, let's define exit_thread as an empty inline. This is a cleanup before we change the prototype of exit_thread to accept a task parameter. [akpm@linux-foundation.org: fix mips] Signed-off-by: Jiri Slaby Cc: "David S. Miller" Cc: "H. Peter Anvin" Cc: "James E.J. Bottomley" Cc: Aurelien Jacquiot Cc: Benjamin Herrenschmidt Cc: Catalin Marinas Cc: Chen Liqin Cc: Chris Metcalf Cc: Chris Zankel Cc: David Howells Cc: Fenghua Yu Cc: Geert Uytterhoeven Cc: Guan Xuetao Cc: Haavard Skinnemoen Cc: Hans-Christian Egtvedt Cc: Heiko Carstens Cc: Helge Deller Cc: Ingo Molnar Cc: Ivan Kokshaysky Cc: James Hogan Cc: Jeff Dike Cc: Jesper Nilsson Cc: Jiri Slaby Cc: Jonas Bonn Cc: Koichi Yasutake Cc: Lennox Wu Cc: Ley Foon Tan Cc: Mark Salter Cc: Martin Schwidefsky Cc: Matt Turner Cc: Max Filippov Cc: Michael Ellerman Cc: Michal Simek Cc: Mikael Starvik Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Ralf Baechle Cc: Rich Felker Cc: Richard Henderson Cc: Richard Kuo Cc: Richard Weinberger Cc: Russell King Cc: Steven Miao Cc: Thomas Gleixner Cc: Tony Luck Cc: Vineet Gupta Cc: Will Deacon Cc: Yoshinori Sato Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/Kconfig | 5 +++++ arch/alpha/kernel/process.c | 8 -------- arch/arc/kernel/process.c | 7 ------- arch/arm/Kconfig | 1 + arch/arm64/kernel/process.c | 7 ------- arch/avr32/Kconfig | 1 + arch/blackfin/include/asm/processor.h | 7 ------- arch/c6x/kernel/process.c | 4 ---- arch/cris/Kconfig | 1 + arch/cris/arch-v10/kernel/process.c | 9 --------- arch/frv/include/asm/processor.h | 7 ------- arch/h8300/include/asm/processor.h | 7 ------- arch/hexagon/kernel/process.c | 7 ------- arch/ia64/Kconfig | 1 + arch/m32r/kernel/process.c | 9 --------- arch/m68k/include/asm/processor.h | 7 ------- arch/metag/Kconfig | 1 + arch/metag/include/asm/processor.h | 2 -- arch/microblaze/include/asm/processor.h | 10 ---------- arch/mips/kernel/process.c | 4 ---- arch/mn10300/Kconfig | 1 + arch/nios2/include/asm/processor.h | 5 ----- arch/openrisc/include/asm/processor.h | 9 --------- arch/parisc/kernel/process.c | 7 ------- arch/powerpc/kernel/process.c | 4 ---- arch/s390/Kconfig | 1 + arch/score/kernel/process.c | 2 -- arch/sh/Kconfig | 1 + arch/sh/kernel/process_32.c | 7 ------- arch/sparc/Kconfig | 1 + arch/tile/Kconfig | 1 + arch/um/kernel/process.c | 4 ---- arch/unicore32/kernel/process.c | 7 ------- arch/x86/Kconfig | 1 + arch/xtensa/Kconfig | 1 + include/linux/sched.h | 7 +++++++ 36 files changed, 24 insertions(+), 140 deletions(-) (limited to 'arch/arc/kernel') diff --git a/arch/Kconfig b/arch/Kconfig index 81869a5e7e17..0f298f9123dc 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -517,6 +517,11 @@ config HAVE_ARCH_MMAP_RND_BITS - ARCH_MMAP_RND_BITS_MIN - ARCH_MMAP_RND_BITS_MAX +config HAVE_EXIT_THREAD + bool + help + An architecture implements exit_thread. + config ARCH_MMAP_RND_BITS_MIN int diff --git a/arch/alpha/kernel/process.c b/arch/alpha/kernel/process.c index 84d13263ce46..b483156698d5 100644 --- a/arch/alpha/kernel/process.c +++ b/arch/alpha/kernel/process.c @@ -210,14 +210,6 @@ start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp) } EXPORT_SYMBOL(start_thread); -/* - * Free current thread data structures etc.. - */ -void -exit_thread(void) -{ -} - void flush_thread(void) { diff --git a/arch/arc/kernel/process.c b/arch/arc/kernel/process.c index a3f750e76b68..b5db9e7fd649 100644 --- a/arch/arc/kernel/process.c +++ b/arch/arc/kernel/process.c @@ -183,13 +183,6 @@ void flush_thread(void) { } -/* - * Free any architecture-specific thread data structures, etc. - */ -void exit_thread(void) -{ -} - int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu) { return 0; diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index b99d25b4133e..956d3575426c 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -50,6 +50,7 @@ config ARM select HAVE_DMA_CONTIGUOUS if MMU select HAVE_DYNAMIC_FTRACE if (!XIP_KERNEL) && !CPU_ENDIAN_BE32 && MMU select HAVE_EFFICIENT_UNALIGNED_ACCESS if (CPU_V6 || CPU_V6K || CPU_V7) && MMU + select HAVE_EXIT_THREAD select HAVE_FTRACE_MCOUNT_RECORD if (!XIP_KERNEL) select HAVE_FUNCTION_GRAPH_TRACER if (!THUMB2_KERNEL) select HAVE_FUNCTION_TRACER if (!XIP_KERNEL) diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c index 48eea6866c67..6cd2612236dc 100644 --- a/arch/arm64/kernel/process.c +++ b/arch/arm64/kernel/process.c @@ -200,13 +200,6 @@ void show_regs(struct pt_regs * regs) __show_regs(regs); } -/* - * Free current thread data structures etc.. - */ -void exit_thread(void) -{ -} - static void tls_thread_flush(void) { asm ("msr tpidr_el0, xzr"); diff --git a/arch/avr32/Kconfig b/arch/avr32/Kconfig index 18b88779e701..e43519a2ca89 100644 --- a/arch/avr32/Kconfig +++ b/arch/avr32/Kconfig @@ -4,6 +4,7 @@ config AVR32 # that we usually don't need on AVR32. select EXPERT select HAVE_CLK + select HAVE_EXIT_THREAD select HAVE_OPROFILE select HAVE_KPROBES select VIRT_TO_BUS diff --git a/arch/blackfin/include/asm/processor.h b/arch/blackfin/include/asm/processor.h index 7acd46653df3..0c265aba94ad 100644 --- a/arch/blackfin/include/asm/processor.h +++ b/arch/blackfin/include/asm/processor.h @@ -75,13 +75,6 @@ static inline void release_thread(struct task_struct *dead_task) { } -/* - * Free current thread data structures etc.. - */ -static inline void exit_thread(void) -{ -} - /* * Return saved PC of a blocked thread. */ diff --git a/arch/c6x/kernel/process.c b/arch/c6x/kernel/process.c index 3ae9f5a166a0..0ee7686a78f3 100644 --- a/arch/c6x/kernel/process.c +++ b/arch/c6x/kernel/process.c @@ -82,10 +82,6 @@ void flush_thread(void) { } -void exit_thread(void) -{ -} - /* * Do necessary setup to start up a newly executed thread. */ diff --git a/arch/cris/Kconfig b/arch/cris/Kconfig index 99bda1ba3d2f..5c0ca8ae9293 100644 --- a/arch/cris/Kconfig +++ b/arch/cris/Kconfig @@ -59,6 +59,7 @@ config CRIS select GENERIC_IOMAP select MODULES_USE_ELF_RELA select CLONE_BACKWARDS2 + select HAVE_EXIT_THREAD if ETRAX_ARCH_V32 select OLD_SIGSUSPEND select OLD_SIGACTION select GPIOLIB diff --git a/arch/cris/arch-v10/kernel/process.c b/arch/cris/arch-v10/kernel/process.c index 02b783457be0..96e5afef6b47 100644 --- a/arch/cris/arch-v10/kernel/process.c +++ b/arch/cris/arch-v10/kernel/process.c @@ -35,15 +35,6 @@ void default_idle(void) local_irq_enable(); } -/* - * Free current thread data structures etc.. - */ - -void exit_thread(void) -{ - /* Nothing needs to be done. */ -} - /* if the watchdog is enabled, we can simply disable interrupts and go * into an eternal loop, and the watchdog will reset the CPU after 0.1s * if on the other hand the watchdog wasn't enabled, we just enable it and wait diff --git a/arch/frv/include/asm/processor.h b/arch/frv/include/asm/processor.h index ae8d423e79d9..73f0a79ad8e6 100644 --- a/arch/frv/include/asm/processor.h +++ b/arch/frv/include/asm/processor.h @@ -96,13 +96,6 @@ extern asmlinkage void *restore_user_regs(const struct user_context *target, ... #define release_segments(mm) do { } while (0) #define forget_segments() do { } while (0) -/* - * Free current thread data structures etc.. - */ -static inline void exit_thread(void) -{ -} - /* * Return saved PC of a blocked thread. */ diff --git a/arch/h8300/include/asm/processor.h b/arch/h8300/include/asm/processor.h index 54e3fd83c336..111df7397ac7 100644 --- a/arch/h8300/include/asm/processor.h +++ b/arch/h8300/include/asm/processor.h @@ -110,13 +110,6 @@ static inline void release_thread(struct task_struct *dead_task) { } -/* - * Free current thread data structures etc.. - */ -static inline void exit_thread(void) -{ -} - /* * Return saved PC of a blocked thread. */ diff --git a/arch/hexagon/kernel/process.c b/arch/hexagon/kernel/process.c index a9ebd471823a..d9edfd3fc52a 100644 --- a/arch/hexagon/kernel/process.c +++ b/arch/hexagon/kernel/process.c @@ -136,13 +136,6 @@ void release_thread(struct task_struct *dead_task) { } -/* - * Free any architecture-specific thread data structures, etc. - */ -void exit_thread(void) -{ -} - /* * Some archs flush debug and FPU info here */ diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig index b534ebab36ea..f80758cb7157 100644 --- a/arch/ia64/Kconfig +++ b/arch/ia64/Kconfig @@ -18,6 +18,7 @@ config IA64 select ACPI_SYSTEM_POWER_STATES_SUPPORT if ACPI select ARCH_MIGHT_HAVE_ACPI_PDC if ACPI select HAVE_UNSTABLE_SCHED_CLOCK + select HAVE_EXIT_THREAD select HAVE_IDE select HAVE_OPROFILE select HAVE_KPROBES diff --git a/arch/m32r/kernel/process.c b/arch/m32r/kernel/process.c index e69221d581d5..a88b1f01e91f 100644 --- a/arch/m32r/kernel/process.c +++ b/arch/m32r/kernel/process.c @@ -101,15 +101,6 @@ void show_regs(struct pt_regs * regs) #endif } -/* - * Free current thread data structures etc.. - */ -void exit_thread(void) -{ - /* Nothing to do. */ - DPRINTK("pid = %d\n", current->pid); -} - void flush_thread(void) { DPRINTK("pid = %d\n", current->pid); diff --git a/arch/m68k/include/asm/processor.h b/arch/m68k/include/asm/processor.h index 20dda1d4b860..a6ce2ec8d693 100644 --- a/arch/m68k/include/asm/processor.h +++ b/arch/m68k/include/asm/processor.h @@ -153,13 +153,6 @@ static inline void release_thread(struct task_struct *dead_task) { } -/* - * Free current thread data structures etc.. - */ -static inline void exit_thread(void) -{ -} - extern unsigned long thread_saved_pc(struct task_struct *tsk); unsigned long get_wchan(struct task_struct *p); diff --git a/arch/metag/Kconfig b/arch/metag/Kconfig index a0fa88da3e31..e47a08d72819 100644 --- a/arch/metag/Kconfig +++ b/arch/metag/Kconfig @@ -11,6 +11,7 @@ config METAG select HAVE_DEBUG_KMEMLEAK select HAVE_DEBUG_STACKOVERFLOW select HAVE_DYNAMIC_FTRACE + select HAVE_EXIT_THREAD select HAVE_FTRACE_MCOUNT_RECORD select HAVE_FUNCTION_TRACER select HAVE_KERNEL_BZIP2 diff --git a/arch/metag/include/asm/processor.h b/arch/metag/include/asm/processor.h index 0838ca699764..a0333ebcac35 100644 --- a/arch/metag/include/asm/processor.h +++ b/arch/metag/include/asm/processor.h @@ -134,8 +134,6 @@ static inline void release_thread(struct task_struct *dead_task) #define copy_segments(tsk, mm) do { } while (0) #define release_segments(mm) do { } while (0) -extern void exit_thread(void); - /* * Return saved PC of a blocked thread. */ diff --git a/arch/microblaze/include/asm/processor.h b/arch/microblaze/include/asm/processor.h index 497a988d79c2..c38d0dd91134 100644 --- a/arch/microblaze/include/asm/processor.h +++ b/arch/microblaze/include/asm/processor.h @@ -70,11 +70,6 @@ static inline void release_thread(struct task_struct *dead_task) { } -/* Free all resources held by a thread. */ -static inline void exit_thread(void) -{ -} - extern unsigned long thread_saved_pc(struct task_struct *t); extern unsigned long get_wchan(struct task_struct *p); @@ -127,11 +122,6 @@ static inline void release_thread(struct task_struct *dead_task) { } -/* Free current thread data structures etc. */ -static inline void exit_thread(void) -{ -} - /* Return saved (kernel) PC of a blocked thread. */ # define thread_saved_pc(tsk) \ ((tsk)->thread.regs ? (tsk)->thread.regs->r15 : 0) diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c index a6b3dc54260a..411c971e3417 100644 --- a/arch/mips/kernel/process.c +++ b/arch/mips/kernel/process.c @@ -73,10 +73,6 @@ void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp) regs->regs[29] = sp; } -void exit_thread(void) -{ -} - int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src) { /* diff --git a/arch/mn10300/Kconfig b/arch/mn10300/Kconfig index 06ddb5501ab1..9627e81a6cbb 100644 --- a/arch/mn10300/Kconfig +++ b/arch/mn10300/Kconfig @@ -1,5 +1,6 @@ config MN10300 def_bool y + select HAVE_EXIT_THREAD select HAVE_OPROFILE select HAVE_UID16 select GENERIC_IRQ_SHOW diff --git a/arch/nios2/include/asm/processor.h b/arch/nios2/include/asm/processor.h index c2ba45c159c7..1c953f0cadbf 100644 --- a/arch/nios2/include/asm/processor.h +++ b/arch/nios2/include/asm/processor.h @@ -75,11 +75,6 @@ static inline void release_thread(struct task_struct *dead_task) { } -/* Free current thread data structures etc.. */ -static inline void exit_thread(void) -{ -} - /* Return saved PC of a blocked thread. */ #define thread_saved_pc(tsk) ((tsk)->thread.kregs->ea) diff --git a/arch/openrisc/include/asm/processor.h b/arch/openrisc/include/asm/processor.h index 4d235e3d2534..70334c9f7d24 100644 --- a/arch/openrisc/include/asm/processor.h +++ b/arch/openrisc/include/asm/processor.h @@ -84,15 +84,6 @@ void start_thread(struct pt_regs *regs, unsigned long nip, unsigned long sp); void release_thread(struct task_struct *); unsigned long get_wchan(struct task_struct *p); -/* - * Free current thread data structures etc.. - */ - -extern inline void exit_thread(void) -{ - /* Nothing needs to be done. */ -} - /* * Return saved PC of a blocked thread. For now, this is the "user" PC */ diff --git a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c index 809905a811ed..40639439d8b3 100644 --- a/arch/parisc/kernel/process.c +++ b/arch/parisc/kernel/process.c @@ -144,13 +144,6 @@ void machine_power_off(void) void (*pm_power_off)(void) = machine_power_off; EXPORT_SYMBOL(pm_power_off); -/* - * Free current thread data structures etc.. - */ -void exit_thread(void) -{ -} - void flush_thread(void) { /* Only needs to handle fpu stuff or perf monitors. diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index ea8a28fd6f31..e2f12cbcade9 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -1329,10 +1329,6 @@ void show_regs(struct pt_regs * regs) show_instructions(regs); } -void exit_thread(void) -{ -} - void flush_thread(void) { #ifdef CONFIG_HAVE_HW_BREAKPOINT diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index de0fcc08dff5..e2c9aaaf64b2 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@ -134,6 +134,7 @@ config S390 select HAVE_DMA_API_DEBUG select HAVE_DYNAMIC_FTRACE select HAVE_DYNAMIC_FTRACE_WITH_REGS + select HAVE_EXIT_THREAD select HAVE_FTRACE_MCOUNT_RECORD select HAVE_FUNCTION_GRAPH_TRACER select HAVE_FUNCTION_TRACER diff --git a/arch/score/kernel/process.c b/arch/score/kernel/process.c index a1519ad3d49d..aae9480706c2 100644 --- a/arch/score/kernel/process.c +++ b/arch/score/kernel/process.c @@ -56,8 +56,6 @@ void start_thread(struct pt_regs *regs, unsigned long pc, unsigned long sp) regs->regs[0] = sp; } -void exit_thread(void) {} - /* * When a process does an "exec", machine state like FPU and debug * registers need to be reset. This is a hook function for that. diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 7ed20fc3fc81..cb93af8f8017 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -71,6 +71,7 @@ config SUPERH32 config SUPERH64 def_bool ARCH = "sh64" + select HAVE_EXIT_THREAD select KALLSYMS config ARCH_DEFCONFIG diff --git a/arch/sh/kernel/process_32.c b/arch/sh/kernel/process_32.c index 2885fc9d9dcd..ee12e9451874 100644 --- a/arch/sh/kernel/process_32.c +++ b/arch/sh/kernel/process_32.c @@ -76,13 +76,6 @@ void start_thread(struct pt_regs *regs, unsigned long new_pc, } EXPORT_SYMBOL(start_thread); -/* - * Free current thread data structures etc.. - */ -void exit_thread(void) -{ -} - void flush_thread(void) { struct task_struct *tsk = current; diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig index db0a26cffa97..27b3a0ad40a0 100644 --- a/arch/sparc/Kconfig +++ b/arch/sparc/Kconfig @@ -20,6 +20,7 @@ config SPARC select HAVE_OPROFILE select HAVE_ARCH_KGDB if !SMP || SPARC64 select HAVE_ARCH_TRACEHOOK + select HAVE_EXIT_THREAD select SYSCTL_EXCEPTION_TRACE select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE select RTC_CLASS diff --git a/arch/tile/Kconfig b/arch/tile/Kconfig index 81719302b056..174746225577 100644 --- a/arch/tile/Kconfig +++ b/arch/tile/Kconfig @@ -3,6 +3,7 @@ config TILE def_bool y + select HAVE_EXIT_THREAD select HAVE_PERF_EVENTS select USE_PMC if PERF_EVENTS select HAVE_DMA_API_DEBUG diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c index 48af59aae129..0b04711f1f18 100644 --- a/arch/um/kernel/process.c +++ b/arch/um/kernel/process.c @@ -103,10 +103,6 @@ void interrupt_end(void) tracehook_notify_resume(regs); } -void exit_thread(void) -{ -} - int get_current_pid(void) { return task_pid_nr(current); diff --git a/arch/unicore32/kernel/process.c b/arch/unicore32/kernel/process.c index b008e9961465..00299c927852 100644 --- a/arch/unicore32/kernel/process.c +++ b/arch/unicore32/kernel/process.c @@ -201,13 +201,6 @@ void show_regs(struct pt_regs *regs) __backtrace(); } -/* - * Free current thread data structures etc.. - */ -void exit_thread(void) -{ -} - void flush_thread(void) { struct thread_info *thread = current_thread_info(); diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index ace79d2da2c3..8ff5b3be95d4 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -105,6 +105,7 @@ config X86 select HAVE_DYNAMIC_FTRACE select HAVE_DYNAMIC_FTRACE_WITH_REGS select HAVE_EFFICIENT_UNALIGNED_ACCESS + select HAVE_EXIT_THREAD select HAVE_FENTRY if X86_64 select HAVE_FTRACE_MCOUNT_RECORD select HAVE_FUNCTION_GRAPH_FP_TEST diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig index 85257afe71c3..64336f666fb6 100644 --- a/arch/xtensa/Kconfig +++ b/arch/xtensa/Kconfig @@ -14,6 +14,7 @@ config XTENSA select GENERIC_PCI_IOMAP select GENERIC_SCHED_CLOCK select HAVE_DMA_API_DEBUG + select HAVE_EXIT_THREAD select HAVE_FUNCTION_TRACER select HAVE_FUTEX_CMPXCHG if !MMU select HAVE_HW_BREAKPOINT if PERF_EVENTS diff --git a/include/linux/sched.h b/include/linux/sched.h index 6b3213d96da6..167c0d4bf3fa 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -2769,7 +2769,14 @@ static inline int copy_thread_tls( } #endif extern void flush_thread(void); + +#ifdef CONFIG_HAVE_EXIT_THREAD extern void exit_thread(void); +#else +static inline void exit_thread(void) +{ +} +#endif extern void exit_files(struct task_struct *); extern void __cleanup_sighand(struct sighand_struct *); -- cgit v1.2.3 From 2547476a5e4061f6addb88d5fc837d3a950f54c4 Mon Sep 17 00:00:00 2001 From: Andrea Gelmini Date: Sat, 21 May 2016 13:45:35 +0200 Subject: Fix typos Signed-off-by: Andrea Gelmini Signed-off-by: Vineet Gupta --- arch/arc/Makefile | 2 +- arch/arc/include/asm/entry-compact.h | 4 ++-- arch/arc/include/asm/mmu_context.h | 2 +- arch/arc/include/asm/pgtable.h | 2 +- arch/arc/include/asm/processor.h | 2 +- arch/arc/include/asm/smp.h | 2 +- arch/arc/include/asm/thread_info.h | 2 +- arch/arc/include/asm/uaccess.h | 2 +- arch/arc/include/uapi/asm/swab.h | 2 +- arch/arc/kernel/perf_event.c | 2 +- arch/arc/kernel/setup.c | 2 +- arch/arc/kernel/signal.c | 2 +- arch/arc/kernel/troubleshoot.c | 2 +- arch/arc/mm/cache.c | 6 +++--- arch/arc/mm/dma.c | 2 +- 15 files changed, 18 insertions(+), 18 deletions(-) (limited to 'arch/arc/kernel') diff --git a/arch/arc/Makefile b/arch/arc/Makefile index 02fabef2891c..d4df6be66d58 100644 --- a/arch/arc/Makefile +++ b/arch/arc/Makefile @@ -127,7 +127,7 @@ libs-y += arch/arc/lib/ $(LIBGCC) boot := arch/arc/boot -#default target for make without any arguements. +#default target for make without any arguments. KBUILD_IMAGE := bootpImage all: $(KBUILD_IMAGE) diff --git a/arch/arc/include/asm/entry-compact.h b/arch/arc/include/asm/entry-compact.h index e0e1faf03c50..14c310f2e0b1 100644 --- a/arch/arc/include/asm/entry-compact.h +++ b/arch/arc/include/asm/entry-compact.h @@ -76,8 +76,8 @@ * We need to be a bit more cautious here. What if a kernel bug in * L1 ISR, caused SP to go whaco (some small value which looks like * USER stk) and then we take L2 ISR. - * Above brlo alone would treat it as a valid L1-L2 sceanrio - * instead of shouting alound + * Above brlo alone would treat it as a valid L1-L2 scenario + * instead of shouting around * The only feasible way is to make sure this L2 happened in * L1 prelogue ONLY i.e. ilink2 is less than a pre-set marker in * L1 ISR before it switches stack diff --git a/arch/arc/include/asm/mmu_context.h b/arch/arc/include/asm/mmu_context.h index 1fd467ef658f..b0b87f2447f5 100644 --- a/arch/arc/include/asm/mmu_context.h +++ b/arch/arc/include/asm/mmu_context.h @@ -83,7 +83,7 @@ static inline void get_new_mmu_context(struct mm_struct *mm) local_flush_tlb_all(); /* - * Above checke for rollover of 8 bit ASID in 32 bit container. + * Above check for rollover of 8 bit ASID in 32 bit container. * If the container itself wrapped around, set it to a non zero * "generation" to distinguish from no context */ diff --git a/arch/arc/include/asm/pgtable.h b/arch/arc/include/asm/pgtable.h index 034bbdc0ff61..858f98ef7f1b 100644 --- a/arch/arc/include/asm/pgtable.h +++ b/arch/arc/include/asm/pgtable.h @@ -47,7 +47,7 @@ * Page Tables are purely for Linux VM's consumption and the bits below are * suited to that (uniqueness). Hence some are not implemented in the TLB and * some have different value in TLB. - * e.g. MMU v2: K_READ bit is 8 and so is GLOBAL (possible becoz they live in + * e.g. MMU v2: K_READ bit is 8 and so is GLOBAL (possible because they live in * seperate PD0 and PD1, which combined forms a translation entry) * while for PTE perspective, they are 8 and 9 respectively * with MMU v3: Most bits (except SHARED) represent the exact hardware pos diff --git a/arch/arc/include/asm/processor.h b/arch/arc/include/asm/processor.h index f9048994b22f..16b630fbeb6a 100644 --- a/arch/arc/include/asm/processor.h +++ b/arch/arc/include/asm/processor.h @@ -78,7 +78,7 @@ struct task_struct; #define KSTK_ESP(tsk) (task_pt_regs(tsk)->sp) /* - * Where abouts of Task's sp, fp, blink when it was last seen in kernel mode. + * Where about of Task's sp, fp, blink when it was last seen in kernel mode. * Look in process.c for details of kernel stack layout */ #define TSK_K_ESP(tsk) (tsk->thread.ksp) diff --git a/arch/arc/include/asm/smp.h b/arch/arc/include/asm/smp.h index 991380438d6b..89fdd1b0a76e 100644 --- a/arch/arc/include/asm/smp.h +++ b/arch/arc/include/asm/smp.h @@ -86,7 +86,7 @@ static inline const char *arc_platform_smp_cpuinfo(void) * (1) These insn were introduced only in 4.10 release. So for older released * support needed. * - * (2) In a SMP setup, the LLOCK/SCOND atomiticity across CPUs needs to be + * (2) In a SMP setup, the LLOCK/SCOND atomicity across CPUs needs to be * gaurantted by the platform (not something which core handles). * Assuming a platform won't, SMP Linux needs to use spinlocks + local IRQ * disabling for atomicity. diff --git a/arch/arc/include/asm/thread_info.h b/arch/arc/include/asm/thread_info.h index 3af67455659a..2d79e527fa50 100644 --- a/arch/arc/include/asm/thread_info.h +++ b/arch/arc/include/asm/thread_info.h @@ -103,7 +103,7 @@ static inline __attribute_const__ struct thread_info *current_thread_info(void) /* * _TIF_ALLWORK_MASK includes SYSCALL_TRACE, but we don't need it. - * SYSCALL_TRACE is anways seperately/unconditionally tested right after a + * SYSCALL_TRACE is anyway seperately/unconditionally tested right after a * syscall, so all that reamins to be tested is _TIF_WORK_MASK */ diff --git a/arch/arc/include/asm/uaccess.h b/arch/arc/include/asm/uaccess.h index d1da6032b715..a78d5670884f 100644 --- a/arch/arc/include/asm/uaccess.h +++ b/arch/arc/include/asm/uaccess.h @@ -32,7 +32,7 @@ #define __kernel_ok (segment_eq(get_fs(), KERNEL_DS)) /* - * Algorthmically, for __user_ok() we want do: + * Algorithmically, for __user_ok() we want do: * (start < TASK_SIZE) && (start+len < TASK_SIZE) * where TASK_SIZE could either be retrieved from thread_info->addr_limit or * emitted directly in code. diff --git a/arch/arc/include/uapi/asm/swab.h b/arch/arc/include/uapi/asm/swab.h index 095599a73195..71f3918b0fc3 100644 --- a/arch/arc/include/uapi/asm/swab.h +++ b/arch/arc/include/uapi/asm/swab.h @@ -74,7 +74,7 @@ __tmp ^ __in; \ }) -#elif (ARC_BSWAP_TYPE == 2) /* Custom single cycle bwap instruction */ +#elif (ARC_BSWAP_TYPE == 2) /* Custom single cycle bswap instruction */ #define __arch_swab32(x) \ ({ \ diff --git a/arch/arc/kernel/perf_event.c b/arch/arc/kernel/perf_event.c index 6fd48021324b..08f03d9b5b3e 100644 --- a/arch/arc/kernel/perf_event.c +++ b/arch/arc/kernel/perf_event.c @@ -108,7 +108,7 @@ static void arc_perf_event_update(struct perf_event *event, int64_t delta = new_raw_count - prev_raw_count; /* - * We don't afaraid of hwc->prev_count changing beneath our feet + * We aren't afraid of hwc->prev_count changing beneath our feet * because there's no way for us to re-enter this function anytime. */ local64_set(&hwc->prev_count, new_raw_count); diff --git a/arch/arc/kernel/setup.c b/arch/arc/kernel/setup.c index f63b8bfefb0c..2ee7a4d758a8 100644 --- a/arch/arc/kernel/setup.c +++ b/arch/arc/kernel/setup.c @@ -392,7 +392,7 @@ void __init setup_arch(char **cmdline_p) /* * If we are here, it is established that @uboot_arg didn't * point to DT blob. Instead if u-boot says it is cmdline, - * Appent to embedded DT cmdline. + * append to embedded DT cmdline. * setup_machine_fdt() would have populated @boot_command_line */ if (uboot_tag == 1) { diff --git a/arch/arc/kernel/signal.c b/arch/arc/kernel/signal.c index 004b7f0bc76c..6cb3736b6b83 100644 --- a/arch/arc/kernel/signal.c +++ b/arch/arc/kernel/signal.c @@ -34,7 +34,7 @@ * -ViXS were still seeing crashes when using insmod to load drivers. * It turned out that the code to change Execute permssions for TLB entries * of user was not guarded for interrupts (mod_tlb_permission) - * This was cauing TLB entries to be overwritten on unrelated indexes + * This was causing TLB entries to be overwritten on unrelated indexes * * Vineetg: July 15th 2008: Bug #94183 * -Exception happens in Delay slot of a JMP, and before user space resumes, diff --git a/arch/arc/kernel/troubleshoot.c b/arch/arc/kernel/troubleshoot.c index a6f91e88ce36..934150e7ac48 100644 --- a/arch/arc/kernel/troubleshoot.c +++ b/arch/arc/kernel/troubleshoot.c @@ -276,7 +276,7 @@ static int tlb_stats_open(struct inode *inode, struct file *file) return 0; } -/* called on user read(): display the couters */ +/* called on user read(): display the counters */ static ssize_t tlb_stats_output(struct file *file, /* file descriptor */ char __user *user_buf, /* user buffer */ size_t len, /* length of buffer */ diff --git a/arch/arc/mm/cache.c b/arch/arc/mm/cache.c index 9e5eddbb856f..5a294b2c3cb3 100644 --- a/arch/arc/mm/cache.c +++ b/arch/arc/mm/cache.c @@ -215,7 +215,7 @@ slc_chk: * ------------------ * This ver of MMU supports variable page sizes (1k-16k): although Linux will * only support 8k (default), 16k and 4k. - * However from hardware perspective, smaller page sizes aggrevate aliasing + * However from hardware perspective, smaller page sizes aggravate aliasing * meaning more vaddr bits needed to disambiguate the cache-line-op ; * the existing scheme of piggybacking won't work for certain configurations. * Two new registers IC_PTAG and DC_PTAG inttoduced. @@ -302,7 +302,7 @@ void __cache_line_loop_v3(phys_addr_t paddr, unsigned long vaddr, /* * This is technically for MMU v4, using the MMU v3 programming model - * Special work for HS38 aliasing I-cache configuratino with PAE40 + * Special work for HS38 aliasing I-cache configuration with PAE40 * - upper 8 bits of paddr need to be written into PTAG_HI * - (and needs to be written before the lower 32 bits) * Note that PTAG_HI is hoisted outside the line loop @@ -936,7 +936,7 @@ void arc_cache_init(void) ic->ver, CONFIG_ARC_MMU_VER); /* - * In MMU v4 (HS38x) the alising icache config uses IVIL/PTAG + * In MMU v4 (HS38x) the aliasing icache config uses IVIL/PTAG * pair to provide vaddr/paddr respectively, just as in MMU v3 */ if (is_isa_arcv2() && ic->alias) diff --git a/arch/arc/mm/dma.c b/arch/arc/mm/dma.c index 8c8e36fa5659..73d7e4c75b7d 100644 --- a/arch/arc/mm/dma.c +++ b/arch/arc/mm/dma.c @@ -10,7 +10,7 @@ * DMA Coherent API Notes * * I/O is inherently non-coherent on ARC. So a coherent DMA buffer is - * implemented by accessintg it using a kernel virtual address, with + * implemented by accessing it using a kernel virtual address, with * Cache bit off in the TLB entry. * * The default DMA address == Phy address which is 0x8000_0000 based. -- cgit v1.2.3 From 60f2b4b8af548150cc56bf6fd213e47897964794 Mon Sep 17 00:00:00 2001 From: Vineet Gupta Date: Mon, 30 May 2016 19:21:22 +0530 Subject: ARC: [intc-compact] simplify code for 2 priority levels ARC700 support for 2 interrupt priorities historically allowed even slow perpherals such as emac and uart to setup high priority interrupts which was wrong from the beginning as they could possibly delay the more critical timer interrupt. The hardware support for 2 level interrupts in ARCompact is less than ideal anyways (judging from the "hacks" in low level entry code and thus is not used in productions systems I know of. So reduce the scope of this to timer only, thereby reducing a bunch of complexity. Signed-off-by: Vineet Gupta --- arch/arc/Kconfig | 22 ++-------------------- arch/arc/kernel/entry-compact.S | 18 ++---------------- arch/arc/kernel/intc-compact.c | 6 ++---- 3 files changed, 6 insertions(+), 40 deletions(-) (limited to 'arch/arc/kernel') diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig index 0dcbacfdea4b..b14826a4f59c 100644 --- a/arch/arc/Kconfig +++ b/arch/arc/Kconfig @@ -186,9 +186,6 @@ if SMP config ARC_HAS_COH_CACHES def_bool n -config ARC_HAS_REENTRANT_IRQ_LV2 - def_bool n - config ARC_MCIP bool "ARConnect Multicore IP (MCIP) Support " depends on ISA_ARCV2 @@ -366,25 +363,10 @@ config NODES_SHIFT if ISA_ARCOMPACT config ARC_COMPACT_IRQ_LEVELS - bool "ARCompact IRQ Priorities: High(2)/Low(1)" + bool "Setup Timer IRQ as high Priority" default n - # Timer HAS to be high priority, for any other high priority config - select ARC_IRQ3_LV2 # if SMP, LV2 enabled ONLY if ARC implementation has LV2 re-entrancy - depends on !SMP || ARC_HAS_REENTRANT_IRQ_LV2 - -if ARC_COMPACT_IRQ_LEVELS - -config ARC_IRQ3_LV2 - bool - -config ARC_IRQ5_LV2 - bool - -config ARC_IRQ6_LV2 - bool - -endif #ARC_COMPACT_IRQ_LEVELS + depends on !SMP config ARC_FPU_SAVE_RESTORE bool "Enable FPU state persistence across context switch" diff --git a/arch/arc/kernel/entry-compact.S b/arch/arc/kernel/entry-compact.S index 0cb0abaa0479..98812c1248df 100644 --- a/arch/arc/kernel/entry-compact.S +++ b/arch/arc/kernel/entry-compact.S @@ -91,27 +91,13 @@ VECTOR mem_service ; 0x8, Mem exception (0x1) VECTOR instr_service ; 0x10, Instrn Error (0x2) ; ******************** Device ISRs ********************** -#ifdef CONFIG_ARC_IRQ3_LV2 -VECTOR handle_interrupt_level2 -#else -VECTOR handle_interrupt_level1 -#endif - -VECTOR handle_interrupt_level1 - -#ifdef CONFIG_ARC_IRQ5_LV2 -VECTOR handle_interrupt_level2 -#else -VECTOR handle_interrupt_level1 -#endif - -#ifdef CONFIG_ARC_IRQ6_LV2 +#ifdef CONFIG_ARC_COMPACT_IRQ_LEVELS VECTOR handle_interrupt_level2 #else VECTOR handle_interrupt_level1 #endif -.rept 25 +.rept 28 VECTOR handle_interrupt_level1 ; Other devices .endr diff --git a/arch/arc/kernel/intc-compact.c b/arch/arc/kernel/intc-compact.c index c5cceca36118..ce9deb953ca9 100644 --- a/arch/arc/kernel/intc-compact.c +++ b/arch/arc/kernel/intc-compact.c @@ -28,10 +28,8 @@ void arc_init_IRQ(void) { int level_mask = 0; - /* setup any high priority Interrupts (Level2 in ARCompact jargon) */ - level_mask |= IS_ENABLED(CONFIG_ARC_IRQ3_LV2) << 3; - level_mask |= IS_ENABLED(CONFIG_ARC_IRQ5_LV2) << 5; - level_mask |= IS_ENABLED(CONFIG_ARC_IRQ6_LV2) << 6; + /* Is timer high priority Interrupt (Level2 in ARCompact jargon) */ + level_mask |= IS_ENABLED(CONFIG_ARC_COMPACT_IRQ_LEVELS) << TIMER0_IRQ; /* * Write to register, even if no LV2 IRQs configured to reset it -- cgit v1.2.3