On 02/01/2012 04:15 PM, Daniel Lezcano wrote:
Yes, but the problem is the same also. Did you try by removing atomic_inc and set nrunnings to nrkthread ?
Unfortunately it's still here: Unable to handle kernel paging request at virtual address 7f0a411c pgd = 80004000 [7f0a411c] *pgd=bf163811, *pte=00000000, *ppte=00000000 Internal error: Oops: 80000007 [#1] PREEMPT SMP Modules linked in: [last unloaded: testmod] CPU: 0 Tainted: G O (3.3.0-rc2+ #2) PC is at 0x7f0a411c LR is at __schedule+0x684/0x6e4 pc : [<7f0a411c>] lr : [<802c0bdc>] psr: 600f0113 sp : bf3b5f78 ip : 00000000 fp : 00000000 r10: 00000000 r9 : 00000000 r8 : 7f0a4538 r7 : 00000002 r6 : 00000400 r5 : 0000003c r4 : 00000001 r3 : 00000000 r2 : bf3b5eb0 r1 : bf219580 r0 : 00000001 Flags: nZCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment kernel Control: 10c5387d Table: bfbec04a DAC: 00000015 Process test/124 (pid: 6772, stack limit = 0xbf3b42f8) Stack: (0xbf3b5f78 to 0xbf3b6000) 5f60: 7b11940d 0000003c 5f80: 000f4240 00000000 00000001 000b07b6 bf8c9e44 00000000 7f0a4000 00000013 5fa0: 00000000 80049260 00000000 00000000 00000000 00000000 00000000 00000000 5fc0: dead4ead ffffffff ffffffff 8048b2b8 00000000 00000000 8036a4d9 bf3b5fdc 5fe0: bf3b5fdc 271aee1c bf8c9e44 800491d4 8000eabc 8000eabc bfefc811 bfefcc11 Code: bad PC value If someone wants to look at it, I'm attaching everything. The patch is almost nothing beyond exporting irq_time_read() to modules. Note it's quite rare - to reproduce it, I do while true; do insmod testmod.ko usehrtime=1 && rmmod testmod.ko; sleep 1; done and wait for a few minutes. Dmitry
#include <linux/kernel.h> #include <linux/sched.h> #include <linux/kthread.h> #include <linux/hardirq.h> #include <linux/module.h> #include <linux/slab.h> #include <linux/ktime.h> MODULE_LICENSE("GPL"); static int nrthreads = 128; module_param(nrthreads, int, 0644); static int loopcount = 1024; module_param(loopcount, int, 0644); static int usehrtime = 0; module_param(usehrtime, int, 0644); static int slack = 50000; module_param(slack, int, 0644); static int msecs = 1; module_param(msecs, int, 0644); static DEFINE_PER_CPU(u64, cpu_irq_time); static DECLARE_COMPLETION(done); static struct task_struct **threads; static atomic_t nrunning; static ktime_t start; static void timeout_init_irq_time(void *unused) { int cpu = smp_processor_id(); per_cpu(cpu_irq_time, cpu) = irq_time_read(cpu); } static void timeout_show_irq_time(void *unused) { int cpu = smp_processor_id(); u64 irqtime = irq_time_read(cpu) - per_cpu(cpu_irq_time, cpu); printk("cpu%d spent %llu usecs in irqs\n", cpu, div64_u64(irqtime, NSEC_PER_USEC)); } static int test(void *unused) { int i; ktime_t expires = ktime_set(0, msecs * NSEC_PER_MSEC); for (i = 0; !kthread_should_stop() && i < loopcount; i++) { if (usehrtime) { set_current_state(TASK_UNINTERRUPTIBLE); schedule_hrtimeout_range(&expires, slack, HRTIMER_MODE_REL); } else schedule_timeout_uninterruptible(msecs_to_jiffies(msecs)); } if (atomic_dec_and_test(&nrunning)) { on_each_cpu(timeout_show_irq_time, NULL, 1); printk("-- timeout test end, %lld msecs elapsed --\n", ktime_to_ms(ktime_sub(ktime_get(), start))); complete(&done); } return 0; } static int __init testmod_init(void) { int i; printk("-- %d-threads, %d-loops timeout test for %d-msecs timeouts, use %s", nrthreads, loopcount, msecs, (usehrtime ? "high-res timeout " : "jiffies timeout ")); if (usehrtime) printk("with %u-nsecs slack --\n", slack); else printk("--\n"); start = ktime_get(); atomic_set(&nrunning, nrthreads); on_each_cpu(timeout_init_irq_time, NULL, 1); threads = kmalloc(nrthreads * sizeof(struct task_struct *), GFP_KERNEL); if (!threads) return -ENOMEM; for (i = 0; i < nrthreads; i++) { threads[i] = kthread_run(test, NULL, "test/%d", i); if (IS_ERR(threads[i])) { int j, err = PTR_ERR(threads[i]); for (j = 0; j < i; j++) kthread_stop(threads[j]); kfree(threads); return err; } } return 0; } static void __exit testmod_exit(void) { wait_for_completion(&done); kfree(threads); } module_init(testmod_init); module_exit(testmod_exit);
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 5bed94e..4759676 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -805,17 +805,6 @@ config SCHED_MC making when dealing with multi-core CPU chips at a cost of slightly increased overhead in some places. If unsure say N here. -config IRQ_TIME_ACCOUNTING - bool "Fine granularity task level IRQ time accounting" - default n - ---help--- - Select this option to enable fine granularity task irq time - accounting. This is done by reading a timestamp on each - transitions between softirq and hardirq state, so there can be a - small performance impact. - - If in doubt, say N here. - source "kernel/Kconfig.preempt" config X86_UP_APIC diff --git a/include/linux/hardirq.h b/include/linux/hardirq.h index bb7f309..3d08f8d 100644 --- a/include/linux/hardirq.h +++ b/include/linux/hardirq.h @@ -137,6 +137,7 @@ static inline void account_system_vtime(struct task_struct *tsk) } #else extern void account_system_vtime(struct task_struct *tsk); +extern u64 irq_time_read(int cpu); #endif #if defined(CONFIG_TINY_RCU) || defined(CONFIG_TINY_PREEMPT_RCU) diff --git a/kernel/sched/core.c b/kernel/sched/core.c index df00cb0..b033d78 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -762,7 +762,7 @@ static DEFINE_PER_CPU(u64, cpu_hardirq_time); static DEFINE_PER_CPU(u64, cpu_softirq_time); static DEFINE_PER_CPU(u64, irq_start_time); -static int sched_clock_irqtime; +static int sched_clock_irqtime = 1; void enable_sched_clock_irqtime(void) { @@ -789,7 +789,7 @@ static inline void irq_time_write_end(void) __this_cpu_inc(irq_time_seq.sequence); } -static inline u64 irq_time_read(int cpu) +u64 __sched irq_time_read(int cpu) { u64 irq_time; unsigned seq; @@ -811,12 +811,14 @@ static inline void irq_time_write_end(void) { } -static inline u64 irq_time_read(int cpu) +u64 __sched irq_time_read(int cpu) { return per_cpu(cpu_softirq_time, cpu) + per_cpu(cpu_hardirq_time, cpu); } #endif /* CONFIG_64BIT */ +EXPORT_SYMBOL(irq_time_read); + /* * Called before incrementing preempt_count on {soft,}irq_enter * and before decrementing preempt_count on {soft,}irq_exit. diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 8745ac7..d6d7afc 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -299,6 +299,17 @@ config SCHEDSTATS application, you can say N to avoid the very slight overhead this adds. +config IRQ_TIME_ACCOUNTING + bool "Fine granularity task level IRQ time accounting" + default n + ---help--- + Select this option to enable fine granularity task irq time + accounting. This is done by reading a timestamp on each + transitions between softirq and hardirq state, so there can be a + small performance impact. + + If in doubt, say N here. + config TIMER_STATS bool "Collect kernel timers statistics" depends on DEBUG_KERNEL && PROC_FS
_______________________________________________ linaro-dev mailing list linaro-dev@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-dev