1 /* _VX_SCHED_H defined below */
3 #if defined(__KERNEL__) && defined(_VX_INFO_DEF_)
5 #include <linux/spinlock.h>
6 #include <linux/jiffies.h>
7 #include <linux/cpumask.h>
8 #include <asm/atomic.h>
12 uint64_t user_ticks; /* token tick events */
13 uint64_t sys_ticks; /* token tick events */
14 uint64_t hold_ticks; /* token ticks paused */
15 uint64_t unused[5]; /* cacheline ? */
18 /* context sub struct */
21 atomic_t tokens; /* number of CPU tokens */
22 spinlock_t tokens_lock; /* lock for token bucket */
24 int fill_rate; /* Fill rate: add X tokens... */
25 int interval; /* Divisor: per Y jiffies */
26 int tokens_min; /* Limit: minimum for unhold */
27 int tokens_max; /* Limit: no more than N tokens */
28 uint32_t jiffies; /* last time accounted */
30 int priority_bias; /* bias offset for priority */
31 cpumask_t cpus_allowed; /* cpu mask for context */
33 struct _vx_ticks cpu[NR_CPUS];
36 static inline void vx_info_init_sched(struct _vx_sched *sched)
40 /* scheduling; hard code starting values as constants */
43 sched->tokens_min = HZ >> 4;
44 sched->tokens_max = HZ >> 1;
45 sched->jiffies = jiffies;
46 sched->tokens_lock = SPIN_LOCK_UNLOCKED;
48 atomic_set(&sched->tokens, HZ >> 2);
49 sched->cpus_allowed = CPU_MASK_ALL;
50 sched->priority_bias = 0;
53 sched->cpu[i].user_ticks = 0;
54 sched->cpu[i].sys_ticks = 0;
55 sched->cpu[i].hold_ticks = 0;
59 static inline void vx_info_exit_sched(struct _vx_sched *sched)
64 static inline int vx_info_proc_sched(struct _vx_sched *sched, char *buffer)
69 length += sprintf(buffer,
76 ,atomic_read(&sched->tokens)
84 for_each_online_cpu(i) {
85 length += sprintf(buffer + length,
86 "cpu %d: %lld %lld %lld\n"
88 ,sched->cpu[i].user_ticks
89 ,sched->cpu[i].sys_ticks
90 ,sched->cpu[i].hold_ticks
98 #else /* _VX_INFO_DEF_ */
104 /* sched vserver commands */
106 #define VCMD_set_sched_v2 VC_CMD(SCHED, 1, 2)
107 #define VCMD_set_sched VC_CMD(SCHED, 1, 3)
109 struct vcmd_set_sched_v2 {
118 struct vcmd_set_sched_v3 {
125 int32_t priority_bias;
129 #define VXSM_FILL_RATE 0x0001
130 #define VXSM_INTERVAL 0x0002
131 #define VXSM_TOKENS 0x0010
132 #define VXSM_TOKENS_MIN 0x0020
133 #define VXSM_TOKENS_MAX 0x0040
134 #define VXSM_PRIO_BIAS 0x0100
136 #define SCHED_KEEP (-2)
140 extern int vc_set_sched_v1(uint32_t, void __user *);
141 extern int vc_set_sched_v2(uint32_t, void __user *);
142 extern int vc_set_sched(uint32_t, void __user *);
145 #define VAVAVOOM_RATIO 50
147 #define MAX_PRIO_BIAS 20
148 #define MIN_PRIO_BIAS -20
153 /* scheduling stuff */
155 int effective_vavavoom(struct task_struct *, int);
157 int vx_tokens_recalc(struct vx_info *);
161 static inline int vx_tokens_avail(struct vx_info *vxi)
163 return atomic_read(&vxi->sched.tokens);
166 static inline void vx_consume_token(struct vx_info *vxi)
168 atomic_dec(&vxi->sched.tokens);
171 static inline int vx_need_resched(struct task_struct *p)
173 #ifdef CONFIG_VSERVER_HARDCPU
174 struct vx_info *vxi = p->vx_info;
176 int slice = --p->time_slice;
178 #ifdef CONFIG_VSERVER_HARDCPU
182 if ((tokens = vx_tokens_avail(vxi)) > 0)
183 vx_consume_token(vxi);
184 /* for tokens > 0, one token was consumed */
193 static inline void vx_onhold_inc(struct vx_info *vxi)
195 int onhold = atomic_read(&vxi->cvirt.nr_onhold);
197 atomic_inc(&vxi->cvirt.nr_onhold);
199 vxi->cvirt.onhold_last = jiffies;
202 static inline void __vx_onhold_update(struct vx_info *vxi)
204 int cpu = smp_processor_id();
205 uint32_t now = jiffies;
206 uint32_t delta = now - vxi->cvirt.onhold_last;
208 vxi->cvirt.onhold_last = now;
209 vxi->sched.cpu[cpu].hold_ticks += delta;
212 static inline void vx_onhold_dec(struct vx_info *vxi)
214 if (atomic_dec_and_test(&vxi->cvirt.nr_onhold))
215 __vx_onhold_update(vxi);
218 #endif /* __KERNEL__ */
220 #endif /* _VX_SCHED_H */