aboutsummaryrefslogblamecommitdiffstats
path: root/kernel/timer.c
blob: 9c3c62b0c4bc89ebd307ff79950039021d157861 (plain) (tree)
1
2
3
4


                        
                                                      

















                                                                             
                         




                            
                                






                               
                        
                       
                           
                           
                        
                       






                        


                               



                                                            


                                    






                                            
             
                                       
  
 
                  
                                       
  
 
                  

                                         
                                    
                                 




                             
                        
 
                                 
                               
                                                                         
 
                                                      
                                                                       
 
                                                                           

 
                                                                      
 
                                                                                    



                                                                 
                                                       


                  
                                                                    
 
                                                                      
                                                                         

 

                                                                   




















                                                                              
                                                    
           
                                                     










                                                                     
























                                                                          






                                                                        
                                                                             











                                                                          
                                                               


                                                                



                                                              






                                                             
                                                                     







                                                                          
                                                               


                                            
                                                                      






                                                                      
                                                                           







                                                                          
                                                               






                                                                   
































































                                                                              

                                                      
                                   















                                                                  
                                                                                








































                                                                          









                                                                             




                                                               

                                       








                                                                            

      



                                                




                                                      


                                    
   




































































                                                                              
                                           
























                                                                   


                                                     
 


                                                        

                                                              
                                       
 
                                           












                                                                       


















                                                               


                                                    

                                 
                                                    
                          




                                                    
                                                            
 
 












                                                                         
   
                                      
                                      


                                                                   
  
                                                                      

                         


                                               
 
                          
                                       
 
                              
 


                                                          
 
                                         

                                    
                                         
 
                                                         
                                                  


                                                
                                
 






                                             
                                                                









                                                                          
                                                                  
                                                             
                                     
 
                               

                  
                                                             
                                                    

                                                               
                                                                







                                                                    
                 

                                                                              
 
                                          
                            
                          
 
                                                
                                 
 



                                              


                                                               
                        


                                        

         
                                       
 


                                                

                                                                     


                                            
                               
                  




                                                                            
                   
                                                           
                                                                  
                                                    
                                                 

                                               
                                                    


                 
                                 


                                                            
                                        

           
                                                   



                   
   


                                                       
  



                                                                     
   
                                                                      
 
                                                                   
 
                                 
 















                                                                             
                                
                                                       
                



                                               
 
                                                      
         
                                       











                                                  
   

                                       
                                   
  
                                                                       















                                                                           

                                              




                                                         
                                                              

                         
                                                                    
 

                         
   





















                                                                     



































                                                                          
                                              


                                                            











                                                                    
                                

   











                                                                           
                               
                            
                    
 
                                                  



                                                      


                                                                       

                                
                                                           
         
 
                   
 

                         



                                                    

                                                                          


                                                   
                               







                                              
                                                  


                                       


                                                               






                                                   

                                     
                 
   






                                                                           
                                                                       
                                                                     
                                                                         


                                                                       
  


















                                                                     
                                                                          


                                            
                     

                            



                                                              
                              

                                              
                                 
      




                                                      



                                                       
                            
         
 
                              

      
                                                                      

                                                         



                                                     
 
          

                                                            
           
                                                               
                                                            
                                                
         



                     




























                                                                              








                                                                       


         


                                                                                  





                                                                    
                                                       


                                 
                                   
                                                             
                                           
                                                    
                                                           
 







                                                                             

                                                                     
                                           


                                                  
                                                                                

                                             
 

                                                         
                                                    
                                               
 
                                                     
                                                       
                                                   

                 
                                   
                                     

 
                   

                                                            

                                                             
   
                                                                   
 
                                                          
                                                                     
                                          
                               
                               

                                           
                                                
            
                                                                       

                                                            
 
                                  
                                               



                                                            
                 







                                                  





                               

                                             
                                                  

                                                        
                    
                                                                           


                                                                    
                                          

                                                                       
















                                                                        
         

                       
 








                                                                  
                            


                                       
 




                                                                  
 
                                              
                                              







                                                                








                                                                    

                                      

                       

   
                                                                        
                                  
   
                                                         
 
                                                             
                              
 





                                                                           
                               


                                                                  






                                                    

      
  
                                                                            







                                                                         
                                           
                           
                                            
                      



                               
                         
                                


  



                                                                     
                                                             
 
                              
 








                                                        
                             


                                     





                                                                  
                                             
 
                                        



















                                                                           
                       
 
                                      


  



                                                     
   
                        

                
 
                        
                                                                   
                          
 


                   
                       

                                             
                             

 
                        

                                             
                              

 
                       

                                             
                             

 
                        

                                             
                               





                                                 
                                                      



























                                                                       
                                                         























                                                                           
                                  
                                                                          

                                                        






                                                      
                                                                              
                                                             


                                          


                                                      




                                         

                                



                                                                         

                                                                       

                                                


                                              






                                                                  

                                                                         

                                                  


                                                
                                           
                       
 
                                     

 
   
                                      
                                   
   
                                    
 

                                           
                           
 
                                                
 


                                                        
 
                                                            
 
                                 
 

                          









                                                                    

                                                                      

                         
                                  










                                                                       
                                                                         



                                                                        













                                     
                                                       



                           
 





                                                             
                                             

              
                               
                                                          
 
                                   

                                      
                                


                                                              

                                                                        


                                                                  






                                                                        
                                                        
                        





                                                                              
                                      
                                                
                 


                                                
         
 
                                    
 









                                                  
                                               
                 


                         
                                                                                  



                                   
                                                                         
                                       
                                                


                                                                        
                                                    
         

 
                                             
 

                                   


                                

                                            




                                                             
                                                                

                                        
 
                                      







                                                                    
                                     
                                         
                                


                               
                                                                  


                                                                 

                

                            
                                   


                                                        


                         
                             








                                    
                                                        





                                           
                                                                             
                                                                  
 

                           
                                 
                                          
                                                       

 







                                                            

                                                                    




                      
                                                   





                                                            

                                                                  



                                         





















                                                                         
/*
 *  linux/kernel/timer.c
 *
 *  Kernel internal timers, basic process system calls
 *
 *  Copyright (C) 1991, 1992  Linus Torvalds
 *
 *  1997-01-28  Modified by Finn Arne Gangstad to make timers scale better.
 *
 *  1997-09-10  Updated NTP code according to technical memorandum Jan '96
 *              "A Kernel Model for Precision Timekeeping" by Dave Mills
 *  1998-12-24  Fixed a xtime SMP race (we need the xtime_lock rw spinlock to
 *              serialize accesses to xtime/lost_ticks).
 *                              Copyright (C) 1998  Andrea Arcangeli
 *  1999-03-10  Improved NTP compatibility by Ulrich Windl
 *  2002-05-31	Move sys_sysinfo here and make its locking sane, Robert Love
 *  2000-10-05  Implemented scalable SMP per-CPU timer handling.
 *                              Copyright (C) 2000, 2001, 2002  Ingo Molnar
 *              Designed by David S. Miller, Alexey Kuznetsov and Ingo Molnar
 */

#include <linux/kernel_stat.h>
#include <linux/export.h>
#include <linux/interrupt.h>
#include <linux/percpu.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/swap.h>
#include <linux/pid_namespace.h>
#include <linux/notifier.h>
#include <linux/thread_info.h>
#include <linux/time.h>
#include <linux/jiffies.h>
#include <linux/posix-timers.h>
#include <linux/cpu.h>
#include <linux/syscalls.h>
#include <linux/delay.h>
#include <linux/tick.h>
#include <linux/kallsyms.h>
#include <linux/irq_work.h>
#include <linux/sched.h>
#include <linux/slab.h>

#include <asm/uaccess.h>
#include <asm/unistd.h>
#include <asm/div64.h>
#include <asm/timex.h>
#include <asm/io.h>

#define CREATE_TRACE_POINTS
#include <trace/events/timer.h>

u64 jiffies_64 __cacheline_aligned_in_smp = INITIAL_JIFFIES;

EXPORT_SYMBOL(jiffies_64);

/*
 * per-CPU timer vector definitions:
 */
#define TVN_BITS (CONFIG_BASE_SMALL ? 4 : 6)
#define TVR_BITS (CONFIG_BASE_SMALL ? 6 : 8)
#define TVN_SIZE (1 << TVN_BITS)
#define TVR_SIZE (1 << TVR_BITS)
#define TVN_MASK (TVN_SIZE - 1)
#define TVR_MASK (TVR_SIZE - 1)

struct tvec {
	struct list_head vec[TVN_SIZE];
};

struct tvec_root {
	struct list_head vec[TVR_SIZE];
};

struct tvec_base {
	spinlock_t lock;
	struct timer_list *running_timer;
	unsigned long timer_jiffies;
	unsigned long next_timer;
	struct tvec_root tv1;
	struct tvec tv2;
	struct tvec tv3;
	struct tvec tv4;
	struct tvec tv5;
} ____cacheline_aligned;

struct tvec_base boot_tvec_bases;
EXPORT_SYMBOL(boot_tvec_bases);
static DEFINE_PER_CPU(struct tvec_base *, tvec_bases) = &boot_tvec_bases;

/* Functions below help us manage 'deferrable' flag */
static inline unsigned int tbase_get_deferrable(struct tvec_base *base)
{
	return ((unsigned int)(unsigned long)base & TBASE_DEFERRABLE_FLAG);
}

static inline struct tvec_base *tbase_get_base(struct tvec_base *base)
{
	return ((struct tvec_base *)((unsigned long)base & ~TBASE_DEFERRABLE_FLAG));
}

static inline void timer_set_deferrable(struct timer_list *timer)
{
	timer->base = TBASE_MAKE_DEFERRED(timer->base);
}

static inline void
timer_set_base(struct timer_list *timer, struct tvec_base *new_base)
{
	timer->base = (struct tvec_base *)((unsigned long)(new_base) |
				      tbase_get_deferrable(timer->base));
}

static unsigned long round_jiffies_common(unsigned long j, int cpu,
		bool force_up)
{
	int rem;
	unsigned long original = j;

	/*
	 * We don't want all cpus firing their timers at once hitting the
	 * same lock or cachelines, so we skew each extra cpu with an extra
	 * 3 jiffies. This 3 jiffies came originally from the mm/ code which
	 * already did this.
	 * The skew is done by adding 3*cpunr, then round, then subtract this
	 * extra offset again.
	 */
	j += cpu * 3;

	rem = j % HZ;

	/*
	 * If the target jiffie is just after a whole second (which can happen
	 * due to delays of the timer irq, long irq off times etc etc) then
	 * we should round down to the whole second, not up. Use 1/4th second
	 * as cutoff for this rounding as an extreme upper bound for this.
	 * But never round down if @force_up is set.
	 */
	if (rem < HZ/4 && !force_up) /* round down */
		j = j - rem;
	else /* round up */
		j = j - rem + HZ;

	/* now that we have rounded, subtract the extra skew again */
	j -= cpu * 3;

	if (j <= jiffies) /* rounding ate our timeout entirely; */
		return original;
	return j;
}

/**
 * __round_jiffies - function to round jiffies to a full second
 * @j: the time in (absolute) jiffies that should be rounded
 * @cpu: the processor number on which the timeout will happen
 *
 * __round_jiffies() rounds an absolute time in the future (in jiffies)
 * up or down to (approximately) full seconds. This is useful for timers
 * for which the exact time they fire does not matter too much, as long as
 * they fire approximately every X seconds.
 *
 * By rounding these timers to whole seconds, all such timers will fire
 * at the same time, rather than at various times spread out. The goal
 * of this is to have the CPU wake up less, which saves power.
 *
 * The exact rounding is skewed for each processor to avoid all
 * processors firing at the exact same time, which could lead
 * to lock contention or spurious cache line bouncing.
 *
 * The return value is the rounded version of the @j parameter.
 */
unsigned long __round_jiffies(unsigned long j, int cpu)
{
	return round_jiffies_common(j, cpu, false);
}
EXPORT_SYMBOL_GPL(__round_jiffies);

/**
 * __round_jiffies_relative - function to round jiffies to a full second
 * @j: the time in (relative) jiffies that should be rounded
 * @cpu: the processor number on which the timeout will happen
 *
 * __round_jiffies_relative() rounds a time delta  in the future (in jiffies)
 * up or down to (approximately) full seconds. This is useful for timers
 * for which the exact time they fire does not matter too much, as long as
 * they fire approximately every X seconds.
 *
 * By rounding these timers to whole seconds, all such timers will fire
 * at the same time, rather than at various times spread out. The goal
 * of this is to have the CPU wake up less, which saves power.
 *
 * The exact rounding is skewed for each processor to avoid all
 * processors firing at the exact same time, which could lead
 * to lock contention or spurious cache line bouncing.
 *
 * The return value is the rounded version of the @j parameter.
 */
unsigned long __round_jiffies_relative(unsigned long j, int cpu)
{
	unsigned long j0 = jiffies;

	/* Use j0 because jiffies might change while we run */
	return round_jiffies_common(j + j0, cpu, false) - j0;
}
EXPORT_SYMBOL_GPL(__round_jiffies_relative);

/**