[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] Fix xtime_lock handling to avoid deadlock in sched_clock().
# HG changeset patch # User kaf24@xxxxxxxxxxxxxxxxxxxx # Node ID b63577ff53a3161ac73b55e0aa87803e76c8bde5 # Parent 5a33233a608e9d790228d03a23f3407988f1577f Fix xtime_lock handling to avoid deadlock in sched_clock(). Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx> diff -r 5a33233a608e -r b63577ff53a3 linux-2.6-xen-sparse/arch/xen/i386/kernel/time.c --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/time.c Fri Aug 5 09:53:04 2005 +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/time.c Fri Aug 5 14:57:43 2005 @@ -233,6 +233,10 @@ time_t wtm_sec, xtime_sec; u64 tmp, usec; + if ((shadow_tv.tv_sec == s->wc_sec) && + (shadow_tv.tv_usec == s->wc_usec)) + return; + shadow_tv.tv_sec = s->wc_sec; shadow_tv.tv_usec = s->wc_usec; @@ -263,9 +267,9 @@ /* * Reads a consistent set of time-base values from Xen, into a shadow data - * area. Must be called with the xtime_lock held for writing. - */ -static void __get_time_values_from_xen(void) + * area. + */ +static void get_time_values_from_xen(void) { shared_info_t *s = HYPERVISOR_shared_info; struct vcpu_time_info *src; @@ -286,10 +290,6 @@ while (dst->version != src->time_version1); dst->tsc_to_usec_mul = dst->tsc_to_nsec_mul / 1000; - - if ((shadow_tv.tv_sec != s->wc_sec) || - (shadow_tv.tv_usec != s->wc_usec)) - update_wallclock(); } static inline int time_values_up_to_date(int cpu) @@ -341,10 +341,10 @@ unsigned long seq; unsigned long usec, sec; unsigned long max_ntp_tick; - unsigned long flags; s64 nsec; unsigned int cpu; struct shadow_time_info *shadow; + u32 local_time_version; cpu = get_cpu(); shadow = &per_cpu(shadow_time, cpu); @@ -352,6 +352,7 @@ do { unsigned long lost; + local_time_version = shadow->version; seq = read_seqbegin(&xtime_lock); usec = get_usec_offset(shadow); @@ -387,12 +388,11 @@ * overflowed). Detect that and recalculate * with fresh values. */ - write_seqlock_irqsave(&xtime_lock, flags); - __get_time_values_from_xen(); - write_sequnlock_irqrestore(&xtime_lock, flags); + get_time_values_from_xen(); continue; } - } while (read_seqretry(&xtime_lock, seq)); + } while (read_seqretry(&xtime_lock, seq) || + (local_time_version != shadow->version)); put_cpu(); @@ -435,7 +435,7 @@ again: nsec = (s64)tv->tv_nsec - (s64)get_nsec_offset(shadow); if (unlikely(!time_values_up_to_date(cpu))) { - __get_time_values_from_xen(); + get_time_values_from_xen(); goto again; } @@ -517,21 +517,21 @@ { int cpu = get_cpu(); struct shadow_time_info *shadow = &per_cpu(shadow_time, cpu); - s64 off; - unsigned long flags; - - for ( ; ; ) { - off = get_nsec_offset(shadow); - if (time_values_up_to_date(cpu)) - break; - write_seqlock_irqsave(&xtime_lock, flags); - __get_time_values_from_xen(); - write_sequnlock_irqrestore(&xtime_lock, flags); - } + u64 time; + u32 local_time_version; + + do { + local_time_version = shadow->version; + smp_rmb(); + time = shadow->system_timestamp + get_nsec_offset(shadow); + if (!time_values_up_to_date(cpu)) + get_time_values_from_xen(); + smp_rmb(); + } while (local_time_version != shadow->version); put_cpu(); - return shadow->system_timestamp + off; + return time; } EXPORT_SYMBOL(monotonic_clock); @@ -565,7 +565,7 @@ struct shadow_time_info *shadow = &per_cpu(shadow_time, cpu); do { - __get_time_values_from_xen(); + get_time_values_from_xen(); delta = delta_cpu = shadow->system_timestamp + get_nsec_offset(shadow); @@ -602,6 +602,8 @@ update_process_times(user_mode(regs)); profile_tick(CPU_PROFILING, regs); } + + update_wallclock(); } /* @@ -788,7 +790,8 @@ return; } #endif - __get_time_values_from_xen(); + get_time_values_from_xen(); + update_wallclock(); xtime.tv_sec = shadow_tv.tv_sec; xtime.tv_nsec = shadow_tv.tv_usec * NSEC_PER_USEC; set_normalized_timespec(&wall_to_monotonic, @@ -872,7 +875,8 @@ init_cpu_khz(); /* Get timebases for new environment. */ - __get_time_values_from_xen(); + get_time_values_from_xen(); + update_wallclock(); /* Reset our own concept of passage of system time. */ processed_system_time = _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |