aboutsummaryrefslogblamecommitdiffstats
path: root/include/litmus/sched_mc.h
blob: 1d491ce6a31a743984a4c6f967e42125d4980e2f (plain) (tree)
1
2
3
4
5
6
7
8
9


                          





                                                            
                            

  

                             
                     
                           







                          



                                                                              




                               
                                             
                                                                                       
                                                          
 
                          

                                                                      


                                                                       


                                                                 
                                                                 
                                         
 
  
                                                
   


                                                        


                              

                                                
      

  
   















                                                                              
                                                                           



                                                             

                                                                    

                                                                             
                   

                                       
                                       
                                      


                                      
                                      
      
                                     
  

   
                                                           



                                                                         




                                           
 


                                                 
                                                         







                                                                           
                                            



                                                        


                       
#ifndef _LINUX_SCHED_MC_H_
#define _LINUX_SCHED_MC_H_

/* criticality levels */
enum crit_level {
	/* probably don't need to assign these (paranoid) */
	CRIT_LEVEL_A = 0,
	CRIT_LEVEL_B = 1,
	CRIT_LEVEL_C = 2,
	NUM_CRIT_LEVELS = 3,
};

struct mc_task {
	enum crit_level crit;
	int lvl_a_id;
	int lvl_a_eligible;
};

struct mc_job {
	int is_ghost:1;
	lt_t ghost_budget;
};

#ifdef __KERNEL__
/*
 * These are used only in the kernel. Userspace programs like RTSpin won't see
 * them.
 */
struct mc_data {
	struct mc_task mc_task;
	struct mc_job mc_job;
};

#define tsk_mc_data(t)	 (tsk_rt(t)->mc_data)
#define tsk_mc_crit(t)	 (tsk_mc_data(t) ? tsk_mc_data(t)->mc_task.crit : CRIT_LEVEL_C)
#define is_ghost(t)	 (tsk_mc_data(t)->mc_job.is_ghost)

#define TS "(%s/%d:%d:%s)"
#define TA(t) (t) ? tsk_mc_data(t) ? is_ghost(t) ? "ghost" : t->comm \
						 : t->comm : "NULL", \
	      (t) ? t->pid : 1,					\
	      (t) ? t->rt_param.job_params.job_no : 1,		\
	      (t && get_task_domain(t)) ? get_task_domain(t)->name : ""
#define STRACE(fmt, args...) \
	sched_trace_log_message("%d P%d      [%s@%s:%d]: " fmt,	\
				TRACE_ARGS,  ## args)
#define TRACE_MC_TASK(t, fmt, args...)				\
	STRACE(TS " " fmt, TA(t), ##args)

/*
 * The MC-CE scheduler uses this as domain data.
 */
struct ce_dom_data {
	int cpu;
	struct task_struct *scheduled, *should_schedule;
#ifdef CONFIG_MERGE_TIMERS
	struct rt_event event;
#else
	struct hrtimer_start_on_info timer_info;
	struct hrtimer timer;
#endif
};

/**
 * enum crit_state - Logically add / remove CPUs from criticality levels.
 *
 * Global crit levels need to use a two step process to remove CPUs so
 * that the CPUs can be removed without holding domain locks.
 *
 * @CS_ACTIVE	The criticality entry can run a task
 * @CS_ACTIVATE The criticality entry can run a task, but hasn't had its
 *		position updated in a global heap. Set with ONLY CPU lock.
 * @CS_REMOVE   The criticality entry is logically removed, but hasn't had its
 *		position adjusted in a global heap. This should be set when
 *		ONLY the CPU state is locked.
 * @CS_REMOVED	The criticality entry has been removed from the crit level
 */
enum crit_state { CS_ACTIVE, CS_ACTIVATE, CS_REMOVE, CS_REMOVED };

/**
 * struct crit_entry - State of a CPU within each criticality level system.
 * @level	Criticality level of this entry
 * @linked	Logically running task, ghost or regular
 * @domain	Domain from which to draw tasks
 * @usable	False if a higher criticality task is running
 * @event	For ghost task budget enforcement (merge timers)
 * @timer	For ghost task budget enforcement (not merge timers)
 * @node	Used to sort crit_entries by preemptability in global domains
 */
struct crit_entry {
	enum crit_level		level;
	struct task_struct*	linked;
	struct domain*		domain;
	enum crit_state		state;
#ifdef CONFIG_MERGE_TIMERS
	struct rt_event		event;
#else
	struct hrtimer		timer;
#endif
	struct bheap_node*	node;
};

/**
 * struct domain_data - Wrap domains with related CPU state
 * @domain	A domain for a criticality level
 * @heap	The preemptable heap of crit entries (for global domains)
 * @crit_entry	The crit entry for this domain (for partitioned domains)
 */
struct domain_data {
	struct domain 		domain;
	struct bheap*		heap;
	struct crit_entry*	crit_entry;
};

/*
 * Functions that are used with the MC-CE plugin.
 */
long mc_ce_set_domains(const int, struct domain_data*[]);
unsigned int mc_ce_get_expected_job(const int, const int);

/*
 * These functions are (lazily) inserted into the MC plugin code so that it
 * manipulates the MC-CE state.
 */
long mc_ce_admit_task_common(struct task_struct*);
void mc_ce_task_exit_common(struct task_struct*);
lt_t mc_ce_timer_callback_common(domain_t*);
void mc_ce_release_at_common(struct task_struct*, lt_t);
long mc_ce_activate_plugin_common(void);
long mc_ce_deactivate_plugin_common(void);

#endif /* __KERNEL__ */

#endif