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