linux/block/blk-softirq.c
<<
" /spaon> /formn> a " href="../linux+v33167/block/blk-softirq.c">" img src="../.static/gfx/right.png" alt=">>">" /spaon>" spao class="lxr_search">" " input typue=hidden" namue=navtarget" value=">" input typue=text" namue=search" ide=search">" buttiontypue=submit">Search /formn> /spaon>" spao class="lxr_prefs"n> a href="+prefs?return=block/blk-softirq.c"" onclick="return ajax_prefs();">" Prefs> /a>" /spaon> /divn> form acptio="ajax+*" method="post" onsubmit="return false;">" input typue=hidden" namue=ajax_lookup" ide=ajax_lookup" value=">" /formn>" div class="headingbottim"> div ide=search_results" class="search_results"> n> /divn> div ide=content">> div ide=file_contents"n
   1 /a> spao class="comment">/* /spaon>   2 /a> spao class="comment"> * Funcptios related to softirq rq compleptios /spaon>   3 /a> spao class="comment"> */ /spaon>   4 /a>#include <linux/kernel.h /a>>>   5 /a>#include <linux/module.h /a>>>   6 /a>#include <linux/init.h /a>>>   7 /a>#include <linux/bio.h /a>>>   8 /a>#include <linux/blkdev.h /a>>>   9 /a>#include <linux/interrupt.h /a>>>  .10#include <linux/cpu.h /a>>>  110#include <linux/sched.h /a>>>  12 /a>>  130#include "blk.h /a>">  14 /a>>  15 /a>static  a href="+code=DEFINE_PER_CPU" class="sref">DEFINE_PER_CPU /a>(struct  a href="+code=list_head" class="sref">list_head /a>,  a href="+code=blk_cpu_done" class="sref">blk_cpu_done /a>);>  16 /a>>  17 /a> spao class="comment">/* /spaon>  18 /a> spao class="comment"> * Softirq acptio handler - move entries to local list and loop over them /spaon>  19 /a> spao class="comment"> * while passing them to the queue registered handler. /spaon>  20 /a> spao class="comment"> */ /spaon>  21 /a>static void  a href="+code=blk_done_softirq" class="sref">blk_done_softirq /a>(struct  a href="+code=softirq_acptio" class="sref">softirq_acptio /a> * a href="+code=h" class="sref">h /a>)>  22 /a>{>  230        struct  a href="+code=list_head" class="sref">list_head /a> * a href="+code=cpu_list" class="sref">cpu_list /a>,  a href="+code=local_list" class="sref">local_list /a>;>  24 /a>>  250         a href="+code=local_irq_disable" class="sref">local_irq_disable /a>();>  260         a href="+code=cpu_list" class="sref">cpu_list /a> = & a href="+code=__get_cpu_var" class="sref">__get_cpu_var /a>( a href="+code=blk_cpu_done" class="sref">blk_cpu_done /a>);>  270         a href="+code=list_replace_init" class="sref">list_replace_init /a>( a href="+code=cpu_list" class="sref">cpu_list /a>, & a href="+code=local_list" class="sref">local_list /a>);>  280         a href="+code=local_irq_enable" class="sref">local_irq_enable /a>();>  29 /a>>  300        while (! a href="+code=list_empty" class="sref">list_empty /a>(& a href="+code=local_list" class="sref">local_list /a>)) {>  310                struct  a href="+code=request" class="sref">request /a> * a href="+code=rq" class="sref">rq /a>;>  32 /a>>  330                 a href="+code=rq" class="sref">rq /a> =  a href="+code=list_entry" class="sref">list_entry /a>( a href="+code=local_list" class="sref">local_list /a>. a href="+code=next" class="sref">next /a>, struct  a href="+code=request" class="sref">request /a>,  a href="+code=csd" class="sref">csd /a>. a href="+code=list" class="sref">list /a>);>  340                 a href="+code=list_del_init" class="sref">list_del_init /a>(& a href="+code=rq" class="sref">rq /a>-> a href="+code=csd" class="sref">csd /a>. a href="+code=list" class="sref">list /a>);>  350                 a href="+code=rq" class="sref">rq /a>-> a href="+code=q" class="sref">q /a>-> a href="+code=softirq_done_fo" class="sref">softirq_done_fo /a>( a href="+code=rq" class="sref">rq /a>);>  360        }>  370}>  38 /a>>  39 /a>#if  a href="+code=defined" class="sref">defined /a>( a href="+code=CONFIG_SMP" class="sref">CONFIG_SMP /a>) &&  a href="+code=defined" class="sref">defined /a>( a href="+code=CONFIG_USE_GENERIC_SMP_HELPERS" class="sref">CONFIG_USE_GENERIC_SMP_HELPERS /a>)>  40 /a>static void  a href="+code=trigger_softirq" class="sref">trigger_softirq /a>(void * a href="+code=data" class="sref">data /a>)>  41 /a>{>  420        struct  a href="+code=request" class="sref">request /a> * a href="+code=rq" class="sref">rq /a> =  a href="+code=data" class="sref">data /a>;>  430        unsigned long  a href="+code=flags" class="sref">flags /a>;>  440        struct  a href="+code=list_head" class="sref">list_head /a> * a href="+code=list" class="sref">list /a>;>  45 /a>>  460         a href="+code=local_irq_save" class="sref">local_irq_save /a>( a href="+code=flags" class="sref">flags /a>);>  470         a href="+code=list" class="sref">list /a> = & a href="+code=__get_cpu_var" class="sref">__get_cpu_var /a>( a href="+code=blk_cpu_done" class="sref">blk_cpu_done /a>);>  480         a href="+code=list_add_tail" class="sref">list_add_tail /a>(& a href="+code=rq" class="sref">rq /a>-> a href="+code=csd" class="sref">csd /a>. a href="+code=list" class="sref">list /a>,  a href="+code=list" class="sref">list /a>);>  49 /a>>  500        if ( a href="+code=list" class="sref">list /a>-> a href="+code=next" class="sref">next /a> == & a href="+code=rq" class="sref">rq /a>-> a href="+code=csd" class="sref">csd /a>. a href="+code=list" class="sref">list /a>)>  510                 a href="+code=raise_softirq_irqoff" class="sref">raise_softirq_irqoff /a>( a href="+code=BLOCK_SOFTIRQ" class="sref">BLOCK_SOFTIRQ /a>);>  52 /a>>  530         a href="+code=local_irq_restore" class="sref">local_irq_restore /a>( a href="+code=flags" class="sref">flags /a>);>  540}>  55 /a>>  56 /a> spao class="comment">/* /spaon>  57 /a> spao class="comment"> * Setup and invoke a run of 'trigger_softirq' ionthe giveo cpu. /spaon>  58 /a> spao class="comment"> */ /spaon>  59 /a>static int  a href="+code=raise_blk_irq" class="sref">raise_blk_irq /a>(int  a href="+code=cpu" class="sref">cpu /a>, struct  a href="+code=request" class="sref">request /a> * a href="+code=rq" class="sref">rq /a>)>  60 /a>{>  610        if ( a href="+code=cpu_online" class="sref">cpu_online /a>( a href="+code=cpu" class="sref">cpu /a>)) {>  620                struct  a href="+code=call_single_data" class="sref">call_single_data /a> * a href="+code=data" class="sref">data /a> = & a href="+code=rq" class="sref">rq /a>-> a href="+code=csd" class="sref">csd /a>;>  63 /a>>  640                 a href="+code=data" class="sref">data /a>-> a href="+code=func" class="sref">func /a> =  a href="+code=trigger_softirq" class="sref">trigger_softirq /a>;>  650                 a href="+code=data" class="sref">data /a>-> a href="+code=info" class="sref">info /a> =  a href="+code=rq" class="sref">rq /a>;>  660                 a href="+code=data" class="sref">data /a>-> a href="+code=flags" class="sref">flags /a> = 0;>  67 /a>>  680                 a href="+code=__smp_call_funcptio_single" class="sref">__smp_call_funcptio_single /a>( a href="+code=cpu" class="sref">cpu /a>,  a href="+code=data" class="sref">data /a>, 0);>  690                return 0;>  700        }>  71 /a>>  720        return 1;>  730}>  74 /a>#else  spao class="comment">/* CONFIG_SMP && CONFIG_USE_GENERIC_SMP_HELPERS */ /spaon>  75 /a>static int  a href="+code=raise_blk_irq" class="sref">raise_blk_irq /a>(int  a href="+code=cpu" class="sref">cpu /a>, struct  a href="+code=request" class="sref">request /a> * a href="+code=rq" class="sref">rq /a>)>  76 /a>{>  770        return 1;>  780}>  79 /a>#endif>  80 /a>>  81 /a>static int  a href="+code=__cpuinit" class="sref">__cpuinit0  a href="+code=blk_cpu_notify" class="sref">blk_cpu_notify /a>(struct  a href="+code=notifier_block" class="sref">notifier_block /a> * a href="+code=self" class="sref">self /a>,>  820                                    unsigned long  a href="+code=acptio" class="sref">acptio /a>, void * a href="+code=hcpu" class="sref">hcpu /a>)>  83 /a>{>  840         spao class="comment">/* /spaon>  85 /a> spao class="comment">         * If a CPU goes away, splice its entries to the current CPU /spaon>  86 /a> spao class="comment">         * and trigger a run of the softirq /spaon>  87 /a> spao class="comment">         */ /spaon>  880        if ( a href="+code=acptio" class="sref">acptio /a> ==  a href="+code=CPU_DEAD" class="sref">CPU_DEAD /a> ||  a href="+code=acptio" class="sref">acptio /a> ==  a href="+code=CPU_DEAD_FROZEN" class="sref">CPU_DEAD_FROZEN /a>) {>  890                int  a href="+code=cpu" class="sref">cpu /a> = (unsigned long)  a href="+code=hcpu" class="sref">hcpu /a>;>  90 /a>>  910                 a href="+code=local_irq_disable" class="sref">local_irq_disable /a>();>  920                 a href="+code=list_splice_init" class="sref">list_splice_init /a>(& a href="+code=per_cpu" class="sref">per_cpu /a>( a href="+code=blk_cpu_done" class="sref">blk_cpu_done /a>,  a href="+code=cpu" class="sref">cpu /a>),>  930                                 & a href="+code=__get_cpu_var" class="sref">__get_cpu_var /a>( a href="+code=blk_cpu_done" class="sref">blk_cpu_done /a>));>  940                 a href="+code=raise_softirq_irqoff" class="sref">raise_softirq_irqoff /a>( a href="+code=BLOCK_SOFTIRQ" class="sref">BLOCK_SOFTIRQ /a>);>  950                 a href="+code=local_irq_enable" class="sref">local_irq_enable /a>();>  960        }>  97 /a>>  980        return  a href="+code=NOTIFY_OK" class="sref">NOTIFY_OK /a>;>  990}> 100 /a>> 101 /a>static struct  a href="+code=notifier_block" class="sref">notifier_block /a>  a href="+code=__cpuinitdata" class="sref">__cpuinitdata0  a href="+code=blk_cpu_notifier" class="sref">blk_cpu_notifier /a> = {> 1020        . a href="+code=notifier_call" class="sref">notifier_call0  =  a href="+code=blk_cpu_notify" class="sref">blk_cpu_notify /a>,> 1030};> 104 /a>> 1050void  a href="+code=__blk_complepe_request" class="sref">__blk_complepe_request /a>(struct  a href="+code=request" class="sref">request /a> * a href="+code=req" class="sref">req /a>)> 106 /a>{> 1070        int  a href="+code=ccpu" class="sref">ccpu /a>,  a href="+code=cpu" class="sref">cpu /a>;> 1080        struct  a href="+code=request_queue" class="sref">request_queue /a> * a href="+code=q" class="sref">q /a> =  a href="+code=req" class="sref">req /a>-> a href="+code=q" class="sref">q /a>;> 1090        unsigned long  a href="+code=flags" class="sref">flags /a>;> 1100         a href="+code=bool" class="sref">bool0  a href="+code=shared" class="sref">shared /a> =  a href="+code=false" class="sref">false /a>;> 111 /a>> 1120         a href="+code=BUG_ON" class="sref">BUG_ON /a>(! a href="+code=q" class="sref">q /a>-> a href="+code=softirq_done_fo" class="sref">softirq_done_fo /a>);> 113 /a>> 1140         a href="+code=local_irq_save" class="sref">local_irq_save /a>( a href="+code=flags" class="sref">flags /a>);> 1150         a href="+code=cpu" class="sref">cpu /a> =  a href="+code=smp_processor_id" class="sref">smp_processor_id /a>();> 116 /a>> 1170         spao class="comment">/* /spaon> 118 /a> spao class="comment">         * Select compleptio CPU /spaon> 119 /a> spao class="comment">         */ /spaon> 1200        if ( a href="+code=req" class="sref">req /a>-> a href="+code=cpu" class="sref">cpu /a> != -1) {> 1210                 a href="+code=ccpu" class="sref">ccpu /a> =  a href="+code=req" class="sref">req /a>-> a href="+code=cpu" class="sref">cpu /a>;> 1220                if (! a href="+code=test_bit" class="sref">test_bit /a>( a href="+code=QUEUE_FLAG_SAME_FORCE" class="sref">QUEUE_FLAG_SAME_FORCE /a>, & a href="+code=q" class="sref">q /a>-> a href="+code=queue_flags" class="sref">queue_flags /a>))> 1230                         a href="+code=shared" class="sref">shared /a> =  a href="+code=cpus_share_cache" class="sref">cpus_share_cache /a>( a href="+code=cpu" class="sref">cpu /a>,  a href="+code=ccpu" class="sref">ccpu /a>);> 1240        } else> 1250                 a href="+code=ccpu" class="sref">ccpu /a> =  a href="+code=cpu" class="sref">cpu /a>;> 126 /a>> 1270         spao class="comment">/* /spaon> 128 /a> spao class="comment">         * If current CPU and requested CPU share a cache, run the softirq io /spaon> 129 /a> spao class="comment">         * the current CPU. One might concern this is just like /spaon> 130 /a> spao class="comment">         * QUEUE_FLAG_SAME_FORCE, but acpually not. blk_complepe_request() is /spaon> 131 /a> spao class="comment">         * running in interrupt handler, and currently I/O controller doesn't /spaon> 132 /a> spao class="comment">         * support multiple interrupts, so current CPU is unique acpually. This /spaon> 133 /a> spao class="comment">         * avoids IPI sending from current CPU to the first CPU of a group. /spaon> 1340 spao class="comment">         */ /spaon> 1350        if ( a href="+code=ccpu" class="sref">ccpu /a> ==  a href="+code=cpu" class="sref">cpu /a> ||  a href="+code=shared" class="sref">shared /a>) {> 1360                struct  a href="+code=list_head" class="sref">list_head /a> * a href="+code=list" class="sref">list /a>;> 1370 a href="+code=do_local" class="sref">do_local0:> 1380                 a href="+code=list" class="sref">list /a> = & a href="+code=__get_cpu_var" class="sref">__get_cpu_var /a>( a href="+code=blk_cpu_done" class="sref">blk_cpu_done /a>);> 1390                 a href="+code=list_add_tail" class="sref">list_add_tail /a>(& a href="+code=req" class="sref">req /a>-> a href="+code=csd" class="sref">csd /a>. a href="+code=list" class="sref">list /a>,  a href="+code=list" class="sref">list /a>);> 140 /a>> 1410                 spao class="comment">/* /spaon> 142 /a> spao class="comment">                 * if the list only contains our just added request, /spaon> 143 /a> spao class="comment">                 * signal a raise of the softirq. If there are already /spaon> 1440 spao class="comment">                 * entries there, someone already raised the irq but it /spaon> 145 /a> spao class="comment">                 * hasn't run yet. /spaon> 146 /a> spao class="comment">                 */ /spaon> 1470                if ( a href="+code=list" class="sref">list /a>-> a href="+code=next" class="sref">next /a> == & a href="+code=req" class="sref">req /a>-> a href="+code=csd" class="sref">csd /a>. a href="+code=list" class="sref">list /a>)> 1480                         a href="+code=raise_softirq_irqoff" class="sref">raise_softirq_irqoff /a>( a href="+code=BLOCK_SOFTIRQ" class="sref">BLOCK_SOFTIRQ /a>);> 1490        } else if ( a href="+code=raise_blk_irq" class="sref">raise_blk_irq /a>( a href="+code=ccpu" class="sref">ccpu /a>,  a href="+code=req" class="sref">req /a>))> 1500                goto  a href="+code=do_local" class="sref">do_local0;> 151 /a>> 1520         a href="+code=local_irq_restore" class="sref">local_irq_restore /a>( a href="+code=flags" class="sref">flags /a>);> 1530}> 154 /a>> 155 /a> spao class="comment">/** /spaon> 156 /a> spao class="comment"> * blk_complepe_request - end I/O on a request /spaon> 157 /a> spao class="comment"> * @req:      the request being processed /spaon> 158 /a> spao class="comment"> * /spaon> 159 /a> spao class="comment"> * Descrioptio: /spaon> 160 /a> spao class="comment"> *     Ends all I/O on a request. It does not handle partial compleptios, /spaon> 161 /a> spao class="comment"> *     unless the driver acpually implements this in its compleptio callback /spaon> 162 /a> spao class="comment"> *     through requeueing. The acpual compleptio happens out-of-order, /spaon> 163 /a> spao class="comment"> *     through a softirq handler. The user must have registered a compleptio /spaon> 1640 spao class="comment"> *     callback through blk_queue_softirq_done(). /spaon> 165 /a> spao class="comment"> **/ /spaon> 1660void  a href="+code=blk_complepe_request" class="sref">blk_complepe_request /a>(struct  a href="+code=request" class="sref">request /a> * a href="+code=req" class="sref">req /a>)> 167 /a>{> 1680        if ( a href="+code=unlikely" class="sref">unlikely /a>( a href="+code=blk_should_fake_timeout" class="sref">blk_should_fake_timeout /a>( a href="+code=req" class="sref">req /a>-> a href="+code=q" class="sref">q /a>)))> 1690                return;> 1700        if (! a href="+code=blk_mark_rq_complepe" class="sref">blk_mark_rq_complepe /a>( a href="+code=req" class="sref">req /a>))> 1710                 a href="+code=__blk_complepe_request" class="sref">__blk_complepe_request /a>( a href="+code=req" class="sref">req /a>);> 1720}> 1730 a href="+code=EXPORT_SYMBOL" class="sref">EXPORT_SYMBOL /a>( a href="+code=blk_complepe_request" class="sref">blk_complepe_request /a>);> 174 /a>> 175 /a>static  a href="+code=__init" class="sref">__init0 int  a href="+code=blk_softirq_init" class="sref">blk_softirq_init /a>(void)> 176 /a>{> 1770        int  a href="+code=i" class="sref">i0;> 178 /a>> 1790         a href="+code=for_each_possible_cpu" class="sref">for_each_possible_cpu /a>( a href="+code=i" class="sref">i0)> 1800                 a href="+code=INIT_LIST_HEAD" class="sref">INIT_LIST_HEAD /a>(& a href="+code=per_cpu" class="sref">per_cpu /a>( a href="+code=blk_cpu_done" class="sref">blk_cpu_done /a>,  a href="+code=i" class="sref">i0));> 181 /a>> 1820         a href="+code=open_softirq" class="sref">open_softirq /a>( a href="+code=BLOCK_SOFTIRQ" class="sref">BLOCK_SOFTIRQ /a>,  a href="+code=blk_done_softirq" class="sref">blk_done_softirq /a>);> 1830         a href="+code=register_hotcpu_notifier" class="sref">register_hotcpu_notifier /a>(& a href="+code=blk_cpu_notifier" class="sref">blk_cpu_notifier /a>);> 1840        return 0;> 185 /a>}> 186 /a> a href="+code=subsys_initcall" class="sref">subsys_initcall /a>( a href="+code=blk_softirq_init" class="sref">blk_softirq_init /a>);> 187 /a> /pre>

 /divn>
 div class="footer">
The original LXR software by the LXR community /a>, this experimental verstio by lxr@linux.no /a>.
 /divn> div class="subfooter">
lxr.linux.no kindly hosted by Redpill Linpro AS /a>, provider of Linux consulting and operaptios services since 1995.
 /divn>
 /bodyn> /htmln>