aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/kernel/process.c
diff options
context:
space:
mode:
authorHeiko Carstens <heiko.carstens@de.ibm.com>2008-04-17 07:46:23 +0200
committerHeiko Carstens <heiko.carstens@de.ibm.com>2008-04-17 07:47:05 +0200
commit43ca5c3a1cefdaa09231d64485b8f676118bf1e0 (patch)
tree37e71a475b96b811935fc484cb0633701953b5c0 /arch/s390/kernel/process.c
parente1776856286bef076f400ec062b150b6f3c353cd (diff)
downloadlinux-43ca5c3a1cefdaa09231d64485b8f676118bf1e0.tar.gz
[S390] Convert monitor calls to function calls.
Remove the program check generating monitor calls and use function calls instead. Theres is no real advantage in using monitor calls, but they do make debugging harder, because of all the program checks it generates. Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com> Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Diffstat (limited to 'arch/s390/kernel/process.c')
-rw-r--r--arch/s390/kernel/process.c70
1 files changed, 30 insertions, 40 deletions
diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c
index ce203154d8ce3a..eb768ce88672e9 100644
--- a/arch/s390/kernel/process.c
+++ b/arch/s390/kernel/process.c
@@ -76,6 +76,7 @@ unsigned long thread_saved_pc(struct task_struct *tsk)
* Need to know about CPUs going idle?
*/
static ATOMIC_NOTIFIER_HEAD(idle_chain);
+DEFINE_PER_CPU(struct s390_idle_data, s390_idle);
int register_idle_notifier(struct notifier_block *nb)
{
@@ -89,9 +90,33 @@ int unregister_idle_notifier(struct notifier_block *nb)
}
EXPORT_SYMBOL(unregister_idle_notifier);
-void do_monitor_call(struct pt_regs *regs, long interruption_code)
+static int s390_idle_enter(void)
+{
+ struct s390_idle_data *idle;
+ int nr_calls = 0;
+ void *hcpu;
+ int rc;
+
+ hcpu = (void *)(long)smp_processor_id();
+ rc = __atomic_notifier_call_chain(&idle_chain, S390_CPU_IDLE, hcpu, -1,
+ &nr_calls);
+ if (rc == NOTIFY_BAD) {
+ nr_calls--;
+ __atomic_notifier_call_chain(&idle_chain, S390_CPU_NOT_IDLE,
+ hcpu, nr_calls, NULL);
+ return rc;
+ }
+ idle = &__get_cpu_var(s390_idle);
+ spin_lock(&idle->lock);
+ idle->idle_count++;
+ idle->in_idle = 1;
+ idle->idle_enter = get_clock();
+ spin_unlock(&idle->lock);
+ return NOTIFY_OK;
+}
+
+void s390_idle_leave(void)
{
-#ifdef CONFIG_SMP
struct s390_idle_data *idle;
idle = &__get_cpu_var(s390_idle);
@@ -99,10 +124,6 @@ void do_monitor_call(struct pt_regs *regs, long interruption_code)
idle->idle_time += get_clock() - idle->idle_enter;
idle->in_idle = 0;
spin_unlock(&idle->lock);
-#endif
- /* disable monitor call class 0 */
- __ctl_clear_bit(8, 15);
-
atomic_notifier_call_chain(&idle_chain, S390_CPU_NOT_IDLE,
(void *)(long) smp_processor_id());
}
@@ -113,61 +134,30 @@ extern void s390_handle_mcck(void);
*/
static void default_idle(void)
{
- int cpu, rc;
- int nr_calls = 0;
- void *hcpu;
-#ifdef CONFIG_SMP
- struct s390_idle_data *idle;
-#endif
-
/* CPU is going idle. */
- cpu = smp_processor_id();
- hcpu = (void *)(long)cpu;
local_irq_disable();
if (need_resched()) {
local_irq_enable();
return;
}
-
- rc = __atomic_notifier_call_chain(&idle_chain, S390_CPU_IDLE, hcpu, -1,
- &nr_calls);
- if (rc == NOTIFY_BAD) {
- nr_calls--;
- __atomic_notifier_call_chain(&idle_chain, S390_CPU_NOT_IDLE,
- hcpu, nr_calls, NULL);
+ if (s390_idle_enter() == NOTIFY_BAD) {
local_irq_enable();
return;
}
-
- /* enable monitor call class 0 */
- __ctl_set_bit(8, 15);
-
#ifdef CONFIG_HOTPLUG_CPU
- if (cpu_is_offline(cpu)) {
+ if (cpu_is_offline(smp_processor_id())) {
preempt_enable_no_resched();
cpu_die();
}
#endif
-
local_mcck_disable();
if (test_thread_flag(TIF_MCCK_PENDING)) {
local_mcck_enable();
- /* disable monitor call class 0 */
- __ctl_clear_bit(8, 15);
- atomic_notifier_call_chain(&idle_chain, S390_CPU_NOT_IDLE,
- hcpu);
+ s390_idle_leave();
local_irq_enable();
s390_handle_mcck();
return;
}
-#ifdef CONFIG_SMP
- idle = &__get_cpu_var(s390_idle);
- spin_lock(&idle->lock);
- idle->idle_count++;
- idle->in_idle = 1;
- idle->idle_enter = get_clock();
- spin_unlock(&idle->lock);
-#endif
trace_hardirqs_on();
/* Wait for external, I/O or machine check interrupt. */
__load_psw_mask(psw_kernel_bits | PSW_MASK_WAIT |