forked from mirrors/linux
		
	net: hns3: add 8 BD limit for tx flow
A single transmit packet can span up to 8 descriptors according to the HW limit. If a skb has more than 8 frags, driver uses skb_copy to get a new skb which has less frags. Signed-off-by: Peng Li <lipeng321@huawei.com> Signed-off-by: Huazhong Tan <tanhuazhong@huawei.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
		
							parent
							
								
									1cce5eb650
								
							
						
					
					
						commit
						51e8439f34
					
				
					 1 changed files with 27 additions and 1 deletions
				
			
		| 
						 | 
					@ -1133,6 +1133,7 @@ static int hns3_nic_maybe_stop_tso(struct sk_buff **out_skb, int *bnum,
 | 
				
			||||||
				   struct hns3_enet_ring *ring)
 | 
									   struct hns3_enet_ring *ring)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct sk_buff *skb = *out_skb;
 | 
						struct sk_buff *skb = *out_skb;
 | 
				
			||||||
 | 
						struct sk_buff *new_skb = NULL;
 | 
				
			||||||
	struct skb_frag_struct *frag;
 | 
						struct skb_frag_struct *frag;
 | 
				
			||||||
	int bdnum_for_frag;
 | 
						int bdnum_for_frag;
 | 
				
			||||||
	int frag_num;
 | 
						int frag_num;
 | 
				
			||||||
| 
						 | 
					@ -1155,7 +1156,19 @@ static int hns3_nic_maybe_stop_tso(struct sk_buff **out_skb, int *bnum,
 | 
				
			||||||
		buf_num += bdnum_for_frag;
 | 
							buf_num += bdnum_for_frag;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (buf_num > ring_space(ring))
 | 
						if (unlikely(buf_num > HNS3_MAX_BD_PER_FRAG)) {
 | 
				
			||||||
 | 
							buf_num = (skb->len + HNS3_MAX_BD_SIZE - 1) / HNS3_MAX_BD_SIZE;
 | 
				
			||||||
 | 
							if (ring_space(ring) < buf_num)
 | 
				
			||||||
 | 
								return -EBUSY;
 | 
				
			||||||
 | 
							/* manual split the send packet */
 | 
				
			||||||
 | 
							new_skb = skb_copy(skb, GFP_ATOMIC);
 | 
				
			||||||
 | 
							if (!new_skb)
 | 
				
			||||||
 | 
								return -ENOMEM;
 | 
				
			||||||
 | 
							dev_kfree_skb_any(skb);
 | 
				
			||||||
 | 
							*out_skb = new_skb;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (unlikely(ring_space(ring) < buf_num))
 | 
				
			||||||
		return -EBUSY;
 | 
							return -EBUSY;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	*bnum = buf_num;
 | 
						*bnum = buf_num;
 | 
				
			||||||
| 
						 | 
					@ -1166,11 +1179,24 @@ static int hns3_nic_maybe_stop_tx(struct sk_buff **out_skb, int *bnum,
 | 
				
			||||||
				  struct hns3_enet_ring *ring)
 | 
									  struct hns3_enet_ring *ring)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct sk_buff *skb = *out_skb;
 | 
						struct sk_buff *skb = *out_skb;
 | 
				
			||||||
 | 
						struct sk_buff *new_skb = NULL;
 | 
				
			||||||
	int buf_num;
 | 
						int buf_num;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* No. of segments (plus a header) */
 | 
						/* No. of segments (plus a header) */
 | 
				
			||||||
	buf_num = skb_shinfo(skb)->nr_frags + 1;
 | 
						buf_num = skb_shinfo(skb)->nr_frags + 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (unlikely(buf_num > HNS3_MAX_BD_PER_FRAG)) {
 | 
				
			||||||
 | 
							buf_num = (skb->len + HNS3_MAX_BD_SIZE - 1) / HNS3_MAX_BD_SIZE;
 | 
				
			||||||
 | 
							if (ring_space(ring) < buf_num)
 | 
				
			||||||
 | 
								return -EBUSY;
 | 
				
			||||||
 | 
							/* manual split the send packet */
 | 
				
			||||||
 | 
							new_skb = skb_copy(skb, GFP_ATOMIC);
 | 
				
			||||||
 | 
							if (!new_skb)
 | 
				
			||||||
 | 
								return -ENOMEM;
 | 
				
			||||||
 | 
							dev_kfree_skb_any(skb);
 | 
				
			||||||
 | 
							*out_skb = new_skb;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (unlikely(ring_space(ring) < buf_num))
 | 
						if (unlikely(ring_space(ring) < buf_num))
 | 
				
			||||||
		return -EBUSY;
 | 
							return -EBUSY;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue