macvtap: limit head length of skb allocated
We currently use hdr_len as a hint of head length which is advertised by guest. But when guest advertise a very big value, it can lead to an 64K+ allocating of kmalloc() which has a very high possibility of failure when host memory is fragmented or under heavy stress. The huge hdr_len also reduce the effect of zerocopy or even disable if a gso skb is linearized in guest. To solves those issues, this patch introduces an upper limit (PAGE_SIZE) of the head, which guarantees an order 0 allocation each time. Cc: Stefan Hajnoczi <stefanha@redhat.com> Cc: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Jason Wang <jasowang@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
		
							parent
							
								
									96f8d9ecf2
								
							
						
					
					
						commit
						16a3fa2863
					
				| @ -628,6 +628,7 @@ static ssize_t macvtap_get_user(struct macvtap_queue *q, struct msghdr *m, | ||||
| 				const struct iovec *iv, unsigned long total_len, | ||||
| 				size_t count, int noblock) | ||||
| { | ||||
| 	int good_linear = SKB_MAX_HEAD(NET_IP_ALIGN); | ||||
| 	struct sk_buff *skb; | ||||
| 	struct macvlan_dev *vlan; | ||||
| 	unsigned long len = total_len; | ||||
| @ -670,6 +671,8 @@ static ssize_t macvtap_get_user(struct macvtap_queue *q, struct msghdr *m, | ||||
| 
 | ||||
| 	if (m && m->msg_control && sock_flag(&q->sk, SOCK_ZEROCOPY)) { | ||||
| 		copylen = vnet_hdr.hdr_len ? vnet_hdr.hdr_len : GOODCOPY_LEN; | ||||
| 		if (copylen > good_linear) | ||||
| 			copylen = good_linear; | ||||
| 		linear = copylen; | ||||
| 		if (iov_pages(iv, vnet_hdr_len + copylen, count) | ||||
| 		    <= MAX_SKB_FRAGS) | ||||
| @ -678,7 +681,10 @@ static ssize_t macvtap_get_user(struct macvtap_queue *q, struct msghdr *m, | ||||
| 
 | ||||
| 	if (!zerocopy) { | ||||
| 		copylen = len; | ||||
| 		linear = vnet_hdr.hdr_len; | ||||
| 		if (vnet_hdr.hdr_len > good_linear) | ||||
| 			linear = good_linear; | ||||
| 		else | ||||
| 			linear = vnet_hdr.hdr_len; | ||||
| 	} | ||||
| 
 | ||||
| 	skb = macvtap_alloc_skb(&q->sk, NET_IP_ALIGN, copylen, | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user