ipv4: use skb coalescing in defragmentation
ip_frag_reasm() can use skb_try_coalesce() to build optimized skb, reducing memory used by them (truesize), and reducing number of cache line misses and overhead for the consumer. Signed-off-by: Eric Dumazet <edumazet@google.com> Cc: Alexander Duyck <alexander.h.duyck@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
		
					parent
					
						
							
								bad43ca832
							
						
					
				
			
			
				commit
				
					
						3cc4949269
					
				
			
		
					 1 changed files with 20 additions and 6 deletions
				
			
		|  | @ -545,6 +545,7 @@ static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev, | ||||||
| 	int len; | 	int len; | ||||||
| 	int ihlen; | 	int ihlen; | ||||||
| 	int err; | 	int err; | ||||||
|  | 	int sum_truesize; | ||||||
| 	u8 ecn; | 	u8 ecn; | ||||||
| 
 | 
 | ||||||
| 	ipq_kill(qp); | 	ipq_kill(qp); | ||||||
|  | @ -611,19 +612,32 @@ static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev, | ||||||
| 		atomic_add(clone->truesize, &qp->q.net->mem); | 		atomic_add(clone->truesize, &qp->q.net->mem); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	skb_shinfo(head)->frag_list = head->next; |  | ||||||
| 	skb_push(head, head->data - skb_network_header(head)); | 	skb_push(head, head->data - skb_network_header(head)); | ||||||
| 
 | 
 | ||||||
| 	for (fp=head->next; fp; fp = fp->next) { | 	sum_truesize = head->truesize; | ||||||
| 		head->data_len += fp->len; | 	for (fp = head->next; fp;) { | ||||||
| 		head->len += fp->len; | 		bool headstolen; | ||||||
|  | 		int delta; | ||||||
|  | 		struct sk_buff *next = fp->next; | ||||||
|  | 
 | ||||||
|  | 		sum_truesize += fp->truesize; | ||||||
| 		if (head->ip_summed != fp->ip_summed) | 		if (head->ip_summed != fp->ip_summed) | ||||||
| 			head->ip_summed = CHECKSUM_NONE; | 			head->ip_summed = CHECKSUM_NONE; | ||||||
| 		else if (head->ip_summed == CHECKSUM_COMPLETE) | 		else if (head->ip_summed == CHECKSUM_COMPLETE) | ||||||
| 			head->csum = csum_add(head->csum, fp->csum); | 			head->csum = csum_add(head->csum, fp->csum); | ||||||
| 		head->truesize += fp->truesize; | 
 | ||||||
|  | 		if (skb_try_coalesce(head, fp, &headstolen, &delta)) { | ||||||
|  | 			kfree_skb_partial(fp, headstolen); | ||||||
|  | 		} else { | ||||||
|  | 			if (!skb_shinfo(head)->frag_list) | ||||||
|  | 				skb_shinfo(head)->frag_list = fp; | ||||||
|  | 			head->data_len += fp->len; | ||||||
|  | 			head->len += fp->len; | ||||||
|  | 			head->truesize += fp->truesize; | ||||||
|  | 		} | ||||||
|  | 		fp = next; | ||||||
| 	} | 	} | ||||||
| 	atomic_sub(head->truesize, &qp->q.net->mem); | 	atomic_sub(sum_truesize, &qp->q.net->mem); | ||||||
| 
 | 
 | ||||||
| 	head->next = NULL; | 	head->next = NULL; | ||||||
| 	head->dev = dev; | 	head->dev = dev; | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Eric Dumazet
				Eric Dumazet