summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/asm-s390/cputime.h170
-rw-r--r--include/asm-s390/hardirq.h1
-rw-r--r--include/asm-s390/lowcore.h47
-rw-r--r--include/asm-s390/system.h18
-rw-r--r--include/asm-s390/timer.h2
-rw-r--r--include/linux/hardirq.h18
6 files changed, 241 insertions, 15 deletions
diff --git a/include/asm-s390/cputime.h b/include/asm-s390/cputime.h
index ad989e5d369c..216d861337e6 100644
--- a/include/asm-s390/cputime.h
+++ b/include/asm-s390/cputime.h
@@ -1,6 +1,168 @@
-#ifndef __S390_CPUTIME_H
-#define __S390_CPUTIME_H
+/*
+ * include/asm-s390/cputime.h
+ *
+ * (C) Copyright IBM Corp. 2004
+ *
+ * Author: Martin Schwidefsky <schwidefsky@de.ibm.com>
+ */
-#include <asm-generic/cputime.h>
+#ifndef _S390_CPUTIME_H
+#define _S390_CPUTIME_H
-#endif /* __S390_CPUTIME_H */
+/* We want to use micro-second resolution. */
+
+typedef unsigned long long cputime_t;
+typedef unsigned long long cputime64_t;
+
+#ifndef __s390x__
+
+static inline unsigned int
+__div(unsigned long long n, unsigned int base)
+{
+ register_pair rp;
+
+ rp.pair = n >> 1;
+ asm ("dr %0,%1" : "+d" (rp) : "d" (base >> 1));
+ return rp.subreg.odd;
+}
+
+#else /* __s390x__ */
+
+static inline unsigned int
+__div(unsigned long long n, unsigned int base)
+{
+ return n / base;
+}
+
+#endif /* __s390x__ */
+
+#define cputime_zero (0ULL)
+#define cputime_max ((~0UL >> 1) - 1)
+#define cputime_add(__a, __b) ((__a) + (__b))
+#define cputime_sub(__a, __b) ((__a) - (__b))
+#define cputime_eq(__a, __b) ((__a) == (__b))
+#define cputime_gt(__a, __b) ((__a) > (__b))
+#define cputime_ge(__a, __b) ((__a) >= (__b))
+#define cputime_lt(__a, __b) ((__a) < (__b))
+#define cputime_le(__a, __b) ((__a) <= (__b))
+#define cputime_to_jiffies(__ct) (__div((__ct), 1000000 / HZ))
+#define jiffies_to_cputime(__hz) ((cputime_t)(__hz) * (1000000 / HZ))
+
+#define cputime64_zero (0ULL)
+#define cputime64_add(__a, __b) ((__a) + (__b))
+#define cputime_to_cputime64(__ct) (__ct)
+
+static inline u64
+cputime64_to_jiffies64(cputime64_t cputime)
+{
+ do_div(cputime, 1000000 / HZ);
+ return cputime;
+}
+
+/*
+ * Convert cputime to milliseconds and back.
+ */
+static inline unsigned int
+cputime_to_msecs(const cputime_t cputime)
+{
+ return __div(cputime, 1000);
+}
+
+static inline cputime_t
+msecs_to_cputime(const unsigned int m)
+{
+ return (cputime_t) m * 1000;
+}
+
+/*
+ * Convert cputime to milliseconds and back.
+ */
+static inline unsigned int
+cputime_to_secs(const cputime_t cputime)
+{
+ return __div(cputime, 1000000);
+}
+
+static inline cputime_t
+secs_to_cputime(const unsigned int s)
+{
+ return (cputime_t) s * 1000000;
+}
+
+/*
+ * Convert cputime to timespec and back.
+ */
+static inline cputime_t
+timespec_to_cputime(const struct timespec *value)
+{
+ return value->tv_nsec / 1000 + (u64) value->tv_sec * 1000000;
+}
+
+static inline void
+cputime_to_timespec(const cputime_t cputime, struct timespec *value)
+{
+#ifndef __s390x__
+ register_pair rp;
+
+ rp.pair = cputime >> 1;
+ asm ("dr %0,%1" : "+d" (rp) : "d" (1000000 >> 1));
+ value->tv_nsec = rp.subreg.even * 1000;
+ value->tv_sec = rp.subreg.odd;
+#else
+ value->tv_nsec = (cputime % 1000000) * 1000;
+ value->tv_sec = cputime / 1000000;
+#endif
+}
+
+/*
+ * Convert cputime to timeval and back.
+ * Since cputime and timeval have the same resolution (microseconds)
+ * this is easy.
+ */
+static inline cputime_t
+timeval_to_cputime(const struct timeval *value)
+{
+ return value->tv_usec + (u64) value->tv_sec * 1000000;
+}
+
+static inline void
+cputime_to_timeval(const cputime_t cputime, struct timeval *value)
+{
+#ifndef __s390x__
+ register_pair rp;
+
+ rp.pair = cputime >> 1;
+ asm ("dr %0,%1" : "+d" (rp) : "d" (1000000 >> 1));
+ value->tv_usec = rp.subreg.even;
+ value->tv_sec = rp.subreg.odd;
+#else
+ value->tv_usec = cputime % 1000000;
+ value->tv_sec = cputime / 1000000;
+#endif
+}
+
+/*
+ * Convert cputime to clock and back.
+ */
+static inline clock_t
+cputime_to_clock_t(cputime_t cputime)
+{
+ return __div(cputime, 1000000 / USER_HZ);
+}
+
+static inline cputime_t
+clock_t_to_cputime(unsigned long x)
+{
+ return (cputime_t) x * (1000000 / USER_HZ);
+}
+
+/*
+ * Convert cputime64 to clock.
+ */
+static inline clock_t
+cputime64_to_clock_t(cputime64_t cputime)
+{
+ return __div(cputime, 1000000 / USER_HZ);
+}
+
+#endif /* _S390_CPUTIME_H */
diff --git a/include/asm-s390/hardirq.h b/include/asm-s390/hardirq.h
index 1580b7b2b05e..53e59b4760c5 100644
--- a/include/asm-s390/hardirq.h
+++ b/include/asm-s390/hardirq.h
@@ -16,6 +16,7 @@
#include <linux/threads.h>
#include <linux/sched.h>
#include <linux/cache.h>
+#include <linux/interrupt.h>
#include <asm/lowcore.h>
/* irq_cpustat_t is unused currently, but could be converted
diff --git a/include/asm-s390/lowcore.h b/include/asm-s390/lowcore.h
index 0aa1c0f1e705..df5172fc589d 100644
--- a/include/asm-s390/lowcore.h
+++ b/include/asm-s390/lowcore.h
@@ -56,13 +56,18 @@
#define __LC_RETURN_PSW 0x200
-#define __LC_IRB 0x210
-
-#define __LC_DIAG44_OPCODE 0x250
-
#define __LC_SAVE_AREA 0xC00
#ifndef __s390x__
+#define __LC_IRB 0x208
+#define __LC_SYNC_ENTER_TIMER 0x248
+#define __LC_ASYNC_ENTER_TIMER 0x250
+#define __LC_EXIT_TIMER 0x258
+#define __LC_LAST_UPDATE_TIMER 0x260
+#define __LC_USER_TIMER 0x268
+#define __LC_SYSTEM_TIMER 0x270
+#define __LC_LAST_UPDATE_CLOCK 0x278
+#define __LC_STEAL_CLOCK 0x280
#define __LC_KERNEL_STACK 0xC40
#define __LC_THREAD_INFO 0xC44
#define __LC_ASYNC_STACK 0xC48
@@ -76,6 +81,16 @@
#define __LC_CURRENT 0xC90
#define __LC_INT_CLOCK 0xC98
#else /* __s390x__ */
+#define __LC_IRB 0x210
+#define __LC_SYNC_ENTER_TIMER 0x250
+#define __LC_ASYNC_ENTER_TIMER 0x258
+#define __LC_EXIT_TIMER 0x260
+#define __LC_LAST_UPDATE_TIMER 0x268
+#define __LC_USER_TIMER 0x270
+#define __LC_SYSTEM_TIMER 0x278
+#define __LC_LAST_UPDATE_CLOCK 0x280
+#define __LC_STEAL_CLOCK 0x288
+#define __LC_DIAG44_OPCODE 0x290
#define __LC_KERNEL_STACK 0xD40
#define __LC_THREAD_INFO 0xD48
#define __LC_ASYNC_STACK 0xD50
@@ -87,7 +102,7 @@
#define __LC_IPLDEV 0xDB8
#define __LC_JIFFY_TIMER 0xDC0
#define __LC_CURRENT 0xDD8
-#define __LC_INT_CLOCK 0xDe8
+#define __LC_INT_CLOCK 0xDE8
#endif /* __s390x__ */
#define __LC_PANIC_MAGIC 0xE00
@@ -169,7 +184,15 @@ struct _lowcore
psw_t return_psw; /* 0x200 */
__u8 irb[64]; /* 0x208 */
- __u8 pad8[0xc00-0x248]; /* 0x248 */
+ __u64 sync_enter_timer; /* 0x248 */
+ __u64 async_enter_timer; /* 0x250 */
+ __u64 exit_timer; /* 0x258 */
+ __u64 last_update_timer; /* 0x260 */
+ __u64 user_timer; /* 0x268 */
+ __u64 system_timer; /* 0x270 */
+ __u64 last_update_clock; /* 0x278 */
+ __u64 steal_clock; /* 0x280 */
+ __u8 pad8[0xc00-0x288]; /* 0x288 */
/* System info area */
__u32 save_area[16]; /* 0xc00 */
@@ -250,8 +273,16 @@ struct _lowcore
psw_t io_new_psw; /* 0x1f0 */
psw_t return_psw; /* 0x200 */
__u8 irb[64]; /* 0x210 */
- __u32 diag44_opcode; /* 0x250 */
- __u8 pad8[0xc00-0x254]; /* 0x254 */
+ __u64 sync_enter_timer; /* 0x250 */
+ __u64 async_enter_timer; /* 0x258 */
+ __u64 exit_timer; /* 0x260 */
+ __u64 last_update_timer; /* 0x268 */
+ __u64 user_timer; /* 0x270 */
+ __u64 system_timer; /* 0x278 */
+ __u64 last_update_clock; /* 0x280 */
+ __u64 steal_clock; /* 0x288 */
+ __u32 diag44_opcode; /* 0x290 */
+ __u8 pad8[0xc00-0x294]; /* 0x294 */
/* System info area */
__u64 save_area[16]; /* 0xc00 */
__u8 pad9[0xd40-0xc80]; /* 0xc80 */
diff --git a/include/asm-s390/system.h b/include/asm-s390/system.h
index d9f3498136e1..e8596077e057 100644
--- a/include/asm-s390/system.h
+++ b/include/asm-s390/system.h
@@ -105,11 +105,29 @@ static inline void restore_access_regs(unsigned int *acrs)
#define prepare_arch_switch(rq, next) do { } while(0)
#define task_running(rq, p) ((rq)->curr == (p))
+
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+extern void account_user_vtime(struct task_struct *);
+extern void account_system_vtime(struct task_struct *);
+
+#define finish_arch_switch(rq, prev) do { \
+ set_fs(current->thread.mm_segment); \
+ spin_unlock(&(rq)->lock); \
+ account_system_vtime(prev); \
+ local_irq_enable(); \
+} while (0)
+
+#else
+
+#define account_system_vtime(prev)
+
#define finish_arch_switch(rq, prev) do { \
set_fs(current->thread.mm_segment); \
spin_unlock_irq(&(rq)->lock); \
} while (0)
+#endif
+
#define nop() __asm__ __volatile__ ("nop")
#define xchg(ptr,x) \
diff --git a/include/asm-s390/timer.h b/include/asm-s390/timer.h
index 454d1ea85c54..ea0788967c51 100644
--- a/include/asm-s390/timer.h
+++ b/include/asm-s390/timer.h
@@ -37,8 +37,6 @@ struct vtimer_queue {
__u64 idle; /* temp var for idle */
};
-void set_vtimer(__u64 expires);
-
extern void init_virt_timer(struct vtimer_list *timer);
extern void add_virt_timer(void *new);
extern void add_virt_timer_periodic(void *new);
diff --git a/include/linux/hardirq.h b/include/linux/hardirq.h
index ba0fcb34c8cd..ebc712e91066 100644
--- a/include/linux/hardirq.h
+++ b/include/linux/hardirq.h
@@ -4,6 +4,7 @@
#include <linux/config.h>
#include <linux/smp_lock.h>
#include <asm/hardirq.h>
+#include <asm/system.h>
/*
* We put the hardirq and softirq counter into the preemption
@@ -84,7 +85,22 @@ extern void synchronize_irq(unsigned int irq);
#define nmi_enter() irq_enter()
#define nmi_exit() sub_preempt_count(HARDIRQ_OFFSET)
-#define irq_enter() add_preempt_count(HARDIRQ_OFFSET)
+#ifndef CONFIG_VIRT_CPU_ACCOUNTING
+static inline void account_user_vtime(struct task_struct *tsk)
+{
+}
+
+static inline void account_system_vtime(struct task_struct *tsk)
+{
+}
+#endif
+
+#define irq_enter() \
+ do { \
+ account_system_vtime(current); \
+ add_preempt_count(HARDIRQ_OFFSET); \
+ } while (0)
+
extern void irq_exit(void);
#endif /* LINUX_HARDIRQ_H */