linux/kernel/stop_machine.c
<<
> "v3/spaval "v3/formal "v3a > "v href="../linux+v3t12 > "v3img src="../.static/gfx/right.png" alt=">>"> >3/spaval >3spav class="lxr_search"> > > "v3input typ> hidden" nam> navtarget" > "> > "v3input typ> text" nam> search" id search"> > "v3butt16"typ> submit">Search3spav class="lxr_prefs"al "v3a href="+prefs?return=kernel/stop_machine.c" > "v onclick="return ajax_prefs();"> > "vPrefsl "v3/a> >3/spaval "v v3/dival "v v3form acon v="ajax+*" method="post" onsubmit="return false;"> >3input typ> hidden" nam> ajax_lookup" id ajax_lookup" > "> "v v3/formal "v v3div class="headingbott1m">l 3div id file_contents"a
 L1">v v13/a>3spav class="comment">/*3/spaval
 L2">v v23/a>3spav class="comment"> * kernel/stop_machine.c3/spaval
 L3">v v33/a>3spav class="comment"> *3/spaval
 L4">v v43/a>3spav class="comment"> * Copyright (C) 2008, 2005 "v vIBM Corporaon v.3/spaval
 L5">v v53/a>3spav class="comment"> * Copyright (C) 2008, 2005 "v vRustyvRussell rusty@rustcorp.com.au3/spaval
 L6">v v63/a>3spav class="comment"> * Copyright (C) 2010           SUSE LinuxvProducts GmbH3/spaval
 L7">v v73/a>3spav class="comment"> * Copyright (C) 2010           Tejun Heo <tj@kernel.org>3/spaval
 L8">v v83/a>3spav class="comment"> *3/spaval
 L9">v v93/a>3spav class="comment"> * This file is released under the GPLv2 and any later versn v.3/spaval
 L10">v  3spav class="comment"> */3/spaval
 L11">v 113/a>#include <linux/compleon v.h3/a>>l
 L12">v 123/a>#include <linux/cpu.h3/a>>l
 L13">v 133/a>#include <linux/init.h3/a>>l
 L14">v 143/a>#include <linux/kthread.h3/a>>l
 L15">v 153/a>#include <linux/export.h3/a>>l
 L16">v 163/a>#include <linux/percpu.h3/a>>l
 L17">v 173/a>#include <linux/sched.h3/a>>l
 L18">v 183/a>#include <linux/stop_machine.h3/a>>l
 L19">v 193/a>#include <linux/interrupt.h3/a>>l
 L20">v 203/a>#include <linux/kallsyms.h3/a>>l
 L21">v 213/a>#include <linux/smpboot.h3/a>>l
 L22">v 223/a>#include <linux/at1mic.h3/a>>l
 L23">v 233/a>l
 L24">v 243/a>3spav class="comment">/*3/spaval
 L25">v 253/a>3spav class="comment"> * Structure to determine compleon v condion v and record errors.  May3/spaval
 L26">v 263/a>3spav class="comment"> * be shared by works  v different cpus.3/spaval
 L27">v 273/a>3spav class="comment"> */3/spaval
 L28">v 283/a>structv3a href="+code=cpu_stop_done" class="sref">cpu_stop_done3/a> {l
 L29">v 293/a>        3a href="+code=at1mic_t" class="sref">at1mic_t3/a>                3a href="+code=nr_todo" class="sref">nr_todo3/a>;        3spav class="comment">/* nr left to execute */3/spaval
 L30">v 303/a>        3a href="+code=bool" class="sref">bool3/a>                    3a href="+code=executed" class="sref">executed3/a>;       3spav class="comment">/* actually executed? */3/spaval
 L31">v 313/a>        int                     3a href="+code=ret" class="sref">ret3/a>;            3spav class="comment">/* collected return 
	  > */3/spaval
 L32">v 323/a>        structv3a href="+code=compleon v" class="sref">compleon v3/a>       3a href="+code=compleon v" class="sref">compleon v3/a>;     3spav class="comment">/* fired if nr_todo reaches 0 */3/spaval
 L33">v 333/a>};l
 L34">v 343/a>l
 L35">v 353/a>3spav class="comment">/* the actual stopper,  ve per every possible cpu, enabled  v online cpus */3/spaval
 L36">v 363/a>structv3a href="+code=cpu_stopper" class="sref">cpu_stopper3/a> {l
 L37">v 373/a>        3a href="+code=spinlock_t" class="sref">spinlock_t3/a>              3a href="+code=lock" class="sref">lock3/a>;l
 L38">v 383/a>        3a href="+code=bool" class="sref">bool3/a>                    3a href="+code=enabled" class="sref">enabled3/a>;        3spav class="comment">/* is this stopper enabled? */3/spaval
 L39">v 393/a>        structv3a href="+code=list_head" class="sref">list_head3/a>        3a href="+code=works" class="sref">works3/a>;          3spav class="comment">/* list of pending works */3/spaval
 L40">v 403/a>};l
 L41">v 413/a>l
 L42">v 423/a>static 3a href="+code=DEFINE_PER_CPU" class="sref">DEFINE_PER_CPU3/a>(structv3a href="+code=cpu_stopper" class="sref">cpu_stopper3/a>,v3a href="+code=cpu_stopper" class="sref">cpu_stopper3/a>);l
 L43">v 433/a>static 3a href="+code=DEFINE_PER_CPU" class="sref">DEFINE_PER_CPU3/a>(structv3a href="+code=task_struct" class="sref">task_struct3/a> *,v3a href="+code=cpu_stopper_task" class="sref">cpu_stopper_task3/a>);l
 L44">v 443/a>static 3a href="+code=bool" class="sref">bool3/a> 3a href="+code=stop_machine_initialized" class="sref">stop_machine_initialized3/a> = 3a href="+code=false" class="sref">false3/a>;l
 L45">v 453/a>l
 L46">v 463/a>static voidv3a href="+code=cpu_stop_init_done" class="sref">cpu_stop_init_done3/a>(structv3a href="+code=cpu_stop_done" class="sref">cpu_stop_done3/a> *3a href="+code=done" class="sref">done3/a>, unsigned intv3a href="+code=nr_todo" class="sref">nr_todo3/a>)l
 L47">v 473/a>{l
 L48">v 483/a>        3a href="+code=memset" class="sref">memset3/a>(3a href="+code=done" class="sref">done3/a>, 0, sizeof(*3a href="+code=done" class="sref">done3/a>));l
 L49">v 493/a>        3a href="+code=at1mic_set" class="sref">at1mic_set3/a>(&3a href="+code=done" class="sref">done3/a>->3a href="+code=nr_todo" class="sref">nr_todo3/a>,v3a href="+code=nr_todo" class="sref">nr_todo3/a>);l
 L50">v 503/a>        3a href="+code=init_compleon v" class="sref">init_compleon v3/a>(&3a href="+code=done" class="sref">done3/a>->3a href="+code=compleon v" class="sref">compleon v3/a>);l
 L51">v 513/a>}l
 L52">v 523/a>l
 L53">v 533/a>3spav class="comment">/* signal compleon v unless @done is NULL */3/spaval
 L54">v 543/a>static voidv3a href="+code=cpu_stop_signal_done" class="sref">cpu_stop_signal_done3/a>(structv3a href="+code=cpu_stop_done" class="sref">cpu_stop_done3/a> *3a href="+code=done" class="sref">done3/a>, 3a href="+code=bool" class="sref">bool3/a> 3a href="+code=executed" class="sref">executed3/a>)l
 L55">v 553/a>{l
 L56">v 563/a>        if (3a href="+code=done" class="sref">done3/a>) {l
 L57">v 573/a>                if (3a href="+code=executed" class="sref">executed3/a>)l
 L58">v 583/a>                        3a href="+code=done" class="sref">done3/a>->3a href="+code=executed" class="sref">executed3/a> = 3a href="+code=true" class="sref">true3/a>;l
 L59">v 593/a>                if (3a href="+code=at1mic_dec_and_test" class="sref">at1mic_dec_and_test3/a>(&3a href="+code=done" class="sref">done3/a>->3a href="+code=nr_todo" class="sref">nr_todo3/a>))l
 L60">v 603/a>                        3a href="+code=compleoe" class="sref">compleoe3/a>(&3a href="+code=done" class="sref">done3/a>->3a href="+code=compleon v" class="sref">compleon v3/a>);l
 L61">v 613/a>        }l
 L62">v 623/a>}l
 L63">v 633/a>l
 L64">v 643/a>3spav class="comment">/* queue @work to @stopper.  if offline, @work is compleoed immediately */3/spaval
 L65">v 653/a>static voidv3a href="+code=cpu_stop_queue_work" class="sref">cpu_stop_queue_work3/a>(unsigned intv3a href="+code=cpu" class="sref">cpu3/a>, structv3a href="+code=cpu_stop_work" class="sref">cpu_stop_work3/a> *3a href="+code=work" class="sref">work3/a>)l
 L66">v 663/a>{l
 L67">v 673/a>        structv3a href="+code=cpu_stopper" class="sref">cpu_stopper3/a> *3a href="+code=stopper" class="sref">stopper3/a> = &3a href="+code=per_cpu" class="sref">per_cpu3/a>(3a href="+code=cpu_stopper" class="sref">cpu_stopper3/a>,v3a href="+code=cpu" class="sref">cpu3/a>);l
 L68">v 683/a>        structv3a href="+code=task_struct" class="sref">task_struct3/a> *3a href="+code=p" class="sref">p3/a> = 3a href="+code=per_cpu" class="sref">per_cpu3/a>(3a href="+code=cpu_stopper_task" class="sref">cpu_stopper_task3/a>,v3a href="+code=cpu" class="sref">cpu3/a>);l
 L69">v 693/a>l
 L70">v 703/a>        unsigned long 3a href="+code=flags" class="sref">flags3/a>;l
 L71">v 713/a>l
 L72">v 723/a>        3a href="+code=spin_lock_irqsave" class="sref">spin_lock_irqsave3/a>(&3a href="+code=stopper" class="sref">stopper3/a>->3a href="+code=lock" class="sref">lock3/a>,v3a href="+code=flags" class="sref">flags3/a>);l
 L73">v 733/a>l
 L74">v 743/a>        if (3a href="+code=stopper" class="sref">stopper3/a>->3a href="+code=enabled" class="sref">enabled3/a>) {l
 L75">v 753/a>                3a href="+code=list_add_tail" class="sref">list_add_tail3/a>(&3a href="+code=work" class="sref">work3/a>->3a href="+code=list" class="sref">list3/a>,v&3a href="+code=stopper" class="sref">stopper3/a>->3a href="+code=works" class="sref">works3/a>);l
 L76">v 763/a>                3a href="+code=wake_up_process" class="sref">wake_up_process3/a>(3a href="+code=p" class="sref">p3/a>);l
 L77">v 773/a>        } elsel
 L78">v 783/a>                3a href="+code=cpu_stop_signal_done" class="sref">cpu_stop_signal_done3/a>(3a href="+code=work" class="sref">work3/a>->3a href="+code=done" class="sref">done3/a>, 3a href="+code=false" class="sref">false3/a>);l
 L79">v 793/a>l
 L80">v 803/a>        3a href="+code=spin_unlock_irqrestore" class="sref">spin_unlock_irqrestore3/a>(&3a href="+code=stopper" class="sref">stopper3/a>->3a href="+code=lock" class="sref">lock3/a>,v3a href="+code=flags" class="sref">flags3/a>);l
 L81">v 813/a>}l
 L8>v 72823/a>lv 7383" class="line" nam>
 L83">v 833/a>3spav class="comment">/**3/spaval
 L84">v 843/a>3spav class="comment"> * stop_one_cpu - stop a cpu3/spaval
 L85">v 853/a>3spav class="comment"> * @cpu: cpu to stop3/spaval
 L86">v 863/a>3spav class="comment"> * @fn: funcon v to execute3/spaval
 L87">v 873/a>3spav class="comment"> * @arg: argument to @fn3/spaval
 L88">v 883/a>3spav class="comment"> *3/spaval
 L89">v 893/a>3spav class="comment"> * Execute @fn(@arg)  v @cpu.  @fn is run in a process context with3/spaval
 L90">v 93spav class="comment"> * the highest priority preempting any task  v the cpu and3/spaval
 L91">v 913/a>3spav class="comment"> * monopolizing it.  This funcon v returns after the executn v is3/spaval
 L9>v 72923/a>3spav class="comment"> * compleoe.3/spavalv 7393" class="line" nam>
 L93">v 933/a>3spav class="comment"> *3/spaval
 L94">v 943/a>3spav class="comment"> * This funcon v doesn't guarantee @cpu stays online till @fn3/spaval
 L95">v 953/a>3spav class="comment"> * compleoes.  If @cpu goes down in the middle, executn v may happen3/spaval
 L96">v 963/a>3spav class="comment"> * partially or fully ov different cpus.  @fn should either be ready3/spaval
 L97">v 973/a>3spav class="comment"> * for that or the caller should ensure that @cpu stays online until3/spaval
 L98">v 983/a>3spav class="comment"> * this funcon v compleoes.3/spaval
 L99">v 993/a>3spav class="comment"> *3/spaval
 L100">v1003/a>3spav class="comment"> * CONTEXT:3/spaval
 L101">v1013/a>3spav class="comment"> * Might sleep.3/spaval
 L102">v1023/a>3spav class="comment"> *3/spaval
 L103">v1033/a>3spav class="comment"> * RETURNS:3/spaval
 L104">v1043/a>3spav class="comment"> * -ENOENT if @fn(@arg) was not executed because @cpu was offline;3/spaval
 L105">v1053/a>3spav class="comment"> * otherwise, the return 
	  > of @fn.3/spaval
 L106">v1063/a>3spav class="comment"> */3/spaval
 L107">v1073/a>intv3a href="+code=stop_one_cpu" class="sref">stop_one_cpu3/a>(unsigned intv3a href="+code=cpu" class="sref">cpu3/a>, 3a href="+code=cpu_stop_fn_t" class="sref">cpu_stop_fn_t3/a> 3a href="+code=fv" class="sref">fn3/a>, voidv*3a href="+code=arg" class="sref">arg3/a>)l
 L108">v1083/a>{l
 L109">v1093/a>        structv3a href="+code=cpu_stop_done" class="sref">cpu_stop_done3/a> 3a href="+code=done" class="sref">done3/a>;l
 L110">v1103/a>        structv3a href="+code=cpu_stop_work" class="sref">cpu_stop_work3/a> 3a href="+code=work" class="sref">work3/a> = { .3a href="+code=fv" class="sref">fn3/a> = 3a href="+code=fv" class="sref">fn3/a>, .3a href="+code=arg" class="sref">arg3/a> = 3a href="+code=arg" class="sref">arg3/a>, .3a href="+code=done" class="sref">done3/a> = &3a href="+code=done" class="sref">done3/a> };l
 L111">v1113/a>l
 L112">v1123/a>        3a href="+code=cpu_stop_init_done" class="sref">cpu_stop_init_done3/a>(&3a href="+code=done" class="sref">done3/a>, 1);l
 L113">v1133/a>        3a href="+code=cpu_stop_queue_work" class="sref">cpu_stop_queue_work3/a>(3a href="+code=cpu" class="sref">cpu3/a>, &3a href="+code=work" class="sref">work3/a>);l
 L114">v1143/a>        3a href="+code=wait_for_compleon v" class="sref">wait_for_compleon v3/a>(&3a href="+code=done" class="sref">done3/a>.3a href="+code=compleon v" class="sref">compleon v3/a>);l
 L115">v1153/a>        return 3a href="+code=done" class="sref">done3/a>.3a href="+code=executed" class="sref">executed3/a> ? 3a href="+code=done" class="sref">done3/a>.3a href="+code=ret" class="sref">ret3/a> : -3a href="+code=ENOENT" class="sref">ENOENT3/a>;l
 L116">v1163/a>}l
 L117">v1173/a>l
 L118">v1183/a>3spav class="comment">/**3/spaval
 L119">v1193/a>3spav class="comment"> * stop_one_cpu_nowait - stop a cpu but don't wait for compleon v3/spaval
 L120">v1203/a>3spav class="comment"> * @cpu: cpu to stop3/spaval
 L121">v1213/a>3spav class="comment"> * @fn: funcon v to execute3/spaval
 L122">v1223/a>3spav class="comment"> * @arg: argument to @fn3/spaval
 L123">v1233/a>3spav class="comment"> *3/spaval
 L124">v1243/a>3spav class="comment"> * Similar to stop_one_cpu() but doesn't wait for compleon v.  The3/spaval
 L125">v1253/a>3spav class="comment"> * caller is responsible for ensuring @work_buf is currently unused3/spaval
 L126">v1263/a>3spav class="comment"> * and will remaiv untouched until stopper starts executnng @fn.3/spaval
 L127">v1273/a>3spav class="comment"> *3/spaval
 L128">v1283/a>3spav class="comment"> * CONTEXT:3/spaval
 L129">v1293/a>3spav class="comment"> * Don't care.3/spaval
 L130">v133spav class="comment"> */3/spaval
 L131">v1313/a>voidv3a href="+code=stop_one_cpu_nowait" class="sref">stop_one_cpu_nowait3/a>(unsigned intv3a href="+code=cpu" class="sref">cpu3/a>, 3a href="+code=cpu_stop_fn_t" class="sref">cpu_stop_fn_t3/a> 3a href="+code=fv" class="sref">fn3/a>, voidv*3a href="+code=arg" class="sref">arg3/a>,l
 L132">v1323/a>                        structv3a href="+code=cpu_stop_work" class="sref">cpu_stop_work3/a> *3a href="+code=work_buf" class="sref">work_buf3/a>)l
 L133">v1333/a>{l
 L134">v1343/a>        *3a href="+code=work_buf" class="sref">work_buf3/a> = (structv3a href="+code=cpu_stop_work" class="sref">cpu_stop_work3/a>){ .3a href="+code=fv" class="sref">fn3/a> = 3a href="+code=fv" class="sref">fn3/a>, .3a href="+code=arg" class="sref">arg3/a> = 3a href="+code=arg" class="sref">arg3/a>, };l
 L135">v1353/a>        3a href="+code=cpu_stop_queue_work" class="sref">cpu_stop_queue_work3/a>(3a href="+code=cpu" class="sref">cpu3/a>, 3a href="+code=work_buf" class="sref">work_buf3/a>);l
 L136">v1363/a>}l
 L137">v1373/a>l
 L138">v1383/a>3spav class="comment">/* static data for stop_cpus */3/spaval
 L139">v1393/a>static 3a href="+code=DEFINE_MUTEX" class="sref">DEFINE_MUTEX3/a>(3a href="+code=stop_cpus_mutex" class="sref">stop_cpus_mutex3/a>);l
 L140">v1403/a>static 3a href="+code=DEFINE_PER_CPU" class="sref">DEFINE_PER_CPU3/a>(structv3a href="+code=cpu_stop_work" class="sref">cpu_stop_work3/a>, 3a href="+code=stop_cpus_work" class="sref">stop_cpus_work3/a>);l
 L141">v1413/a>l
 L142">v1423/a>static voidv3a href="+code=queue_stop_cpus_work" class="sref">queue_stop_cpus_work3/a>(const structv3a href="+code=cpumask" class="sref">cpumask3/a> *3a href="+code=cpumask" class="sref">cpumask3/a>,l
 L143">v1433/a>                                 3a href="+code=cpu_stop_fn_t" class="sref">cpu_stop_fn_t3/a> 3a href="+code=fv" class="sref">fn3/a>, voidv*3a href="+code=arg" class="sref">arg3/a>,l
 L144">v1443/a>                                 structv3a href="+code=cpu_stop_done" class="sref">cpu_stop_done3/a> *3a href="+code=done" class="sref">done3/a>)l
 L145">v1453/a>{l
 L146">v1463/a>        structv3a href="+code=cpu_stop_work" class="sref">cpu_stop_work3/a> *3a href="+code=work" class="sref">work3/a>;l
 L147">v1473/a>        unsigned intv3a href="+code=cpu" class="sref">cpu3/a>;l
 L148">v1483/a>l
 L149">v1493/a>        3spav class="comment">/* initialize works and done */3/spaval
 L150">v1503/a>        3a href="+code=for_each_cpu" class="sref">for_each_cpu3/a>(3a href="+code=cpu" class="sref">cpu3/a>, 3a href="+code=cpumask" class="sref">cpumask3/a>) {l
 L151">v1513/a>                3a href="+code=work" class="sref">work3/a> = &3a href="+code=per_cpu" class="sref">per_cpu3/a>(3a href="+code=stop_cpus_work" class="sref">stop_cpus_work3/a>,v3a href="+code=cpu" class="sref">cpu3/a>);l
 L152">v1523/a>                3a href="+code=work" class="sref">work3/a>->3a href="+code=fv" class="sref">fn3/a> = 3a href="+code=fv" class="sref">fn3/a>;l
 L153">v1533/a>                3a href="+code=work" class="sref">work3/a>->3a href="+code=arg" class="sref">arg3/a> = 3a href="+code=arg" class="sref">arg3/a>;l
 L154">v1543/a>                3a href="+code=work" class="sref">work3/a>->3a href="+code=done" class="sref">done3/a> = 3a href="+code=done" class="sref">done3/a>;l
 L155">v1553/a>        }l
 L156">v1563/a>l
 L157">v1573/a>        3spav class="comment">/*3/spaval
 L158">v1583/a>3spav class="comment">         * Disable preemption while queuenng to avoidvgettnng3/spaval
 L159">v1593/a>3spav class="comment">         * preempted by a stopper which might wait for other stoppers3/spaval
 L160">v163spav class="comment">         * to enter @fn which cav lead to deadlock.3/spaval
 L161">v1613/a>3spav class="comment">         */3/spaval
 L162">v1623/a>        3a href="+code=preempt_disable" class="sref">preempt_disable3/a>();l
 L163">v1633/a>        3a href="+code=for_each_cpu" class="sref">for_each_cpu3/a>(3a href="+code=cpu" class="sref">cpu3/a>, 3a href="+code=cpumask" class="sref">cpumask3/a>)l
 L164">v1643/a>                3a href="+code=cpu_stop_queue_work" class="sref">cpu_stop_queue_work3/a>(3a href="+code=cpu" class="sref">cpu3/a>, &3a href="+code=per_cpu" class="sref">per_cpu3/a>(3a href="+code=stop_cpus_work" class="sref">stop_cpus_work3/a>,v3a href="+code=cpu" class="sref">cpu3/a>));l
 L165">v1653/a>        3a href="+code=preempt_enable" class="sref">preempt_enable3/a>();l
 L166">v1663/a>}l
 L167">v1673/a>l
 L168">v1683/a>static intv3a href="+code=__stop_cpus" class="sref">__stop_cpus3/a>(const structv3a href="+code=cpumask" class="sref">cpumask3/a> *3a href="+code=cpumask" class="sref">cpumask3/a>,l
 L169">v1693/a>                       3a href="+code=cpu_stop_fn_t" class="sref">cpu_stop_fn_t3/a> 3a href="+code=fv" class="sref">fn3/a>, voidv*3a href="+code=arg" class="sref">arg3/a>)l
 L170">v1703/a>{l
 L171">v1713/a>        structv3a href="+code=cpu_stop_done" class="sref">cpu_stop_done3/a> 3a href="+code=done" class="sref">done3/a>;l
 L172">v1723/a>l
 L173">v1733/a>        3a href="+code=cpu_stop_init_done" class="sref">cpu_stop_init_done3/a>(&3a href="+code=done" class="sref">done3/a>, 3a href="+code=cpumask_weight" class="sref">cpumask_weight3/a>(3a href="+code=cpumask" class="sref">cpumask3/a>));l
 L174">v1743/a>        3a href="+code=queue_stop_cpus_work" class="sref">queue_stop_cpus_work3/a>(3a href="+code=cpumask" class="sref">cpumask3/a>, 3a href="+code=fv" class="sref">fn3/a>, 3a href="+code=arg" class="sref">arg3/a>, &3a href="+code=done" class="sref">done3/a>);l
 L175">v1753/a>        3a href="+code=wait_for_compleon v" class="sref">wait_for_compleon v3/a>(&3a href="+code=done" class="sref">done3/a>.3a href="+code=compleon v" class="sref">compleon v3/a>);l
 L176">v1763/a>        return 3a href="+code=done" class="sref">done3/a>.3a href="+code=executed" class="sref">executed3/a> ? 3a href="+code=done" class="sref">done3/a>.3a href="+code=ret" class="sref">ret3/a> : -3a href="+code=ENOENT" class="sref">ENOENT3/a>;l
 L177">v1773/a>}l
 L178">v1783/a>l
 L179">v1793/a>3spav class="comment">/**3/spaval
 L180">v1803/a>3spav class="comment"> * stop_cpus - stop multiple cpus3/spaval
 L181">v1813/a>3spav class="comment"> * @cpumask: cpus to stop3/spaval
 L18>v 71823/a>3spav class="comment"> * @fn: funcon v to execute3/spavalv 73183" class="line" nam>
 L183">v1833/a>3spav class="comment"> * @arg: argument to @fn3/spaval
 L184">v1843/a>3spav class="comment"> *3/spaval
 L185">v1853/a>3spav class="comment"> * Execute @fn(@arg)  v online cpus in @cpumask.  On each target cpu,3/spaval
 L186">v1863/a>3spav class="comment"> * @fn is run in a process context with the highest priority3/spaval
 L187">v1873/a>3spav class="comment"> * preempting any task  v the cpu and monopolizing it.  This funcon v3/spaval
 L188">v1883/a>3spav class="comment"> * returns after all executn vs are compleoe.3/spaval
 L189">v1893/a>3spav class="comment"> *3/spaval
 L190">v193spav class="comment"> * This funcon v doesn't guarantee the cpus in @cpumask stay online3/spaval
 L191">v1913/a>3spav class="comment"> * till @fn compleoes.  If some cpus go down in the middle, executn v3/spaval
 L19>v 71923/a>3spav class="comment"> *  v the cpu may happen partially or fully ov different cpus.  @fn3/spavalv 73193" class="line" nam>
 L193">v1933/a>3spav class="comment"> * should either be ready for that or the caller should ensure that3/spaval
 L194">v1943/a>3spav class="comment"> * the cpus stay online until this funcon v compleoes.3/spaval
 L195">v1953/a>3spav class="comment"> *3/spaval
 L196">v1963/a>3spav class="comment"> * All stop_cpus() calls are serialized making it safe for @fn to wait3/spaval
 L197">v1973/a>3spav class="comment"> * for all cpus to start executnng it.3/spaval
 L198">v1983/a>3spav class="comment"> *3/spaval
 L199">v1993/a>3spav class="comment"> * CONTEXT:3/spaval
 L200">v2003/a>3spav class="comment"> * Might sleep.3/spaval
 L201">v2013/a>3spav class="comment"> *3/spaval
 L202">v2023/a>3spav class="comment"> * RETURNS:3/spaval
 L203">v2033/a>3spav class="comment"> * -ENOENT if @fn(@arg) was not executed at all because all cpus in3/spaval
 L204">v2043/a>3spav class="comment"> * @cpumask were offline; otherwise, 0 if all executn vs of @fn3/spaval
 L205">v2053/a>3spav class="comment"> * returned 0, any n v zero return 
	  > if any returned n v zero.3/spaval
 L206">v2063/a>3spav class="comment"> */3/spaval
 L207">v2073/a>intv3a href="+code=stop_cpus" class="sref">stop_cpus3/a>(const structv3a href="+code=cpumask" class="sref">cpumask3/a> *3a href="+code=cpumask" class="sref">cpumask3/a>, 3a href="+code=cpu_stop_fn_t" class="sref">cpu_stop_fn_t3/a> 3a href="+code=fv" class="sref">fn3/a>, voidv*3a href="+code=arg" class="sref">arg3/a>)l
 L208">v2083/a>{l
 L209">v2093/a>        intv3a href="+code=ret" class="sref">ret3/a>;l
 L210">v2103/a>l
 L211">v2113/a>        3spav class="comment">/* static works are used, process one request at a time */3/spaval
 L212">v2123/a>        3a href="+code=mutex_lock" class="sref">mutex_lock3/a>(&3a href="+code=stop_cpus_mutex" class="sref">stop_cpus_mutex3/a>);l
 L213">v2133/a>        3a href="+code=ret" class="sref">ret3/a> = 3a href="+code=__stop_cpus" class="sref">__stop_cpus3/a>(3a href="+code=cpumask" class="sref">cpumask3/a>, 3a href="+code=fv" class="sref">fn3/a>, 3a href="+code=arg" class="sref">arg3/a>);l
 L214">v2143/a>        3a href="+code=mutex_unlock" class="sref">mutex_unlock3/a>(&3a href="+code=stop_cpus_mutex" class="sref">stop_cpus_mutex3/a>);l
 L215">v2153/a>        return 3a href="+code=ret" class="sref">ret3/a>;l
 L216">v2163/a>}l
 L217">v2173/a>l
 L218">v2183/a>3spav class="comment">/**3/spaval
 L219">v2193/a>3spav class="comment"> * try_stop_cpus - try to stop multiple cpus3/spaval
 L220">v2203/a>3spav class="comment"> * @cpumask: cpus to stop3/spaval
 L221">v2213/a>3spav class="comment"> * @fn: funcon v to execute3/spaval
 L222">v2223/a>3spav class="comment"> * @arg: argument to @fn3/spaval
 L223">v2233/a>3spav class="comment"> *3/spaval
 L224">v2243/a>3spav class="comment"> * Identical to stop_cpus() except that it fails with -EAGAIN if3/spaval
 L225">v2253/a>3spav class="comment"> * someone else is already usnng the facility.3/spaval
 L226">v2263/a>3spav class="comment"> *3/spaval
 L227">v2273/a>3spav class="comment"> * CONTEXT:3/spaval
 L228">v2283/a>3spav class="comment"> * Might sleep.3/spaval
 L229">v2293/a>3spav class="comment"> *3/spaval
 L230">v233spav class="comment"> * RETURNS:3/spaval
 L231">v2313/a>3spav class="comment"> * -EAGAIN if someone else is already stoppnng cpus, -ENOENT if3/spaval
 L232">v2323/a>3spav class="comment"> * @fn(@arg) was not executed at all because all cpus in @cpumask were3/spaval
 L233">v2333/a>3spav class="comment"> * offline; otherwise, 0 if all executn vs of @fn returned 0, any n v3/spaval
 L234">v2343/a>3spav class="comment"> * zero return 
	  > if any returned n v zero.3/spaval
 L235">v2353/a>3spav class="comment"> */3/spaval
 L236">v2363/a>intv3a href="+code=try_stop_cpus" class="sref">try_stop_cpus3/a>(const structv3a href="+code=cpumask" class="sref">cpumask3/a> *3a href="+code=cpumask" class="sref">cpumask3/a>, 3a href="+code=cpu_stop_fn_t" class="sref">cpu_stop_fn_t3/a> 3a href="+code=fv" class="sref">fn3/a>, voidv*3a href="+code=arg" class="sref">arg3/a>)l
 L237">v2373/a>{l
 L238">v2383/a>        intv3a href="+code=ret" class="sref">ret3/a>;l
 L239">v2393/a>l
 L240">v2403/a>        3spav class="comment">/* static works are used, process one request at a time */3/spaval
 L241">v2413/a>        if (!3a href="+code=mutex_trylock" class="sref">mutex_trylock3/a>(&3a href="+code=stop_cpus_mutex" class="sref">stop_cpus_mutex3/a>))l
 L242">v2423/a>                return -3a href="+code=EAGAIN" class="sref">EAGAIN3/a>;l
 L243">v2433/a>        3a href="+code=ret" class="sref">ret3/a> = 3a href="+code=__stop_cpus" class="sref">__stop_cpus3/a>(3a href="+code=cpumask" class="sref">cpumask3/a>, 3a href="+code=fv" class="sref">fn3/a>, 3a href="+code=arg" class="sref">arg3/a>);l
 L244">v2443/a>        3a href="+code=mutex_unlock" class="sref">mutex_unlock3/a>(&3a href="+code=stop_cpus_mutex" class="sref">stop_cpus_mutex3/a>);l
 L245">v2453/a>        return 3a href="+code=ret" class="sref">ret3/a>;l
 L246">v2463/a>}l
 L247">v2473/a>l
 L248">v2483/a>static intv3a href="+code=cpu_stop_should_ruv" class="sref">cpu_stop_should_ruv3/a>(unsigned intv3a href="+code=cpu" class="sref">cpu3/a>)l
 L249">v2493/a>{l
 L250">v2503/a>        structv3a href="+code=cpu_stopper" class="sref">cpu_stopper3/a> *3a href="+code=stopper" class="sref">stopper3/a> = &3a href="+code=per_cpu" class="sref">per_cpu3/a>(3a href="+code=cpu_stopper" class="sref">cpu_stopper3/a>,v3a href="+code=cpu" class="sref">cpu3/a>);l
 L251">v2513/a>        unsigned long 3a href="+code=flags" class="sref">flags3/a>;l
 L252">v2523/a>        intv3a href="+code=ruv" class="sref">ruv3/a>;l
 L253">v2533/a>l
 L254">v2543/a>        3a href="+code=spin_lock_irqsave" class="sref">spin_lock_irqsave3/a>(&3a href="+code=stopper" class="sref">stopper3/a>->3a href="+code=lock" class="sref">lock3/a>,v3a href="+code=flags" class="sref">flags3/a>);l
 L255">v2553/a>        3a href="+code=ruv" class="sref">ruv3/a> = !3a href="+code=list_empty" class="sref">list_empty3/a>(&3a href="+code=stopper" class="sref">stopper3/a>->3a href="+code=works" class="sref">works3/a>);l
 L256">v2563/a>        3a href="+code=spin_unlock_irqrestore" class="sref">spin_unlock_irqrestore3/a>(&3a href="+code=stopper" class="sref">stopper3/a>->3a href="+code=lock" class="sref">lock3/a>,v3a href="+code=flags" class="sref">flags3/a>);l
 L257">v2573/a>        return 3a href="+code=ruv" class="sref">ruv3/a>;l
 L258">v2583/a>}l
 L259">v2593/a>l
 L260">v2603/a>static voidv3a href="+code=cpu_stopper_thread" class="sref">cpu_stopper_thread3/a>(unsigned intv3a href="+code=cpu" class="sref">cpu3/a>)l
 L261">v2613/a>{l
 L262">v2623/a>        structv3a href="+code=cpu_stopper" class="sref">cpu_stopper3/a> *3a href="+code=stopper" class="sref">stopper3/a> = &3a href="+code=per_cpu" class="sref">per_cpu3/a>(3a href="+code=cpu_stopper" class="sref">cpu_stopper3/a>,v3a href="+code=cpu" class="sref">cpu3/a>);l
 L263">v2633/a>        structv3a href="+code=cpu_stop_work" class="sref">cpu_stop_work3/a> *3a href="+code=work" class="sref">work3/a>;l
 L264">v2643/a>        intv3a href="+code=ret" class="sref">ret3/a>;l
 L265">v2653/a>l
 L266">v2663/a>3a href="+code=repeat" class="sref">repeat3/a>:l
 L267">v2673/a>        3a href="+code=work" class="sref">work3/a> = 3a href="+code=NULL" class="sref">NULL3/a>;l
 L268">v2683/a>        3a href="+code=spin_lock_irq" class="sref">spin_lock_irq3/a>(&3a href="+code=stopper" class="sref">stopper3/a>->3a href="+code=lock" class="sref">lock3/a>);l
 L269">v2693/a>        if (!3a href="+code=list_empty" class="sref">list_empty3/a>(&3a href="+code=stopper" class="sref">stopper3/a>->3a href="+code=works" class="sref">works3/a>)) {l
 L270">v2703/a>                3a href="+code=work" class="sref">work3/a> = 3a href="+code=list_first_entry" class="sref">list_first_entry3/a>(&3a href="+code=stopper" class="sref">stopper3/a>->3a href="+code=works" class="sref">works3/a>,l
 L271">v2713/a>                                        structv3a href="+code=cpu_stop_work" class="sref">cpu_stop_work3/a>, 3a href="+code=list" class="sref">list3/a>);l
 L272">v2723/a>                3a href="+code=list_del_init" class="sref">list_del_init3/a>(&3a href="+code=work" class="sref">work3/a>->3a href="+code=list" class="sref">list3/a>);l
 L273">v2733/a>        }l
 L274">v2743/a>        3a href="+code=spin_unlock_irq" class="sref">spin_unlock_irq3/a>(&3a href="+code=stopper" class="sref">stopper3/a>->3a href="+code=lock" class="sref">lock3/a>);l
 L275">v2753/a>l
 L276">v2763/a>        if (3a href="+code=work" class="sref">work3/a>) {l
 L277">v2773/a>                3a href="+code=cpu_stop_fn_t" class="sref">cpu_stop_fn_t3/a> 3a href="+code=fv" class="sref">fn3/a> = 3a href="+code=work" class="sref">work3/a>->3a href="+code=fv" class="sref">fn3/a>;l
 L278">v2783/a>                voidv*3a href="+code=arg" class="sref">arg3/a> = 3a href="+code=work" class="sref">work3/a>->3a href="+code=arg" class="sref">arg3/a>;l
 L279">v2793/a>                structv3a href="+code=cpu_stop_done" class="sref">cpu_stop_done3/a> *3a href="+code=done" class="sref">done3/a> = 3a href="+code=work" class="sref">work3/a>->3a href="+code=done" class="sref">done3/a>;l
 L280">v2803/a>                char 3a href="+code=ksym_buf" class="sref">ksym_buf3/a>[3a href="+code=KSYM_NAME_LEN" class="sref">KSYM_NAME_LEN3/a>] 3a href="+code=__maybe_unused" class="sref">__maybe_unused3/a>;l
 L281">v2813/a>l
 L28>v 72823/a>                3spav class="comment">/* cpu stop callbacks are not allowed to sleep */3/spavalv 73283" class="line" nam>
 L283">v2833/a>                3a href="+code=preempt_disable" class="sref">preempt_disable3/a>();l
 L284">v2843/a>l
 L285">v2853/a>                3a href="+code=ret" class="sref">ret3/a> = 3a href="+code=fv" class="sref">fn3/a>(3a href="+code=arg" class="sref">arg3/a>);l
 L286">v2863/a>                if (3a href="+code=ret" class="sref">ret3/a>)l
 L287">v2873/a>                        3a href="+code=done" class="sref">done3/a>->3a href="+code=ret" class="sref">ret3/a> = 3a href="+code=ret" class="sref">ret3/a>;l
 L288">v2883/a>l
 L289">v2893/a>                3spav class="comment">/* restore preemption and check it's still balanced */3/spaval
 L290">v2903/a>                3a href="+code=preempt_enable" class="sref">preempt_enable3/a>();l
 L291">v2913/a>                3a href="+code=WARN_ONCE" class="sref">WARN_ONCE3/a>(3a href="+code=preempt_count" class="sref">preempt_count3/a>(),l
 L29>v 72923/a>                          3spav class="string">"cpu_stop: %s(%p) leaked preempt count\n"3/spava,lv 73293" class="line" nam>
 L293">v2933/a>                          3a href="+code=kallsyms_lookup" class="sref">kallsyms_lookup3/a>((unsigned long)3a href="+code=fv" class="sref">fn3/a>, 3a href="+code=NULL" class="sref">NULL3/a>, 3a href="+code=NULL" class="sref">NULL3/a>, 3a href="+code=NULL" class="sref">NULL3/a>,l
 L294">v2943/a>                                          3a href="+code=ksym_buf" class="sref">ksym_buf3/a>), 3a href="+code=arg" class="sref">arg3/a>);l
 L295">v2953/a>l
 L296">v2963/a>                3a href="+code=cpu_stop_signal_done" class="sref">cpu_stop_signal_done3/a>(3a href="+code=done" class="sref">done3/a>, 3a href="+code=true" class="sref">true3/a>);l
 L297">v2973/a>                goto 3a href="+code=repeat" class="sref">repeat3/a>;l
 L298">v2983/a>        }l
 L299">v2993/a>}l
 L300">v3003/a>l
 L301">v3013/a>extern 
oidv3a href="+code=sched_set_stop_task" class="sref">sched_set_stop_task3/a>(intv3a href="+code=cpu" class="sref">cpu3/a>, structv3a href="+code=task_struct" class="sref">task_struct3/a> *3a href="+code=stop" class="sref">stop3/a>);l
 L302">v3023/a>l
 L303">v3033/a>static voidv3a href="+code=cpu_stop_create" class="sref">cpu_stop_create3/a>(unsigned intv3a href="+code=cpu" class="sref">cpu3/a>)l
 L304">v3043/a>{l
 L305">v3053/a>        3a href="+code=sched_set_stop_task" class="sref">sched_set_stop_task3/a>(3a href="+code=cpu" class="sref">cpu3/a>, 3a href="+code=per_cpu" class="sref">per_cpu3/a>(3a href="+code=cpu_stopper_task" class="sref">cpu_stopper_task3/a>,v3a href="+code=cpu" class="sref">cpu3/a>));l
 L306">v3063/a>}l
 L307">v3073/a>l
 L308">v3083/a>static voidv3a href="+code=cpu_stop_park" class="sref">cpu_stop_park3/a>(unsigned intv3a href="+code=cpu" class="sref">cpu3/a>)l
 L309">v3093/a>{l
 L310">v3103/a>        structv3a href="+code=cpu_stopper" class="sref">cpu_stopper3/a> *3a href="+code=stopper" class="sref">stopper3/a> = &3a href="+code=per_cpu" class="sref">per_cpu3/a>(3a href="+code=cpu_stopper" class="sref">cpu_stopper3/a>,v3a href="+code=cpu" class="sref">cpu3/a>);l
 L311">v3113/a>        structv3a href="+code=cpu_stop_work" class="sref">cpu_stop_work3/a> *3a href="+code=work" class="sref">work3/a>;l
 L312">v3123/a>        unsigned long 3a href="+code=flags" class="sref">flags3/a>;l
 L313">v3133/a>l
 L314">v3143/a>        3spav class="comment">/* drain remainnng works */3/spaval
 L315">v3153/a>        3a href="+code=spin_lock_irqsave" class="sref">spin_lock_irqsave3/a>(&3a href="+code=stopper" class="sref">stopper3/a>->3a href="+code=lock" class="sref">lock3/a>,v3a href="+code=flags" class="sref">flags3/a>);l
 L316">v3163/a>        3a href="+code=list_for_each_entry" class="sref">list_for_each_entry3/a>(3a href="+code=work" class="sref">work3/a>, &3a href="+code=stopper" class="sref">stopper3/a>->3a href="+code=works" class="sref">works3/a>, 3a href="+code=list" class="sref">list3/a>)l
 L317">v3173/a>                3a href="+code=cpu_stop_signal_done" class="sref">cpu_stop_signal_done3/a>(3a href="+code=work" class="sref">work3/a>->3a href="+code=done" class="sref">done3/a>,v3a href="+code=false" class="sref">false3/a>);l
 L318">v3183/a>        3a href="+code=stopper" class="sref">stopper3/a>->3a href="+code=enabled" class="sref">enabled3/a> = 3a href="+code=false" class="sref">false3/a>;l
 L319">v3193/a>        3a href="+code=spin_unlock_irqrestore" class="sref">spin_unlock_irqrestore3/a>(&3a href="+code=stopper" class="sref">stopper3/a>->3a href="+code=lock" class="sref">lock3/a>,v3a href="+code=flags" class="sref">flags3/a>);l
 L320">v3203/a>}l
 L321">v3213/a>l
 L322">v3223/a>static voidv3a href="+code=cpu_stop_unpark" class="sref">cpu_stop_unpark3/a>(unsigned intv3a href="+code=cpu" class="sref">cpu3/a>)l
 L323">v3233/a>{l
 L324">v3243/a>        structv3a href="+code=cpu_stopper" class="sref">cpu_stopper3/a> *3a href="+code=stopper" class="sref">stopper3/a> = &3a href="+code=per_cpu" class="sref">per_cpu3/a>(3a href="+code=cpu_stopper" class="sref">cpu_stopper3/a>,v3a href="+code=cpu" class="sref">cpu3/a>);l
 L325">v3253/a>l
 L326">v3263/a>        3a href="+code=spin_lock_irq" class="sref">spin_lock_irq3/a>(&3a href="+code=stopper" class="sref">stopper3/a>->3a href="+code=lock" class="sref">lock3/a>);l
 L327">v3273/a>        3a href="+code=stopper" class="sref">stopper3/a>->3a href="+code=enabled" class="sref">enabled3/a> = 3a href="+code=true" class="sref">true3/a>;l
 L328">v3283/a>        3a href="+code=spin_unlock_irq" class="sref">spin_unlock_irq3/a>(&3a href="+code=stopper" class="sref">stopper3/a>->3a href="+code=lock" class="sref">lock3/a>);l
 L329">v3293/a>}l
 L330">v3303/a>l
 L331">v3313/a>static structv3a href="+code=smp_hotplug_thread" class="sref">smp_hotplug_thread3/a> 3a href="+code=cpu_stop_threads" class="sref">cpu_stop_threads3/a> = {l
 L332">v3323/a>        .3a href="+code=store" class="sref">store3/a>                  = &3a href="+code=cpu_stopper_task" class="sref">cpu_stopper_task3/a>,l
 L333">v3333/a>        .3a href="+code=thread_should_ruv" class="sref">thread_should_ruv3/a>      = 3a href="+code=cpu_stop_should_ruv" class="sref">cpu_stop_should_ruv3/a>,l
 L334">v3343/a>        .3a href="+code=thread_fv" class="sref">thread_fv3/a>              = 3a href="+code=cpu_stopper_thread" class="sref">cpu_stopper_thread3/a>,l
 L335">v3353/a>        .3a href="+code=thread_comm" class="sref">thread_comm3/a>            = 3spav class="string">"migration/%u"3/spava,l
 L336">v3363/a>        .3a href="+code=create" class="sref">create3/a>                 = 3a href="+code=cpu_stop_create" class="sref">cpu_stop_create3/a>,l
 L337">v3373/a>        .3a href="+code=setup" class="sref">setup3/a>                  = 3a href="+code=cpu_stop_unpark" class="sref">cpu_stop_unpark3/a>,l
 L338">v3383/a>        .3a href="+code=park" class="sref">park3/a>                   = 3a href="+code=cpu_stop_park" class="sref">cpu_stop_park3/a>,l
 L339">v3393/a>        .3a href="+code=pre_unpark" class="sref">pre_unpark3/a>             = 3a href="+code=cpu_stop_unpark" class="sref">cpu_stop_unpark3/a>,l
 L340">v3403/a>        .3a href="+code=selfparking" class="sref">selfparking3/a>            = 3a href="+code=true" class="sref">true3/a>,l
 L341">v3413/a>};l
 L342">v3423/a>l
 L343">v3433/a>static intv3a href="+code=__init" class="sref">__init3/a> 3a href="+code=cpu_stop_init" class="sref">cpu_stop_init3/a>(void)l
 L344">v3443/a>{l
 L345">v3453/a>        unsigned intv3a href="+code=cpu" class="sref">cpu3/a>;l
 L346">v3463/a>l
 L347">v3473/a>        3a href="+code=for_each_possible_cpu" class="sref">for_each_possible_cpu3/a>(3a href="+code=cpu" class="sref">cpu3/a>) {l
 L348">v3483/a>                structv3a href="+code=cpu_stopper" class="sref">cpu_stopper3/a> *3a href="+code=stopper" class="sref">stopper3/a> = &3a href="+code=per_cpu" class="sref">per_cpu3/a>(3a href="+code=cpu_stopper" class="sref">cpu_stopper3/a>,v3a href="+code=cpu" class="sref">cpu3/a>);l
 L349">v3493/a>l
 L350">v3503/a>                3a href="+code=spin_lock_init" class="sref">spin_lock_init3/a>(&3a href="+code=stopper" class="sref">stopper3/a>->3a href="+code=lock" class="sref">lock3/a>);l
 L351">v3513/a>                3a href="+code=INIT_LIST_HEAD" class="sref">INIT_LIST_HEAD3/a>(&3a href="+code=stopper" class="sref">stopper3/a>->3a href="+code=works" class="sref">works3/a>);l
 L352">v3523/a>        }l
 L353">v3533/a>l
 L354">v3543/a>        3a href="+code=BUG_ON" class="sref">BUG_ON3/a>(3a href="+code=smpboot_register_percpu_thread" class="sref">smpboot_register_percpu_thread3/a>(&3a href="+code=cpu_stop_threads" class="sref">cpu_stop_threads3/a>));l
 L355">v3553/a>        3a href="+code=stop_machine_initialized" class="sref">stop_machine_initialized3/a> = 3a href="+code=true" class="sref">true3/a>;l
 L356">v3563/a>        return 0;l
 L357">v3573/a>}l
 L358">v3583/a>3a href="+code=early_initcall" class="sref">early_initcall3/a>(3a href="+code=cpu_stop_init" class="sref">cpu_stop_init3/a>);l
 L359">v3593/a>l
 L360">v3603/a>#ifdef 3a href="+code=CONFIG_STOP_MACHINE" class="sref">CONFIG_STOP_MACHINE3/a>l
 L361">v3613/a>l
 L362">v3623/a>3spav class="comment">/* This controls the threads ov each CPU. */3/spaval
 L363">v3633/a>enum 3a href="+code=stopmachine_state" class="sref">stopmachine_state3/a> {l
 L364">v3643/a>        3spav class="comment">/* Dummy startnng state for thread. */3/spaval
 L365">v3653/a>        3a href="+code=STOPMACHINE_NONE" class="sref">STOPMACHINE_NONE3/a>,l
 L366">v3663/a>        3spav class="comment">/* Awaitnng everyone to be scheduled. */3/spaval
 L367">v3673/a>        3a href="+code=STOPMACHINE_PREPARE" class="sref">STOPMACHINE_PREPARE3/a>,l
 L368">v3683/a>        3spav class="comment">/* Disable interrupts. */3/spaval
 L369">v3693/a>        3a href="+code=STOPMACHINE_DISABLE_IRQ" class="sref">STOPMACHINE_DISABLE_IRQ3/a>,l
 L370">v3703/a>        3spav class="comment">/* Ruv the funcon v */3/spaval
 L371">v3713/a>        3a href="+code=STOPMACHINE_RUN" class="sref">STOPMACHINE_RUN3/a>,l
 L372">v3723/a>        3spav class="comment">/* Exit */3/spaval
 L373">v3733/a>        3a href="+code=STOPMACHINE_EXIT" class="sref">STOPMACHINE_EXIT3/a>,l
 L374">v3743/a>};l
 L375">v3753/a>l
 L376">v3763/a>structv3a href="+code=stop_machine_data" class="sref">stop_machine_data3/a> {l
 L377">v3773/a>        intvvvvvvvvvvvvvvvvvvvvv(*3a href="+code=fv" class="sref">fn3/a>)(voidv*);l
 L378">v3783/a>        voidvvvvvvvvvvvvvvvvvvvv*3a href="+code=data" class="sref">data3/a>;l
 L379">v3793/a>        3spav class="comment">/* Like num_online_cpus(), but hotplug cpu uses us, so we need this. */3/spaval
 L380">v3803/a>        unsigned intvvvvvvvvvvvv3a href="+code=num_threads" class="sref">num_threads3/a>;l
 L381">v3813/a>        const structv3a href="+code=cpumask" class="sref">cpumask3/a> vvv*3a href="+code=aconve_cpus" class="sref">aconve_cpus3/a>;l
 L38>v 73823/a>lv 73383" class="line" nam>
 L383">v3833/a>        enum 3a href="+code=stopmachine_state" class="sref">stopmachine_state3/a>  3a href="+code=state" class="sref">state3/a>;l
 L384">v3843/a>        3a href="+code=atomic_t" class="sref">atomic_t3/a>                3a href="+code=thread_ack" class="sref">thread_ack3/a>;l
 L385">v3853/a>};l
 L386">v3863/a>l
 L387">v3873/a>static voidv3a href="+code=set_state" class="sref">set_state3/a>(structv3a href="+code=stop_machine_data" class="sref">stop_machine_data3/a> *3a href="+code=smdata" class="sref">smdata3/a>,l
 L388">v3883/a>                      enum 3a href="+code=stopmachine_state" class="sref">stopmachine_state3/a> 3a href="+code=newstate" class="sref">newstate3/a>)l
 L389">v3893/a>{l
 L390">v3903/a>        3spav class="comment">/* Reset ack counter. */3/spaval
 L391">v3913/a>        3a href="+code=atomic_set" class="sref">atomic_set3/a>(&3a href="+code=smdata" class="sref">smdata3/a>->3a href="+code=thread_ack" class="sref">thread_ack3/a>,v3a href="+code=smdata" class="sref">smdata3/a>->3a href="+code=num_threads" class="sref">num_threads3/a>);l
 L39>v 73923/a>        3a href="+code=smp_wmb" class="sref">smp_wmb3/a>();lv 73393" class="line" nam>
 L393">v3933/a>        3a href="+code=smdata" class="sref">smdata3/a>->3a href="+code=state" class="sref">state3/a> = 3a href="+code=newstate" class="sref">newstate3/a>;l
 L394">v3943/a>}l
 L395">v3953/a>l
 L396">v3963/a>3spav class="comment">/* Last one to ack a state moves to the next state. */3/spaval
 L397">v3973/a>static voidv3a href="+code=ack_state" class="sref">ack_state3/a>(structv3a href="+code=stop_machine_data" class="sref">stop_machine_data3/a> *3a href="+code=smdata" class="sref">smdata3/a>)l
 L398">v3983/a>{l
 L399">v3993/a>        if (3a href="+code=atomic_dec_and_test" class="sref">atomic_dec_and_test3/a>(&3a href="+code=smdata" class="sref">smdata3/a>->3a href="+code=thread_ack" class="sref">thread_ack3/a>))l
 L400">v4003/a>                3a href="+code=set_state" class="sref">set_state3/a>(3a href="+code=smdata" class="sref">smdata3/a>, 3a href="+code=smdata" class="sref">smdata3/a>->3a href="+code=state" class="sref">state3/a> + 1);l
 L401">v4013/a>}l
 L402">v4023/a>l
 L403">v4033/a>3spav class="comment">/* This is the cpu_stop funcon v which stops the CPU. */3/spaval
 L404">v4043/a>static intv3a href="+code=stop_machine_cpu_stop" class="sref">stop_machine_cpu_stop3/a>(voidv*3a href="+code=data" class="sref">data3/a>)l
 L405">v4053/a>{l
 L406">v4063/a>        structv3a href="+code=stop_machine_data" class="sref">stop_machine_data3/a> *3a href="+code=smdata" class="sref">smdata3/a> = 3a href="+code=data" class="sref">data3/a>;l
 L407">v4073/a>        enum 3a href="+code=stopmachine_state" class="sref">stopmachine_state3/a> 3a href="+code=curstate" class="sref">curstate3/a> = 3a href="+code=STOPMACHINE_NONE" class="sref">STOPMACHINE_NONE3/a>;l
 L408">v4083/a>        intv3a href="+code=cpu" class="sref">cpu3/a> = 3a href="+code=smp_processor_id" class="sref">smp_processor_id3/a>(), 3a href="+code=err" class="sref">err3/a> = 0;l
 L409">v4093/a>        unsigned long 3a href="+code=flags" class="sref">flags3/a>;l
 L410">v4103/a>        3a href="+code=bool" class="sref">bool3/a> 3a href="+code=is_aconve" class="sref">is_aconve3/a>;l
 L411">v4113/a>l
 L412">v4123/a>        3spav class="comment">/*3/spaval
 L413">v4133/a>3spav class="comment">         * When called from stop_machine_from_inaconve_cpu(), irq might3/spaval
 L414">v4143/a>3spav class="comment">         * already be disabled.  Save the state and restore it ov exit.3/spaval
 L415">v4153/a>3spav class="comment">         */3/spaval
 L416">v4163/a>        3a href="+code=local_save_flags" class="sref">local_save_flags3/a>(3a href="+code=flags" class="sref">flags3/a>);l
 L417">v4173/a>l
 L418">v4183/a>        if (!3a href="+code=smdata" class="sref">smdata3/a>->3a href="+code=aconve_cpus" class="sref">aconve_cpus3/a>)l
 L419">v4193/a>                3a href="+code=is_aconve" class="sref">is_aconve3/a> = 3a href="+code=cpu" class="sref">cpu3/a> == 3a href="+code=cpumask_first" class="sref">cpumask_first3/a>(3a href="+code=cpu_online_mask" class="sref">cpu_online_mask3/a>);l
 L420">v4203/a>        elsel
 L421">v4213/a>                3a href="+code=is_aconve" class="sref">is_aconve3/a> = 3a href="+code=cpumask_test_cpu" class="sref">cpumask_test_cpu3/a>(3a href="+code=cpu" class="sref">cpu3/a>, 3a href="+code=smdata" class="sref">smdata3/a>->3a href="+code=aconve_cpus" class="sref">aconve_cpus3/a>);l
 L422">v4223/a>l
 L423">v4233/a>        3spav class="comment">/* Simple state machine */3/spaval
 L424">v4243/a>        do {l
 L425">v4253/a>                3spav class="comment">/* Chill out and ensure we re-read stopmachine_state. */3/spaval
 L426">v4263/a>                3a href="+code=cpu_relax" class="sref">cpu_relax3/a>();l
 L427">v4273/a>                if (3a href="+code=smdata" class="sref">smdata3/a>->3a href="+code=state" class="sref">state3/a> != 3a href="+code=curstate" class="sref">curstate3/a>) {l
 L428">v4283/a>                        3a href="+code=curstate" class="sref">curstate3/a> = 3a href="+code=smdata" class="sref">smdata3/a>->3a href="+code=state" class="sref">state3/a>;l
 L429">v4293/a>                        switch (3a href="+code=curstate" class="sref">curstate3/a>) {l
 L430">v4303/a>                        case 3a href="+code=STOPMACHINE_DISABLE_IRQ" class="sref">STOPMACHINE_DISABLE_IRQ3/a>:l
 L431">v4313/a>                                3a href="+code=local_irq_disable" class="sref">local_irq_disable3/a>();l
 L432">v4323/a>                                3a href="+code=hard_irq_disable" class="sref">hard_irq_disable3/a>();l
 L433">v4333/a>                                break;l
 L434">v4343/a>                        case 3a href="+code=STOPMACHINE_RUN" class="sref">STOPMACHINE_RUN3/a>:l
 L435">v4353/a>                                if (3a href="+code=is_aconve" class="sref">is_aconve3/a>)l
 L436">v4363/a>                                        3a href="+code=err" class="sref">err3/a> = 3a href="+code=smdata" class="sref">smdata3/a>->3a href="+code=fv" class="sref">fn3/a>(3a href="+code=smdata" class="sref">smdata3/a>->3a href="+code=data" class="sref">data3/a>);l
 L437">v4373/a>                                break;l
 L438">v4383/a>                        default:l
 L439">v4393/a>                                break;l
 L440">v4403/a>                        }l
 L441">v4413/a>                        3a href="+code=ack_state" class="sref">ack_state3/a>(3a href="+code=smdata" class="sref">smdata3/a>);l
 L442">v4423/a>                }l
 L443">v4433/a>        } while (3a href="+code=curstate" class="sref">curstate3/a> != 3a href="+code=STOPMACHINE_EXIT" class="sref">STOPMACHINE_EXIT3/a>);l
 L444">v4443/a>l
 L445">v4453/a>        3a href="+code=local_irq_restore" class="sref">local_irq_restore3/a>(3a href="+code=flags" class="sref">flags3/a>);l
 L446">v4463/a>        return 3a href="+code=err" class="sref">err3/a>;l
 L447">v4473/a>}l
 L448">v4483/a>l
 L449">v4493/a>intv3a href="+code=__stop_machine" class="sref">__stop_machine3/a>(intv(*3a href="+code=fv" class="sref">fn3/a>)(voidv*), voidv*3a href="+code=data" class="sref">data3/a>, const structv3a href="+code=cpumask" class="sref">cpumask3/a> *3a href="+code=cpus" class="sref">cpus3/a>)l
 L450">v4503/a>{l
 L451">v4513/a>        structv3a href="+code=stop_machine_data" class="sref">stop_machine_data3/a> 3a href="+code=smdata" class="sref">smdata3/a> = { .3a href="+code=fv" class="sref">fn3/a> = 3a href="+code=fv" class="sref">fn3/a>, .3a href="+code=data" class="sref">data3/a> = 3a href="+code=data" class="sref">data3/a>,l
 L452">v4523/a>                                            .3a href="+code=num_threads" class="sref">num_threads3/a> = 3a href="+code=num_online_cpus" class="sref">num_online_cpus3/a>(),l
 L453">v4533/a>                                            .3a href="+code=aconve_cpus" class="sref">aconve_cpus3/a> = 3a href="+code=cpus" class="sref">cpus3/a> };l
 L454">v4543/a>l
 L455">v4553/a>        if (!3a href="+code=stop_machine_initialized" class="sref">stop_machine_initialized3/a>) {l
 L456">v4563/a>                3spav class="comment">/*3/spaval
 L457">v4573/a>3spav class="comment">                 * Handle the case where stop_machine() is called3/spaval
 L458">v4583/a>3spav class="comment">                 * early in boot before stop_machine() has been3/spaval
 L459">v4593/a>3spav class="comment">                 * initialized.3/spaval
 L460">v4603/a>3spav class="comment">                 */3/spaval
 L461">v4613/a>                unsigned long 3a href="+code=flags" class="sref">flags3/a>;l
 L462">v4623/a>                intv3a href="+code=ret" class="sref">ret3/a>;l
 L463">v4633/a>l
 L464">v4643/a>                3a href="+code=WARN_ON_ONCE" class="sref">WARN_ON_ONCE3/a>(3a href="+code=smdata" class="sref">smdata3/a>.3a href="+code=num_threads" class="sref">num_threads3/a> != 1);l
 L465">v4653/a>l
 L466">v4663/a>                3a href="+code=local_irq_save" class="sref">local_irq_save3/a>(3a href="+code=flags" class="sref">flags3/a>);l
 L467">v4673/a>                3a href="+code=hard_irq_disable" class="sref">hard_irq_disable3/a>();l
 L468">v4683/a>                3a href="+code=ret" class="sref">ret3/a> = (*3a href="+code=fv" class="sref">fn3/a>)(3a href="+code=data" class="sref">data3/a>);l
 L469">v4693/a>                3a href="+code=local_irq_restore" class="sref">local_irq_restore3/a>(3a href="+code=flags" class="sref">flags3/a>);l
 L470">v4703/a>l
 L471">v4713/a>                return 3a href="+code=ret" class="sref">ret3/a>;l
 L472">v4723/a>        }l
 L473">v4733/a>l
 L474">v4743/a>        3spav class="comment">/* Set the initial state and stop all online cpus. */3/spaval
 L475">v * H2     }lv3""sref">flahould_ruv3/a>,l<44s="line" nam>
 3rdata3/a>);lflags3/a>);lcpu3/a> == 3a href="+code=cpumask_firs+code=cpumask_testkernel/stop_machine.c#L404" id
 L404" class="line" nam>
 L40st_for_each_entry" clas13/a>                        3a href="+code=ack_state" class="sreff="+code=4top_machine_data" class=4sref"47 class="sref">err3/a>;l
 L447">v4473/a>}l
 L448">v4483/a>l
 L449">v4493/a>intv3a href="+code=__stop_machine" class="sref">__stop_machine3/a>(intv(*3a href="+code=fv" class="sref">fn3/a>)(voidv*), voidv*3a href="+code=data" class="sref">data3/a>, const structv3a href="+code=cpumask" cnel/line_cpus4), but hotplug cpu uses 4s, so48class="sref">cpus3/a>)lnum_thr;l
 L462">v4623a> vvv*3a4href="+code=aconve_cpus"4class4"sref">aconve_cpus3/a>;l
 L422">v4223/a>l
23/ome up or down du3/a>793/a>        3spav class="comment">/* Like num_o4machine_s4ate3/a>  3a href="+code=4tate"4class="sref">state3/a>;l
 L467">v4673/a>                3a hr         4a href="+code=thread_ack4 clas48online cpus. */3/spavalv4483/a>l 3a href="+code=smdata" class="sref"ine" class="sref">__stop_machine3/a>(intv(*3+code=data" class="sref">data3/a>, const stL467">v4673/a>                3a hr        3a.c#L385" id
 L385" class4"line48nt">         */3/spaval
 L467">v4673/a>                3a hr ="+code=4ne.c#L386" id
 L386" cla4s="li487ss="sref">flags3/a>);l
 L462">v4623avvvvvvvv4a3/a> *3a href="+code=sm4ata" 4lass="s="sref">err3/a>;l
 L464">vref="kernel/stop_machine.c449" id
 L449" c L467">v4673/a>                3a hrtop_machi4e.c#L389" id
 L389" clas4="lin49ass="sref">flags3/a>);l/4 Rese4 ack c>v4223/a>l->3a 4ref="+code=num_threads" 4lass=49" nam>
 L361">v3613/a>ltop_mach4   3a href="+code=smp_wm4" cla49ss="comment">/*3/spavalthine.c#L456" id
 L456" class="line" nam>achine_s4 = 3a href="+code=newsta4e" cl49pu(), irq might3/spaval(i:op_maa>(i ptr" id
 Le @fn()>thine.c#L456" id
 L456" class="line" nam>        4e.c#L394" id
 L394" clas4="lin49ore it ov exit.3/spavalthine.c#L456" id
 L456" class="line" nam>       3ane.c#L395" id
 L395" cla4s="li4e" nam>
 L395">v3953/a>l="+code=4 one to ack a state move4 to t49ss="comment">/*3/spaval
23bep_machine.c#La="li id
 Lachine.c#L456" id
 L456" class="line" nam>vvvvvvvv4a3/a> *3a href="+code=sm4ata" 49ine() is called3/spavale_state34e.c#L398" id
 L398" clas4="lin49hine() has been3/spaval->35 href="+code=thread_ack"5class50 * initialized.3/spaval
 L459">v455mdata3/a>5>3a href="+code=state5 clas50ack c>v4223/a>l
 L361">v3613/a>l
 L402">v4023/a>l7busy-stop" id
synchronizhref=425" ixecup_mac@fn directly" id
" claachine.c#L456" id
 L456" class="line" na5t4p_machi5e= 3a href="+code=newsta5hich 50pu(), irq might3/spaval
 L395">v3953/a>l/*3/spaval *3a href="+code=sm5="sre50ine() is called3/spavalv4 claixecup_ona of3@fn ags3/ahin0, anyanf=4zerolags3/a>value">v4 nyachine.c#L456" id
 L456" class="line" na5">bool3/a5 3a href="+code=is_aconv5" cla51ack c>v4223/a>l
 L361">v3613/a>l/* Like num_o5ine" nam>5 L412">v4123/a>        35pav c5ass="c */3/spaval
 L449">v4493/a>intv3a href="+code=__stop_machine" class="sref">__stop_machine3/a>(intv(*pav class="comment">/* Like num_o5i4p_machi5rom stop_machine_from_in5conve51                break;lfn3/a>)(voidv*), voidv*3a href="+code=data" class="sref">data3/a>, const structv3a href="+code=cpumask" cnel5eady be d5sabled.  Save the state 5nd re51class="sref">data3/a>)l
5L415">v4153/a>3spav clas5="com51 nam>
 L405">v4053/a>{l
 L451">v4513/a>        structv3a href="+code=stop_machine_data" class="sref">stop_machine_data3/a> 3a href="+code=smdata" class="sref">smdata3/a> = { .3a href="+code=fv" class="sref">fn3/a> = 3a href="+code=fv" class="sref">fn3/a>, .3a href="+code=data" cl5al_save_f5ags3/a>(3a href="+code=f5ags" 51lass="sref">data3/a>);l
 L453">v4533/a>                                            .3a href="+code=aconve_cpus" class="sref5stop_mach5ne.c#L417" id
 L417" cla5s="li5e" nam>
 L417"{lv4513/a> doel/stop_machine.cdoelam>
ef="+code=aconve_cpus" class="sref5s9p_machi5href="+code=aconve_cpus"5class5"sref">aconve_;l
 L462">v4625 href="+c5de=cpu_online_mask" clas5="sre52ass="sref">flags3/a>);l
 L450">v4203/a>   >
 L395">v3953/a>l        3spav class="comment">/* Like num_o5>->3a 5ref="+code=aconve_cpus" 5lass=52ref">num_threads3/a>);l
 L408">v4083/a>   raw_="line" nam>
 L4nam>
 register_percpu_thread3/a>(&3a h5stop_mach5ne.c#L422" id
 L422" cla5s="li5e" nam>
 L422">" nam>
 L464">v4643/a>                3a href="+code=WARN_ON_ONCE" class="sref">WARN_ON_ONCE3/a>(3a hre                     453" class="line" nam>
 L4    453" class=nam>
 >, 3;a>   >
 L395">v3953/a>l/* Like num_o5>4p_machi5spav class="comment">/* 5imple52ass="sref">cpus3/a> };l
 L454">v4243/a>   >v4223/a>l        3spav class="comment">/* Like num_o5>e" nam>
5out and ensure we re-rea5 stop5achine_state.       }43/a>lspin_lock_inimutex_trysrefd
 L475" class="line" nam>nel/    _mutex               rnel/    _mutexst sttructv3a href="+code=cpumask" cnel5         5a href="+code=cpu_relax"5class5"sref">cpu_relax3/a>()id
 L354" class_mactop_machine.c#L426" id
 L426" class="line" nam>
 L426">v4263/a>      5ate3/a> !5 3a href="+code=curstate5 clas52 nam>
 L447">v4473/a>}lsmdat53/a>->3a href="+code=5tate"52class="sref">data3/a>;lL414o Ler="liam25" ixecupe directly" id
" cla "li        3spav class="comment">/* Like num_o5   switch5(3a href="+code=curstate5 clas53lass="sref">flags3/a>;l
 L475">v * H2     }lv3""sref">flahould_ruv3/a>,l<44s="line" nam>
 3rdata3/a>);l
kernel/stop_machi    453" class="line" nam>
 L4    453" class=nam>
 a3/a>);l53ref">num_threads3/a>);l"line" nam>
 L4queue_rnel/    _3/a>354" id
 L354" class_mac id
 L>cpu3/a> == 3a href="+co id
 L>cpu3firs+code=cpumask_testkernel/stop_machine.c#L404" id
 L404" class="line" nam>
 L40st_for_each_entry" clas13/a>                        3">fn3/a>, .3a href="+code=data" cl5ef="+code5hard_irq_disable" class=5sref"5hard_irq_disable3/a>();l
a3/a>);lv4333/a>        5     53lass="sref">state3/a>;lv4483/a>l
 L40475" class="line" nam>
 L475">v * H2     }lSTOPMACHINE_NONE3/a>,l        3spav class="comment">/* Like num_o5ref">smda5a3/a>->3a href="+code5data"5class="sref">d      }43/a>l
="+code=WARN_ON__replep_on/stop_machine.c_replep_onst sttructv3a href="+code=cpumask" cnel5line" nam5
 L437">v4373/a>        5     5                 breakid
 L354" class_mactop_machine.c#L426" id
 L426" class="line" nam>
 L426">v4263/a>      5lass="lin5" nam>
 L438">v4383/a>  5     53f">cpu_stop_init3/a>);lv4393/a>        5     54lass="sref">flags3/a>;lspin_lock_inimutex_unsrefd
 L475" class="line" nam>nel/    _mutex               rnel/    _mutexst st="line" nam>
 L426">v4263/a>      5L440" cla5s="line" nam>
 L440">v4453/a> 5              ags3/a>);lv4513/a> doel/stop_machine.cdoelam>
="+code=WARN_ON_top_machine.c#L462" id
 L462" class="line" nam>
 L462">v4625">ack_sta5e3/a>(3a href="+code=smd5ta" c5ass="ss="sref">err3/a>;l
 L542">v54472">v4723/a>        }lSTOPM#endifo {l/* Like num_o5stop_mach5ne.c#L444" id
 L444" cla5s="li5e" nam


="e originla LXR softwar" by Le av class=http://sourcd Lge.net/projects/lxr">LXR rneluhiny L40st93/a ixperil/stla versef=4by av class=mailto:lxr@id ux.no">lxr@id ux.noam> =
lxr.id ux.no kindly"hosthinby av class=http://www.redpill-id pro.no">Redpill Ld pro AS L40st invidlr of3Ld uxea hrulp_mac25" "perap_ona servicls58ince 1995.