From bb8c29caffdda55d3df0315ff2485f7df7290b1d Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Tue, 7 Jul 2009 16:37:05 +0200 Subject: [S390] udelay: disable lockdep to avoid false positives Our udelay implementation enables interrupts to receive a special timer interrupt regardless of the context it is called from. This might lead to false positive lockdep reports. Since lockdep isn't aware of the fact that only a single interrupt source is enabled it warns about possible deadlocks that in reality won't happen, like the one below. To fix this disable lockdep before enabling interrupts. [ 254.040888] ================================= [ 254.040904] [ INFO: inconsistent lock state ] [ 254.040910] 2.6.30 #9 [ 254.040914] --------------------------------- [ 254.040920] inconsistent {IN-HARDIRQ-W} -> {HARDIRQ-ON-W} usage. [ 254.040927] swapper/0 [HC0[0]:SC1[1]:HE1:SE0] takes: [ 254.040934] (sch->lock){?.-...}, at: [<00000000002e4778>] ccw_device_timeout+0x48/0x2f0 [ 254.040961] {IN-HARDIRQ-W} state was registered at: [ 254.040969] [<0000000000096f74>] __lock_acquire+0x9d4/0x188c [ 254.040985] [<0000000000097f68>] lock_acquire+0x13c/0x16c [ 254.040998] [<00000000004527e0>] _spin_lock+0x74/0xb8 [ 254.041016] [<0000000000457eb2>] do_IRQ+0xde/0x208 [ 254.041031] [<000000000002d190>] io_return+0x0/0x8 [ 254.041049] [<0000000000029faa>] vtime_stop_cpu+0xbe/0x114 [ 254.041066] irq event stamp: 259629 [ 254.041076] hardirqs last enabled at (259628): [<000000000045238e>] _spin_unlock_irq+0x5e/0x9c [ 254.041095] hardirqs last disabled at (259629): [<000000000045292e>] _spin_lock_irq+0x4a/0xc4 [ 254.041126] softirqs last enabled at (259614): [<000000000006500e>] __do_softirq+0x296/0x2b0 [ 254.041137] softirqs last disabled at (259619): [<0000000000024cf6>] do_softirq+0x102/0x108 [ 254.041147] [ 254.041148] other info that might help us debug this: [ 254.041153] 2 locks held by swapper/0: [ 254.041157] #0: (&priv->timer){+.-...}, at: [<000000000006bf9a>] run_timer_softirq+0x19a/0x340 [ 254.041170] #1: (sch->lock){?.-...}, at: [<00000000002e4778>] ccw_device_timeout+0x48/0x2f0 [ 254.041182] [ 254.041310] Call Trace: [ 254.041313] ([<00000000000174fc>] show_trace+0x16c/0x170) [ 254.041321] [<0000000000017578>] show_stack+0x78/0x104 [ 254.041327] [<000000000044d0ca>] dump_stack+0xc6/0xd4 [ 254.041342] [<00000000000949b4>] print_usage_bug+0x1c8/0x1fc [ 254.041353] [<0000000000094e8a>] mark_lock+0x4a2/0x670 [ 254.041364] [<00000000000950e2>] mark_held_locks+0x8a/0xb4 [ 254.041375] [<0000000000095398>] trace_hardirqs_on_caller+0x74/0x1ac [ 254.041388] [<00000000000954fa>] trace_hardirqs_on+0x2a/0x38 [ 254.041402] [<000000000025f1ec>] __udelay_disabled+0xac/0xfc [ 254.041419] [<000000000025f432>] __udelay+0x12a/0x148 [ 254.041433] [<00000000002d64d8>] cio_commit_config+0x170/0x290 [ 254.041451] [<00000000002d6978>] cio_disable_subchannel+0x120/0x1cc [ 254.041468] [<00000000002e32a4>] ccw_device_recog_done+0x54/0x2f4 [ 254.041485] [<00000000002e3638>] ccw_device_sense_id_done+0x50/0x90 [ 254.041508] [<00000000002e615a>] snsid_callback+0xfa/0x3a8 [ 254.041515] [<00000000002dd96c>] ccwreq_stop+0x80/0x90 [ 254.041523] [<00000000002dda8e>] ccw_request_timeout+0xc2/0xd0 [ 254.041530] [<00000000002e2f70>] ccw_device_request_event+0x58/0x90 [ 254.041537] [<00000000002e47ae>] ccw_device_timeout+0x7e/0x2f0 [ 254.041555] [<000000000006c02a>] run_timer_softirq+0x22a/0x340 [ 254.041566] [<0000000000064eb0>] __do_softirq+0x138/0x2b0 [ 254.041578] [<0000000000024cf6>] do_softirq+0x102/0x108 [ 254.041590] [<00000000000647ce>] irq_exit+0xee/0x114 [ 254.041603] [<0000000000457d88>] do_extint+0x130/0x17c [ 254.041617] [<000000000002d41e>] ext_no_vtime+0x1e/0x22 [ 254.041631] [<0000000000029faa>] vtime_stop_cpu+0xbe/0x114 [ 254.041646] ([<0000000000029f58>] vtime_stop_cpu+0x6c/0x114) [ 254.041662] [<000000000001d842>] cpu_idle+0x122/0x1c0 [ 254.041679] [<00000000004482c6>] start_secondary+0xce/0xe0 [ 254.041696] [<0000000000000000>] 0x0 [ 254.041715] [<0000000000000000>] 0x0 [ 254.041745] INFO: lockdep is turned off. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/lib/delay.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch/s390/lib') diff --git a/arch/s390/lib/delay.c b/arch/s390/lib/delay.c index 3f5f680726e..97c1eca83cc 100644 --- a/arch/s390/lib/delay.c +++ b/arch/s390/lib/delay.c @@ -36,9 +36,11 @@ static void __udelay_disabled(unsigned long usecs) cr0 = (cr0_saved & 0xffff00e0) | 0x00000800; __ctl_load(cr0 , 0, 0); mask = psw_kernel_bits | PSW_MASK_WAIT | PSW_MASK_EXT; + lockdep_off(); trace_hardirqs_on(); __load_psw_mask(mask); local_irq_disable(); + lockdep_on(); __ctl_load(cr0_saved, 0, 0); local_tick_enable(clock_saved); set_clock_comparator(S390_lowcore.clock_comparator); -- cgit v1.2.3 From 5075baca2e95840d76210c3cfda56134007462c9 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Tue, 7 Jul 2009 16:37:09 +0200 Subject: [S390] add __ucmpdi2() helper function Provide __ucmpdi2() helper function on 31 bit so we don't run again and again in compile errors like this one: kernel/built-in.o: In function `T.689': perf_counter.c:(.text+0x56c86): undefined reference to `__ucmpdi2' Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/lib/Makefile | 2 +- arch/s390/lib/ucmpdi2.c | 26 ++++++++++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 arch/s390/lib/ucmpdi2.c (limited to 'arch/s390/lib') diff --git a/arch/s390/lib/Makefile b/arch/s390/lib/Makefile index ab6735df2d2..97975ec7a27 100644 --- a/arch/s390/lib/Makefile +++ b/arch/s390/lib/Makefile @@ -3,6 +3,6 @@ # lib-y += delay.o string.o uaccess_std.o uaccess_pt.o -obj-$(CONFIG_32BIT) += div64.o qrnnd.o +obj-$(CONFIG_32BIT) += div64.o qrnnd.o ucmpdi2.o lib-$(CONFIG_64BIT) += uaccess_mvcos.o lib-$(CONFIG_SMP) += spinlock.o diff --git a/arch/s390/lib/ucmpdi2.c b/arch/s390/lib/ucmpdi2.c new file mode 100644 index 00000000000..3e05ff53258 --- /dev/null +++ b/arch/s390/lib/ucmpdi2.c @@ -0,0 +1,26 @@ +#include + +union ull_union { + unsigned long long ull; + struct { + unsigned int high; + unsigned int low; + } ui; +}; + +int __ucmpdi2(unsigned long long a, unsigned long long b) +{ + union ull_union au = {.ull = a}; + union ull_union bu = {.ull = b}; + + if (au.ui.high < bu.ui.high) + return 0; + else if (au.ui.high > bu.ui.high) + return 2; + if (au.ui.low < bu.ui.low) + return 0; + else if (au.ui.low > bu.ui.low) + return 2; + return 1; +} +EXPORT_SYMBOL(__ucmpdi2); -- cgit v1.2.3