Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 313870
b: refs/heads/master
c: 27f6b41
h: refs/heads/master
v: v3
  • Loading branch information
Martin Schwidefsky committed Jul 20, 2012
1 parent b9378ef commit d8e40d5
Show file tree
Hide file tree
Showing 14 changed files with 223 additions and 473 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: 921486b92bcb1b82ab6668dcbb36d05604966351
refs/heads/master: 27f6b416626a240e1b46f646d2e0c5266f4eac95
130 changes: 14 additions & 116 deletions trunk/arch/s390/appldata/appldata_base.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
#include <linux/suspend.h>
#include <linux/platform_device.h>
#include <asm/appldata.h>
#include <asm/timer.h>
#include <asm/vtimer.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include <asm/smp.h>
Expand Down Expand Up @@ -82,8 +82,7 @@ static struct ctl_table appldata_dir_table[] = {
/*
* Timer
*/
static DEFINE_PER_CPU(struct vtimer_list, appldata_timer);
static atomic_t appldata_expire_count = ATOMIC_INIT(0);
static struct vtimer_list appldata_timer;

static DEFINE_SPINLOCK(appldata_timer_lock);
static int appldata_interval = APPLDATA_CPU_INTERVAL;
Expand Down Expand Up @@ -113,10 +112,7 @@ static LIST_HEAD(appldata_ops_list);
*/
static void appldata_timer_function(unsigned long data)
{
if (atomic_dec_and_test(&appldata_expire_count)) {
atomic_set(&appldata_expire_count, num_online_cpus());
queue_work(appldata_wq, (struct work_struct *) data);
}
queue_work(appldata_wq, (struct work_struct *) data);
}

/*
Expand All @@ -129,7 +125,6 @@ static void appldata_work_fn(struct work_struct *work)
struct list_head *lh;
struct appldata_ops *ops;

get_online_cpus();
mutex_lock(&appldata_ops_mutex);
list_for_each(lh, &appldata_ops_list) {
ops = list_entry(lh, struct appldata_ops, list);
Expand All @@ -138,7 +133,6 @@ static void appldata_work_fn(struct work_struct *work)
}
}
mutex_unlock(&appldata_ops_mutex);
put_online_cpus();
}

/*
Expand Down Expand Up @@ -166,20 +160,6 @@ int appldata_diag(char record_nr, u16 function, unsigned long buffer,

/****************************** /proc stuff **********************************/

/*
* appldata_mod_vtimer_wrap()
*
* wrapper function for mod_virt_timer(), because smp_call_function_single()
* accepts only one parameter.
*/
static void __appldata_mod_vtimer_wrap(void *p) {
struct {
struct vtimer_list *timer;
u64 expires;
} *args = p;
mod_virt_timer_periodic(args->timer, args->expires);
}

#define APPLDATA_ADD_TIMER 0
#define APPLDATA_DEL_TIMER 1
#define APPLDATA_MOD_TIMER 2
Expand All @@ -190,49 +170,28 @@ static void __appldata_mod_vtimer_wrap(void *p) {
* Add, delete or modify virtual timers on all online cpus.
* The caller needs to get the appldata_timer_lock spinlock.
*/
static void
__appldata_vtimer_setup(int cmd)
static void __appldata_vtimer_setup(int cmd)
{
u64 per_cpu_interval;
int i;
u64 timer_interval = (u64) appldata_interval * 1000 * TOD_MICRO;

switch (cmd) {
case APPLDATA_ADD_TIMER:
if (appldata_timer_active)
break;
per_cpu_interval = (u64) (appldata_interval*1000 /
num_online_cpus()) * TOD_MICRO;
for_each_online_cpu(i) {
per_cpu(appldata_timer, i).expires = per_cpu_interval;
smp_call_function_single(i, add_virt_timer_periodic,
&per_cpu(appldata_timer, i),
1);
}
appldata_timer.expires = timer_interval;
add_virt_timer_periodic(&appldata_timer);
appldata_timer_active = 1;
break;
case APPLDATA_DEL_TIMER:
for_each_online_cpu(i)
del_virt_timer(&per_cpu(appldata_timer, i));
del_virt_timer(&appldata_timer);
if (!appldata_timer_active)
break;
appldata_timer_active = 0;
atomic_set(&appldata_expire_count, num_online_cpus());
break;
case APPLDATA_MOD_TIMER:
per_cpu_interval = (u64) (appldata_interval*1000 /
num_online_cpus()) * TOD_MICRO;
if (!appldata_timer_active)
break;
for_each_online_cpu(i) {
struct {
struct vtimer_list *timer;
u64 expires;
} args;
args.timer = &per_cpu(appldata_timer, i);
args.expires = per_cpu_interval;
smp_call_function_single(i, __appldata_mod_vtimer_wrap,
&args, 1);
}
mod_virt_timer_periodic(&appldata_timer, timer_interval);
}
}

Expand Down Expand Up @@ -263,14 +222,12 @@ appldata_timer_handler(ctl_table *ctl, int write,
len = *lenp;
if (copy_from_user(buf, buffer, len > sizeof(buf) ? sizeof(buf) : len))
return -EFAULT;
get_online_cpus();
spin_lock(&appldata_timer_lock);
if (buf[0] == '1')
__appldata_vtimer_setup(APPLDATA_ADD_TIMER);
else if (buf[0] == '0')
__appldata_vtimer_setup(APPLDATA_DEL_TIMER);
spin_unlock(&appldata_timer_lock);
put_online_cpus();
out:
*lenp = len;
*ppos += len;
Expand Down Expand Up @@ -303,20 +260,17 @@ appldata_interval_handler(ctl_table *ctl, int write,
goto out;
}
len = *lenp;
if (copy_from_user(buf, buffer, len > sizeof(buf) ? sizeof(buf) : len)) {
if (copy_from_user(buf, buffer, len > sizeof(buf) ? sizeof(buf) : len))
return -EFAULT;
}
interval = 0;
sscanf(buf, "%i", &interval);
if (interval <= 0)
return -EINVAL;

get_online_cpus();
spin_lock(&appldata_timer_lock);
appldata_interval = interval;
__appldata_vtimer_setup(APPLDATA_MOD_TIMER);
spin_unlock(&appldata_timer_lock);
put_online_cpus();
out:
*lenp = len;
*ppos += len;
Expand Down Expand Up @@ -483,14 +437,12 @@ static int appldata_freeze(struct device *dev)
int rc;
struct list_head *lh;

get_online_cpus();
spin_lock(&appldata_timer_lock);
if (appldata_timer_active) {
__appldata_vtimer_setup(APPLDATA_DEL_TIMER);
appldata_timer_suspended = 1;
}
spin_unlock(&appldata_timer_lock);
put_online_cpus();

mutex_lock(&appldata_ops_mutex);
list_for_each(lh, &appldata_ops_list) {
Expand All @@ -514,14 +466,12 @@ static int appldata_restore(struct device *dev)
int rc;
struct list_head *lh;

get_online_cpus();
spin_lock(&appldata_timer_lock);
if (appldata_timer_suspended) {
__appldata_vtimer_setup(APPLDATA_ADD_TIMER);
appldata_timer_suspended = 0;
}
spin_unlock(&appldata_timer_lock);
put_online_cpus();

mutex_lock(&appldata_ops_mutex);
list_for_each(lh, &appldata_ops_list) {
Expand Down Expand Up @@ -565,61 +515,17 @@ static struct platform_driver appldata_pdrv = {

/******************************* init / exit *********************************/

static void __cpuinit appldata_online_cpu(int cpu)
{
init_virt_timer(&per_cpu(appldata_timer, cpu));
per_cpu(appldata_timer, cpu).function = appldata_timer_function;
per_cpu(appldata_timer, cpu).data = (unsigned long)
&appldata_work;
atomic_inc(&appldata_expire_count);
spin_lock(&appldata_timer_lock);
__appldata_vtimer_setup(APPLDATA_MOD_TIMER);
spin_unlock(&appldata_timer_lock);
}

static void __cpuinit appldata_offline_cpu(int cpu)
{
del_virt_timer(&per_cpu(appldata_timer, cpu));
if (atomic_dec_and_test(&appldata_expire_count)) {
atomic_set(&appldata_expire_count, num_online_cpus());
queue_work(appldata_wq, &appldata_work);
}
spin_lock(&appldata_timer_lock);
__appldata_vtimer_setup(APPLDATA_MOD_TIMER);
spin_unlock(&appldata_timer_lock);
}

static int __cpuinit appldata_cpu_notify(struct notifier_block *self,
unsigned long action,
void *hcpu)
{
switch (action) {
case CPU_ONLINE:
case CPU_ONLINE_FROZEN:
appldata_online_cpu((long) hcpu);
break;
case CPU_DEAD:
case CPU_DEAD_FROZEN:
appldata_offline_cpu((long) hcpu);
break;
default:
break;
}
return NOTIFY_OK;
}

static struct notifier_block __cpuinitdata appldata_nb = {
.notifier_call = appldata_cpu_notify,
};

/*
* appldata_init()
*
* init timer, register /proc entries
*/
static int __init appldata_init(void)
{
int i, rc;
int rc;

appldata_timer.function = appldata_timer_function;
appldata_timer.data = (unsigned long) &appldata_work;

rc = platform_driver_register(&appldata_pdrv);
if (rc)
Expand All @@ -637,14 +543,6 @@ static int __init appldata_init(void)
goto out_device;
}

get_online_cpus();
for_each_online_cpu(i)
appldata_online_cpu(i);
put_online_cpus();

/* Register cpu hotplug notifier */
register_hotcpu_notifier(&appldata_nb);

appldata_sysctl_header = register_sysctl_table(appldata_dir_table);
return 0;

Expand Down
6 changes: 4 additions & 2 deletions trunk/arch/s390/include/asm/cputime.h
Original file line number Diff line number Diff line change
Expand Up @@ -168,9 +168,11 @@ struct s390_idle_data {
int nohz_delay;
unsigned int sequence;
unsigned long long idle_count;
unsigned long long idle_enter;
unsigned long long idle_exit;
unsigned long long idle_time;
unsigned long long clock_idle_enter;
unsigned long long clock_idle_exit;
unsigned long long timer_idle_enter;
unsigned long long timer_idle_exit;
};

DECLARE_PER_CPU(struct s390_idle_data, s390_idle);
Expand Down
51 changes: 0 additions & 51 deletions trunk/arch/s390/include/asm/timer.h

This file was deleted.

33 changes: 33 additions & 0 deletions trunk/arch/s390/include/asm/vtimer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* Copyright IBM Corp. 2003, 2012
* Virtual CPU timer
*
* Author(s): Jan Glauber <jan.glauber@de.ibm.com>
*/

#ifndef _ASM_S390_TIMER_H
#define _ASM_S390_TIMER_H

#define VTIMER_MAX_SLICE (0x7fffffffffffffffULL)

struct vtimer_list {
struct list_head entry;
u64 expires;
u64 interval;
void (*function)(unsigned long);
unsigned long data;
};

extern void init_virt_timer(struct vtimer_list *timer);
extern void add_virt_timer(struct vtimer_list *timer);
extern void add_virt_timer_periodic(struct vtimer_list *timer);
extern int mod_virt_timer(struct vtimer_list *timer, u64 expires);
extern int mod_virt_timer_periodic(struct vtimer_list *timer, u64 expires);
extern int del_virt_timer(struct vtimer_list *timer);

extern void init_cpu_vtimer(void);
extern void vtime_init(void);

extern void vtime_stop_cpu(void);

#endif /* _ASM_S390_TIMER_H */
10 changes: 4 additions & 6 deletions trunk/arch/s390/kernel/asm-offsets.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
#include <linux/kbuild.h>
#include <linux/sched.h>
#include <asm/cputime.h>
#include <asm/timer.h>
#include <asm/vdso.h>
#include <asm/pgtable.h>

Expand Down Expand Up @@ -72,11 +71,10 @@ int main(void)
DEFINE(__CLOCK_REALTIME_RES, MONOTONIC_RES_NSEC);
BLANK();
/* idle data offsets */
DEFINE(__IDLE_ENTER, offsetof(struct s390_idle_data, idle_enter));
DEFINE(__IDLE_EXIT, offsetof(struct s390_idle_data, idle_exit));
/* vtimer queue offsets */
DEFINE(__VQ_IDLE_ENTER, offsetof(struct vtimer_queue, idle_enter));
DEFINE(__VQ_IDLE_EXIT, offsetof(struct vtimer_queue, idle_exit));
DEFINE(__CLOCK_IDLE_ENTER, offsetof(struct s390_idle_data, clock_idle_enter));
DEFINE(__CLOCK_IDLE_EXIT, offsetof(struct s390_idle_data, clock_idle_exit));
DEFINE(__TIMER_IDLE_ENTER, offsetof(struct s390_idle_data, timer_idle_enter));
DEFINE(__TIMER_IDLE_EXIT, offsetof(struct s390_idle_data, timer_idle_exit));
/* lowcore offsets */
DEFINE(__LC_EXT_PARAMS, offsetof(struct _lowcore, ext_params));
DEFINE(__LC_EXT_CPU_ADDR, offsetof(struct _lowcore, ext_cpu_addr));
Expand Down
Loading

0 comments on commit d8e40d5

Please sign in to comment.