aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/hrtimer.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/hrtimer.c')
-rw-r--r--kernel/hrtimer.c32
1 files changed, 27 insertions, 5 deletions
diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c
index 11e896903828..6cf73d371203 100644
--- a/kernel/hrtimer.c
+++ b/kernel/hrtimer.c
@@ -1037,6 +1037,7 @@ void hrtimer_start_on_info_init(struct hrtimer_start_on_info *info)
1037{ 1037{
1038 memset(info, 0, sizeof(struct hrtimer_start_on_info)); 1038 memset(info, 0, sizeof(struct hrtimer_start_on_info));
1039 atomic_set(&info->state, HRTIMER_START_ON_INACTIVE); 1039 atomic_set(&info->state, HRTIMER_START_ON_INACTIVE);
1040 INIT_LIST_HEAD(&info->list);
1040} 1041}
1041 1042
1042/** 1043/**
@@ -1055,12 +1056,32 @@ void hrtimer_pull(void)
1055 list_for_each_safe(pos, safe, &list) { 1056 list_for_each_safe(pos, safe, &list) {
1056 info = list_entry(pos, struct hrtimer_start_on_info, list); 1057 info = list_entry(pos, struct hrtimer_start_on_info, list);
1057 TRACE("pulled timer 0x%x\n", info->timer); 1058 TRACE("pulled timer 0x%x\n", info->timer);
1058 list_del(pos); 1059 list_del_init(pos);
1059 hrtimer_start(info->timer, info->time, info->mode); 1060 if (!info->timer) continue;
1061 if (atomic_read(&info->state) != HRTIMER_START_ON_INACTIVE)
1062 hrtimer_start(info->timer, info->time, info->mode);
1063 if (atomic_read(&info->state) == HRTIMER_START_ON_INACTIVE)
1064 hrtimer_cancel(info->timer);
1060 } 1065 }
1061} 1066}
1062 1067
1063/** 1068/**
1069 * hrtimer_pull_cancel - Cancel a remote timer pull
1070 */
1071int hrtimer_pull_cancel(int cpu, struct hrtimer *timer,
1072 struct hrtimer_start_on_info *info)
1073{
1074 struct hrtimer_cpu_base *base = &per_cpu(hrtimer_bases, cpu);
1075
1076 raw_spin_lock(&base->lock);
1077 list_del_init(&info->list);
1078 raw_spin_unlock(&base->lock);
1079
1080 atomic_set(&info->state, HRTIMER_START_ON_INACTIVE);
1081 return hrtimer_try_to_cancel(timer);
1082}
1083
1084/**
1064 * hrtimer_start_on - trigger timer arming on remote cpu 1085 * hrtimer_start_on - trigger timer arming on remote cpu
1065 * @cpu: remote cpu 1086 * @cpu: remote cpu
1066 * @info: save timer information for enqueuing on remote cpu 1087 * @info: save timer information for enqueuing on remote cpu
@@ -1069,8 +1090,8 @@ void hrtimer_pull(void)
1069 * @mode: timer mode 1090 * @mode: timer mode
1070 */ 1091 */
1071int hrtimer_start_on(int cpu, struct hrtimer_start_on_info* info, 1092int hrtimer_start_on(int cpu, struct hrtimer_start_on_info* info,
1072 struct hrtimer *timer, ktime_t time, 1093 struct hrtimer *timer, ktime_t time,
1073 const enum hrtimer_mode mode) 1094 const enum hrtimer_mode mode)
1074{ 1095{
1075 unsigned long flags; 1096 unsigned long flags;
1076 struct hrtimer_cpu_base* base; 1097 struct hrtimer_cpu_base* base;
@@ -1102,7 +1123,8 @@ int hrtimer_start_on(int cpu, struct hrtimer_start_on_info* info,
1102 __hrtimer_start_range_ns(info->timer, info->time, 1123 __hrtimer_start_range_ns(info->timer, info->time,
1103 0, info->mode, 0); 1124 0, info->mode, 0);
1104 } else { 1125 } else {
1105 TRACE("hrtimer_start_on: pulling to remote CPU\n"); 1126 TRACE("hrtimer_start_on: pulling 0x%x to remote CPU\n",
1127 info->timer);
1106 base = &per_cpu(hrtimer_bases, cpu); 1128 base = &per_cpu(hrtimer_bases, cpu);
1107 raw_spin_lock_irqsave(&base->lock, flags); 1129 raw_spin_lock_irqsave(&base->lock, flags);
1108 was_empty = list_empty(&base->to_pull); 1130 was_empty = list_empty(&base->to_pull);