mirror of
https://github.com/adulau/aha.git
synced 2024-12-28 03:36:19 +00:00
Merge branch 'core-fixes-for-linus-2' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'core-fixes-for-linus-2' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: softirq: introduce tasklet_hrtimer infrastructure
This commit is contained in:
commit
612e900c28
2 changed files with 89 additions and 1 deletions
|
@ -14,6 +14,7 @@
|
|||
#include <linux/irqflags.h>
|
||||
#include <linux/smp.h>
|
||||
#include <linux/percpu.h>
|
||||
#include <linux/hrtimer.h>
|
||||
|
||||
#include <asm/atomic.h>
|
||||
#include <asm/ptrace.h>
|
||||
|
@ -519,6 +520,31 @@ extern void tasklet_kill_immediate(struct tasklet_struct *t, unsigned int cpu);
|
|||
extern void tasklet_init(struct tasklet_struct *t,
|
||||
void (*func)(unsigned long), unsigned long data);
|
||||
|
||||
struct tasklet_hrtimer {
|
||||
struct hrtimer timer;
|
||||
struct tasklet_struct tasklet;
|
||||
enum hrtimer_restart (*function)(struct hrtimer *);
|
||||
};
|
||||
|
||||
extern void
|
||||
tasklet_hrtimer_init(struct tasklet_hrtimer *ttimer,
|
||||
enum hrtimer_restart (*function)(struct hrtimer *),
|
||||
clockid_t which_clock, enum hrtimer_mode mode);
|
||||
|
||||
static inline
|
||||
int tasklet_hrtimer_start(struct tasklet_hrtimer *ttimer, ktime_t time,
|
||||
const enum hrtimer_mode mode)
|
||||
{
|
||||
return hrtimer_start(&ttimer->timer, time, mode);
|
||||
}
|
||||
|
||||
static inline
|
||||
void tasklet_hrtimer_cancel(struct tasklet_hrtimer *ttimer)
|
||||
{
|
||||
hrtimer_cancel(&ttimer->timer);
|
||||
tasklet_kill(&ttimer->tasklet);
|
||||
}
|
||||
|
||||
/*
|
||||
* Autoprobing for irqs:
|
||||
*
|
||||
|
|
|
@ -345,7 +345,9 @@ void open_softirq(int nr, void (*action)(struct softirq_action *))
|
|||
softirq_vec[nr].action = action;
|
||||
}
|
||||
|
||||
/* Tasklets */
|
||||
/*
|
||||
* Tasklets
|
||||
*/
|
||||
struct tasklet_head
|
||||
{
|
||||
struct tasklet_struct *head;
|
||||
|
@ -493,6 +495,66 @@ void tasklet_kill(struct tasklet_struct *t)
|
|||
|
||||
EXPORT_SYMBOL(tasklet_kill);
|
||||
|
||||
/*
|
||||
* tasklet_hrtimer
|
||||
*/
|
||||
|
||||
/*
|
||||
* The trampoline is called when the hrtimer expires. If this is
|
||||
* called from the hrtimer interrupt then we schedule the tasklet as
|
||||
* the timer callback function expects to run in softirq context. If
|
||||
* it's called in softirq context anyway (i.e. high resolution timers
|
||||
* disabled) then the hrtimer callback is called right away.
|
||||
*/
|
||||
static enum hrtimer_restart __hrtimer_tasklet_trampoline(struct hrtimer *timer)
|
||||
{
|
||||
struct tasklet_hrtimer *ttimer =
|
||||
container_of(timer, struct tasklet_hrtimer, timer);
|
||||
|
||||
if (hrtimer_is_hres_active(timer)) {
|
||||
tasklet_hi_schedule(&ttimer->tasklet);
|
||||
return HRTIMER_NORESTART;
|
||||
}
|
||||
return ttimer->function(timer);
|
||||
}
|
||||
|
||||
/*
|
||||
* Helper function which calls the hrtimer callback from
|
||||
* tasklet/softirq context
|
||||
*/
|
||||
static void __tasklet_hrtimer_trampoline(unsigned long data)
|
||||
{
|
||||
struct tasklet_hrtimer *ttimer = (void *)data;
|
||||
enum hrtimer_restart restart;
|
||||
|
||||
restart = ttimer->function(&ttimer->timer);
|
||||
if (restart != HRTIMER_NORESTART)
|
||||
hrtimer_restart(&ttimer->timer);
|
||||
}
|
||||
|
||||
/**
|
||||
* tasklet_hrtimer_init - Init a tasklet/hrtimer combo for softirq callbacks
|
||||
* @ttimer: tasklet_hrtimer which is initialized
|
||||
* @function: hrtimer callback funtion which gets called from softirq context
|
||||
* @which_clock: clock id (CLOCK_MONOTONIC/CLOCK_REALTIME)
|
||||
* @mode: hrtimer mode (HRTIMER_MODE_ABS/HRTIMER_MODE_REL)
|
||||
*/
|
||||
void tasklet_hrtimer_init(struct tasklet_hrtimer *ttimer,
|
||||
enum hrtimer_restart (*function)(struct hrtimer *),
|
||||
clockid_t which_clock, enum hrtimer_mode mode)
|
||||
{
|
||||
hrtimer_init(&ttimer->timer, which_clock, mode);
|
||||
ttimer->timer.function = __hrtimer_tasklet_trampoline;
|
||||
tasklet_init(&ttimer->tasklet, __tasklet_hrtimer_trampoline,
|
||||
(unsigned long)ttimer);
|
||||
ttimer->function = function;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(tasklet_hrtimer_init);
|
||||
|
||||
/*
|
||||
* Remote softirq bits
|
||||
*/
|
||||
|
||||
DEFINE_PER_CPU(struct list_head [NR_SOFTIRQS], softirq_work_list);
|
||||
EXPORT_PER_CPU_SYMBOL(softirq_work_list);
|
||||
|
||||
|
|
Loading…
Reference in a new issue