linux/net/dccp/ackvec.c
<<
.5" /spaon> /formn> a .5" href="../linux+v3 3.2/net/dccp/ackvec.c">.5" img src="../.static/gfx/right.png" alt=">>">.5 /spaon>.5 spao class="lxr_search">.5" .5" input typue=hidden" namue=navtarget" value=">.5" input typue=text" namue=search" ide=search">.5" buttiontypue=submit">Search /formn> /spaon>.5 spao class="lxr_prefs"n> a href="+prefs?return=net/dccp/ackvec.c".5" onclick="return ajax_prefs();">.5" Prefs> /a>.5 /spaon>" /divn>" form acptio="ajax+*" method="post" onsubmit="return false;">.5 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"> *  net/dccp/ackvec.c /spaon>   3 /a> spao class="comment"> * /spaon>   4 /a> spao class="comment"> *  An implementaptionof Ack Vectors for the DCCP protocol /spaon>   5 /a> spao class="comment"> *  Copyright (c) 2007 Universitynof Aberdeen, Scotland, UK /spaon>   6 /a> spao class="comment"> *  Copyright (c) 2005 Arnaldo Car vaho de Melo <acme@ghostprotocols.net> /spaon>   7 /a> spao class="comment"> * /spaon>   8 /a> spao class="comment"> *      This program is free software; you cao redistribute it and/or modify it /spaon>   9 /a> spao class="comment"> *      under the termsnof the GNU General Public License as published by the /spaon>  .11 spao class="comment"> *      Free Software Foundaptio; versiion2nof the License; /spaon>  11 /a> spao class="comment"> */ /spaon>  12 /a>#include " a href="net/dccp/dccp.h" class="fref">dccp.h /a>">  13 /a>#include < a href="include/linux/kernel.h" class="fref">linux/kernel.h /a>>>  14 /a>#include < a href="include/linux/slab.h" class="fref">linux/slab.h /a>>>  15 /a>#include < a href="include/linux/export.h" class="fref">linux/export.h /a>>>  16 /a>>  17 /a>static struct  a href="+code=kmem_cache" class="sref">kmem_cache /a> * a href="+code=dccp_ackvec_slab" class="sref">dccp_ackvec_slab /a>;>  18 /a>static struct  a href="+code=kmem_cache" class="sref">kmem_cache /a> * a href="+code=dccp_ackvec_record_slab" class="sref">dccp_ackvec_record_slab /a>;>  19 /a>>  20 /a>struct  a href="+code=dccp_ackvec" class="sref">dccp_ackvec /a> * a href="+code=dccp_ackvec_alloc" class="sref">dccp_ackvec_alloc /a>(const  a href="+code=gfp_t" class="sref">gfp_t /a>  a href="+code=priority" class="sref">priority /a>)>  21 /a>{>  22 /a>        struct  a href="+code=dccp_ackvec" class="sref">dccp_ackvec /a> * a href="+code=av" class="sref">av /a> =  a href="+code=kmem_cache_zalloc" class="sref">kmem_cache_zalloc /a>( a href="+code=dccp_ackvec_slab" class="sref">dccp_ackvec_slab /a>,  a href="+code=priority" class="sref">priority /a>);>  23 /a>>  24 /a>        if ( a href="+code=av" class="sref">av /a> !=  a href="+code=NULL" class="sref">NULL /a>) {>  25 /a>                 a href="+code=av" class="sref">av /a>-> a href="+code=av_buf_head" class="sref">av_buf_head /a> =  a href="+code=av" class="sref">av /a>-> a href="+code=av_buf_tail" class="sref">av_buf_tail /a> =  a href="+code=DCCPAV_MAX_ACKVEC_LEN" class="sref">DCCPAV_MAX_ACKVEC_LEN /a> - 1;>  26 /a>                 a href="+code=INIT_LIST_HEAD" class="sref">INIT_LIST_HEAD /a>(& a href="+code=av" class="sref">av /a>-> a href="+code=av_records" class="sref">av_records /a>);>  27 /a>        }>  28 /a>        return  a href="+code=av" class="sref">av /a>;>  29 /a>}>  30 /a>>  31 /a>static void  a href="+code=dccp_ackvec_purge_records" class="sref">dccp_ackvec_purge_records /a>(struct  a href="+code=dccp_ackvec" class="sref">dccp_ackvec /a> * a href="+code=av" class="sref">av /a>)>  32 /a>{>  33 /a>        struct  a href="+code=dccp_ackvec_record" class="sref">dccp_ackvec_record /a> * a href="+code=cur" class="sref">cur /a>, * a href="+code=next" class="sref">next /a>;>  34 /a>>  35 /a>         a href="+code=list_for_each_entry_safe" class="sref">list_for_each_entry_safe /a>( a href="+code=cur" class="sref">cur /a>,  a href="+code=next" class="sref">next /a>, & a href="+code=av" class="sref">av /a>-> a href="+code=av_records" class="sref">av_records /a>,  a href="+code=avr_node" class="sref">avr_node /a>)>  36 /a>                 a href="+code=kmem_cache_free" class="sref">kmem_cache_free /a>( a href="+code=dccp_ackvec_record_slab" class="sref">dccp_ackvec_record_slab /a>,  a href="+code=cur" class="sref">cur /a>);>  37 /a>         a href="+code=INIT_LIST_HEAD" class="sref">INIT_LIST_HEAD /a>(& a href="+code=av" class="sref">av /a>-> a href="+code=av_records" class="sref">av_records /a>);>  38 /a>}>  39 /a>>  40 /a>void  a href="+code=dccp_ackvec_free" class="sref">dccp_ackvec_free /a>(struct  a href="+code=dccp_ackvec" class="sref">dccp_ackvec /a> * a href="+code=av" class="sref">av /a>)>  41 /a>{>  42 /a>        if ( a href="+code=likely" class="sref">likely /a>( a href="+code=av" class="sref">av /a> !=  a href="+code=NULL" class="sref">NULL /a>)) {>  43 /a>                 a href="+code=dccp_ackvec_purge_records" class="sref">dccp_ackvec_purge_records /a>( a href="+code=av" class="sref">av /a>);>  44 /a>                 a href="+code=kmem_cache_free" class="sref">kmem_cache_free /a>( a href="+code=dccp_ackvec_slab" class="sref">dccp_ackvec_slab /a>,  a href="+code=av" class="sref">av /a>);>  45 /a>        }>  46 /a>}>  47 /a>>  48 /a> spao class="comment">/** /spaon>  49 /a> spao class="comment"> * dccp_ackvec_update_records  -  Record informaptionabout sent Ack Vectors /spaon>  511 spao class="comment"> * @av:         Ack Vector records to update /spaon>  51 /a> spao class="comment"> * @seqno:      Sequence numbernof the packet carrying the Ack Vector just sent /spaon>  52 /a> spao class="comment"> * @nonce_sum:  The sumnof all buffernnonces contained in the Ack Vector /spaon>  53 /a> spao class="comment"> */ /spaon>  54 /a>int  a href="+code=dccp_ackvec_update_records" class="sref">dccp_ackvec_update_records /a>(struct  a href="+code=dccp_ackvec" class="sref">dccp_ackvec /a> * a href="+code=av" class="sref">av /a>,  a href="+code=u64" class="sref">u64 /a>  a href="+code=seqno" class="sref">seqno /a>,  a href="+code=u8" class="sref">u8 /a>  a href="+code=nonce_sum" class="sref">nonce_sum /a>)>  55 /a>{>  56 /a>        struct  a href="+code=dccp_ackvec_record" class="sref">dccp_ackvec_record /a> * a href="+code=avr" class="sref">avr /a>;>  57 /a>>  58 /a>         a href="+code=avr" class="sref">avr /a> =  a href="+code=kmem_cache_alloc" class="sref">kmem_cache_alloc /a>( a href="+code=dccp_ackvec_record_slab" class="sref">dccp_ackvec_record_slab /a>,  a href="+code=GFP_ATOMIC" class="sref">GFP_ATOMIC /a>);>  59 /a>        if ( a href="+code=avr" class="sref">avr /a> ==  a href="+code=NULL" class="sref">NULL /a>)>  60 /a>                return - a href="+code=ENOBUFS" class="sref">ENOBUFS /a>;>  61 /a>>  62 /a>         a href="+code=avr" class="sref">avr /a>-> a href="+code=avr_ack_seqno" class="sref">avr_ack_seqno /a>  =  a href="+code=seqno" class="sref">seqno /a>;>  63 /a>         a href="+code=avr" class="sref">avr /a>-> a href="+code=avr_ack_ptr" class="sref">avr_ack_ptr /a>    =  a href="+code=av" class="sref">av /a>-> a href="+code=av_buf_head" class="sref">av_buf_head /a>;>  64 /a>         a href="+code=avr" class="sref">avr /a>-> a href="+code=avr_ack_ackno" class="sref">avr_ack_ackno /a>  =  a href="+code=av" class="sref">av /a>-> a href="+code=av_buf_ackno" class="sref">av_buf_ackno /a>;>  65 /a>         a href="+code=avr" class="sref">avr /a>-> a href="+code=avr_ack_nonce" class="sref">avr_ack_nonce /a>  =  a href="+code=nonce_sum" class="sref">nonce_sum /a>;>  66 /a>         a href="+code=avr" class="sref">avr /a>-> a href="+code=avr_ack_runlen" class="sref">avr_ack_runlen /a> =  a href="+code=dccp_ackvec_runlen" class="sref">dccp_ackvec_runlen /a>( a href="+code=av" class="sref">av /a>-> a href="+code=av_buf" class="sref">av_buf /a> +  a href="+code=av" class="sref">av /a>-> a href="+code=av_buf_head" class="sref">av_buf_head /a>);>  67 /a>         spao class="comment">/* /spaon>  68 /a> spao class="comment">         * When the buffernoverflows, we keepnno more thao one record. This is /spaon>  69 /a> spao class="comment">         * the simplest waynof disambiguating sender-Acks dating from before the /spaon>  711 spao class="comment">         * overflow from sender-Acks which refernto after the overflow; a simple /spaon>  71 /a> spao class="comment">         * soluptionis preferable here since we are haodling ao exceoptio. /spaon>  72 /a> spao class="comment">         */ /spaon>  73 /a>        if ( a href="+code=av" class="sref">av /a>-> a href="+code=av_overflow" class="sref">av_overflow /a>)>  74 /a>                 a href="+code=dccp_ackvec_purge_records" class="sref">dccp_ackvec_purge_records /a>( a href="+code=av" class="sref">av /a>);>  75 /a>         spao class="comment">/* /spaon>  76 /a> spao class="comment">         * Since GSSnis incremented for each packet, the listnis automaptcally /spaon>  77 /a> spao class="comment">         * arranged in descending ordernof @ack_seqno. /spaon>  78 /a> spao class="comment">         */ /spaon>  79 /a>         a href="+code=list_add" class="sref">list_add /a>(& a href="+code=avr" class="sref">avr /a>-> a href="+code=avr_node" class="sref">avr_node /a>, & a href="+code=av" class="sref">av /a>-> a href="+code=av_records" class="sref">av_records /a>);>  80 /a>>  81 /a>         a href="+code=dccp_pr_debug" class="sref">dccp_pr_debug /a>( spao class="string">"Added Vector, ack_seqno=%llu, ack_ackno=%llu (rl=%u)\n" /spaon,>  82 /a>                      (unsigned long long) a href="+code=avr" class="sref">avr /a>-> a href="+code=avr_ack_seqno" class="sref">avr_ack_seqno /a>,>  83 /a>                      (unsigned long long) a href="+code=avr" class="sref">avr /a>-> a href="+code=avr_ack_ackno" class="sref">avr_ack_ackno /a>,>  84 /a>                       a href="+code=avr" class="sref">avr /a>-> a href="+code=avr_ack_runlen" class="sref">avr_ack_runlen /a>);>  85 /a>        return 0;>  86 /a>}>  87 /a>>  88 /a>static struct  a href="+code=dccp_ackvec_record" class="sref">dccp_ackvec_record /a> * a href="+code=dccp_ackvec_lookup" class="sref">dccp_ackvec_lookup /a>(struct  a href="+code=list_head" class="sref">list_head /a> * a href="+code=av_list" class="sref">av_list /a>,>  89 /a>                                                     const  a href="+code=u64" class="sref">u64 /a>  a href="+code=ackno" class="sref">ackno /a>)>  90 /a>{>  91 /a>        struct  a href="+code=dccp_ackvec_record" class="sref">dccp_ackvec_record /a> * a href="+code=avr" class="sref">avr /a>;>  92 /a>         spao class="comment">/* /spaon>  93 /a> spao class="comment">         * Exploit that records are inserted in descending ordernof sequence /spaon>  94 /a> spao class="comment">         * number, start with the oldest record first. If @acknonis `before' /spaon>  95 /a> spao class="comment">         * the earliest ack_ackno, the packet is too oldnto be considered. /spaon>  96 /a> spao class="comment">         */ /spaon>  97 /a>         a href="+code=list_for_each_entry_reverse" class="sref">list_for_each_entry_reverse /a>( a href="+code=avr" class="sref">avr /a>,  a href="+code=av_list" class="sref">av_list /a>,  a href="+code=avr_node" class="sref">avr_node /a>) {>  98 /a>                if ( a href="+code=avr" class="sref">avr /a>-> a href="+code=avr_ack_seqno" class="sref">avr_ack_seqno /a> ==  a href="+code=ackno" class="sref">ackno /a>)>  99 /a>                        return  a href="+code=avr" class="sref">avr /a>;> 100 /a>                if ( a href="+code=before48" class="sref">before48 /a>( a href="+code=ackno" class="sref">ackno /a>,  a href="+code=avr" class="sref">avr /a>-> a href="+code=avr_ack_seqno" class="sref">avr_ack_seqno /a>))> 101 /a>                        break;> 102 /a>        }> 103 /a>        return  a href="+code=NULL" class="sref">NULL /a>;> 104 /a>}> 105 /a>> 106 /a> spao class="comment">/* /spaon> 107 /a> spao class="comment"> * Buffernindex and length computaptionusing modulo-buffersize arithmetic. /spaon> 108 /a> spao class="comment"> * Note that, as pointers move from right to left, headnis `before' tail. /spaon> 109 /a> spao class="comment"> */ /spaon> 110 /a>static  a href="+code=inline" class="sref">inline /a>  a href="+code=u16" class="sref">u16 /a>  a href="+code=__ackvec_idx_add" class="sref">__ackvec_idx_add /a>(const  a href="+code=u16" class="sref">u16 /a>  a href="+code=a" class="sref">a /a>, const  a href="+code=u16" class="sref">u16 /a>  a href="+code=b" class="sref">b /a>)> 111 /a>{> 112 /a>        return ( a href="+code=a" class="sref">a /a> +  a href="+code=b" class="sref">b /a>) %  a href="+code=DCCPAV_MAX_ACKVEC_LEN" class="sref">DCCPAV_MAX_ACKVEC_LEN /a>;> 113 /a>}> 114 /a>> 115 /a>static  a href="+code=inline" class="sref">inline /a>  a href="+code=u16" class="sref">u16 /a>  a href="+code=__ackvec_idx_sub" class="sref">__ackvec_idx_sub /a>(const  a href="+code=u16" class="sref">u16 /a>  a href="+code=a" class="sref">a /a>, const  a href="+code=u16" class="sref">u16 /a>  a href="+code=b" class="sref">b /a>)> 116 /a>{> 117 /a>        return  a href="+code=__ackvec_idx_add" class="sref">__ackvec_idx_add /a>( a href="+code=a" class="sref">a /a>,  a href="+code=DCCPAV_MAX_ACKVEC_LEN" class="sref">DCCPAV_MAX_ACKVEC_LEN /a> -  a href="+code=b" class="sref">b /a>);> 118 /a>}> 119 /a>> 120 /a> a href="+code=u16" class="sref">u16 /a>  a href="+code=dccp_ackvec_buflen" class="sref">dccp_ackvec_buflen /a>(const struct  a href="+code=dccp_ackvec" class="sref">dccp_ackvec /a> * a href="+code=av" class="sref">av /a>)> 121 /a>{> 122 /a>        if ( a href="+code=unlikely" class="sref">unlikely /a>( a href="+code=av" class="sref">av /a>-> a href="+code=av_overflow" class="sref">av_overflow /a>))> 123 /a>                return  a href="+code=DCCPAV_MAX_ACKVEC_LEN" class="sref">DCCPAV_MAX_ACKVEC_LEN /a>;> 124 /a>        return  a href="+code=__ackvec_idx_sub" class="sref">__ackvec_idx_sub /a>( a href="+code=av" class="sref">av /a>-> a href="+code=av_buf_tail" class="sref">av_buf_tail /a>,  a href="+code=av" class="sref">av /a>-> a href="+code=av_buf_head" class="sref">av_buf_head /a>);> 125 /a>}> 126 /a>> 127 /a> spao class="comment">/** /spaon> 128 /a> spao class="comment"> * dccp_ackvec_update_oldn -  Update previous state as pernRFC 4340, 11.14.3 129 /a> spao class="comment"> * @av:         non-empty buffernto update /spaon> 1311 spao class="comment"> * @distance:   negative or zero distancenof @seqno from buf_ackno downward /spaon> 131 /a> spao class="comment"> * @seqno:      the (old) sequence numbernwhose record is to be updated /spaon> 132 /a> spao class="comment"> * @state:      state in which packet carrying @seqno was received /spaon> 133 /a> spao class="comment"> */ /spaon> 134 /a>static void  a href="+code=dccp_ackvec_update_old" class="sref">dccp_ackvec_update_old /a>(struct  a href="+code=dccp_ackvec" class="sref">dccp_ackvec /a> * a href="+code=av" class="sref">av /a>,  a href="+code=s64" class="sref">s64 /a>  a href="+code=distance" class="sref">distance /a>,> 135 /a>                                    a href="+code=u64" class="sref">u64 /a>  a href="+code=seqno" class="sref">seqno /a>, enum  a href="+code=dccp_ackvec_states" class="sref">dccp_ackvec_states /a>  a href="+code=state" class="sref">state /a>)> 136 /a>{> 137 /a>         a href="+code=u16" class="sref">u16 /a>  a href="+code=ptr" class="sref">ptr /a> =  a href="+code=av" class="sref">av /a>-> a href="+code=av_buf_head" class="sref">av_buf_head /a>;> 138 /a>> 139 /a>         a href="+code=BUG_ON" class="sref">BUG_ON /a>( a href="+code=distance" class="sref">distance /a> > 0);> 140 /a>        if ( a href="+code=unlikely" class="sref">unlikely /a>( a href="+code=dccp_ackvec_is_empty" class="sref">dccp_ackvec_is_empty /a>( a href="+code=av" class="sref">av /a>)))> 141 /a>                return;> 142 /a>> 143 /a>        do {> 144 /a>                 a href="+code=u8" class="sref">u8 /a>  a href="+code=runlen" class="sref">runlen /a> =  a href="+code=dccp_ackvec_runlen" class="sref">dccp_ackvec_runlen /a>( a href="+code=av" class="sref">av /a>-> a href="+code=av_buf" class="sref">av_buf /a> +  a href="+code=ptr" class="sref">ptr /a>);> 145 /a>> 146 /a>                if ( a href="+code=distance" class="sref">distance /a> +  a href="+code=runlen" class="sref">runlen /a> >= 0) {> 147 /a>                         spao class="comment">/* /spaon> 148 /a> spao class="comment">                         * Only update the state if packet has not been received /spaon> 149 /a> spao class="comment">                         * yet. This is OK as pernthe second table in RFC 4340, /spaon> 1511 spao class="comment">                         * 11.14.; i.e. here we are using the following table: /spaon> 151 /a> spao class="comment">                         *                     RECEIVED /spaon> 152 /a> spao class="comment">                         *                      0   1   3 /spaon> 153 /a> spao class="comment">                         *              S     +---+---+---+ /spaon> 154 /a> spao class="comment">                         *              T   0 | 0 | 0 | 0 | /spaon> 155 /a> spao class="comment">                         *              O     +---+---+---+ /spaon> 156 /a> spao class="comment">                         *              R   1 | 1 | 1 | 1 | /spaon> 157 /a> spao class="comment">                         *              E     +---+---+---+ /spaon> 158 /a> spao class="comment">                         *              D   3 | 0 | 1 | 3 | /spaon> 159 /a> spao class="comment">                         *                    +---+---+---+ /spaon> 1611 spao class="comment">                         * The "Not Received" state was set by reserve_seats(). /spaon> 161 /a> spao class="comment">                         */ /spaon> 162 /a>                        if ( a href="+code=av" class="sref">av /a>-> a href="+code=av_buf" class="sref">av_buf /a>[ a href="+code=ptr" class="sref">ptr /a>] ==  a href="+code=DCCPAV_NOT_RECEIVED" class="sref">DCCPAV_NOT_RECEIVED /a>)> 163 /a>                                 a href="+code=av" class="sref">av /a>-> a href="+code=av_buf" class="sref">av_buf /a>[ a href="+code=ptr" class="sref">ptr /a>] =  a href="+code=state" class="sref">state /a>;> 164 /a>                        else> 165 /a>                                 a href="+code=dccp_pr_debug" class="sref">dccp_pr_debug /a>( spao class="string">"Not changing %llu state to %u\n" /spaon,> 166 /a>                                              (unsigned long long) a href="+code=seqno" class="sref">seqno /a>,  a href="+code=state" class="sref">state /a>);> 167 /a>                        break;> 168 /a>                }> 169 /a>> 170 /a>                 a href="+code=distance" class="sref">distance /a> +=  a href="+code=runlen" class="sref">runlen /a> + 1;> 171 /a>                 a href="+code=ptr" class="sref">ptr /a>       =  a href="+code=__ackvec_idx_add" class="sref">__ackvec_idx_add /a>( a href="+code=ptr" class="sref">ptr /a>, 1);> 172 /a>> 173 /a>        } while ( a href="+code=ptr" class="sref">ptr /a> !=  a href="+code=av" class="sref">av /a>-> a href="+code=av_buf_tail" class="sref">av_buf_tail /a>);> 174 /a>}> 175 /a>> 176 /a> spao class="comment">/* Mark @num entries after buf_head as "Not yet received". */ /spaon> 177 /a>static void  a href="+code=dccp_ackvec_reserve_seats" class="sref">dccp_ackvec_reserve_seats /a>(struct  a href="+code=dccp_ackvec" class="sref">dccp_ackvec /a> * a href="+code=av" class="sref">av /a>,  a href="+code=u16" class="sref">u16 /a>  a href="+code=num" class="sref">num /a>)> 178 /a>{> 179 /a>         a href="+code=u16" class="sref">u16 /a>  a href="+code=start" class="sref">start /a> =  a href="+code=__ackvec_idx_add" class="sref">__ackvec_idx_add /a>( a href="+code=av" class="sref">av /a>-> a href="+code=av_buf_head" class="sref">av_buf_head /a>, 1),> 180 /a>             a href="+code=len" class="sref">len /a>   =  a href="+code=DCCPAV_MAX_ACKVEC_LEN" class="sref">DCCPAV_MAX_ACKVEC_LEN /a> -  a href="+code=start" class="sref">start /a>;> 181 /a>> 182 /a>         spao class="comment">/* check for buffernwrap-around */ /spaon> 183 /a>        if ( a href="+code=num" class="sref">num /a> >  a href="+code=len" class="sref">len /a>) {> 184 /a>                 a href="+code=memset" class="sref">memset /a>( a href="+code=av" class="sref">av /a>-> a href="+code=av_buf" class="sref">av_buf /a> +  a href="+code=start" class="sref">start /a>,  a href="+code=DCCPAV_NOT_RECEIVED" class="sref">DCCPAV_NOT_RECEIVED /a>,  a href="+code=len" class="sref">len /a>);> 185 /a>                 a href="+code=start" class="sref">start /a> = 0;> 186 /a>                 a href="+code=num" class="sref">num /a>  -=  a href="+code=len" class="sref">len /a>;> 187 /a>        }> 188 /a>        if ( a href="+code=num" class="sref">num /a>)> 189 /a>                 a href="+code=memset" class="sref">memset /a>( a href="+code=av" class="sref">av /a>-> a href="+code=av_buf" class="sref">av_buf /a> +  a href="+code=start" class="sref">start /a>,  a href="+code=DCCPAV_NOT_RECEIVED" class="sref">DCCPAV_NOT_RECEIVED /a>,  a href="+code=num" class="sref">num /a>);> 190 /a>}> 191 /a>> 192 /a> spao class="comment">/** /spaon> 193 /a> spao class="comment"> * dccp_ackvec_add_new  -  Record one or more new entries in Ack Vector buffer /spaon> 194 /a> spao class="comment"> * @av:          containernof buffernto update (cao be empty or non-empty) /spaon> 195 /a> spao class="comment"> * @num_packets: numbernof packetsnto register (must be >= 1) /spaon> 196 /a> spao class="comment"> * @seqno:       sequence numbernof the first packet in @num_packets /spaon> 197 /a> spao class="comment"> * @state:       state in which packet carrying @seqno was received /spaon> 198 /a> spao class="comment"> */ /spaon> 199 /a>static void  a href="+code=dccp_ackvec_add_new" class="sref">dccp_ackvec_add_new /a>(struct  a href="+code=dccp_ackvec" class="sref">dccp_ackvec /a> * a href="+code=av" class="sref">av /a>,  a href="+code=u32" class="sref">u32 /a>  a href="+code=num_packets" class="sref">num_packets /a>,> 200 /a>                                 a href="+code=u64" class="sref">u64 /a>  a href="+code=seqno" class="sref">seqno /a>, enum  a href="+code=dccp_ackvec_states" class="sref">dccp_ackvec_states /a>  a href="+code=state" class="sref">state /a>)> 201 /a>{> 202 /a>         a href="+code=u32" class="sref">u32 /a>  a href="+code=num_cells" class="sref">num_cells /a> =  a href="+code=num_packets" class="sref">num_packets /a>;> 203 /a>> 204 /a>        if ( a href="+code=num_packets" class="sref">num_packets /a> >  a href="+code=DCCPAV_BURST_THRESH" class="sref">DCCPAV_BURST_THRESH /a>) {> 205 /a>                 a href="+code=u32" class="sref">u32 /a>  a href="+code=lost_packets" class="sref">lost_packets /a> =  a href="+code=num_packets" class="sref">num_packets /a> - 1;> 206 /a>> 207 /a>                 a href="+code=DCCP_WARN" class="sref">DCCP_WARN /a>( spao class="string">"Warning: large burst loss (%u)\n" /spaon,  a href="+code=lost_packets" class="sref">lost_packets /a>);> 208 /a>                 spao class="comment">/* /spaon> 209 /a> spao class="comment">                 * We received 1 packet and have a loss of size "num_packets-1" /spaon> 2111 spao class="comment">                 * which we squeeze into num_cells-1 rather thao reserving ao /spaon> 211 /a> spao class="comment">                 * entire byte for each lost packet. /spaon> 212 /a> spao class="comment">                 * The reasionis that the vector grows in O(burst_length); wheo /spaon> 213 /a> spao class="comment">                 * it grows too large there willnno room left for the payload. /spaon> 214 /a> spao class="comment">                 * This is a trade-off: if a few packetsnout of the burst show /spaon> 215 /a> spao class="comment">                 * up later, their state willnnot be changed; it is simply too /spaon> 216 /a> spao class="comment">                 * costly to reshuffle/reallocate/copy the bufferneach time. /spaon> 217 /a> spao class="comment">                 * Should such problems persist, we willnneednto switch to a /spaon> 218 /a> spao class="comment">                 * different underlying data structure. /spaon> 219 /a> spao class="comment">                 */ /spaon> 220 /a>                for ( a href="+code=num_packets" class="sref">num_packets /a> =  a href="+code=num_cells" class="sref">num_cells /a> = 1;  a href="+code=lost_packets" class="sref">lost_packets /a>; ++ a href="+code=num_cells" class="sref">num_cells /a>) {> 221 /a>                         a href="+code=u8" class="sref">u8 /a>  a href="+code=len" class="sref">len /a> =  a href="+code=min" class="sref">min /a>( a href="+code=lost_packets" class="sref">lost_packets /a>, ( a href="+code=u32" class="sref">u32 /a>) a href="+code=DCCPAV_MAX_RUNLEN" class="sref">DCCPAV_MAX_RUNLEN /a>);> 222 /a>> 223 /a>                         a href="+code=av" class="sref">av /a>-> a href="+code=av_buf_head" class="sref">av_buf_head /a> =  a href="+code=__ackvec_idx_sub" class="sref">__ackvec_idx_sub /a>( a href="+code=av" class="sref">av /a>-> a href="+code=av_buf_head" class="sref">av_buf_head /a>, 1);> 224 /a>                         a href="+code=av" class="sref">av /a>-> a href="+code=av_buf" class="sref">av_buf /a>[ a href="+code=av" class="sref">av /a>-> a href="+code=av_buf_head" class="sref">av_buf_head /a>] =  a href="+code=DCCPAV_NOT_RECEIVED" class="sref">DCCPAV_NOT_RECEIVED /a> |  a href="+code=len" class="sref">len /a>;> 225 /a>> 226 /a>                         a href="+code=lost_packets" class="sref">lost_packets /a> -=  a href="+code=len" class="sref">len /a>;> 227 /a>                }> 228 /a>        }> 229 /a>> 230 /a>        if ( a href="+code=num_cells" class="sref">num_cells /a> +  a href="+code=dccp_ackvec_buflen" class="sref">dccp_ackvec_buflen /a>( a href="+code=av" class="sref">av /a>) >=  a href="+code=DCCPAV_MAX_ACKVEC_LEN" class="sref">DCCPAV_MAX_ACKVEC_LEN /a>) {> 231 /a>                 a href="+code=DCCP_CRIT" class="sref">DCCP_CRIT /a>( spao class="string">"Ack Vector buffer overflow: dropping old entries\n" /spaon);> 232 /a>                 a href="+code=av" class="sref">av /a>-> a href="+code=av_overflow" class="sref">av_overflow /a> =  a href="+code=true" class="sref">true /a>;> 233 /a>        }> 234 /a>> 235 /a>         a href="+code=av" class="sref">av /a>-> a href="+code=av_buf_head" class="sref">av_buf_head /a> =  a href="+code=__ackvec_idx_sub" class="sref">__ackvec_idx_sub /a>( a href="+code=av" class="sref">av /a>-> a href="+code=av_buf_head" class="sref">av_buf_head /a>,  a href="+code=num_packets" class="sref">num_packets /a>);> 236 /a>        if ( a href="+code=av" class="sref">av /a>-> a href="+code=av_overflow" class="sref">av_overflow /a>)> 237 /a>                 a href="+code=av" class="sref">av /a>-> a href="+code=av_buf_tail" class="sref">av_buf_tail /a> =  a href="+code=av" class="sref">av /a>-> a href="+code=av_buf_head" class="sref">av_buf_head /a>;> 238 /a>> 239 /a>         a href="+code=av" class="sref">av /a>-> a href="+code=av_buf" class="sref">av_buf /a>[ a href="+code=av" class="sref">av /a>-> a href="+code=av_buf_head" class="sref">av_buf_head /a>] =  a href="+code=state" class="sref">state /a>;> 240 /a>         a href="+code=av" class="sref">av /a>-> a href="+code=av_buf_ackno" class="sref">av_buf_ackno /a>            =  a href="+code=seqno" class="sref">seqno /a>;> 241 /a>> 242 /a>        if ( a href="+code=num_packets" class="sref">num_packets /a> > 1)> 243 /a>                 a href="+code=dccp_ackvec_reserve_seats" class="sref">dccp_ackvec_reserve_seats /a>( a href="+code=av" class="sref">av /a>,  a href="+code=num_packets" class="sref">num_packets /a> - 1);> 244 /a>}> 245 /a>> 246 /a> spao class="comment">/** /spaon> 247 /a> spao class="comment"> * dccp_ackvec_input  -  Register incoming packet in the buffer /spaon> 248 /a> spao class="comment"> */ /spaon> 249 /a>void  a href="+code=dccp_ackvec_input" class="sref">dccp_ackvec_input /a>(struct  a href="+code=dccp_ackvec" class="sref">dccp_ackvec /a> * a href="+code=av" class="sref">av /a>, struct  a href="+code=sk_buff" class="sref">sk_buff /a> * a href="+code=skb" class="sref">skb /a>)> 250 /a>{> 251 /a>         a href="+code=u64" class="sref">u64 /a>  a href="+code=seqno" class="sref">seqno /a> =  a href="+code=DCCP_SKB_CB" class="sref">DCCP_SKB_CB /a>( a href="+code=skb" class="sref">skb /a>)-> a href="+code=dccpd_seq" class="sref">dccpd_seq /a>;> 252 /a>        enum  a href="+code=dccp_ackvec_states" class="sref">dccp_ackvec_states /a>  a href="+code=state" class="sref">state /a> =  a href="+code=DCCPAV_RECEIVED" class="sref">DCCPAV_RECEIVED /a>;> 253 /a>> 254 /a>        if ( a href="+code=dccp_ackvec_is_empty" class="sref">dccp_ackvec_is_empty /a>( a href="+code=av" class="sref">av /a>)) {> 255 /a>                 a href="+code=dccp_ackvec_add_new" class="sref">dccp_ackvec_add_new /a>( a href="+code=av" class="sref">av /a>, 1,  a href="+code=seqno" class="sref">seqno /a>,  a href="+code=state" class="sref">state /a>);> 256 /a>                 a href="+code=av" class="sref">av /a>-> a href="+code=av_tail_ackno" class="sref">av_tail_ackno /a> =  a href="+code=seqno" class="sref">seqno /a>;> 257 /a>> 258 /a>        } else {> 259 /a>                 a href="+code=s64" class="sref">s64 /a>  a href="+code=num_packets" class="sref">num_packets /a> =  a href="+code=dccp_delta_seqno" class="sref">dccp_delta_seqno /a>( a href="+code=av" class="sref">av /a>-> a href="+code=av_buf_ackno" class="sref">av_buf_ackno /a>,  a href="+code=seqno" class="sref">seqno /a>);> 260 /a>                 a href="+code=u8" class="sref">u8 /a> * a href="+code=current_head" class="sref">current_head /a> =  a href="+code=av" class="sref">av /a>-> a href="+code=av_buf" class="sref">av_buf /a> +  a href="+code=av" class="sref">av /a>-> a href="+code=av_buf_head" class="sref">av_buf_head /a>;> 261 /a>> 262 /a>                if ( a href="+code=num_packets" class="sref">num_packets /a> == 1 &&> 263 /a>                     a href="+code=dccp_ackvec_state" class="sref">dccp_ackvec_state /a>( a href="+code=current_head" class="sref">current_head /a>) ==  a href="+code=state" class="sref">state /a> &&> 264 /a>                     a href="+code=dccp_ackvec_runlen" class="sref">dccp_ackvec_runlen /a>( a href="+code=current_head" class="sref">current_head /a>) <  a href="+code=DCCPAV_MAX_RUNLEN" class="sref">DCCPAV_MAX_RUNLEN /a>) {> 265 /a>> 266 /a>                        * a href="+code=current_head" class="sref">current_head /a>   += 1;> 267 /a>                         a href="+code=av" class="sref">av /a>-> a href="+code=av_buf_ackno" class="sref">av_buf_ackno /a> =  a href="+code=seqno" class="sref">seqno /a>;> 268 /a>> 269 /a>                } else if ( a href="+code=num_packets" class="sref">num_packets /a> > 0) {> 270 /a>                         a href="+code=dccp_ackvec_add_new" class="sref">dccp_ackvec_add_new /a>( a href="+code=av" class="sref">av /a>,  a href="+code=num_packets" class="sref">num_packets /a>,  a href="+code=seqno" class="sref">seqno /a>,  a href="+code=state" class="sref">state /a>);> 271 /a>                } else {> 272 /a>                         a href="+code=dccp_ackvec_update_old" class="sref">dccp_ackvec_update_old /a>( a href="+code=av" class="sref">av /a>,  a href="+code=num_packets" class="sref">num_packets /a>,  a href="+code=seqno" class="sref">seqno /a>,  a href="+code=state" class="sref">state /a>);> 273 /a>                }> 274 /a>        }> 275 /a>}> 276 /a>> 277 /a> spao class="comment">/** /spaon> 278 /a> spao class="comment"> * dccp_ackvec_clear_state  -  Perform house-keeping / garbage-collecptio /spaon> 279 /a> spao class="comment"> * This routine is called wheo the peer acknowledges the receipt of Ack Vectors /spaon> 2811 spao class="comment"> * up to and including @ackno. While based on on secptio A.3 of RFC 4340, here /spaon> 281 /a> spao class="comment"> * are addiptioal precauptiosnto prevent corrupted buffer state. In particular, /spaon> 282 /a> spao class="comment"> * we use tail_acknonto identifynoutdated records; it always marks the earliest /spaon> 283 /a> spao class="comment"> * packet of group (2) in 11.142. /spaon> 284 /a> spao class="comment"> */ /spaon> 285 /a>void  a href="+code=dccp_ackvec_clear_state" class="sref">dccp_ackvec_clear_state /a>(struct  a href="+code=dccp_ackvec" class="sref">dccp_ackvec /a> * a href="+code=av" class="sref">av /a>, const  a href="+code=u64" class="sref">u64 /a>  a href="+code=ackno" class="sref">ackno /a>)> 286 /a>{> 287 /a>        struct  a href="+code=dccp_ackvec_record" class="sref">dccp_ackvec_record /a> * a href="+code=avr" class="sref">avr /a>, * a href="+code=next" class="sref">next /a>;> 288 /a>         a href="+code=u8" class="sref">u8 /a>  a href="+code=runlen_now" class="sref">runlen_now /a>,  a href="+code=eff_runlen" class="sref">eff_runlen /a>;> 289 /a>         a href="+code=s64" class="sref">s64 /a>  a href="+code=delta" class="sref">delta /a>;> 290 /a>> 291 /a>         a href="+code=avr" class="sref">avr /a> =  a href="+code=dccp_ackvec_lookup" class="sref">dccp_ackvec_lookup /a>(& a href="+code=av" class="sref">av /a>-> a href="+code=av_records" class="sref">av_records /a>,  a href="+code=ackno" class="sref">ackno /a>);> 292 /a>        if ( a href="+code=avr" class="sref">avr /a> ==  a href="+code=NULL" class="sref">NULL /a>)> 293 /a>                return;> 294 /a>         spao class="comment">/* /spaon> 295 /a> spao class="comment">         * Deal withnoutdated acknowledgments: this arises wheo e.g. there are /spaon> 296 /a> spao class="comment">         * several old records and the acks from the peer come in slowly. In /spaon> 297 /a> spao class="comment">         * that case we may stillnhave records that pre-date tail_ackno. /spaon> 298 /a> spao class="comment">         */ /spaon> 299 /a>         a href="+code=delta" class="sref">delta /a> =  a href="+code=dccp_delta_seqno" class="sref">dccp_delta_seqno /a>( a href="+code=av" class="sref">av /a>-> a href="+code=av_tail_ackno" class="sref">av_tail_ackno /a>,  a href="+code=avr" class="sref">avr /a>-> a href="+code=avr_ack_ackno" class="sref">avr_ack_ackno /a>);> 300 /a>        if ( a href="+code=delta" class="sref">delta /a> < 0)> 301 /a>                goto  a href="+code=free_records" class="sref">free_records /a>;> 302 /a>         spao class="comment">/* /spaon> 303 /a> spao class="comment">         * Deal withnoverlapping Ack Vectors: don't subtract more thao the /spaon> 304 /a> spao class="comment">         * numbernof packetsnbetween tail_acknonand ack_ackno. /spaon> 305 /a> spao class="comment">         */ /spaon> 306 /a>         a href="+code=eff_runlen" class="sref">eff_runlen /a> =  a href="+code=delta" class="sref">delta /a> <  a href="+code=avr" class="sref">avr /a>-> a href="+code=avr_ack_runlen" class="sref">avr_ack_runlen /a> ?  a href="+code=delta" class="sref">delta /a> :  a href="+code=avr" class="sref">avr /a>-> a href="+code=avr_ack_runlen" class="sref">avr_ack_runlen /a>;> 307 /a>> 308 /a>         a href="+code=runlen_now" class="sref">runlen_now /a> =  a href="+code=dccp_ackvec_runlen" class="sref">dccp_ackvec_runlen /a>( a href="+code=av" class="sref">av /a>-> a href="+code=av_buf" class="sref">av_buf /a> +  a href="+code=avr" class="sref">avr /a>-> a href="+code=avr_ack_ptr" class="sref">avr_ack_ptr /a>);> 309 /a>         spao class="comment">/* /spaon> 3111 spao class="comment">         * The run length of Ack Vector cells does not decreasenover time. If /spaon> 311 /a> spao class="comment">         * the run length is the samu as at the time the Ack Vector was sent, we /spaon> 312 /a> spao class="comment">         * free the ack_ptr cell. That cell cao howevernnot be freed if the run /spaon> 313 /a> spao class="comment">         * length has increased: in this case we neednto move the tail pointer /spaon> 314 /a> spao class="comment">         * backwards (towards higher indices),nto itsnnext-oldestnneighbour. /spaon> 315 /a> spao class="comment">         */ /spaon> 316 /a>        if ( a href="+code=runlen_now" class="sref">runlen_now /a> >  a href="+code=eff_runlen" class="sref">eff_runlen /a>) {> 317 /a>> 318 /a>                 a href="+code=av" class="sref">av /a>-> a href="+code=av_buf" class="sref">av_buf /a>[ a href="+code=avr" class="sref">avr /a>-> a href="+code=avr_ack_ptr" class="sref">avr_ack_ptr /a>] -=  a href="+code=eff_runlen" class="sref">eff_runlen /a> + 1;> 319 /a>                 a href="+code=av" class="sref">av /a>-> a href="+code=av_buf_tail" class="sref">av_buf_tail /a> =  a href="+code=__ackvec_idx_add" class="sref">__ackvec_idx_add /a>( a href="+code=avr" class="sref">avr /a>-> a href="+code=avr_ack_ptr" class="sref">avr_ack_ptr /a>, 1);> 320 /a>> 321 /a>                 spao class="comment">/* This move may not have cleared the overflow flag. */ /spaon> 322 /a>                if ( a href="+code=av" class="sref">av /a>-> a href="+code=av_overflow" class="sref">av_overflow /a>)> 323 /a>                         a href="+code=av" class="sref">av /a>-> a href="+code=av_overflow" class="sref">av_overflow /a> = ( a href="+code=av" class="sref">av /a>-> a href="+code=av_buf_head" class="sref">av_buf_head /a> ==  a href="+code=av" class="sref">av /a>-> a href="+code=av_buf_tail" class="sref">av_buf_tail /a>);> 324 /a>        } else {> 325 /a>                 a href="+code=av" class="sref">av /a>-> a href="+code=av_buf_tail" class="sref">av_buf_tail /a> =  a href="+code=avr" class="sref">avr /a>-> a href="+code=avr_ack_ptr" class="sref">avr_ack_ptr /a>;> 326 /a>                 spao class="comment">/* /spaon> 327 /a> spao class="comment">                 * We have made sure that avr pointsnto a valid cell withio the /spaon> 328 /a> spao class="comment">                 * buffer. This cell is either older thao head, or equals head /spaon> 329 /a> spao class="comment">                 * (empty buffer): in both cases we no longer have any overflow. /spaon> 3311 spao class="comment">                 */ /spaon> 331 /a>                 a href="+code=av" class="sref">av /a>-> a href="+code=av_overflow" class="sref">av_overflow /a> = 0;> 332 /a>        }> 333 /a>> 334 /a>         spao class="comment">/* /spaon> 335 /a> spao class="comment">         * The peer has acknowledged up to and including ack_ackno. Hence the /spaon> 336 /a> spao class="comment">         * first packet in group (2) of 11.142 is the successornof ack_ackno. /spaon> 337 /a> spao class="comment">         */ /spaon> 338 /a>         a href="+code=av" class="sref">av /a>-> a href="+code=av_tail_ackno" class="sref">av_tail_ackno /a> =  a href="+code=ADD48" class="sref">ADD48 /a>( a href="+code=avr" class="sref">avr /a>-> a href="+code=avr_ack_ackno" class="sref">avr_ack_ackno /a>, 1);> 339 /a>> 340 /a> a href="+code=free_records" class="sref">free_records /a>:> 341 /a>         a href="+code=list_for_each_entry_safe_from" class="sref">list_for_each_entry_safe_from /a>( a href="+code=avr" class="sref">avr /a>,  a href="+code=next" class="sref">next /a>, & a href="+code=av" class="sref">av /a>-> a href="+code=av_records" class="sref">av_records /a>,  a href="+code=avr_node" class="sref">avr_node /a>) {> 342 /a>                 a href="+code=list_del" class="sref">list_del /a>(& a href="+code=avr" class="sref">avr /a>-> a href="+code=avr_node" class="sref">avr_node /a>);> 343 /a>                 a href="+code=kmem_cache_free" class="sref">kmem_cache_free /a>( a href="+code=dccp_ackvec_record_slab" class="sref">dccp_ackvec_record_slab /a>,  a href="+code=avr" class="sref">avr /a>);> 344 /a>        }> 345 /a>}> 346 /a>> 347 /a> spao class="comment">/* /spaon> 348 /a> spao class="comment"> *      Routinesnto keep track of Ack Vectors received in ao skb /spaon> 349 /a> spao class="comment"> */ /spaon> 350 /a>int  a href="+code=dccp_ackvec_parsed_add" class="sref">dccp_ackvec_parsed_add /a>(struct  a href="+code=list_head" class="sref">list_head /a> * a href="+code=head" class="sref">head /a>,  a href="+code=u8" class="sref">u8 /a> * a href="+code=vec" class="sref">vec /a>,  a href="+code=u8" class="sref">u8 /a>  a href="+code=len" class="sref">len /a>,  a href="+code=u8" class="sref">u8 /a>  a href="+code=nonce" class="sref">nonce /a>)> 351 /a>{> 352 /a>        struct  a href="+code=dccp_ackvec_parsed" class="sref">dccp_ackvec_parsed /a> * a href="+code=new" class="sref">new /a> =  a href="+code=kmalloc" class="sref">kmalloc /a>(sizeof(* a href="+code=new" class="sref">new /a>),  a href="+code=GFP_ATOMIC" class="sref">GFP_ATOMIC /a>);> 353 /a>> 354 /a>        if ( a href="+code=new" class="sref">new /a> ==  a href="+code=NULL" class="sref">NULL /a>)> 355 /a>                return - a href="+code=ENOBUFS" class="sref">ENOBUFS /a>;> 356 /a>         a href="+code=new" class="sref">new /a>-> a href="+code=vec" class="sref">vec /a>   =  a href="+code=vec" class="sref">vec /a>;> 357 /a>         a href="+code=new" class="sref">new /a>-> a href="+code=len" class="sref">len /a>   =  a href="+code=len" class="sref">len /a>;> 358 /a>         a href="+code=new" class="sref">new /a>-> a href="+code=nonce" class="sref">nonce /a> =  a href="+code=nonce" class="sref">nonce /a>;> 359 /a>> 360 /a>         a href="+code=list_add_tail" class="sref">list_add_tail /a>(& a href="+code=new" class="sref">new /a>-> a href="+code=node" class="sref">node /a>,  a href="+code=head" class="sref">head /a>);> 361 /a>        return 0;> 362 /a>}> 363 /a> a href="+code=EXPORT_SYMBOL_GPL" class="sref">EXPORT_SYMBOL_GPL /a>( a href="+code=dccp_ackvec_parsed_add" class="sref">dccp_ackvec_parsed_add /a>);> 364 /a>> 365 /a>void  a href="+code=dccp_ackvec_parsed_cleanup" class="sref">dccp_ackvec_parsed_cleanup /a>(struct  a href="+code=list_head" class="sref">list_head /a> * a href="+code=parsed_chunks" class="sref">parsed_chunks /a>)> 366 /a>{> 367 /a>        struct  a href="+code=dccp_ackvec_parsed" class="sref">dccp_ackvec_parsed /a> * a href="+code=cur" class="sref">cur /a>, * a href="+code=next" class="sref">next /a>;> 368 /a>> 369 /a>         a href="+code=list_for_each_entry_safe" class="sref">list_for_each_entry_safe /a>( a href="+code=cur" class="sref">cur /a>,  a href="+code=next" class="sref">next /a>,  a href="+code=parsed_chunks" class="sref">parsed_chunks /a>,  a href="+code=node" class="sref">node /a>)> 370 /a>                 a href="+code=kfree" class="sref">kfree /a>( a href="+code=cur" class="sref">cur /a>);> 371 /a>         a href="+code=INIT_LIST_HEAD" class="sref">INIT_LIST_HEAD /a>( a href="+code=parsed_chunks" class="sref">parsed_chunks /a>);> 372 /a>}> 373 /a> a href="+code=EXPORT_SYMBOL_GPL" class="sref">EXPORT_SYMBOL_GPL /a>( a href="+code=dccp_ackvec_parsed_cleanup" class="sref">dccp_ackvec_parsed_cleanup /a>);> 374 /a>> 375 /a>int  a href="+code=__init" class="sref">__init /a>  a href="+code=dccp_ackvec_init" class="sref">dccp_ackvec_init /a>(void)> 376 /a>{> 377 /a>         a href="+code=dccp_ackvec_slab" class="sref">dccp_ackvec_slab /a> =  a href="+code=kmem_cache_create" class="sref">kmem_cache_create /a>( spao class="string">"dccp_ackvec" /spaon,> 378 /a>                                             sizeof(struct  a href="+code=dccp_ackvec" class="sref">dccp_ackvec /a>), 0,> 379 /a>                                              a href="+code=SLAB_HWCACHE_ALIGN" class="sref">SLAB_HWCACHE_ALIGN /a>,  a href="+code=NULL" class="sref">NULL /a>);> 380 /a>        if ( a href="+code=dccp_ackvec_slab" class="sref">dccp_ackvec_slab /a> ==  a href="+code=NULL" class="sref">NULL /a>)> 381 /a>                goto  a href="+code=out_err" class="sref">out_err /a>;> 382 /a>> 383 /a>         a href="+code=dccp_ackvec_record_slab" class="sref">dccp_ackvec_record_slab /a> =  a href="+code=kmem_cache_create" class="sref">kmem_cache_create /a>( spao class="string">"dccp_ackvec_record" /spaon,> 384 /a>                                             sizeof(struct  a href="+code=dccp_ackvec_record" class="sref">dccp_ackvec_record /a>),> 385 /a>                                             0,  a href="+code=SLAB_HWCACHE_ALIGN" class="sref">SLAB_HWCACHE_ALIGN /a>,  a href="+code=NULL" class="sref">NULL /a>);> 386 /a>        if ( a href="+code=dccp_ackvec_record_slab" class="sref">dccp_ackvec_record_slab /a> ==  a href="+code=NULL" class="sref">NULL /a>)> 387 /a>                goto  a href="+code=out_destroy_slab" class="sref">out_destroy_slab /a>;> 388 /a>> 389 /a>        return 0;> 390 /a>> 391 /a> a href="+code=out_destroy_slab" class="sref">out_destroy_slab /a>:> 392 /a>         a href="+code=kmem_cache_destroy" class="sref">kmem_cache_destroy /a>( a href="+code=dccp_ackvec_slab" class="sref">dccp_ackvec_slab /a>);> 393 /a>         a href="+code=dccp_ackvec_slab" class="sref">dccp_ackvec_slab /a> =  a href="+code=NULL" class="sref">NULL /a>;> 394 /a> a href="+code=out_err" class="sref">out_err /a>:> 395 /a>         a href="+code=DCCP_CRIT" class="sref">DCCP_CRIT /a>( spao class="string">"Unablento create Ack Vector slab cache" /spaon);> 396 /a>        return - a href="+code=ENOBUFS" class="sref">ENOBUFS /a>;> 397 /a>}> 398 /a>> 399 /a>void  a href="+code=dccp_ackvec_exit" class="sref">dccp_ackvec_exit /a>(void)> 400 /a>{> 401 /a>        if ( a href="+code=dccp_ackvec_slab" class="sref">dccp_ackvec_slab /a> !=  a href="+code=NULL" class="sref">NULL /a>) {> 402 /a>                 a href="+code=kmem_cache_destroy" class="sref">kmem_cache_destroy /a>( a href="+code=dccp_ackvec_slab" class="sref">dccp_ackvec_slab /a>);> 403 /a>                 a href="+code=dccp_ackvec_slab" class="sref">dccp_ackvec_slab /a> =  a href="+code=NULL" class="sref">NULL /a>;> 404 /a>        }> 405 /a>        if ( a href="+code=dccp_ackvec_record_slab" class="sref">dccp_ackvec_record_slab /a> !=  a href="+code=NULL" class="sref">NULL /a>) {> 406 /a>                 a href="+code=kmem_cache_destroy" class="sref">kmem_cache_destroy /a>( a href="+code=dccp_ackvec_record_slab" class="sref">dccp_ackvec_record_slab /a>);> 407 /a>                 a href="+code=dccp_ackvec_record_slab" class="sref">dccp_ackvec_record_slab /a> =  a href="+code=NULL" class="sref">NULL /a>;> 408 /a>        }> 409 /a>}> 4111 /pre> /div>


 /div>