net: hns3: check FE bit before calling hns3_add_frag()
A BD with FE bit means that it is the last BD of a packet, currently the FE bit is checked before calling hns3_add_frag(), which is unnecessary because the FE bit may have been checked in some case. This patch checks the FE bit before calling hns3_add_frag() after processing the first BD of a SKB and adjust the location of memcpy() to reduce duplication. Signed-off-by: Yunsheng Lin <linyunsheng@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
e1b5e598e5
commit
b2598318eb
@ -2788,7 +2788,6 @@ static bool hns3_parse_vlan_tag(struct hns3_enet_ring *ring,
|
||||
static int hns3_alloc_skb(struct hns3_enet_ring *ring, unsigned int length,
|
||||
unsigned char *va)
|
||||
{
|
||||
#define HNS3_NEED_ADD_FRAG 1
|
||||
struct hns3_desc_cb *desc_cb = &ring->desc_cb[ring->next_to_clean];
|
||||
struct net_device *netdev = ring_to_netdev(ring);
|
||||
struct sk_buff *skb;
|
||||
@ -2832,33 +2831,19 @@ static int hns3_alloc_skb(struct hns3_enet_ring *ring, unsigned int length,
|
||||
desc_cb);
|
||||
ring_ptr_move_fw(ring, next_to_clean);
|
||||
|
||||
return HNS3_NEED_ADD_FRAG;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hns3_add_frag(struct hns3_enet_ring *ring, struct hns3_desc *desc,
|
||||
bool pending)
|
||||
static int hns3_add_frag(struct hns3_enet_ring *ring)
|
||||
{
|
||||
struct sk_buff *skb = ring->skb;
|
||||
struct sk_buff *head_skb = skb;
|
||||
struct sk_buff *new_skb;
|
||||
struct hns3_desc_cb *desc_cb;
|
||||
struct hns3_desc *pre_desc;
|
||||
struct hns3_desc *desc;
|
||||
u32 bd_base_info;
|
||||
int pre_bd;
|
||||
|
||||
/* if there is pending bd, the SW param next_to_clean has moved
|
||||
* to next and the next is NULL
|
||||
*/
|
||||
if (pending) {
|
||||
pre_bd = (ring->next_to_clean - 1 + ring->desc_num) %
|
||||
ring->desc_num;
|
||||
pre_desc = &ring->desc[pre_bd];
|
||||
bd_base_info = le32_to_cpu(pre_desc->rx.bd_base_info);
|
||||
} else {
|
||||
bd_base_info = le32_to_cpu(desc->rx.bd_base_info);
|
||||
}
|
||||
|
||||
while (!(bd_base_info & BIT(HNS3_RXD_FE_B))) {
|
||||
do {
|
||||
desc = &ring->desc[ring->next_to_clean];
|
||||
desc_cb = &ring->desc_cb[ring->next_to_clean];
|
||||
bd_base_info = le32_to_cpu(desc->rx.bd_base_info);
|
||||
@ -2895,7 +2880,7 @@ static int hns3_add_frag(struct hns3_enet_ring *ring, struct hns3_desc *desc,
|
||||
hns3_nic_reuse_page(skb, ring->frag_num++, ring, 0, desc_cb);
|
||||
ring_ptr_move_fw(ring, next_to_clean);
|
||||
ring->pending_buf++;
|
||||
}
|
||||
} while (!(bd_base_info & BIT(HNS3_RXD_FE_B)));
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -3063,28 +3048,23 @@ static int hns3_handle_rx_bd(struct hns3_enet_ring *ring)
|
||||
|
||||
if (ret < 0) /* alloc buffer fail */
|
||||
return ret;
|
||||
if (ret > 0) { /* need add frag */
|
||||
ret = hns3_add_frag(ring, desc, false);
|
||||
if (!(bd_base_info & BIT(HNS3_RXD_FE_B))) { /* need add frag */
|
||||
ret = hns3_add_frag(ring);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* As the head data may be changed when GRO enable, copy
|
||||
* the head data in after other data rx completed
|
||||
*/
|
||||
memcpy(skb->data, ring->va,
|
||||
ALIGN(ring->pull_len, sizeof(long)));
|
||||
}
|
||||
} else {
|
||||
ret = hns3_add_frag(ring, desc, true);
|
||||
ret = hns3_add_frag(ring);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* As the head data may be changed when GRO enable, copy
|
||||
* the head data in after other data rx completed
|
||||
*/
|
||||
/* As the head data may be changed when GRO enable, copy
|
||||
* the head data in after other data rx completed
|
||||
*/
|
||||
if (skb->len > HNS3_RX_HEAD_SIZE)
|
||||
memcpy(skb->data, ring->va,
|
||||
ALIGN(ring->pull_len, sizeof(long)));
|
||||
}
|
||||
|
||||
ret = hns3_handle_bdinfo(ring, skb);
|
||||
if (unlikely(ret)) {
|
||||
|
Loading…
Reference in New Issue
Block a user