WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] Fix xtime_lock handling to avoid deadlock in sched_clock

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] Fix xtime_lock handling to avoid deadlock in sched_clock().
From: Xen patchbot -unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Fri, 05 Aug 2005 10:56:10 -0400
Delivery-date: Fri, 05 Aug 2005 14:56:41 +0000
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# 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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] Fix xtime_lock handling to avoid deadlock in sched_clock()., Xen patchbot -unstable <=