View | Details | Raw Unified | Return to bug 11970 | Differences between
and this patch

Collapse All | Expand All

(-)a/include/linux/clocksource.h (+3 lines)
Lines 79-84 struct clocksource { Link Here
79
	/* timekeeping specific data, ignore */
79
	/* timekeeping specific data, ignore */
80
	cycle_t cycle_interval;
80
	cycle_t cycle_interval;
81
	u64	xtime_interval;
81
	u64	xtime_interval;
82
	u32	raw_interval;
82
	/*
83
	/*
83
	 * Second part is written at each timer interrupt
84
	 * Second part is written at each timer interrupt
84
	 * Keep it in a different cache line to dirty no
85
	 * Keep it in a different cache line to dirty no
Lines 87-92 struct clocksource { Link Here
87
	cycle_t cycle_last ____cacheline_aligned_in_smp;
88
	cycle_t cycle_last ____cacheline_aligned_in_smp;
88
	u64 xtime_nsec;
89
	u64 xtime_nsec;
89
	s64 error;
90
	s64 error;
91
	struct timespec raw_time;
90
92
91
#ifdef CONFIG_CLOCKSOURCE_WATCHDOG
93
#ifdef CONFIG_CLOCKSOURCE_WATCHDOG
92
	/* Watchdog related data, used by the framework */
94
	/* Watchdog related data, used by the framework */
Lines 215-220 static inline void clocksource_calculate_interval(struct clocksource *c, Link Here
215
217
216
	/* Go back from cycles -> shifted ns, this time use ntp adjused mult */
218
	/* Go back from cycles -> shifted ns, this time use ntp adjused mult */
217
	c->xtime_interval = (u64)c->cycle_interval * c->mult;
219
	c->xtime_interval = (u64)c->cycle_interval * c->mult;
220
	c->raw_interval = ((u64)c->cycle_interval * c->mult_orig) >> c->shift;
218
}
221
}
219
222
220
223
(-)a/include/linux/time.h (+2 lines)
Lines 117-122 extern int do_setitimer(int which, struct itimerval *value, Link Here
117
extern unsigned int alarm_setitimer(unsigned int seconds);
117
extern unsigned int alarm_setitimer(unsigned int seconds);
118
extern int do_getitimer(int which, struct itimerval *value);
118
extern int do_getitimer(int which, struct itimerval *value);
119
extern void getnstimeofday(struct timespec *tv);
119
extern void getnstimeofday(struct timespec *tv);
120
extern void getrawmonotonic(struct timespec *ts);
120
extern void getboottime(struct timespec *ts);
121
extern void getboottime(struct timespec *ts);
121
extern void monotonic_to_bootbased(struct timespec *ts);
122
extern void monotonic_to_bootbased(struct timespec *ts);
122
123
Lines 214-219 struct itimerval { Link Here
214
#define CLOCK_MONOTONIC			1
215
#define CLOCK_MONOTONIC			1
215
#define CLOCK_PROCESS_CPUTIME_ID	2
216
#define CLOCK_PROCESS_CPUTIME_ID	2
216
#define CLOCK_THREAD_CPUTIME_ID		3
217
#define CLOCK_THREAD_CPUTIME_ID		3
218
#define CLOCK_MONOTONIC_RAW		4
217
219
218
/*
220
/*
219
 * The IDs of various hardware clocks:
221
 * The IDs of various hardware clocks:
(-)a/kernel/posix-timers.c (+15 lines)
Lines 223-228 static int posix_ktime_get_ts(clockid_t which_clock, struct timespec *tp) Link Here
223
}
223
}
224
224
225
/*
225
/*
226
 * Get monotonic time for posix timers
227
 */
228
static int posix_get_monotonic_raw(clockid_t which_clock, struct timespec *tp)
229
{
230
	getrawmonotonic(tp);
231
	return 0;
232
}
233
234
/*
226
 * Initialize everything, well, just everything in Posix clocks/timers ;)
235
 * Initialize everything, well, just everything in Posix clocks/timers ;)
227
 */
236
 */
228
static __init int init_posix_timers(void)
237
static __init int init_posix_timers(void)
Lines 235-243 static __init int init_posix_timers(void) Link Here
235
		.clock_get = posix_ktime_get_ts,
244
		.clock_get = posix_ktime_get_ts,
236
		.clock_set = do_posix_clock_nosettime,
245
		.clock_set = do_posix_clock_nosettime,
237
	};
246
	};
247
	struct k_clock clock_monotonic_raw = {
248
		.clock_getres = hrtimer_get_res,
249
		.clock_get = posix_get_monotonic_raw,
250
		.clock_set = do_posix_clock_nosettime,
251
	};
238
252
239
	register_posix_clock(CLOCK_REALTIME, &clock_realtime);
253
	register_posix_clock(CLOCK_REALTIME, &clock_realtime);
240
	register_posix_clock(CLOCK_MONOTONIC, &clock_monotonic);
254
	register_posix_clock(CLOCK_MONOTONIC, &clock_monotonic);
255
	register_posix_clock(CLOCK_MONOTONIC_RAW, &clock_monotonic_raw);
241
256
242
	posix_timers_cache = kmem_cache_create("posix_timers_cache",
257
	posix_timers_cache = kmem_cache_create("posix_timers_cache",
243
					sizeof (struct k_itimer), 0, SLAB_PANIC,
258
					sizeof (struct k_itimer), 0, SLAB_PANIC,
(-)a/kernel/time/timekeeping.c (+44 lines)
Lines 75-80 static void clocksource_forward_now(void) Link Here
75
75
76
	nsec = cyc2ns(clock, cycle_delta);
76
	nsec = cyc2ns(clock, cycle_delta);
77
	timespec_add_ns(&xtime, nsec);
77
	timespec_add_ns(&xtime, nsec);
78
79
	nsec = ((s64)cycle_delta * clock->mult_orig) >> clock->shift;
80
	clock->raw_time.tv_nsec += nsec;
78
}
81
}
79
82
80
/**
83
/**
Lines 183-188 static void change_clocksource(void) Link Here
183
186
184
	clocksource_forward_now();
187
	clocksource_forward_now();
185
188
189
	new->raw_time = clock->raw_time;
190
186
	clock = new;
191
	clock = new;
187
	clock->cycle_last = 0;
192
	clock->cycle_last = 0;
188
	clock->cycle_last = clocksource_read(new);
193
	clock->cycle_last = clocksource_read(new);
Lines 205-210 static inline void change_clocksource(void) { } Link Here
205
#endif
210
#endif
206
211
207
/**
212
/**
213
 * getrawmonotonic - Returns the raw monotonic time in a timespec
214
 * @ts:		pointer to the timespec to be set
215
 *
216
 * Returns the raw monotonic time (completely un-modified by ntp)
217
 */
218
void getrawmonotonic(struct timespec *ts)
219
{
220
	unsigned long seq;
221
	s64 nsecs;
222
	cycle_t cycle_now, cycle_delta;
223
224
	do {
225
		seq = read_seqbegin(&xtime_lock);
226
227
		/* read clocksource: */
228
		cycle_now = clocksource_read(clock);
229
230
		/* calculate the delta since the last update_wall_time: */
231
		cycle_delta = (cycle_now - clock->cycle_last) & clock->mask;
232
233
		/* convert to nanoseconds: */
234
		nsecs = ((s64)cycle_delta * clock->mult_orig) >> clock->shift;
235
236
		*ts = clock->raw_time;
237
238
	} while (read_seqretry(&xtime_lock, seq));
239
240
	timespec_add_ns(ts, nsecs);
241
}
242
EXPORT_SYMBOL(getrawmonotonic);
243
244
245
/**
208
 * timekeeping_valid_for_hres - Check if timekeeping is suitable for hres
246
 * timekeeping_valid_for_hres - Check if timekeeping is suitable for hres
209
 */
247
 */
210
int timekeeping_valid_for_hres(void)
248
int timekeeping_valid_for_hres(void)
Lines 466-471 void update_wall_time(void) Link Here
466
			second_overflow();
504
			second_overflow();
467
		}
505
		}
468
506
507
		clock->raw_time.tv_nsec += clock->raw_interval;
508
		if (clock->raw_time.tv_nsec >= NSEC_PER_SEC) {
509
			clock->raw_time.tv_nsec -= NSEC_PER_SEC;
510
			clock->raw_time.tv_sec++;
511
		}
512
469
		/* accumulate error between NTP and clock interval */
513
		/* accumulate error between NTP and clock interval */
470
		clock->error += tick_length;
514
		clock->error += tick_length;
471
		clock->error -= clock->xtime_interval << (NTP_SCALE_SHIFT - clock->shift);
515
		clock->error -= clock->xtime_interval << (NTP_SCALE_SHIFT - clock->shift);

Return to bug 11970