[PATCH] lockdep: irqtrace subsystem, s390 support
authorHeiko Carstens <heiko.carstens@de.ibm.com>
Mon, 3 Jul 2006 07:24:46 +0000 (00:24 -0700)
committerLinus Torvalds <torvalds@g5.osdl.org>
Mon, 3 Jul 2006 22:27:03 +0000 (15:27 -0700)
irqtrace support for s390.

Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: Arjan van de Ven <arjan@infradead.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
arch/s390/Kconfig.debug
arch/s390/kernel/entry.S
arch/s390/kernel/entry64.S
arch/s390/kernel/irq.c
arch/s390/kernel/process.c
drivers/s390/char/sclp.c
drivers/s390/cio/cio.c
include/asm-s390/irqflags.h [new file with mode: 0644]
include/asm-s390/system.h

index f53b6d5..2283933 100644 (file)
@@ -1,5 +1,9 @@
 menu "Kernel hacking"
 
+config TRACE_IRQFLAGS_SUPPORT
+       bool
+       default y
+
 source "lib/Kconfig.debug"
 
 endmenu
index d8948c3..5b5799a 100644 (file)
@@ -58,6 +58,21 @@ STACK_SIZE  = 1 << STACK_SHIFT
 
 #define BASED(name) name-system_call(%r13)
 
+#ifdef CONFIG_TRACE_IRQFLAGS
+       .macro  TRACE_IRQS_ON
+       l       %r1,BASED(.Ltrace_irq_on)
+       basr    %r14,%r1
+       .endm
+
+       .macro  TRACE_IRQS_OFF
+       l       %r1,BASED(.Ltrace_irq_off)
+       basr    %r14,%r1
+       .endm
+#else
+#define TRACE_IRQS_ON
+#define TRACE_IRQS_OFF
+#endif
+
 /*
  * Register usage in interrupt handlers:
  *    R9  - pointer to current task structure
@@ -361,6 +376,7 @@ ret_from_fork:
        st      %r15,SP_R15(%r15)       # store stack pointer for new kthread
 0:     l       %r1,BASED(.Lschedtail)
        basr    %r14,%r1
+       TRACE_IRQS_ON
         stosm   __SF_EMPTY(%r15),0x03     # reenable interrupts
        b       BASED(sysc_return)
 
@@ -516,6 +532,7 @@ pgm_no_vtime3:
        mvc     __THREAD_per+__PER_address(4,%r1),__LC_PER_ADDRESS
        mvc     __THREAD_per+__PER_access_id(1,%r1),__LC_PER_ACCESS_ID
        oi      __TI_flags+3(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP
+       TRACE_IRQS_ON
        stosm   __SF_EMPTY(%r15),0x03   # reenable interrupts
        b       BASED(sysc_do_svc)
 
@@ -539,9 +556,11 @@ io_int_handler:
 io_no_vtime:
 #endif
        l       %r9,__LC_THREAD_INFO    # load pointer to thread_info struct
+       TRACE_IRQS_OFF
         l       %r1,BASED(.Ldo_IRQ)        # load address of do_IRQ
         la      %r2,SP_PTREGS(%r15) # address of register-save area
         basr    %r14,%r1          # branch to standard irq handler
+       TRACE_IRQS_ON
 
 io_return:
         tm      SP_PSW+1(%r15),0x01    # returning to user ?
@@ -651,10 +670,12 @@ ext_int_handler:
 ext_no_vtime:
 #endif
        l       %r9,__LC_THREAD_INFO    # load pointer to thread_info struct
+       TRACE_IRQS_OFF
        la      %r2,SP_PTREGS(%r15)    # address of register-save area
        lh      %r3,__LC_EXT_INT_CODE  # get interruption code
        l       %r1,BASED(.Ldo_extint)
        basr    %r14,%r1
+       TRACE_IRQS_ON
        b       BASED(io_return)
 
 __critical_end:
@@ -731,8 +752,10 @@ mcck_no_vtime:
        stosm   __SF_EMPTY(%r15),0x04   # turn dat on
        tm      __TI_flags+3(%r9),_TIF_MCCK_PENDING
        bno     BASED(mcck_return)
+       TRACE_IRQS_OFF
        l       %r1,BASED(.Ls390_handle_mcck)
        basr    %r14,%r1                # call machine check handler
+       TRACE_IRQS_ON
 mcck_return:
        mvc     __LC_RETURN_MCCK_PSW(8),SP_PSW(%r15) # move return PSW
        ni      __LC_RETURN_MCCK_PSW+1,0xfd # clear wait state bit
@@ -1012,7 +1035,11 @@ cleanup_io_leave_insn:
 .Lvfork:       .long  sys_vfork
 .Lschedtail:   .long  schedule_tail
 .Lsysc_table:  .long  sys_call_table
-
+#ifdef CONFIG_TRACE_IRQFLAGS
+.Ltrace_irq_on:.long  trace_hardirqs_on
+.Ltrace_irq_off:
+              .long  trace_hardirqs_off
+#endif
 .Lcritical_start:
                .long  __critical_start + 0x80000000
 .Lcritical_end:
index 1ca499f..56f5f61 100644 (file)
@@ -58,6 +58,19 @@ _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK | _TIF_NEED_RESCHED | \
 
 #define BASED(name) name-system_call(%r13)
 
+#ifdef CONFIG_TRACE_IRQFLAGS
+       .macro  TRACE_IRQS_ON
+        brasl  %r14,trace_hardirqs_on
+       .endm
+
+       .macro  TRACE_IRQS_OFF
+        brasl  %r14,trace_hardirqs_off
+       .endm
+#else
+#define TRACE_IRQS_ON
+#define TRACE_IRQS_OFF
+#endif
+
        .macro  STORE_TIMER lc_offset
 #ifdef CONFIG_VIRT_CPU_ACCOUNTING
        stpt    \lc_offset
@@ -354,6 +367,7 @@ ret_from_fork:
        jo      0f
        stg     %r15,SP_R15(%r15)       # store stack pointer for new kthread
 0:     brasl   %r14,schedule_tail
+       TRACE_IRQS_ON
         stosm   24(%r15),0x03     # reenable interrupts
        j       sysc_return
 
@@ -535,6 +549,7 @@ pgm_no_vtime3:
        mvc     __THREAD_per+__PER_address(8,%r1),__LC_PER_ADDRESS
        mvc     __THREAD_per+__PER_access_id(1,%r1),__LC_PER_ACCESS_ID
        oi      __TI_flags+7(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP
+       TRACE_IRQS_ON
        stosm   __SF_EMPTY(%r15),0x03   # reenable interrupts
        j       sysc_do_svc
 
@@ -557,8 +572,10 @@ io_int_handler:
 io_no_vtime:
 #endif
        lg      %r9,__LC_THREAD_INFO    # load pointer to thread_info struct
+       TRACE_IRQS_OFF
         la      %r2,SP_PTREGS(%r15)    # address of register-save area
        brasl   %r14,do_IRQ            # call standard irq handler
+       TRACE_IRQS_ON
 
 io_return:
         tm      SP_PSW+1(%r15),0x01    # returning to user ?
@@ -665,9 +682,11 @@ ext_int_handler:
 ext_no_vtime:
 #endif
        lg      %r9,__LC_THREAD_INFO    # load pointer to thread_info struct
+       TRACE_IRQS_OFF
        la      %r2,SP_PTREGS(%r15)    # address of register-save area
        llgh    %r3,__LC_EXT_INT_CODE  # get interruption code
        brasl   %r14,do_extint
+       TRACE_IRQS_ON
        j       io_return
 
 __critical_end:
@@ -743,7 +762,9 @@ mcck_no_vtime:
        stosm   __SF_EMPTY(%r15),0x04   # turn dat on
        tm      __TI_flags+7(%r9),_TIF_MCCK_PENDING
        jno     mcck_return
+       TRACE_IRQS_OFF
        brasl   %r14,s390_handle_mcck
+       TRACE_IRQS_ON
 mcck_return:
        mvc     __LC_RETURN_MCCK_PSW(16),SP_PSW(%r15) # move return PSW
        ni      __LC_RETURN_MCCK_PSW+1,0xfd # clear wait state bit
index 480b6a5..e347190 100644 (file)
@@ -97,7 +97,7 @@ asmlinkage void do_softirq(void)
 
        account_system_vtime(current);
 
-       __local_bh_enable();
+       _local_bh_enable();
 
        local_irq_restore(flags);
 }
index 1f93991..78c8e55 100644 (file)
@@ -142,6 +142,7 @@ static void default_idle(void)
                return;
        }
 
+       trace_hardirqs_on();
        /* Wait for external, I/O or machine check interrupt. */
        __load_psw_mask(PSW_KERNEL_BITS | PSW_MASK_WAIT |
                        PSW_MASK_IO | PSW_MASK_EXT);
index 4138564..985d161 100644 (file)
@@ -383,6 +383,7 @@ void
 sclp_sync_wait(void)
 {
        unsigned long psw_mask;
+       unsigned long flags;
        unsigned long cr0, cr0_sync;
        u64 timeout;
 
@@ -395,9 +396,11 @@ sclp_sync_wait(void)
                          sclp_tod_from_jiffies(sclp_request_timer.expires -
                                                jiffies);
        }
+       local_irq_save(flags);
        /* Prevent bottom half from executing once we force interrupts open */
        local_bh_disable();
        /* Enable service-signal interruption, disable timer interrupts */
+       trace_hardirqs_on();
        __ctl_store(cr0, 0, 0);
        cr0_sync = cr0;
        cr0_sync |= 0x00000200;
@@ -415,11 +418,10 @@ sclp_sync_wait(void)
                barrier();
                cpu_relax();
        }
-       /* Restore interrupt settings */
-       asm volatile ("SSM 0(%0)"
-                     : : "a" (&psw_mask) : "memory");
+       local_irq_disable();
        __ctl_load(cr0, 0, 0);
-       __local_bh_enable();
+       _local_bh_enable();
+       local_irq_restore(flags);
 }
 
 EXPORT_SYMBOL(sclp_sync_wait);
index a342326..6fec90e 100644 (file)
@@ -147,7 +147,7 @@ cio_tpi(void)
                sch->driver->irq(&sch->dev);
        spin_unlock(&sch->lock);
        irq_exit ();
-       __local_bh_enable();
+       _local_bh_enable();
        return 1;
 }
 
diff --git a/include/asm-s390/irqflags.h b/include/asm-s390/irqflags.h
new file mode 100644 (file)
index 0000000..65f4db6
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ *  include/asm-s390/irqflags.h
+ *
+ *    Copyright (C) IBM Corp. 2006
+ *    Author(s): Heiko Carstens <heiko.carstens@de.ibm.com>
+ */
+
+#ifndef __ASM_IRQFLAGS_H
+#define __ASM_IRQFLAGS_H
+
+#ifdef __KERNEL__
+
+/* interrupt control.. */
+#define raw_local_irq_enable() ({ \
+       unsigned long  __dummy; \
+       __asm__ __volatile__ ( \
+               "stosm 0(%1),0x03" \
+               : "=m" (__dummy) : "a" (&__dummy) : "memory" ); \
+       })
+
+#define raw_local_irq_disable() ({ \
+       unsigned long __flags; \
+       __asm__ __volatile__ ( \
+               "stnsm 0(%1),0xfc" : "=m" (__flags) : "a" (&__flags) ); \
+       __flags; \
+       })
+
+#define raw_local_save_flags(x) \
+       __asm__ __volatile__("stosm 0(%1),0" : "=m" (x) : "a" (&x), "m" (x) )
+
+#define raw_local_irq_restore(x) \
+       __asm__ __volatile__("ssm   0(%0)" : : "a" (&x), "m" (x) : "memory")
+
+#define raw_irqs_disabled()            \
+({                                     \
+       unsigned long flags;            \
+       local_save_flags(flags);        \
+       !((flags >> __FLAG_SHIFT) & 3); \
+})
+
+static inline int raw_irqs_disabled_flags(unsigned long flags)
+{
+       return !((flags >> __FLAG_SHIFT) & 3);
+}
+
+/* For spinlocks etc */
+#define raw_local_irq_save(x)  ((x) = raw_local_irq_disable())
+
+#endif /* __KERNEL__ */
+#endif /* __ASM_IRQFLAGS_H */
index 71a0732..9ab186f 100644 (file)
@@ -301,34 +301,6 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size)
 #define set_mb(var, value)      do { var = value; mb(); } while (0)
 #define set_wmb(var, value)     do { var = value; wmb(); } while (0)
 
-/* interrupt control.. */
-#define local_irq_enable() ({ \
-        unsigned long  __dummy; \
-        __asm__ __volatile__ ( \
-                "stosm 0(%1),0x03" \
-               : "=m" (__dummy) : "a" (&__dummy) : "memory" ); \
-        })
-
-#define local_irq_disable() ({ \
-        unsigned long __flags; \
-        __asm__ __volatile__ ( \
-                "stnsm 0(%1),0xfc" : "=m" (__flags) : "a" (&__flags) ); \
-        __flags; \
-        })
-
-#define local_save_flags(x) \
-        __asm__ __volatile__("stosm 0(%1),0" : "=m" (x) : "a" (&x), "m" (x) )
-
-#define local_irq_restore(x) \
-        __asm__ __volatile__("ssm   0(%0)" : : "a" (&x), "m" (x) : "memory")
-
-#define irqs_disabled()                        \
-({                                     \
-       unsigned long flags;            \
-       local_save_flags(flags);        \
-        !((flags >> __FLAG_SHIFT) & 3);        \
-})
-
 #ifdef __s390x__
 
 #define __ctl_load(array, low, high) ({ \
@@ -442,8 +414,7 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size)
         })
 #endif /* __s390x__ */
 
-/* For spinlocks etc */
-#define local_irq_save(x)      ((x) = local_irq_disable())
+#include <linux/irqflags.h>
 
 /*
  * Use to set psw mask except for the first byte which
@@ -482,4 +453,3 @@ extern void (*_machine_power_off)(void);
 #endif /* __KERNEL__ */
 
 #endif
-