Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 75061
b: refs/heads/master
c: cdc6f27
h: refs/heads/master
i:
  75059: 4372bd3
v: v3
  • Loading branch information
Thomas Gleixner authored and Ingo Molnar committed Dec 18, 2007
1 parent 49e380e commit 9f95297
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 36 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: bd87f1f028ddaad45d4a9a3621dfe688c840ba41
refs/heads/master: cdc6f27d9e3c2f7ca1a3e19c6eabb1ad6a2add5d
56 changes: 21 additions & 35 deletions trunk/kernel/time/tick-broadcast.c
Original file line number Diff line number Diff line change
Expand Up @@ -383,46 +383,20 @@ int tick_resume_broadcast_oneshot(struct clock_event_device *bc)
return 0;
}

/*
* Reprogram the broadcast device:
*
* Called with tick_broadcast_lock held and interrupts disabled.
*/
static int tick_broadcast_reprogram(void)
{
ktime_t expires = { .tv64 = KTIME_MAX };
struct tick_device *td;
int cpu;

/*
* Find the event which expires next:
*/
for (cpu = first_cpu(tick_broadcast_oneshot_mask); cpu != NR_CPUS;
cpu = next_cpu(cpu, tick_broadcast_oneshot_mask)) {
td = &per_cpu(tick_cpu_device, cpu);
if (td->evtdev->next_event.tv64 < expires.tv64)
expires = td->evtdev->next_event;
}

if (expires.tv64 == KTIME_MAX)
return 0;

return tick_broadcast_set_event(expires, 0);
}

/*
* Handle oneshot mode broadcasting
*/
static void tick_handle_oneshot_broadcast(struct clock_event_device *dev)
{
struct tick_device *td;
cpumask_t mask;
ktime_t now;
ktime_t now, next_event;
int cpu;

spin_lock(&tick_broadcast_lock);
again:
dev->next_event.tv64 = KTIME_MAX;
next_event.tv64 = KTIME_MAX;
mask = CPU_MASK_NONE;
now = ktime_get();
/* Find all expired events */
Expand All @@ -431,19 +405,31 @@ static void tick_handle_oneshot_broadcast(struct clock_event_device *dev)
td = &per_cpu(tick_cpu_device, cpu);
if (td->evtdev->next_event.tv64 <= now.tv64)
cpu_set(cpu, mask);
else if (td->evtdev->next_event.tv64 < next_event.tv64)
next_event.tv64 = td->evtdev->next_event.tv64;
}

/*
* Wakeup the cpus which have an expired event. The broadcast
* device is reprogrammed in the return from idle code.
* Wakeup the cpus which have an expired event.
*/
tick_do_broadcast(mask);

/*
* Two reasons for reprogram:
*
* - The global event did not expire any CPU local
* events. This happens in dyntick mode, as the maximum PIT
* delta is quite small.
*
* - There are pending events on sleeping CPUs which were not
* in the event mask
*/
if (!tick_do_broadcast(mask)) {
if (next_event.tv64 != KTIME_MAX) {
/*
* The global event did not expire any CPU local
* events. This happens in dyntick mode, as the
* maximum PIT delta is quite small.
* Rearm the broadcast device. If event expired,
* repeat the above
*/
if (tick_broadcast_reprogram())
if (tick_broadcast_set_event(next_event, 0))
goto again;
}
spin_unlock(&tick_broadcast_lock);
Expand Down

0 comments on commit 9f95297

Please sign in to comment.