Skip to content

Commit

Permalink
Merge branch 'timers-core-for-linus' of git://git.kernel.org/pub/scm/…
Browse files Browse the repository at this point in the history
…linux/kernel/git/tip/tip

* 'timers-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (23 commits)
  time, s390: Get rid of compile warning
  dw_apb_timer: constify clocksource name
  time: Cleanup old CONFIG_GENERIC_TIME references that snuck in
  time: Change jiffies_to_clock_t() argument type to unsigned long
  alarmtimers: Fix error handling
  clocksource: Make watchdog reset lockless
  posix-cpu-timers: Cure SMP accounting oddities
  s390: Use direct ktime path for s390 clockevent device
  clockevents: Add direct ktime programming function
  clockevents: Make minimum delay adjustments configurable
  nohz: Remove "Switched to NOHz mode" debugging messages
  proc: Consider NO_HZ when printing idle and iowait times
  nohz: Make idle/iowait counter update conditional
  nohz: Fix update_ts_time_stat idle accounting
  cputime: Clean up cputime_to_usecs and usecs_to_cputime macros
  alarmtimers: Rework RTC device selection using class interface
  alarmtimers: Add try_to_cancel functionality
  alarmtimers: Add more refined alarm state tracking
  alarmtimers: Remove period from alarm structure
  alarmtimers: Remove interval cap limit hack
  ...
  • Loading branch information
Linus Torvalds committed Oct 26, 2011
2 parents 8a4a891 + e35f95b commit 39adff5
Show file tree
Hide file tree
Showing 30 changed files with 477 additions and 258 deletions.
4 changes: 0 additions & 4 deletions arch/arm/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -346,7 +346,6 @@ config ARCH_GEMINI
config ARCH_PRIMA2
bool "CSR SiRFSoC PRIMA2 ARM Cortex A9 Platform"
select CPU_V7
select GENERIC_TIME
select NO_IOPORT
select GENERIC_CLOCKEVENTS
select CLKDEV_LOOKUP
Expand Down Expand Up @@ -520,7 +519,6 @@ config ARCH_LPC32XX
select ARM_AMBA
select USB_ARCH_HAS_OHCI
select CLKDEV_LOOKUP
select GENERIC_TIME
select GENERIC_CLOCKEVENTS
help
Support for the NXP LPC32XX family of processors
Expand Down Expand Up @@ -599,7 +597,6 @@ config ARCH_TEGRA
bool "NVIDIA Tegra"
select CLKDEV_LOOKUP
select CLKSRC_MMIO
select GENERIC_TIME
select GENERIC_CLOCKEVENTS
select GENERIC_GPIO
select HAVE_CLK
Expand Down Expand Up @@ -914,7 +911,6 @@ config ARCH_VT8500
config ARCH_ZYNQ
bool "Xilinx Zynq ARM Cortex A9 Platform"
select CPU_V7
select GENERIC_TIME
select GENERIC_CLOCKEVENTS
select CLKDEV_LOOKUP
select ARM_GIC
Expand Down
3 changes: 0 additions & 3 deletions arch/mn10300/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,6 @@ config GENERIC_CMOS_UPDATE
config GENERIC_HWEIGHT
def_bool y

config GENERIC_TIME
def_bool y

config GENERIC_CLOCKEVENTS
def_bool y

Expand Down
13 changes: 9 additions & 4 deletions arch/s390/kernel/time.c
Original file line number Diff line number Diff line change
Expand Up @@ -109,10 +109,14 @@ static void fixup_clock_comparator(unsigned long long delta)
set_clock_comparator(S390_lowcore.clock_comparator);
}

static int s390_next_event(unsigned long delta,
static int s390_next_ktime(ktime_t expires,
struct clock_event_device *evt)
{
S390_lowcore.clock_comparator = get_clock() + delta;
u64 nsecs;

nsecs = ktime_to_ns(ktime_sub(expires, ktime_get_monotonic_offset()));
do_div(nsecs, 125);
S390_lowcore.clock_comparator = TOD_UNIX_EPOCH + (nsecs << 9);
set_clock_comparator(S390_lowcore.clock_comparator);
return 0;
}
Expand All @@ -137,14 +141,15 @@ void init_cpu_timer(void)
cpu = smp_processor_id();
cd = &per_cpu(comparators, cpu);
cd->name = "comparator";
cd->features = CLOCK_EVT_FEAT_ONESHOT;
cd->features = CLOCK_EVT_FEAT_ONESHOT |
CLOCK_EVT_FEAT_KTIME;
cd->mult = 16777;
cd->shift = 12;
cd->min_delta_ns = 1;
cd->max_delta_ns = LONG_MAX;
cd->rating = 400;
cd->cpumask = cpumask_of(cpu);
cd->set_next_event = s390_next_event;
cd->set_next_ktime = s390_next_ktime;
cd->set_mode = s390_set_mode;

clockevents_register_device(cd);
Expand Down
3 changes: 0 additions & 3 deletions arch/tile/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,6 @@ config NEED_PER_CPU_PAGE_FIRST_CHUNK
config SYS_SUPPORTS_HUGETLBFS
def_bool y

config GENERIC_TIME
def_bool y

config GENERIC_CLOCKEVENTS
def_bool y

Expand Down
1 change: 0 additions & 1 deletion arch/tile/configs/tilegx_defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ CONFIG_HAVE_ARCH_ALLOC_REMAP=y
CONFIG_HAVE_SETUP_PER_CPU_AREA=y
CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK=y
CONFIG_SYS_SUPPORTS_HUGETLBFS=y
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_DEFAULT_MIGRATION_COST=10000000
Expand Down
1 change: 0 additions & 1 deletion arch/tile/configs/tilepro_defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ CONFIG_HAVE_ARCH_ALLOC_REMAP=y
CONFIG_HAVE_SETUP_PER_CPU_AREA=y
CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK=y
CONFIG_SYS_SUPPORTS_HUGETLBFS=y
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_DEFAULT_MIGRATION_COST=10000000
Expand Down
1 change: 0 additions & 1 deletion arch/um/defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ CONFIG_LOCKDEP_SUPPORT=y
# CONFIG_STACKTRACE_SUPPORT is not set
CONFIG_GENERIC_CALIBRATE_DELAY=y
CONFIG_GENERIC_BUG=y
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_IRQ_RELEASE_METHOD=y
CONFIG_HZ=100
Expand Down
1 change: 1 addition & 0 deletions arch/x86/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ config X86
select GENERIC_IRQ_PROBE
select GENERIC_PENDING_IRQ if SMP
select GENERIC_IRQ_SHOW
select GENERIC_CLOCKEVENTS_MIN_ADJUST
select IRQ_FORCED_THREADING
select USE_GENERIC_SMP_HELPERS if SMP
select HAVE_BPF_JIT if (X86_64 && NET)
Expand Down
1 change: 0 additions & 1 deletion arch/xtensa/configs/iss_defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ CONFIG_GENERIC_GPIO=y
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_NO_IOPORT=y
CONFIG_HZ=100
CONFIG_GENERIC_TIME=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
CONFIG_CONSTRUCTORS=y

Expand Down
1 change: 0 additions & 1 deletion arch/xtensa/configs/s6105_defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ CONFIG_GENERIC_GPIO=y
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_NO_IOPORT=y
CONFIG_HZ=100
CONFIG_GENERIC_TIME=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"

#
Expand Down
2 changes: 1 addition & 1 deletion drivers/clocksource/dw_apb_timer.c
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,7 @@ static void apbt_restart_clocksource(struct clocksource *cs)
* dw_apb_clocksource_register() as the next step.
*/
struct dw_apb_clocksource *
dw_apb_clocksource_init(unsigned rating, char *name, void __iomem *base,
dw_apb_clocksource_init(unsigned rating, const char *name, void __iomem *base,
unsigned long freq)
{
struct dw_apb_clocksource *dw_cs = kzalloc(sizeof(*dw_cs), GFP_KERNEL);
Expand Down
4 changes: 3 additions & 1 deletion drivers/cpufreq/cpufreq_conservative.c
Original file line number Diff line number Diff line change
Expand Up @@ -120,10 +120,12 @@ static inline cputime64_t get_cpu_idle_time_jiffy(unsigned int cpu,

static inline cputime64_t get_cpu_idle_time(unsigned int cpu, cputime64_t *wall)
{
u64 idle_time = get_cpu_idle_time_us(cpu, wall);
u64 idle_time = get_cpu_idle_time_us(cpu, NULL);

if (idle_time == -1ULL)
return get_cpu_idle_time_jiffy(cpu, wall);
else
idle_time += get_cpu_iowait_time_us(cpu, wall);

return idle_time;
}
Expand Down
4 changes: 3 additions & 1 deletion drivers/cpufreq/cpufreq_ondemand.c
Original file line number Diff line number Diff line change
Expand Up @@ -144,10 +144,12 @@ static inline cputime64_t get_cpu_idle_time_jiffy(unsigned int cpu,

static inline cputime64_t get_cpu_idle_time(unsigned int cpu, cputime64_t *wall)
{
u64 idle_time = get_cpu_idle_time_us(cpu, wall);
u64 idle_time = get_cpu_idle_time_us(cpu, NULL);

if (idle_time == -1ULL)
return get_cpu_idle_time_jiffy(cpu, wall);
else
idle_time += get_cpu_iowait_time_us(cpu, wall);

return idle_time;
}
Expand Down
41 changes: 34 additions & 7 deletions fs/proc/stat.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <linux/time.h>
#include <linux/irqnr.h>
#include <asm/cputime.h>
#include <linux/tick.h>

#ifndef arch_irq_stat_cpu
#define arch_irq_stat_cpu(cpu) 0
Expand All @@ -21,6 +22,35 @@
#define arch_idle_time(cpu) 0
#endif

static cputime64_t get_idle_time(int cpu)
{
u64 idle_time = get_cpu_idle_time_us(cpu, NULL);
cputime64_t idle;

if (idle_time == -1ULL) {
/* !NO_HZ so we can rely on cpustat.idle */
idle = kstat_cpu(cpu).cpustat.idle;
idle = cputime64_add(idle, arch_idle_time(cpu));
} else
idle = usecs_to_cputime(idle_time);

return idle;
}

static cputime64_t get_iowait_time(int cpu)
{
u64 iowait_time = get_cpu_iowait_time_us(cpu, NULL);
cputime64_t iowait;

if (iowait_time == -1ULL)
/* !NO_HZ so we can rely on cpustat.iowait */
iowait = kstat_cpu(cpu).cpustat.iowait;
else
iowait = usecs_to_cputime(iowait_time);

return iowait;
}

static int show_stat(struct seq_file *p, void *v)
{
int i, j;
Expand All @@ -42,9 +72,8 @@ static int show_stat(struct seq_file *p, void *v)
user = cputime64_add(user, kstat_cpu(i).cpustat.user);
nice = cputime64_add(nice, kstat_cpu(i).cpustat.nice);
system = cputime64_add(system, kstat_cpu(i).cpustat.system);
idle = cputime64_add(idle, kstat_cpu(i).cpustat.idle);
idle = cputime64_add(idle, arch_idle_time(i));
iowait = cputime64_add(iowait, kstat_cpu(i).cpustat.iowait);
idle = cputime64_add(idle, get_idle_time(i));
iowait = cputime64_add(iowait, get_iowait_time(i));
irq = cputime64_add(irq, kstat_cpu(i).cpustat.irq);
softirq = cputime64_add(softirq, kstat_cpu(i).cpustat.softirq);
steal = cputime64_add(steal, kstat_cpu(i).cpustat.steal);
Expand Down Expand Up @@ -76,14 +105,12 @@ static int show_stat(struct seq_file *p, void *v)
(unsigned long long)cputime64_to_clock_t(guest),
(unsigned long long)cputime64_to_clock_t(guest_nice));
for_each_online_cpu(i) {

/* Copy values here to work around gcc-2.95.3, gcc-2.96 */
user = kstat_cpu(i).cpustat.user;
nice = kstat_cpu(i).cpustat.nice;
system = kstat_cpu(i).cpustat.system;
idle = kstat_cpu(i).cpustat.idle;
idle = cputime64_add(idle, arch_idle_time(i));
iowait = kstat_cpu(i).cpustat.iowait;
idle = get_idle_time(i);
iowait = get_iowait_time(i);
irq = kstat_cpu(i).cpustat.irq;
softirq = kstat_cpu(i).cpustat.softirq;
steal = kstat_cpu(i).cpustat.steal;
Expand Down
4 changes: 2 additions & 2 deletions include/asm-generic/cputime.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ typedef u64 cputime64_t;
/*
* Convert cputime to microseconds and back.
*/
#define cputime_to_usecs(__ct) jiffies_to_usecs(__ct);
#define usecs_to_cputime(__msecs) usecs_to_jiffies(__msecs);
#define cputime_to_usecs(__ct) jiffies_to_usecs(__ct)
#define usecs_to_cputime(__msecs) usecs_to_jiffies(__msecs)

/*
* Convert cputime to seconds and back.
Expand Down
51 changes: 45 additions & 6 deletions include/linux/alarmtimer.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,16 @@ enum alarmtimer_type {
ALARM_NUMTYPE,
};

enum alarmtimer_restart {
ALARMTIMER_NORESTART,
ALARMTIMER_RESTART,
};


#define ALARMTIMER_STATE_INACTIVE 0x00
#define ALARMTIMER_STATE_ENQUEUED 0x01
#define ALARMTIMER_STATE_CALLBACK 0x02

/**
* struct alarm - Alarm timer structure
* @node: timerqueue node for adding to the event list this value
Expand All @@ -25,16 +35,45 @@ enum alarmtimer_type {
*/
struct alarm {
struct timerqueue_node node;
ktime_t period;
void (*function)(struct alarm *);
enum alarmtimer_restart (*function)(struct alarm *, ktime_t now);
enum alarmtimer_type type;
bool enabled;
int state;
void *data;
};

void alarm_init(struct alarm *alarm, enum alarmtimer_type type,
void (*function)(struct alarm *));
void alarm_start(struct alarm *alarm, ktime_t start, ktime_t period);
void alarm_cancel(struct alarm *alarm);
enum alarmtimer_restart (*function)(struct alarm *, ktime_t));
void alarm_start(struct alarm *alarm, ktime_t start);
int alarm_try_to_cancel(struct alarm *alarm);
int alarm_cancel(struct alarm *alarm);

u64 alarm_forward(struct alarm *alarm, ktime_t now, ktime_t interval);

/*
* A alarmtimer is active, when it is enqueued into timerqueue or the
* callback function is running.
*/
static inline int alarmtimer_active(const struct alarm *timer)
{
return timer->state != ALARMTIMER_STATE_INACTIVE;
}

/*
* Helper function to check, whether the timer is on one of the queues
*/
static inline int alarmtimer_is_queued(struct alarm *timer)
{
return timer->state & ALARMTIMER_STATE_ENQUEUED;
}

/*
* Helper function to check, whether the timer is running the callback
* function
*/
static inline int alarmtimer_callback_running(struct alarm *timer)
{
return timer->state & ALARMTIMER_STATE_CALLBACK;
}


#endif
12 changes: 8 additions & 4 deletions include/linux/clockchips.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,20 +45,22 @@ enum clock_event_nofitiers {
*/
#define CLOCK_EVT_FEAT_PERIODIC 0x000001
#define CLOCK_EVT_FEAT_ONESHOT 0x000002
#define CLOCK_EVT_FEAT_KTIME 0x000004
/*
* x86(64) specific misfeatures:
*
* - Clockevent source stops in C3 State and needs broadcast support.
* - Local APIC timer is used as a dummy device.
*/
#define CLOCK_EVT_FEAT_C3STOP 0x000004
#define CLOCK_EVT_FEAT_DUMMY 0x000008
#define CLOCK_EVT_FEAT_C3STOP 0x000008
#define CLOCK_EVT_FEAT_DUMMY 0x000010

/**
* struct clock_event_device - clock event device descriptor
* @event_handler: Assigned by the framework to be called by the low
* level handler of the event source
* @set_next_event: set next event function
* @set_next_event: set next event function using a clocksource delta
* @set_next_ktime: set next event function using a direct ktime value
* @next_event: local storage for the next event in oneshot mode
* @max_delta_ns: maximum delta value in ns
* @min_delta_ns: minimum delta value in ns
Expand All @@ -81,6 +83,8 @@ struct clock_event_device {
void (*event_handler)(struct clock_event_device *);
int (*set_next_event)(unsigned long evt,
struct clock_event_device *);
int (*set_next_ktime)(ktime_t expires,
struct clock_event_device *);
ktime_t next_event;
u64 max_delta_ns;
u64 min_delta_ns;
Expand Down Expand Up @@ -140,7 +144,7 @@ extern void clockevents_set_mode(struct clock_event_device *dev,
enum clock_event_mode mode);
extern int clockevents_register_notifier(struct notifier_block *nb);
extern int clockevents_program_event(struct clock_event_device *dev,
ktime_t expires, ktime_t now);
ktime_t expires, bool force);

extern void clockevents_handle_noop(struct clock_event_device *dev);

Expand Down
2 changes: 1 addition & 1 deletion include/linux/dw_apb_timer.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ struct dw_apb_clock_event_device *
dw_apb_clockevent_init(int cpu, const char *name, unsigned rating,
void __iomem *base, int irq, unsigned long freq);
struct dw_apb_clocksource *
dw_apb_clocksource_init(unsigned rating, char *name, void __iomem *base,
dw_apb_clocksource_init(unsigned rating, const char *name, void __iomem *base,
unsigned long freq);
void dw_apb_clocksource_register(struct dw_apb_clocksource *dw_cs);
void dw_apb_clocksource_start(struct dw_apb_clocksource *dw_cs);
Expand Down
2 changes: 1 addition & 1 deletion include/linux/jiffies.h
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,7 @@ extern void jiffies_to_timespec(const unsigned long jiffies,
extern unsigned long timeval_to_jiffies(const struct timeval *value);
extern void jiffies_to_timeval(const unsigned long jiffies,
struct timeval *value);
extern clock_t jiffies_to_clock_t(long x);
extern clock_t jiffies_to_clock_t(unsigned long x);
extern unsigned long clock_t_to_jiffies(unsigned long x);
extern u64 jiffies_64_to_clock_t(u64 x);
extern u64 nsec_to_clock_t(u64 x);
Expand Down
5 changes: 4 additions & 1 deletion include/linux/posix-timers.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,10 @@ struct k_itimer {
unsigned long incr;
unsigned long expires;
} mmtimer;
struct alarm alarmtimer;
struct {
struct alarm alarmtimer;
ktime_t interval;
} alarm;
struct rcu_head rcu;
} it;
};
Expand Down
Loading

0 comments on commit 39adff5

Please sign in to comment.