timekeeping: Provide y2038 safe accessor to the seconds portion of CLOCK_REALTIME
ktime_get_real_seconds() is the replacement function for get_seconds() returning the seconds portion of CLOCK_REALTIME in a time64_t. For 64bit the function is equivivalent to get_seconds(), but for 32bit it protects the readout with the timekeeper sequence count. This is required because 32-bit machines cannot access 64-bit tk->xtime_sec variable atomically. [tglx: Massaged changelog and added docbook comment ] Signed-off-by: Heena Sirwani <heenasirwani@gmail.com> Reviewed-by: Arnd Bergman <arnd@arndb.de> Cc: John Stultz <john.stultz@linaro.org> Cc: opw-kernel@googlegroups.com Link: http://lkml.kernel.org/r/7adcfaa8962b8ad58785d9a2456c3f77d93c0ffb.1414578445.git.heenasirwani@gmail.com Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
This commit is contained in:
		
					parent
					
						
							
								9e3680b175
							
						
					
				
			
			
				commit
				
					
						dbe7aa622d
					
				
			
		
					 2 changed files with 31 additions and 0 deletions
				
			
		| 
						 | 
					@ -29,6 +29,7 @@ struct timespec get_monotonic_coarse(void);
 | 
				
			||||||
extern void getrawmonotonic(struct timespec *ts);
 | 
					extern void getrawmonotonic(struct timespec *ts);
 | 
				
			||||||
extern void ktime_get_ts64(struct timespec64 *ts);
 | 
					extern void ktime_get_ts64(struct timespec64 *ts);
 | 
				
			||||||
extern time64_t ktime_get_seconds(void);
 | 
					extern time64_t ktime_get_seconds(void);
 | 
				
			||||||
 | 
					extern time64_t ktime_get_real_seconds(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern int __getnstimeofday64(struct timespec64 *tv);
 | 
					extern int __getnstimeofday64(struct timespec64 *tv);
 | 
				
			||||||
extern void getnstimeofday64(struct timespec64 *tv);
 | 
					extern void getnstimeofday64(struct timespec64 *tv);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -676,6 +676,36 @@ time64_t ktime_get_seconds(void)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL_GPL(ktime_get_seconds);
 | 
					EXPORT_SYMBOL_GPL(ktime_get_seconds);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * ktime_get_real_seconds - Get the seconds portion of CLOCK_REALTIME
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Returns the wall clock seconds since 1970. This replaces the
 | 
				
			||||||
 | 
					 * get_seconds() interface which is not y2038 safe on 32bit systems.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * For 64bit systems the fast access to tk->xtime_sec is preserved. On
 | 
				
			||||||
 | 
					 * 32bit systems the access must be protected with the sequence
 | 
				
			||||||
 | 
					 * counter to provide "atomic" access to the 64bit tk->xtime_sec
 | 
				
			||||||
 | 
					 * value.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					time64_t ktime_get_real_seconds(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct timekeeper *tk = &tk_core.timekeeper;
 | 
				
			||||||
 | 
						time64_t seconds;
 | 
				
			||||||
 | 
						unsigned int seq;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (IS_ENABLED(CONFIG_64BIT))
 | 
				
			||||||
 | 
							return tk->xtime_sec;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						do {
 | 
				
			||||||
 | 
							seq = read_seqcount_begin(&tk_core.seq);
 | 
				
			||||||
 | 
							seconds = tk->xtime_sec;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						} while (read_seqcount_retry(&tk_core.seq, seq));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return seconds;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					EXPORT_SYMBOL_GPL(ktime_get_real_seconds);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef CONFIG_NTP_PPS
 | 
					#ifdef CONFIG_NTP_PPS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue