Login
[x]
Log in using an account from:
Fedora Account System
Red Hat Associate
Red Hat Customer
Or login using a Red Hat Bugzilla account
Forgot Password
Login:
Hide Forgot
Create an Account
Red Hat Bugzilla – Attachment 152183 Details for
Bug 235940
[JAVA_BLOCKER] timekeeping starvation (sched_football hangs on RHEL5 RT)
[?]
New
Simple Search
Advanced Search
My Links
Browse
Requests
Reports
Current State
Search
Tabular reports
Graphical reports
Duplicates
Other Reports
User Changes
Plotly Reports
Bug Status
Bug Severity
Non-Defaults
|
Product Dashboard
Help
Page Help!
Bug Writing Guidelines
What's new
Browser Support Policy
5.0.4.rh83 Release notes
FAQ
Guides index
User guide
Web Services
Contact
Legal
This site requires JavaScript to be enabled to function correctly, please enable it.
[patch]
tested cycles-accumulated patch sent to Ingo
cycles-accumulated.patch (text/plain), 7.24 KB, created by
IBM Bug Proxy
on 2007-04-10 21:45:36 UTC
(
hide
)
Description:
tested cycles-accumulated patch sent to Ingo
Filename:
MIME Type:
Creator:
IBM Bug Proxy
Created:
2007-04-10 21:45:36 UTC
Size:
7.24 KB
patch
obsolete
> arch/x86_64/kernel/vsyscall.c | 5 ++++- > include/linux/clocksource.h | 40 ++++++++++++++++++++++++++++++++++++++-- > kernel/timer.c | 28 ++++++++++++---------------- > 3 files changed, 54 insertions(+), 19 deletions(-) > >linux-2.6.21-rc5_cycles-accumulated_C7.patch >============================================ >Index: 2.6-rt/arch/x86_64/kernel/vsyscall.c >=================================================================== >--- 2.6-rt.orig/arch/x86_64/kernel/vsyscall.c 2007-03-27 17:07:19.000000000 -0700 >+++ 2.6-rt/arch/x86_64/kernel/vsyscall.c 2007-03-28 16:56:48.000000000 -0700 >@@ -104,7 +104,7 @@ static __always_inline long time_syscall > > static __always_inline void do_vgettimeofday(struct timeval * tv) > { >- cycle_t now, base, mask, cycle_delta; >+ cycle_t now, base, accumulated, mask, cycle_delta; > unsigned long seq, mult, shift, nsec_delta; > cycle_t (*vread)(void); > >@@ -133,6 +133,7 @@ static __always_inline void do_vgettimeo > } > now = vread(); > base = __vsyscall_gtod_data.clock.cycle_last; >+ accumulated = __vsyscall_gtod_data.clock.cycle_accumulated; > mask = __vsyscall_gtod_data.clock.mask; > mult = __vsyscall_gtod_data.clock.mult; > shift = __vsyscall_gtod_data.clock.shift; >@@ -143,6 +144,8 @@ static __always_inline void do_vgettimeo > > /* calculate interval: */ > cycle_delta = (now - base) & mask; >+ cycle_delta += accumulated; >+ > /* convert to nsecs: */ > nsec_delta = (cycle_delta * mult) >> shift; > >Index: 2.6-rt/include/linux/clocksource.h >=================================================================== >--- 2.6-rt.orig/include/linux/clocksource.h 2007-03-28 16:56:14.000000000 -0700 >+++ 2.6-rt/include/linux/clocksource.h 2007-03-28 16:56:48.000000000 -0700 >@@ -51,8 +51,12 @@ extern cycle_t preempt_thresh; > * @shift: cycle to nanosecond divisor (power of two) > * @flags: flags describing special properties > * @vread: vsyscall based read >+ * @cycle_last: Used internally by timekeeping core, please ignore. >+ * @cycle_accumulated: Used internally by timekeeping core, please ignore. > * @cycle_interval: Used internally by timekeeping core, please ignore. > * @xtime_interval: Used internally by timekeeping core, please ignore. >+ * @xtime_nsec: Used internally by timekeeping core, please ignore. >+ * @error: Used internally by timekeeping core, please ignore. > */ > struct clocksource { > char *name; >@@ -66,7 +70,7 @@ struct clocksource { > cycle_t (*vread)(void); > > /* timekeeping specific data, ignore */ >- cycle_t cycle_last, cycle_interval; >+ cycle_t cycle_last, cycle_accumulated, cycle_interval; > u64 xtime_nsec, xtime_interval; > s64 error; > >@@ -152,11 +156,43 @@ static inline cycle_t clocksource_read(s > } > > /** >+ * clocksource_get_cycles: - Access the clocksource's accumulated cycle value >+ * @cs: pointer to clocksource being read >+ * @now: current cycle value >+ * >+ * Uses the clocksource to return the current cycle_t value. >+ * NOTE!!!: This is different from clocksource_read, because it >+ * returns the accumulated cycle value! Must hold xtime lock! >+ */ >+static inline cycle_t clocksource_get_cycles(struct clocksource *cs, cycle_t now) >+{ >+ cycle_t offset = (now - cs->cycle_last) & cs->mask; >+ offset += cs->cycle_accumulated; >+ return offset; >+} >+ >+/** >+ * clocksource_accumulate: - Accumulates clocksource cycles >+ * @cs: pointer to clocksource being read >+ * @now: current cycle value >+ * >+ * Used to avoids clocksource hardware overflow by periodically >+ * accumulating the current cycle delta. Must hold xtime write lock! >+ */ >+static inline void clocksource_accumulate(struct clocksource *cs, cycle_t now) >+{ >+ cycle_t offset = (now - cs->cycle_last) & cs->mask; >+ cs->cycle_last = now; >+ cs->cycle_accumulated += offset; >+} >+ >+/** > * cyc2ns - converts clocksource cycles to nanoseconds > * @cs: Pointer to clocksource > * @cycles: Cycles > * > * Uses the clocksource and ntp ajdustment to convert cycle_ts to nanoseconds. >+ * Must hold xtime lock! > * > * XXX - This could use some mult_lxl_ll() asm optimization > */ >@@ -186,7 +222,7 @@ static inline cycles_t ns2cyc(struct clo > * @length_nsec: Desired interval length in nanoseconds. > * > * Calculates a fixed cycle/nsec interval for a given clocksource/adjustment >- * pair and interval request. >+ * pair and interval request. Must hold xtime_lock! > * > * Unless you're the timekeeping code, you should not be using this! > */ >Index: 2.6-rt/kernel/timer.c >=================================================================== >--- 2.6-rt.orig/kernel/timer.c 2007-03-28 16:56:14.000000000 -0700 >+++ 2.6-rt/kernel/timer.c 2007-03-28 17:35:50.000000000 -0700 >@@ -863,16 +863,10 @@ static __read_mostly struct clocksource > */ > s64 __get_nsec_offset(void) > { >- cycle_t cycle_now, cycle_delta; >+ cycle_t cycle_delta; > s64 ns_offset; > >- /* read clocksource: */ >- cycle_now = clocksource_read(clock); >- >- /* calculate the delta since the last update_wall_time: */ >- cycle_delta = (cycle_now - clock->cycle_last) & clock->mask; >- >- /* convert to nanoseconds: */ >+ cycle_delta = clocksource_get_cycles(clock, clocksource_read(clock)); > ns_offset = cyc2ns(clock, cycle_delta); > > return ns_offset; >@@ -1058,7 +1052,7 @@ static void change_clocksource(void) > > clock = new; > clock->cycle_last = now; >- >+ clock->cycle_accumulated = 0; > clock->error = 0; > clock->xtime_nsec = 0; > clocksource_calculate_interval(clock, NTP_INTERVAL_LENGTH); >@@ -1158,6 +1152,7 @@ static int timekeeping_resume(struct sys > } > /* re-base the last cycle value */ > clock->cycle_last = clocksource_read(clock); >+ clock->cycle_accumulated = 0; > clock->error = 0; > timekeeping_suspended = 0; > warp_check_clock_was_changed(); >@@ -1302,27 +1297,28 @@ static void clocksource_adjust(s64 offse > */ > static void update_wall_time(void) > { >- cycle_t offset; >+ cycle_t cycle_now; > > /* Make sure we're fully resumed: */ > if (unlikely(timekeeping_suspended)) > return; > > #ifdef CONFIG_GENERIC_TIME >- offset = (clocksource_read(clock) - clock->cycle_last) & clock->mask; >+ cycle_now = clocksource_read(clock); > #else >- offset = clock->cycle_interval; >+ cycle_now = clock->cycle_last + clock->cycle_interval; > #endif >+ clocksource_accumulate(clock, cycle_now); >+ > clock->xtime_nsec += (s64)xtime.tv_nsec << clock->shift; > > /* normally this loop will run just once, however in the > * case of lost or late ticks, it will accumulate correctly. > */ >- while (offset >= clock->cycle_interval) { >+ while (clock->cycle_accumulated >= clock->cycle_interval) { > /* accumulate one interval */ > clock->xtime_nsec += clock->xtime_interval; >- clock->cycle_last += clock->cycle_interval; >- offset -= clock->cycle_interval; >+ clock->cycle_accumulated -= clock->cycle_interval; > > if (clock->xtime_nsec >= (u64)NSEC_PER_SEC << clock->shift) { > clock->xtime_nsec -= (u64)NSEC_PER_SEC << clock->shift; >@@ -1340,7 +1336,7 @@ static void update_wall_time(void) > } > > /* correct the clock when NTP error is too big */ >- clocksource_adjust(offset); >+ clocksource_adjust(clock->cycle_accumulated); > > /* store full nanoseconds into xtime */ > xtime.tv_nsec = (s64)clock->xtime_nsec >> clock->shift; >@@ -1507,6 +1503,9 @@ static void run_timer_softirq(struct sof > void do_timer(unsigned long ticks) > { > jiffies_64 += ticks; >+#ifdef CONFIG_GENERIC_TIME >+ clocksource_accumulate(clock, clocksource_read(clock)); >+#endif > #ifdef CONFIG_LEDS_TIMER > arch_tick_leds(); > #endif
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 235940
: 152183 |
153395