@@ -6204,64 +6204,58 @@ EXPORT_SYMBOL_GPL(skb_mpls_dec_ttl);
62046204 *
62056205 * @header_len: size of linear part
62066206 * @data_len: needed length in frags
6207- * @max_page_order : max page order desired.
6207+ * @order : max page order desired.
62086208 * @errcode: pointer to error code if any
62096209 * @gfp_mask: allocation mask
62106210 *
62116211 * This can be used to allocate a paged skb, given a maximal order for frags.
62126212 */
62136213struct sk_buff * alloc_skb_with_frags (unsigned long header_len ,
62146214 unsigned long data_len ,
6215- int max_page_order ,
6215+ int order ,
62166216 int * errcode ,
62176217 gfp_t gfp_mask )
62186218{
6219- int npages = (data_len + (PAGE_SIZE - 1 )) >> PAGE_SHIFT ;
62206219 unsigned long chunk ;
62216220 struct sk_buff * skb ;
62226221 struct page * page ;
6223- int i ;
6222+ int nr_frags = 0 ;
62246223
62256224 * errcode = - EMSGSIZE ;
6226- /* Note this test could be relaxed, if we succeed to allocate
6227- * high order pages...
6228- */
6229- if (npages > MAX_SKB_FRAGS )
6225+ if (unlikely (data_len > MAX_SKB_FRAGS * (PAGE_SIZE << order )))
62306226 return NULL ;
62316227
62326228 * errcode = - ENOBUFS ;
62336229 skb = alloc_skb (header_len , gfp_mask );
62346230 if (!skb )
62356231 return NULL ;
62366232
6237- skb -> truesize += npages << PAGE_SHIFT ;
6238-
6239- for (i = 0 ; npages > 0 ; i ++ ) {
6240- int order = max_page_order ;
6241-
6242- while (order ) {
6243- if (npages >= 1 << order ) {
6244- page = alloc_pages ((gfp_mask & ~__GFP_DIRECT_RECLAIM ) |
6245- __GFP_COMP |
6246- __GFP_NOWARN ,
6247- order );
6248- if (page )
6249- goto fill_page ;
6250- /* Do not retry other high order allocations */
6251- order = 1 ;
6252- max_page_order = 0 ;
6253- }
6233+ while (data_len ) {
6234+ if (nr_frags == MAX_SKB_FRAGS - 1 )
6235+ goto failure ;
6236+ while (order && PAGE_ALIGN (data_len ) < (PAGE_SIZE << order ))
62546237 order -- ;
6238+
6239+ if (order ) {
6240+ page = alloc_pages ((gfp_mask & ~__GFP_DIRECT_RECLAIM ) |
6241+ __GFP_COMP |
6242+ __GFP_NOWARN ,
6243+ order );
6244+ if (!page ) {
6245+ order -- ;
6246+ continue ;
6247+ }
6248+ } else {
6249+ page = alloc_page (gfp_mask );
6250+ if (!page )
6251+ goto failure ;
62556252 }
6256- page = alloc_page (gfp_mask );
6257- if (!page )
6258- goto failure ;
6259- fill_page :
62606253 chunk = min_t (unsigned long , data_len ,
62616254 PAGE_SIZE << order );
6262- skb_fill_page_desc (skb , i , page , 0 , chunk );
6255+ skb_fill_page_desc (skb , nr_frags , page , 0 , chunk );
6256+ nr_frags ++ ;
6257+ skb -> truesize += (PAGE_SIZE << order );
62636258 data_len -= chunk ;
6264- npages -= 1 << order ;
62656259 }
62666260 return skb ;
62676261
0 commit comments