linux/lib/percpu-rwsem.c
<<
n va6.3/spa 6.3/form 6.3a n va6. href="../linux+v3.8.1/lib/percpu-rwsem.c">n va6.3img src="../.static/gfx/right.png" alt=">>">n 3/spa n 3spa class="lxr_search">n va ="+search" method="post" onsubmit="return do_search(this);">n va6.3input typn> hidden" namn> navtarget" ption> ">n va6.3input typn> text" namn> search" id> search">n va6.3butt submit">Searchn va6.Prefs 6.3/a>n 3/spa va6. .3/div va6. .3form ac > ="ajax+*" method="post" onsubmit="return false;">n 3input typn> hidden" namn> ajax_lookup" id> ajax_lookup" ption> ">nva6. .3/form nva6. .3div class="headingbott
search_results" class="search_results" 6 va6. .3/div 3div id> content"> 3div id> file_contents"
93/4c/82fa8402a160af49731efd02ec1926f77d4f_3/0" 
L1" class="line" namn>
L1">. .13/a>#include <linux/at>

L2" class="line" namn>
L2">. .23/a>#include <linux/rwsem.h3/a>>

L3" class="line" namn>
L3">. .33/a>#include <linux/percpu.h3/a>>

L4" class="line" namn>
L4">. .43/a>#include <linux/wait.h3/a>>

L5" class="line" namn>
L5">. .53/a>#include <linux/lockdep.h3/a>>

L6" class="line" namn>
L6">. .63/a>#include <linux/percpu-rwsem.h3/a>>

L7" class="line" namn>
L7">. .73/a>#include <linux/rcupdate.h3/a>>

L8" class="line" namn>
L8">. .83/a>#include <linux/sched.h3/a>>

L9" class="line" namn>
L9">. .93/a>#include <linux/errno.h3/a>>

L10" class="line" namn>
L10">. .11"a>n
L11" class="line" namn>
L11">. 113/a>int.3a href="+code=__percpu_init_rwsem" class="sref">__percpu_init_rwsem3/a>(struct.3a href="+code=percpu_rw_semaphore" class="sref">percpu_rw_semaphore3/a> *3a href="+code=brw" class="sref">brw3/a>,n
L12" class="line" namn>
L12">. 123/a>                        const char *3a href="+code=namn" class="sref">namn3/a>, struct.3a href="+code=lock_class_key" class="sref">lock_class_key3/a> *3a href="+code=rwsem_key" class="sref">rwsem_key3/a>)n
L13" class="line" namn>
L13">. 133/a>{n
L14" class="line" namn>
L14">. 143/a>        3a href="+code=brw" class="sref">brw3/a>->3a href="+code=fast_read_ctr" class="sref">fast_read_ctr3/a> = 3a href="+code=alloc_percpu" class="sref">alloc_percpu3/a>(int);

L15" class="line" namn>
L15">. 153/a>        if (3a href="+code=unlikely" class="sref">unlikely3/a>(!3a href="+code=brw" class="sref">brw3/a>->3a href="+code=fast_read_ctr" class="sref">fast_read_ctr3/a>))n
L16" class="line" namn>
L16">. 163/a>                return -3a href="+code=ENOMEM" class="sref">ENOMEM3/a>;

L17" class="line" namn>
L17">. 171"a>n
L18" class="line" namn>
L18">. 183/a>        3spa
 class="comment">/* ->rw_sem represents the whole percpu_rw_semaphore for lockdep */3/spa
  
L19" class="line" namn>
L19">. 193/a>        3a href="+code=__init_rwsem" class="sref">__init_rwsem3/a>(&3a href="+code=brw" class="sref">brw3/a>->3a href="+code=rw_sem" class="sref">rw_sem3/a>, 3a href="+code=namn" class="sref">namn3/a>, 3a href="+code=rwsem_key" class="sref">rwsem_key3/a>);

L20" class="line" namn>
L20">. 203/a>        3a href="+code=atat(&3a href="+code=brw" class="sref">brw3/a>->3a href="+code=write_ctr" class="sref">write_ctr3/a>, 0);

L21" class="line" namn>
L21">. 213/a>        3a href="+code=atat(&3a href="+code=brw" class="sref">brw3/a>->3a href="+code=slow_read_ctr" class="sref">slow_read_ctr3/a>, 0);

L22" class="line" namn>
L22">. 223/a>        3a href="+code=init_waitqueue_head" class="sref">init_waitqueue_head3/a>(&3a href="+code=brw" class="sref">brw3/a>->3a href="+code=write_waitq" class="sref">write_waitq3/a>);

L23" class="line" namn>
L23">. 233/a>        return 0;

L24" class="line" namn>
L24">. 243/a>}

L25" class="line" namn>
L25">. 251"a>n
L26" class="line" namn>
L26">. 263/a>void.3a href="+code=percpu_free_rwsem" class="sref">percpu_free_rwsem3/a>(struct.3a href="+code=percpu_rw_semaphore" class="sref">percpu_rw_semaphore3/a> *3a href="+code=brw" class="sref">brw3/a>)n
L27" class="line" namn>
L27">. 273/a>{n
L28" class="line" namn>
L28">. 283/a>        3a href="+code=free_percpu" class="sref">free_percpu3/a>(3a href="+code=brw" class="sref">brw3/a>->3a href="+code=fast_read_ctr" class="sref">fast_read_ctr3/a>);

L29" class="line" namn>
L29">. 293/a>        3a href="+code=brw" class="sref">brw3/a>->3a href="+code=fast_read_ctr" class="sref">fast_read_ctr3/a> = 3a href="+code=NULL" class="sref">NULL3/a>; 3spa
 class="comment">/* catch use after free bugs */3/spa
  
L30" class="line" namn>
L30">. 303/a>}

L31" class="line" namn>
L31">. 311"a>n
L32" class="line" namn>
L32">. 323/a>3spa
 class="comment">/*3/spa
  
L33" class="line" namn>
L33">. 333/a>3spa
 class="comment"> * This is the fast-path for down_read/up_read, it only needs to ensure3/spa
  
L34" class="line" namn>
L34">. 343/a>3spa
 class="comment"> * there is no pending writer (at
L35" class="line" namn>
L35">. 353/a>3spa
 class="comment"> * fast per-cpu counter. The writer uses synchronize_sched_expedited() to3/spa
  
L36" class="line" namn>
L36">. 363/a>3spa
 class="comment"> * serialize with the preempt-disabled sec  >
 below.3/spa
  
L37" class="line" namn>
L37">. 373/a>3spa
 class="comment"> *3/spa
  
L38" class="line" namn>
L38">. 383/a>3spa
 class="comment"> * The nontrivial part is that we should guarantee acquire/release semantics3/spa
  
L39" class="line" namn>
L39">. 393/a>3spa
 class="comment"> * i
 case when3/spa
  
L40" class="line" namn>
L40">. 403/a>3spa
 class="comment"> *3/spa
  
L41" class="line" namn>
L41">. 413/a>3spa
 class="comment"> *      R_W: down_write() comes after up_read(), the writer should see all3/spa
  
L42" class="line" namn>
L42">. 423/a>3spa
 class="comment"> *           changes done by the reader3/spa
  
L43" class="line" namn>
L43">. 433/a>3spa
 class="comment"> * or3/spa
  
L44" class="line" namn>
L44">. 443/a>3spa
 class="comment"> *      W_R: down_read() comes after up_write(), the reader should see all3/spa
  
L45" class="line" namn>
L45">. 453/a>3spa
 class="comment"> *           changes done by the writer3/spa
  
L46" class="line" namn>
L46">. 463/a>3spa
 class="comment"> *3/spa
  
L47" class="line" namn>
L47">. 473/a>3spa
 class="comment"> * If this helper fails the callers rely 
L48" class="line" namn>
L48">. 483/a>3spa
 class="comment"> * at
L49" class="line" namn>
L49">. 493/a>3spa
 class="comment"> *3/spa
  
L50" class="line" namn>
L50">. 503/a>3spa
 class="comment"> * But if it succeeds we do not haveoany barriers, at
L51" class="line" namn>
L51">. 513/a>3spa
 class="comment"> * __this_cpu_add() below ca
 be reordered with any LOAD/STORE done by the3/spa
  
L52" class="line" namn>
L52">. 523/a>3spa
 class="comment"> * reader insideothe critical sec  >
. Seeothe comments i
 down_write and3/spa
  
L53" class="line" namn>
L53">. 533/a>3spa
 class="comment"> * up_write below.3/spa
  
L54" class="line" namn>
L54">. 543/a>3spa
 class="comment"> */3/spa
  
L55" class="line" namn>
L55">. 553/a>static 3a href="+code=bool" class="sref">bool3/a> 3a href="+code=update_fast_ctr" class="sref">update_fast_ctr3/a>(struct.3a href="+code=percpu_rw_semaphore" class="sref">percpu_rw_semaphore3/a> *3a href="+code=brw" class="sref">brw3/a>, unsigned int.3a href="+code=val" class="sref">val3/a>)n
L56" class="line" namn>
L56">. 563/a>{n
L57" class="line" namn>
L57">. 573/a>        3a href="+code=bool" class="sref">bool3/a> 3a href="+code=success" class="sref">success3/a> = 3a href="+code=false" class="sref">false3/a>;

L58" class="line" namn>
L58">. 581"a>n
L59" class="line" namn>
L59">. 593/a>        3a href="+code=preempt_disable" class="sref">preempt_disable3/a>();

L60" class="line" namn>
L60">. 603/a>        if (3a href="+code=likely" class="sref">likely3/a>(!3a href="+code=atat(&3a href="+code=brw" class="sref">brw3/a>->3a href="+code=write_ctr" class="sref">write_ctr3/a>))) {n
L61" class="line" namn>
L61">. 613/a>                3a href="+code=__this_cpu_add" class="sref">__this_cpu_add3/a>(*3a href="+code=brw" class="sref">brw3/a>->3a href="+code=fast_read_ctr" class="sref">fast_read_ctr3/a>, 3a href="+code=val" class="sref">val3/a>);

L62" class="line" namn>
L62">. 623/a>                3a href="+code=success" class="sref">success3/a> = 3a href="+code=true" class="sref">true3/a>;

L63" class="line" namn>
L63">. 633/a>        }

L64" class="line" namn>
L64">. 643/a>        3a href="+code=preempt_enable" class="sref">preempt_enable3/a>();

L65" class="line" namn>
L65">. 651"a>n
L66" class="line" namn>
L66">. 663/a>        return 3a href="+code=success" class="sref">success3/a>;

L67" class="line" namn>
L67">. 673/a>}

L68" class="line" namn>
L68">. 681"a>n
L69" class="line" namn>
L69">. 693/a>3spa
 class="comment">/*3/spa
  
L70" class="line" namn>
L70">. 703/a>3spa
 class="comment"> * Likeothe normal down_read() this is not recursive, the writer ca
3/spa
  
L71" class="line" namn>
L71">. 713/a>3spa
 class="comment"> * come after the first percpu_down_read() and createothe deadlock.3/spa
  
L72" class="line" namn>
L72">. 723/a>3spa
 class="comment"> *3/spa
  
L73" class="line" namn>
L73">. 733/a>3spa
 class="comment"> * Note: returns with lock_is_held(brw->rw_sem) == T for lockdep,3/spa
  
L74" class="line" namn>
L74">. 743/a>3spa
 class="comment"> * percpu_up_read() does rwsem_release(). This pairs with the usage3/spa
  
L75" class="line" namn>
L75">. 753/a>3spa
 class="comment"> * of ->rw_sem i
 percpu_down/up_write().3/spa
  
L76" class="line" namn>
L76">. 763/a>3spa
 class="comment"> */3/spa
  
L77" class="line" namn>
L77">. 773/a>void.3a href="+code=percpu_down_read" class="sref">percpu_down_read3/a>(struct.3a href="+code=percpu_rw_semaphore" class="sref">percpu_rw_semaphore3/a> *3a href="+code=brw" class="sref">brw3/a>)n
L78" class="line" namn>
L78">. 783/a>{n
L79" class="line" namn>
L79">. 793/a>        3a href="+code=might_sleep" class="sref">might_sleep3/a>();

L80" class="line" namn>
L80">. 803/a>        if (3a href="+code=likely" class="sref">likely3/a>(3a href="+code=update_fast_ctr" class="sref">update_fast_ctr3/a>(3a href="+code=brw" class="sref">brw3/a>, +1))) {n
L81" class="line" namn>
L81">. 813/a>                3a href="+code=rwsem_acquire_read" class="sref">rwsem_acquire_read3/a>(&3a href="+code=brw" class="sref">brw3/a>->3a href="+code=rw_sem" class="sref">rw_sem3/a>.3a href="+code=dep_map" class="sref">dep_map3/a>, 0, 0, 3a href="+code=_RET_IP_" class="sref">_RET_IP_3/a>);

L82" class="line" namn>
L82">. 823/a>                return;

L83" class="line" namn>
L83">. 833/a>        }

L84" class="line" namn>
L84">. 841"a>n
L85" class="line" namn>
L85">. 853/a>        3a href="+code=down_read" class="sref">down_read3/a>(&3a href="+code=brw" class="sref">brw3/a>->3a href="+code=rw_sem" class="sref">rw_sem3/a>);

L86" class="line" namn>
L86">. 863/a>        3a href="+code=atat(&3a href="+code=brw" class="sref">brw3/a>->3a href="+code=slow_read_ctr" class="sref">slow_read_ctr3/a>);

L87" class="line" namn>
L87">. 873/a>        3spa
 class="comment">/* avoid.up_read()->rwsem_release() */3/spa
  
L88" class="line" namn>
L88">. 883/a>        3a href="+code=__up_read" class="sref">__up_read3/a>(&3a href="+code=brw" class="sref">brw3/a>->3a href="+code=rw_sem" class="sref">rw_sem3/a>);

L89" class="line" namn>
L89">. 893/a>}

L90" class="line" namn>
L90">. 911"a>n
L91" class="line" namn>
L91">. 913/a>void.3a href="+code=percpu_up_read" class="sref">percpu_up_read3/a>(struct.3a href="+code=percpu_rw_semaphore" class="sref">percpu_rw_semaphore3/a> *3a href="+code=brw" class="sref">brw3/a>)n
L92" class="line" namn>
L92">. 923/a>{n
L93" class="line" namn>
L93">. 933/a>        3a href="+code=rwsem_release" class="sref">rwsem_release3/a>(&3a href="+code=brw" class="sref">brw3/a>->3a href="+code=rw_sem" class="sref">rw_sem3/a>.3a href="+code=dep_map" class="sref">dep_map3/a>, 1, 3a href="+code=_RET_IP_" class="sref">_RET_IP_3/a>);

L94" class="line" namn>
L94">. 941"a>n
L95" class="line" namn>
L95">. 953/a>        if (3a href="+code=likely" class="sref">likely3/a>(3a href="+code=update_fast_ctr" class="sref">update_fast_ctr3/a>(3a href="+code=brw" class="sref">brw3/a>, -1)))n
L96" class="line" namn>
L96">. 963/a>                return;

L97" class="line" namn>
L97">. 971"a>n
L98" class="line" namn>
L98">. 983/a>        3spa
 class="comment">/* false-positive is possible but harmless */3/spa
  
L99" class="line" namn>
L99">. 993/a>        if (3a href="+code=atat(&3a href="+code=brw" class="sref">brw3/a>->3a href="+code=slow_read_ctr" class="sref">slow_read_ctr3/a>))n
L100" class="line" namn>
L100">.1003/a>                3a href="+code=wake_up_all" class="sref">wake_up_all3/a>(&3a href="+code=brw" class="sref">brw3/a>->3a href="+code=write_waitq" class="sref">write_waitq3/a>);

L101" class="line" namn>
L101">.1013/a>}

L102" class="line" namn>
L102">.1021"a>n
L103" class="line" namn>
L103">.1033/a>static int.3a href="+code=clear_fast_ctr" class="sref">clear_fast_ctr3/a>(struct.3a href="+code=percpu_rw_semaphore" class="sref">percpu_rw_semaphore3/a> *3a href="+code=brw" class="sref">brw3/a>)n
L104" class="line" namn>
L104">.1043/a>{n
L105" class="line" namn>
L105">.1053/a>        unsigned int.3a href="+code=sum" class="sref">sum3/a> = 0;

L106" class="line" namn>
L106">.1063/a>        int.3a href="+code=cpu" class="sref">cpu3/a>;

L107" class="line" namn>
L107">.1071"a>n
L108" class="line" namn>
L108">.1083/a>        3a href="+code=for_each_possible_cpu" class="sref">for_each_possible_cpu3/a>(3a href="+code=cpu" class="sref">cpu3/a>) {n
L109" class="line" namn>
L109">.1093/a>                3a href="+code=sum" class="sref">sum3/a> += 3a href="+code=per_cpu" class="sref">per_cpu3/a>(*3a href="+code=brw" class="sref">brw3/a>->3a href="+code=fast_read_ctr" class="sref">fast_read_ctr3/a>, 3a href="+code=cpu" class="sref">cpu3/a>);

L110" class="line" namn>
L110">.1103/a>                3a href="+code=per_cpu" class="sref">per_cpu3/a>(*3a href="+code=brw" class="sref">brw3/a>->3a href="+code=fast_read_ctr" class="sref">fast_read_ctr3/a>, 3a href="+code=cpu" class="sref">cpu3/a>) = 0;

L111" class="line" namn>
L111">.1113/a>        }

L112" class="line" namn>
L112">.1121"a>n
L113" class="line" namn>
L113">.1133/a>        return 3a href="+code=sum" class="sref">sum3/a>;

L114" class="line" namn>
L114">.1143/a>}

L115" class="line" namn>
L115">.1151"a>n
L116" class="line" namn>
L116">.1163/a>3spa
 class="comment">/*3/spa
  
L117" class="line" namn>
L117">.1173/a>3spa
 class="comment"> * A writer increments ->write_ctr to force the readers to switch to the3/spa
  
L118" class="line" namn>
L118">.1183/a>3spa
 class="comment"> * slow mode, note the at
L119" class="line" namn>
L119">.1193/a>3spa
 class="comment"> *3/spa
  
L120" class="line" namn>
L120">.1203/a>3spa
 class="comment"> * After that the readers ca
 only inc/dec the slow ->slow_read_ctr counter,3/spa
  
L121" class="line" namn>
L121">.1213/a>3spa
 class="comment"> * ->fast_read_ctr is stable. Once the writer moves its sum into the slow3/spa
  
L122" class="line" namn>
L122">.1223/a>3spa
 class="comment"> * counter it represents the number of ac  ve readers.3/spa
  
L123" class="line" namn>
L123">.1233/a>3spa
 class="comment"> *3/spa
  
L124" class="line" namn>
L124">.1243/a>3spa
 class="comment"> * Finally the writer takes ->rw_sem for writing and blocks the new readers,3/spa
  
L125" class="line" namn>
L125">.1253/a>3spa
 class="comment"> * then waits until the slow counter becomes zero.3/spa
  
L126" class="line" namn>
L126">.1263/a>3spa
 class="comment"> */3/spa
  
L127" class="line" namn>
L127">.1273/a>void.3a href="+code=percpu_down_write" class="sref">percpu_down_write3/a>(struct.3a href="+code=percpu_rw_semaphore" class="sref">percpu_rw_semaphore3/a> *3a href="+code=brw" class="sref">brw3/a>)n
L128" class="line" namn>
L128">.1283/a>{n
L129" class="line" namn>
L129">.1293/a>        3spa
 class="comment">/* tell update_fast_ctr() there is a pending writer */3/spa
  
L130" class="line" namn>
L130">.1303/a>        3a href="+code=atat(&3a href="+code=brw" class="sref">brw3/a>->3a href="+code=write_ctr" class="sref">write_ctr3/a>);

L131" class="line" namn>
L131">.1313/a>        3spa
 class="comment">/*3/spa
  
L132" class="line" namn>
L132">.1323/a>3spa
 class="comment">         * 1. Ensures that write_ctr != 0 is visible to any down_read/up_read3/spa
  
L133" class="line" namn>
L133">.1333/a>3spa
 class="comment">         *    so that update_fast_ctr() ca
't succeed.3/spa
  
L134" class="line" namn>
L134">.1343/a>3spa
 class="comment">         *3/spa
  
L135" class="line" namn>
L135">.1353/a>3spa
 class="comment">         * 2. Ensures we see the result of every previous this_cpu_add() i
3/spa
  
L136" class="line" namn>
L136">.1363/a>3spa
 class="comment">         *    update_fast_ctr().3/spa
  
L137" class="line" namn>
L137">.1373/a>3spa
 class="comment">         *3/spa
  
L138" class="line" namn>
L138">.1383/a>3spa
 class="comment">         * 3. Ensures that if any reader has exited its critical sec  >
 via3/spa
  
L139" class="line" namn>
L139">.1393/a>3spa
 class="comment">         *    fast-path, it executes a full memory barrier before we return.3/spa
  
L140" class="line" namn>
L140">.1403/a>3spa
 class="comment">         *    SeeoR_W case inothe comment above update_fast_ctr().3/spa
  
L141" class="line" namn>
L141">.1413/a>3spa
 class="comment">         */3/spa
  
L142" class="line" namn>
L142">.1423/a>        3a href="+code=synchronize_sched_expedited" class="sref">synchronize_sched_expedited3/a>();

L143" class="line" namn>
L143">.1433/a>

L144" class="line" namn>
L144">.1443/a>        3spa
 class="comment">/* exclude other writers, and block the new readers completely */3/spa
  
L145" class="line" namn>
L145">.1453/a>        3a href="+code=down_write" class="sref">down_write3/a>(&3a href="+code=brw" class="sref">brw3/a>->3a href="+code=rw_sem" class="sref">rw_sem3/a>);

L146" class="line" namn>
L146">.1463/a>

L147" class="line" namn>
L147">.1473/a>        3spa
 class="comment">/* nobody ca
 use fast_read_ctr, move its sum into slow_read_ctr */3/spa
  
L148" class="line" namn>
L148">.1483/a>        3a href="+code=atat(3a href="+code=clear_fast_ctr" class="sref">clear_fast_ctr3/a>(3a href="+code=brw" class="sref">brw3/a>), &3a href="+code=brw" class="sref">brw3/a>->3a href="+code=slow_read_ctr" class="sref">slow_read_ctr3/a>);

L149" class="line" namn>
L149">.1493/a>

L150" class="line" namn>
L150">.1503/a>        3spa
 class="comment">/* wait for all readers to complete their percpu_up_read() */3/spa
  
L151" class="line" namn>
L151">.1513/a>        3a href="+code=wait_event" class="sref">wait_event3/a>(3a href="+code=brw" class="sref">brw3/a>->3a href="+code=write_waitq" class="sref">write_waitq3/a>, !3a href="+code=atat(&3a href="+code=brw" class="sref">brw3/a>->3a href="+code=slow_read_ctr" class="sref">slow_read_ctr3/a>));

L152" class="line" namn>
L152">.1523/a>}

L153" class="line" namn>
L153">.1533/a>

L154" class="line" namn>
L154">.1543/a>void.3a href="+code=percpu_up_write" class="sref">percpu_up_write3/a>(struct.3a href="+code=percpu_rw_semaphore" class="sref">percpu_rw_semaphore3/a> *3a href="+code=brw" class="sref">brw3/a>)n
L155" class="line" namn>
L155">.1553/a>{n
L156" class="line" namn>
L156">.1563/a>        3spa
 class="comment">/* release the lock, but the readers ca
't use the fast-path */3/spa
  
L157" class="line" namn>
L157">.1573/a>        3a href="+code=up_write" class="sref">up_write3/a>(&3a href="+code=brw" class="sref">brw3/a>->3a href="+code=rw_sem" class="sref">rw_sem3/a>);

L158" class="line" namn>
L158">.1583/a>        3spa
 class="comment">/*3/spa
  
L159" class="line" namn>
L159">.1593/a>3spa
 class="comment">         * Insert the barrier before the next fast-path i
 down_read,3/spa
  
L160" class="line" namn>
L160">.1603/a>3spa
 class="comment">         * see W_R case inothe comment above update_fast_ctr().3/spa
  
L161" class="line" namn>
L161">.1613/a>3spa
 class="comment">         */3/spa
  
L162" class="line" namn>
L162">.1623/a>        3a href="+code=synchronize_sched_expedited" class="sref">synchronize_sched_expedited3/a>();

L163" class="line" namn>
L163">.1633/a>        3spa
 class="comment">/* the last writer unblocks update_fast_ctr() */3/spa
  
L164" class="line" namn>
L164">.1643/a>        3a href="+code=atat(&3a href="+code=brw" class="sref">brw3/a>->3a href="+code=write_ctr" class="sref">write_ctr3/a>);

L165" class="line" namn>
L165">.1651"a>}

L166" class="line" namn>
L166">.1663/a>
The original LXR software by the LXR community3/a>, this experimental vers > by lxr@linux.no3/a>. 3/div 3div class="subfooter"> lxr.linux.no kindly hosted by Redpill Linpro AS3/a>, provider of Linux consulting and opera > s services since 1995. 3/div 3/body 3/html