> > So the root cause is that we're stuck in gethrestime_sec() somehow.
> > gethrestime_sec() calls gethrestime() -> *gethrestimef() -> 
> > pc_gethrestime().
> >
> > http://cvs.opensolaris.org/source/xref/on/usr/src/uts/i86pc/os/machdep.c#pc_gethrestime
>
> Very interesting... Can you try adding two global variables
> and making both loops in pc_gethrestime() increment them
> individually so that we can find out where we're spinning.
> You can just look at the values of these variables after
> breaking into kmdb.

We're looping in the top loop, because "nslt" is negative:

    583 loop:
    584         lock_prev = hres_lock;
    585         now = hrestime;
    586         nslt = (int)(gethrtime() - hres_last_tick);
    587         if (nslt < 0) {
    588                 /*
    589                  * nslt < 0 means a tick came between sampling
    590                  * gethrtime() and hres_last_tick; restart the loop
    591                  */
    592 
    593                 goto loop;
    594         }

I've dumped the TSC register [*] for both cpu0 (in start_other_cpus()) and cpu1
(in mp_startup()), and the TSC for cpu1 is ahead ~ 0x1.0000.0000 clock
cycles compared to the TSC on cpu0!

TSC(0): 0x13b2406624
TSC(1): 0x14b83607b0

It seems when we're calling gethrtime() on cpu1, and compare the return value
to hres_last_tick (which was probably writen when hres_tick() was running on 
cpu0)
we get a big positive delta, which is casted to a 32-bit signed integer, which
makes the delta negative.

Some values that I dumped inside pc_gethrestime():

- gethrtime() return value: 0x8f54b0014
- hres_last_tick: 0x7faa6bcb2
- gethrtime() - hres_last_tick: 0xfaa44362
- (int)(gethrtime() - hres_last_tick) => -89898142

We're jumping to the to of the "loop:" and repeat the gethrtime()
call, but the  (int)(gethrtime() - hres_last_tick) expression is still a big
64-bit positive value casted to a negative 32-bit signed int, so we're
stuck in an endless loop.



====
[*]

diff -ru ../opensolaris-20060626/usr/src/uts/i86pc/os/mp_startup.c 
usr/src/uts/i86pc/os/mp_startup.c
--- ../opensolaris-20060626/usr/src/uts/i86pc/os/mp_startup.c   2006-06-27 
14:25:08.000000000 +0200
+++ usr/src/uts/i86pc/os/mp_startup.c   2006-07-05 10:53:02.646747548 +0200
@@ -64,6 +64,7 @@
 #include <sys/memnode.h>
 #include <sys/pci_cfgspace.h>
 #include <sys/cpu_module.h>
+#include <sys/promif.h>

 struct cpu     cpus[1];                        /* CPU data */
 struct cpu     *cpu[NCPU] = {&cpus[0]};        /* pointers to all CPUs */
@@ -978,6 +979,7 @@
                mp_startup_init(who);
                started_cpu = 1;
                (*cpu_startf)(who, rm_platter_pa);
+               prom_printf("TSC(%d) = %llx\n", CPU->cpu_id, tsc_read());

                while (!CPU_IN_SET(procset, who)) {

@@ -1130,6 +1132,7 @@
        cpuid_pass3(cp);
        (void) cpuid_pass4(cp);

+       prom_printf("TSC(%d) = %llx\n", CPU->cpu_id, tsc_read());
        init_cpu_info(cp);

        mutex_enter(&cpu_lock);
 
 
This message posted from opensolaris.org
_______________________________________________
opensolaris-code mailing list
[email protected]
http://mail.opensolaris.org/mailman/listinfo/opensolaris-code

Reply via email to