mtu -= hlen +sizeof(struct frag_hdr);if(skb_has_frag_list(skb)) {intfirst_len = skb_pagelen(skb);structsk_buff*frag2;if(first_len - hlen > mtu || ((first_len - hlen) &7) || skb_cloned(skb))gotoslow_path; skb_walk_frags(skb, frag) {/* Correct geometry. */if(frag->...
remaining = *sync_size;for(i =0; remaining >0; i++) {skb_frag_t*frag = &record->frags[i]; __skb_frag_ref(frag); sg_set_page(sg_in + i, skb_frag_page(frag), skb_frag_size(frag), frag->page_offset); remaining -= skb_frag_size(frag);if(remaining <0) sg_in[i].lengt...
static inline void __skb_frag_unref(skb_frag_t *frag, bool recycle) { put_page(skb_frag_page(frag)); struct page *page = skb_frag_page(frag); #ifdef CONFIG_PAGE_POOL if (recycle && page_pool_return_skb_page(page)) return; #endif put_page(page); } /** @@ -3100,7 +3111,...
unsignedchar*head = skb->head;if(skb->head_frag)//表示线性区 数据在page 区 len=size&&&date_len=sieze 通过alloc_page_frag拿到skb->head=data=pageskb_free_frag(head);elsekfree(head); } consume_skb:释放skb,与kfree_skb区别是,kfree_skb用于失败时丢包释放; 也就是:consume_skb 表示 skb是...
(__alloc_page_frag+0x13c/0x15c) 2017-03-05T16:35:55.624957-08:00 kernel: [<803bd390>] (__alloc_page_frag) from [<803c2bbc>] (__alloc_rx_skb+0x58/0xe4) 2017-03-05T16:35:55.624970-08:00 kernel: [<803c2bbc>] (__alloc_rx_skb) from [<803c2c64>] (__netdev_alloc_skb...
> not inline this entire fraglist thing alongside sk_buff? Sorry, that crap about cost of clone still clouds my mind. :-) Actually, the borderline was not between "short" and "long", but between "plain page vector" and "not-so-plain". See below. ...
vaddr + skb_shinfo(skb)->frags[i].page_offset+ offset - start, copy); kunmap_skb_frag(vaddr); if ((len -= copy) == 0) return 0; offset += copy; to += copy; } start = end; } // 拷贝其他碎片skb中的数据部分 if (skb_shinfo(skb)->frag_list) { ...
{17structpage_frag_cache *nc;18unsignedlongflags;19structsk_buff *skb;20boolpfmemalloc;21void*data;2223/*分配长度+ skb_shared_info长度 然后对整个长度进行对齐*/24len +=NET_SKB_PAD;25len += SKB_DATA_ALIGN(sizeof(structskb_shared_info));26len =SKB_DATA_ALIGN(len);2728if(sk_memalloc_...
frag->page = page; frag->page_offset =0; frag->size = (data_len >= PAGE_SIZE ? PAGE_SIZE : data_len); data_len -= PAGE_SIZE; }/* Full success... */break; } err = -ENOBUFS;gotofailure; } set_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags); ...
kunmap(page);if(err)gotofault;if(!(len -= copy))return0; offset += copy; } start = end; } skb_walk_frags(skb, frag_iter) {intend; WARN_ON(start > offset + len); end = start + frag_iter->len;if((copy = end - offset) >0) {if(copy > len) ...