Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 366158
b: refs/heads/master
c: d2348fb
h: refs/heads/master
v: v3
  • Loading branch information
Daniel Lezcano authored and Thomas Gleixner committed Mar 7, 2013
1 parent e1a77b4 commit 279ac07
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 9 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: f9ae39d04ccdec8d8ecf532191b7056c279a22c0
refs/heads/master: d2348fb6fdc6d671ad45b62db237f76c8c115603
5 changes: 5 additions & 0 deletions trunk/include/linux/clockchips.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,11 @@ enum clock_event_nofitiers {
#define CLOCK_EVT_FEAT_C3STOP 0x000008
#define CLOCK_EVT_FEAT_DUMMY 0x000010

/*
* Core shall set the interrupt affinity dynamically in broadcast mode
*/
#define CLOCK_EVT_FEAT_DYNIRQ 0x000020

/**
* struct clock_event_device - clock event device descriptor
* @event_handler: Assigned by the framework to be called by the low
Expand Down
39 changes: 31 additions & 8 deletions trunk/kernel/time/tick-broadcast.c
Original file line number Diff line number Diff line change
Expand Up @@ -401,13 +401,34 @@ struct cpumask *tick_get_broadcast_oneshot_mask(void)
return tick_broadcast_oneshot_mask;
}

static int tick_broadcast_set_event(struct clock_event_device *bc,
/*
* Set broadcast interrupt affinity
*/
static void tick_broadcast_set_affinity(struct clock_event_device *bc,
const struct cpumask *cpumask)
{
if (!(bc->features & CLOCK_EVT_FEAT_DYNIRQ))
return;

if (cpumask_equal(bc->cpumask, cpumask))
return;

bc->cpumask = cpumask;
irq_set_affinity(bc->irq, bc->cpumask);
}

static int tick_broadcast_set_event(struct clock_event_device *bc, int cpu,
ktime_t expires, int force)
{
int ret;

if (bc->mode != CLOCK_EVT_MODE_ONESHOT)
clockevents_set_mode(bc, CLOCK_EVT_MODE_ONESHOT);

return clockevents_program_event(bc, expires, force);
ret = clockevents_program_event(bc, expires, force);
if (!ret)
tick_broadcast_set_affinity(bc, cpumask_of(cpu));
return ret;
}

int tick_resume_broadcast_oneshot(struct clock_event_device *bc)
Expand Down Expand Up @@ -436,7 +457,7 @@ static void tick_handle_oneshot_broadcast(struct clock_event_device *dev)
{
struct tick_device *td;
ktime_t now, next_event;
int cpu;
int cpu, next_cpu = 0;

raw_spin_lock(&tick_broadcast_lock);
again:
Expand All @@ -447,10 +468,12 @@ static void tick_handle_oneshot_broadcast(struct clock_event_device *dev)
/* Find all expired events */
for_each_cpu(cpu, tick_broadcast_oneshot_mask) {
td = &per_cpu(tick_cpu_device, cpu);
if (td->evtdev->next_event.tv64 <= now.tv64)
if (td->evtdev->next_event.tv64 <= now.tv64) {
cpumask_set_cpu(cpu, tmpmask);
else if (td->evtdev->next_event.tv64 < next_event.tv64)
} else if (td->evtdev->next_event.tv64 < next_event.tv64) {
next_event.tv64 = td->evtdev->next_event.tv64;
next_cpu = cpu;
}
}

/*
Expand All @@ -473,7 +496,7 @@ static void tick_handle_oneshot_broadcast(struct clock_event_device *dev)
* Rearm the broadcast device. If event expired,
* repeat the above
*/
if (tick_broadcast_set_event(dev, next_event, 0))
if (tick_broadcast_set_event(dev, next_cpu, next_event, 0))
goto again;
}
raw_spin_unlock(&tick_broadcast_lock);
Expand Down Expand Up @@ -515,7 +538,7 @@ void tick_broadcast_oneshot_control(unsigned long reason)
if (!cpumask_test_and_set_cpu(cpu, tick_broadcast_oneshot_mask)) {
clockevents_set_mode(dev, CLOCK_EVT_MODE_SHUTDOWN);
if (dev->next_event.tv64 < bc->next_event.tv64)
tick_broadcast_set_event(bc, dev->next_event, 1);
tick_broadcast_set_event(bc, cpu, dev->next_event, 1);
}
} else {
if (cpumask_test_and_clear_cpu(cpu, tick_broadcast_oneshot_mask)) {
Expand Down Expand Up @@ -581,7 +604,7 @@ void tick_broadcast_setup_oneshot(struct clock_event_device *bc)
clockevents_set_mode(bc, CLOCK_EVT_MODE_ONESHOT);
tick_broadcast_init_next_event(tmpmask,
tick_next_period);
tick_broadcast_set_event(bc, tick_next_period, 1);
tick_broadcast_set_event(bc, cpu, tick_next_period, 1);
} else
bc->next_event.tv64 = KTIME_MAX;
} else {
Expand Down

0 comments on commit 279ac07

Please sign in to comment.