Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 88430
b: refs/heads/master
c: 43ca5c3
h: refs/heads/master
v: v3
  • Loading branch information
Heiko Carstens committed Apr 17, 2008
1 parent 62796c7 commit 1d13934
Show file tree
Hide file tree
Showing 7 changed files with 43 additions and 47 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: e1776856286bef076f400ec062b150b6f3c353cd
refs/heads/master: 43ca5c3a1cefdaa09231d64485b8f676118bf1e0
70 changes: 30 additions & 40 deletions trunk/arch/s390/kernel/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand All @@ -89,20 +90,40 @@ 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);
spin_lock(&idle->lock);
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());
}
Expand All @@ -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 |
Expand Down
4 changes: 2 additions & 2 deletions trunk/arch/s390/kernel/s390_ext.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
#include <linux/errno.h>
#include <linux/kernel_stat.h>
#include <linux/interrupt.h>

#include <asm/cpu.h>
#include <asm/lowcore.h>
#include <asm/s390_ext.h>
#include <asm/irq_regs.h>
Expand Down Expand Up @@ -119,7 +119,7 @@ void do_extint(struct pt_regs *regs, unsigned short code)

old_regs = set_irq_regs(regs);
irq_enter();
asm volatile ("mc 0,0");
s390_idle_check();
if (S390_lowcore.int_clock >= S390_lowcore.jiffy_timer)
/**
* Make sure that the i/o interrupt did not "overtake"
Expand Down
1 change: 0 additions & 1 deletion trunk/arch/s390/kernel/smp.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,6 @@ static int smp_cpu_state[NR_CPUS];
static int cpu_management;

static DEFINE_PER_CPU(struct cpu, cpu_devices);
DEFINE_PER_CPU(struct s390_idle_data, s390_idle);

static void smp_ext_bitcall(int, ec_bit_sig);

Expand Down
2 changes: 0 additions & 2 deletions trunk/arch/s390/kernel/traps.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ int sysctl_userprocess_debug = 0;

extern pgm_check_handler_t do_protection_exception;
extern pgm_check_handler_t do_dat_exception;
extern pgm_check_handler_t do_monitor_call;
extern pgm_check_handler_t do_asce_exception;

#define stack_pointer ({ void **sp; asm("la %0,0(15)" : "=&d" (sp)); sp; })
Expand Down Expand Up @@ -739,6 +738,5 @@ void __init trap_init(void)
pgm_check_table[0x15] = &operand_exception;
pgm_check_table[0x1C] = &space_switch_exception;
pgm_check_table[0x1D] = &hfp_sqrt_exception;
pgm_check_table[0x40] = &do_monitor_call;
pfault_irq_init();
}
3 changes: 2 additions & 1 deletion trunk/drivers/s390/cio/cio.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include <asm/ipl.h>
#include <asm/chpid.h>
#include <asm/airq.h>
#include <asm/cpu.h>
#include "cio.h"
#include "css.h"
#include "chsc.h"
Expand Down Expand Up @@ -649,7 +650,7 @@ do_IRQ (struct pt_regs *regs)

old_regs = set_irq_regs(regs);
irq_enter();
asm volatile ("mc 0,0");
s390_idle_check();
if (S390_lowcore.int_clock >= S390_lowcore.jiffy_timer)
/**
* Make sure that the i/o interrupt did not "overtake"
Expand Down
8 changes: 8 additions & 0 deletions trunk/include/asm-s390/cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,12 @@ struct s390_idle_data {

DECLARE_PER_CPU(struct s390_idle_data, s390_idle);

void s390_idle_leave(void);

static inline void s390_idle_check(void)
{
if ((&__get_cpu_var(s390_idle))->in_idle)
s390_idle_leave();
}

#endif /* _ASM_S390_CPU_H_ */

0 comments on commit 1d13934

Please sign in to comment.