1 /******************************************************************************
2 * tasklet.h
3 *
4 * Tasklets are dynamically-allocatable tasks run in either VCPU context
5 * (specifically, the idle VCPU's context) or in softirq context, on at most
6 * one CPU at a time. Softirq versus VCPU context execution is specified
7 * during per-tasklet initialisation.
8 */
9
10 #ifndef __XEN_TASKLET_H__
11 #define __XEN_TASKLET_H__
12
13 #include <xen/types.h>
14 #include <xen/list.h>
15 #include <xen/percpu.h>
16
17 struct tasklet
18 {
19 struct list_head list;
20 int scheduled_on;
21 bool_t is_softirq;
22 bool_t is_running;
23 bool_t is_dead;
24 void (*func)(unsigned long);
25 unsigned long data;
26 };
27
28 #define _DECLARE_TASKLET(name, func, data, softirq) \
29 struct tasklet name = { \
30 LIST_HEAD_INIT(name.list), -1, softirq, 0, 0, func, data }
31 #define DECLARE_TASKLET(name, func, data) \
32 _DECLARE_TASKLET(name, func, data, 0)
33 #define DECLARE_SOFTIRQ_TASKLET(name, func, data) \
34 _DECLARE_TASKLET(name, func, data, 1)
35
36 /* Indicates status of tasklet work on each CPU. */
37 DECLARE_PER_CPU(unsigned long, tasklet_work_to_do);
38 #define _TASKLET_enqueued 0 /* Tasklet work is enqueued for this CPU. */
39 #define _TASKLET_scheduled 1 /* Scheduler has scheduled do_tasklet(). */
40 #define TASKLET_enqueued (1ul << _TASKLET_enqueued)
41 #define TASKLET_scheduled (1ul << _TASKLET_scheduled)
42
tasklet_work_to_do(unsigned int cpu)43 static inline bool tasklet_work_to_do(unsigned int cpu)
44 {
45 /*
46 * Work must be enqueued *and* scheduled. Otherwise there is no work to
47 * do, and/or scheduler needs to run to update idle vcpu priority.
48 */
49 return per_cpu(tasklet_work_to_do, cpu) == (TASKLET_enqueued|
50 TASKLET_scheduled);
51 }
52
53 void tasklet_schedule_on_cpu(struct tasklet *t, unsigned int cpu);
54 void tasklet_schedule(struct tasklet *t);
55 void do_tasklet(void);
56 void tasklet_kill(struct tasklet *t);
57 void tasklet_init(
58 struct tasklet *t, void (*func)(unsigned long), unsigned long data);
59 void softirq_tasklet_init(
60 struct tasklet *t, void (*func)(unsigned long), unsigned long data);
61 void tasklet_subsys_init(void);
62
63 #endif /* __XEN_TASKLET_H__ */
64