Fixes set_tls_desc() bug (XCC)
authorBarret Rhoden <brho@cs.berkeley.edu>
Wed, 26 Sep 2012 01:44:00 +0000 (18:44 -0700)
committerBarret Rhoden <brho@cs.berkeley.edu>
Wed, 26 Sep 2012 01:44:00 +0000 (18:44 -0700)
set_tls_desc() has historically set __vcoreid within the TLS to whatever
vcoreid it is being loaded on.  This was an ugly leftover from back in
the day.  It is necessary to do this for uthreads that are starting up
on a vcore (so they know which vcore it is), but we *never* want to do
this for vcore contexts.

This surfaced when handling_vc_preempt(), when we changed into a
remote vcore's TLS.  That would clobber their __vcoreid, which would lead
to all sorts of confusion (using the wrong MCS lock qnode, loading other
vcore TLSs instead of your own, telling uthread's the wrong vcoreid,
etc).

You need to rebuild glibc (copy over the edited file before building).

tests/eth_audio.c
tests/msr_get_cores.c
tests/msr_get_singlecore.c
tools/compilers/gcc-glibc/glibc-2.14.1-ros/sysdeps/ros/vcore-tls.c
user/c3po/threads/ucontext.c
user/parlib/uthread.c

index 6ce01c9..7e74b1c 100644 (file)
@@ -120,6 +120,7 @@ void vcore_entry(void)
        if (vcoreid == 0) {
                clear_notif_pending(vcoreid);
                set_tls_desc(core0_tls, 0);
+               assert(__vcoreid == 0); /* in case anyone uses this */
                /* Load silly state (Floating point) too */
                pop_ros_tf(&vcpd->notif_tf, vcoreid);
                printf("should never see me!");
index 0a92563..e9fc88c 100644 (file)
@@ -100,6 +100,7 @@ void vcore_entry(void)
        if (vcoreid == 0) {
                clear_notif_pending(vcoreid);
                set_tls_desc(core0_tls, 0);
+               assert(__vcoreid == 0); /* in case anyone uses this */
                /* Load silly state (Floating point) too */
                pop_ros_tf(&vcpd->notif_tf, vcoreid);
                panic("should never see me!");
index 176c8cb..e15f0f6 100644 (file)
@@ -101,6 +101,7 @@ void vcore_entry(void)
        if (vcoreid == 0) {
                clear_notif_pending(vcoreid);
                set_tls_desc(core0_tls, 0);
+               assert(__vcoreid == 0); /* in case anyone uses this */
                /* Load silly state (Floating point) too */
                pop_ros_tf(&vcpd->notif_tf, vcoreid);
                panic("should never see me!");
index 183fd80..13c877b 100644 (file)
@@ -5,7 +5,6 @@
 void set_tls_desc(void* addr, int vcoreid)
 {
        __set_tls_desc(addr, vcoreid);
-       __vcoreid = vcoreid;
 }
 
 void *get_tls_desc(int vcoreid)
index e821b1c..71567ad 100644 (file)
@@ -72,6 +72,8 @@ void restore_context(struct u_context *uc)
        current_thread = uc->thread;
        /* Set the proper tls descriptor for the context we are restoring */
     set_tls_desc(uc->tls_desc, vcoreid);
+       /* Tell the uthread which vcore it is on */
+       __vcoreid = vcoreid;
        /* Pop the trapframe */
        pop_ros_tf(&uc->utf, vcoreid);
 }
index 1c28709..77f1576 100644 (file)
@@ -53,6 +53,7 @@ static void uthread_manage_thread0(struct uthread *uthread)
                free(current_uthread);
        current_uthread = uthread;
        set_tls_desc(uthread->tls_desc, 0);
+       __vcoreid = 0;  /* setting the uthread's TLS var */
        assert(!in_vcore_context());
 }
 
@@ -382,6 +383,7 @@ static void __run_cur_uthread(void)
        }
        /* Go ahead and start the uthread */
        set_tls_desc(uthread->tls_desc, vcoreid);
+       __vcoreid = vcoreid;    /* setting the uthread's TLS var */
        /* Depending on where it was saved, we pop differently.  This assumes that
         * if a uthread was not saved, that it was running in the vcpd notif tf.
         * There should never be a time that the TF is unsaved and not in the notif
@@ -400,12 +402,14 @@ static void __run_cur_uthread(void)
  * yielding, etc. USE WITH EXTREME CAUTION! */
 void highjack_current_uthread(struct uthread *uthread)
 {
+       uint32_t vcoreid = vcore_id();
        assert(uthread != current_uthread);
        assert(uthread->tls_desc);
        current_uthread->state = UT_NOT_RUNNING;
        uthread->state = UT_RUNNING;
        vcore_set_tls_var(current_uthread, uthread);
-       set_tls_desc(uthread->tls_desc, vcore_id());
+       set_tls_desc(uthread->tls_desc, vcoreid);
+       __vcoreid = vcoreid;    /* setting the uthread's TLS var */
 }
 
 /* Runs whatever thread is vcore's current_uthread.  This is nothing but a
@@ -428,7 +432,6 @@ void run_current_uthread(void)
  * real run_cur_uth. */
 void run_uthread(struct uthread *uthread)
 {
-       uint32_t vcoreid = vcore_id();
        assert(uthread != current_uthread);
        if (uthread->state != UT_NOT_RUNNING) {
                /* had vcore3 throw this, when the UT blocked on vcore1 and didn't come
@@ -457,6 +460,7 @@ static void __run_current_uthread_raw(void)
        /* utf no longer represents the current state of the uthread */
        current_uthread->flags &= ~UTHREAD_SAVED;
        set_tls_desc(current_uthread->tls_desc, vcoreid);
+       __vcoreid = vcoreid;    /* setting the uthread's TLS var */
        /* Pop the user trap frame */
        pop_ros_tf_raw(&vcpd->notif_tf, vcoreid);
        assert(0);