1250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner/* 2835c34a1687f524c37d4fb8bad18d642c74bed8dDave Jones * check TSC synchronization. 3250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner * 4250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner * Copyright (C) 2006, Red Hat, Inc., Ingo Molnar 5250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner * 6250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner * We check whether all boot CPUs have their TSC's synchronized, 7250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner * print a warning if not and turn off the TSC clock-source. 8250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner * 9250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner * The warp-check is point-to-point between two CPUs, the CPU 10250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner * initiating the bootup is the 'source CPU', the freshly booting 11250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner * CPU is the 'target CPU'. 12250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner * 13250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner * Only two CPUs may participate - they can enter in any order. 14250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner * ( The serial nature of the boot logic and the CPU hotplug lock 15250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner * protects against more than 2 CPUs entering this code. ) 16250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner */ 17250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner#include <linux/spinlock.h> 18250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner#include <linux/kernel.h> 19250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner#include <linux/init.h> 20250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner#include <linux/smp.h> 21250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner#include <linux/nmi.h> 22250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner#include <asm/tsc.h> 23250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner 24250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner/* 25250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner * Entry/exit counters that make sure that both CPUs 26250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner * run the measurement code at once: 27250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner */ 28250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixnerstatic __cpuinitdata atomic_t start_count; 29250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixnerstatic __cpuinitdata atomic_t stop_count; 30250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner 31250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner/* 32250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner * We use a raw spinlock in this exceptional case, because 33250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner * we want to have the fastest, inlined, non-debug version 34250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner * of a critical section, to be able to prove TSC time-warps: 35250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner */ 36edc35bd72e2079b25f99c5da7d7a65dbbffc4a26Thomas Gleixnerstatic __cpuinitdata arch_spinlock_t sync_lock = __ARCH_SPIN_LOCK_UNLOCKED; 37643bec956544d376b7c2a80a3d5c3d0bf94da8d3Ingo Molnar 38250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixnerstatic __cpuinitdata cycles_t last_tsc; 39250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixnerstatic __cpuinitdata cycles_t max_warp; 40250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixnerstatic __cpuinitdata int nr_warps; 41250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner 42250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner/* 43250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner * TSC-warp measurement loop running on both CPUs: 44250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner */ 45b0e5c77903fd717cc5eb02b7b8f5de3c869efc49Suresh Siddhastatic __cpuinit void check_tsc_warp(unsigned int timeout) 46250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner{ 47250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner cycles_t start, now, prev, end; 48250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner int i; 49250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner 5093ce99e849433ede4ce8b410b749dc0cad1100b2Venki Pallipadi rdtsc_barrier(); 516d63de8dbcda98511206897562ecfcdacf18f523Andi Kleen start = get_cycles(); 5293ce99e849433ede4ce8b410b749dc0cad1100b2Venki Pallipadi rdtsc_barrier(); 53250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner /* 54b0e5c77903fd717cc5eb02b7b8f5de3c869efc49Suresh Siddha * The measurement runs for 'timeout' msecs: 55250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner */ 56b0e5c77903fd717cc5eb02b7b8f5de3c869efc49Suresh Siddha end = start + (cycles_t) tsc_khz * timeout; 57250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner now = start; 58250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner 59250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner for (i = 0; ; i++) { 60250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner /* 61250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner * We take the global lock, measure TSC, save the 62250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner * previous TSC that was measured (possibly on 63250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner * another CPU) and update the previous TSC timestamp. 64250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner */ 650199c4e68d1f02894bdefe4b5d9e9ee4aedd8d62Thomas Gleixner arch_spin_lock(&sync_lock); 66250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner prev = last_tsc; 6793ce99e849433ede4ce8b410b749dc0cad1100b2Venki Pallipadi rdtsc_barrier(); 686d63de8dbcda98511206897562ecfcdacf18f523Andi Kleen now = get_cycles(); 6993ce99e849433ede4ce8b410b749dc0cad1100b2Venki Pallipadi rdtsc_barrier(); 70250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner last_tsc = now; 710199c4e68d1f02894bdefe4b5d9e9ee4aedd8d62Thomas Gleixner arch_spin_unlock(&sync_lock); 72250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner 73250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner /* 74250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner * Be nice every now and then (and also check whether 75df43510b18b8439465b4b58556f0495b5f5d771eIngo Molnar * measurement is done [we also insert a 10 million 76250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner * loops safety exit, so we dont lock up in case the 77250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner * TSC readout is totally broken]): 78250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner */ 79250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner if (unlikely(!(i & 7))) { 80df43510b18b8439465b4b58556f0495b5f5d771eIngo Molnar if (now > end || i > 10000000) 81250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner break; 82250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner cpu_relax(); 83250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner touch_nmi_watchdog(); 84250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner } 85250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner /* 86250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner * Outside the critical section we can now see whether 87250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner * we saw a time-warp of the TSC going backwards: 88250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner */ 89250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner if (unlikely(prev > now)) { 900199c4e68d1f02894bdefe4b5d9e9ee4aedd8d62Thomas Gleixner arch_spin_lock(&sync_lock); 91250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner max_warp = max(max_warp, prev - now); 92250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner nr_warps++; 930199c4e68d1f02894bdefe4b5d9e9ee4aedd8d62Thomas Gleixner arch_spin_unlock(&sync_lock); 94250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner } 95ad8ca495bd3e03e6751fc0c6a6af44018ebb4036Ingo Molnar } 96bde78a79a6eb015f33aa4660df1b06f5135def20Arjan van de Ven WARN(!(now-start), 97bde78a79a6eb015f33aa4660df1b06f5135def20Arjan van de Ven "Warning: zero tsc calibration delta: %Ld [max: %Ld]\n", 98ad8ca495bd3e03e6751fc0c6a6af44018ebb4036Ingo Molnar now-start, end-start); 99250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner} 100250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner 101250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner/* 102b0e5c77903fd717cc5eb02b7b8f5de3c869efc49Suresh Siddha * If the target CPU coming online doesn't have any of its core-siblings 103b0e5c77903fd717cc5eb02b7b8f5de3c869efc49Suresh Siddha * online, a timeout of 20msec will be used for the TSC-warp measurement 104b0e5c77903fd717cc5eb02b7b8f5de3c869efc49Suresh Siddha * loop. Otherwise a smaller timeout of 2msec will be used, as we have some 105b0e5c77903fd717cc5eb02b7b8f5de3c869efc49Suresh Siddha * information about this socket already (and this information grows as we 106b0e5c77903fd717cc5eb02b7b8f5de3c869efc49Suresh Siddha * have more and more logical-siblings in that socket). 107b0e5c77903fd717cc5eb02b7b8f5de3c869efc49Suresh Siddha * 108b0e5c77903fd717cc5eb02b7b8f5de3c869efc49Suresh Siddha * Ideally we should be able to skip the TSC sync check on the other 109b0e5c77903fd717cc5eb02b7b8f5de3c869efc49Suresh Siddha * core-siblings, if the first logical CPU in a socket passed the sync test. 110b0e5c77903fd717cc5eb02b7b8f5de3c869efc49Suresh Siddha * But as the TSC is per-logical CPU and can potentially be modified wrongly 111b0e5c77903fd717cc5eb02b7b8f5de3c869efc49Suresh Siddha * by the bios, TSC sync test for smaller duration should be able 112b0e5c77903fd717cc5eb02b7b8f5de3c869efc49Suresh Siddha * to catch such errors. Also this will catch the condition where all the 113b0e5c77903fd717cc5eb02b7b8f5de3c869efc49Suresh Siddha * cores in the socket doesn't get reset at the same time. 114b0e5c77903fd717cc5eb02b7b8f5de3c869efc49Suresh Siddha */ 115b0e5c77903fd717cc5eb02b7b8f5de3c869efc49Suresh Siddhastatic inline unsigned int loop_timeout(int cpu) 116b0e5c77903fd717cc5eb02b7b8f5de3c869efc49Suresh Siddha{ 117b0e5c77903fd717cc5eb02b7b8f5de3c869efc49Suresh Siddha return (cpumask_weight(cpu_core_mask(cpu)) > 1) ? 2 : 20; 118b0e5c77903fd717cc5eb02b7b8f5de3c869efc49Suresh Siddha} 119b0e5c77903fd717cc5eb02b7b8f5de3c869efc49Suresh Siddha 120b0e5c77903fd717cc5eb02b7b8f5de3c869efc49Suresh Siddha/* 121250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner * Source CPU calls into this - it waits for the freshly booted 122250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner * target CPU to arrive and then starts the measurement: 123250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner */ 124250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixnervoid __cpuinit check_tsc_sync_source(int cpu) 125250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner{ 126250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner int cpus = 2; 127250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner 128250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner /* 129250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner * No need to check if we already know that the TSC is not 130250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner * synchronized: 131250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner */ 132250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner if (unsynchronized_tsc()) 133250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner return; 134250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner 13528a00184be261e3dc152ba0d664a067bbe235b6aSuresh Siddha if (tsc_clocksource_reliable) { 1369b3660a55a9052518c91cc7c62d89e22f3f6f490Mike Travis if (cpu == (nr_cpu_ids-1) || system_state != SYSTEM_BOOTING) 1379b3660a55a9052518c91cc7c62d89e22f3f6f490Mike Travis pr_info( 1389b3660a55a9052518c91cc7c62d89e22f3f6f490Mike Travis "Skipped synchronization checks as TSC is reliable.\n"); 139eca0cd028bdf0f6aaceb0d023e9c7501079a7ddaAlok Kataria return; 140eca0cd028bdf0f6aaceb0d023e9c7501079a7ddaAlok Kataria } 141eca0cd028bdf0f6aaceb0d023e9c7501079a7ddaAlok Kataria 142250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner /* 143250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner * Reset it - in case this is a second bootup: 144250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner */ 145250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner atomic_set(&stop_count, 0); 146250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner 147250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner /* 148250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner * Wait for the target to arrive: 149250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner */ 150250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner while (atomic_read(&start_count) != cpus-1) 151250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner cpu_relax(); 152250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner /* 153250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner * Trigger the target to continue into the measurement too: 154250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner */ 155250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner atomic_inc(&start_count); 156250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner 157b0e5c77903fd717cc5eb02b7b8f5de3c869efc49Suresh Siddha check_tsc_warp(loop_timeout(cpu)); 158250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner 159250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner while (atomic_read(&stop_count) != cpus-1) 160250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner cpu_relax(); 161250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner 162250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner if (nr_warps) { 1639b3660a55a9052518c91cc7c62d89e22f3f6f490Mike Travis pr_warning("TSC synchronization [CPU#%d -> CPU#%d]:\n", 1649b3660a55a9052518c91cc7c62d89e22f3f6f490Mike Travis smp_processor_id(), cpu); 165643bec956544d376b7c2a80a3d5c3d0bf94da8d3Ingo Molnar pr_warning("Measured %Ld cycles TSC warp between CPUs, " 166643bec956544d376b7c2a80a3d5c3d0bf94da8d3Ingo Molnar "turning off TSC clock.\n", max_warp); 167250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner mark_tsc_unstable("check_tsc_sync_source failed"); 168250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner } else { 1699b3660a55a9052518c91cc7c62d89e22f3f6f490Mike Travis pr_debug("TSC synchronization [CPU#%d -> CPU#%d]: passed\n", 1709b3660a55a9052518c91cc7c62d89e22f3f6f490Mike Travis smp_processor_id(), cpu); 171250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner } 172250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner 173250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner /* 1744c6b8b4d62fb4cb843c32db71e0a8301039908f3Mike Galbraith * Reset it - just in case we boot another CPU later: 1754c6b8b4d62fb4cb843c32db71e0a8301039908f3Mike Galbraith */ 1764c6b8b4d62fb4cb843c32db71e0a8301039908f3Mike Galbraith atomic_set(&start_count, 0); 1774c6b8b4d62fb4cb843c32db71e0a8301039908f3Mike Galbraith nr_warps = 0; 1784c6b8b4d62fb4cb843c32db71e0a8301039908f3Mike Galbraith max_warp = 0; 1794c6b8b4d62fb4cb843c32db71e0a8301039908f3Mike Galbraith last_tsc = 0; 1804c6b8b4d62fb4cb843c32db71e0a8301039908f3Mike Galbraith 1814c6b8b4d62fb4cb843c32db71e0a8301039908f3Mike Galbraith /* 182250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner * Let the target continue with the bootup: 183250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner */ 184250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner atomic_inc(&stop_count); 185250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner} 186250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner 187250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner/* 188250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner * Freshly booted CPUs call into this: 189250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner */ 190250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixnervoid __cpuinit check_tsc_sync_target(void) 191250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner{ 192250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner int cpus = 2; 193250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner 19428a00184be261e3dc152ba0d664a067bbe235b6aSuresh Siddha if (unsynchronized_tsc() || tsc_clocksource_reliable) 195250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner return; 196250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner 197250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner /* 198250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner * Register this CPU's participation and wait for the 199250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner * source CPU to start the measurement: 200250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner */ 201250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner atomic_inc(&start_count); 202250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner while (atomic_read(&start_count) != cpus) 203250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner cpu_relax(); 204250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner 205b0e5c77903fd717cc5eb02b7b8f5de3c869efc49Suresh Siddha check_tsc_warp(loop_timeout(smp_processor_id())); 206250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner 207250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner /* 208250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner * Ok, we are done: 209250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner */ 210250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner atomic_inc(&stop_count); 211250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner 212250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner /* 213250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner * Wait for the source CPU to print stuff: 214250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner */ 215250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner while (atomic_read(&stop_count) != cpus) 216250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner cpu_relax(); 217250c22777fe1ccd7ac588579a6c16db4c0161cc5Thomas Gleixner} 218