Skip to content

Commit e559709

Browse files
321lipengdavem330
authored andcommitted
net: hns3: Add handling of GRO Pkts not fully RX'ed in NAPI poll
The "FE bit" in the description means the last description for a packets. When HW GRO enable, HW write data to ring every packet/buffer, there is greater probability that driver handle with the describtion but HW still not set the "FE bit". When drier handle the packet and HW still not set "FE bit", driver stores skb and bd_num in rx ring, and continue to use the skb and bd_num in next napi. Signed-off-by: Peng Li <[email protected]> Signed-off-by: Salil Mehta <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent b26a6fe commit e559709

File tree

2 files changed

+140
-62
lines changed

2 files changed

+140
-62
lines changed

drivers/net/ethernet/hisilicon/hns3/hns3_enet.c

Lines changed: 134 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -2383,6 +2383,90 @@ static bool hns3_parse_vlan_tag(struct hns3_enet_ring *ring,
23832383
}
23842384
}
23852385

2386+
static int hns3_alloc_skb(struct hns3_enet_ring *ring, int length,
2387+
unsigned char *va)
2388+
{
2389+
#define HNS3_NEED_ADD_FRAG 1
2390+
struct hns3_desc_cb *desc_cb = &ring->desc_cb[ring->next_to_clean];
2391+
struct net_device *netdev = ring->tqp->handle->kinfo.netdev;
2392+
struct sk_buff *skb;
2393+
2394+
ring->skb = napi_alloc_skb(&ring->tqp_vector->napi, HNS3_RX_HEAD_SIZE);
2395+
skb = ring->skb;
2396+
if (unlikely(!skb)) {
2397+
netdev_err(netdev, "alloc rx skb fail\n");
2398+
2399+
u64_stats_update_begin(&ring->syncp);
2400+
ring->stats.sw_err_cnt++;
2401+
u64_stats_update_end(&ring->syncp);
2402+
2403+
return -ENOMEM;
2404+
}
2405+
2406+
prefetchw(skb->data);
2407+
2408+
ring->pending_buf = 1;
2409+
if (length <= HNS3_RX_HEAD_SIZE) {
2410+
memcpy(__skb_put(skb, length), va, ALIGN(length, sizeof(long)));
2411+
2412+
/* We can reuse buffer as-is, just make sure it is local */
2413+
if (likely(page_to_nid(desc_cb->priv) == numa_node_id()))
2414+
desc_cb->reuse_flag = 1;
2415+
else /* This page cannot be reused so discard it */
2416+
put_page(desc_cb->priv);
2417+
2418+
ring_ptr_move_fw(ring, next_to_clean);
2419+
return 0;
2420+
}
2421+
u64_stats_update_begin(&ring->syncp);
2422+
ring->stats.seg_pkt_cnt++;
2423+
u64_stats_update_end(&ring->syncp);
2424+
2425+
ring->pull_len = eth_get_headlen(va, HNS3_RX_HEAD_SIZE);
2426+
__skb_put(skb, ring->pull_len);
2427+
hns3_nic_reuse_page(skb, 0, ring, ring->pull_len,
2428+
desc_cb);
2429+
ring_ptr_move_fw(ring, next_to_clean);
2430+
2431+
return HNS3_NEED_ADD_FRAG;
2432+
}
2433+
2434+
static int hns3_add_frag(struct hns3_enet_ring *ring, struct hns3_desc *desc,
2435+
struct sk_buff **out_skb, bool pending)
2436+
{
2437+
struct sk_buff *skb = *out_skb;
2438+
struct hns3_desc_cb *desc_cb;
2439+
struct hns3_desc *pre_desc;
2440+
u32 bd_base_info;
2441+
int pre_bd;
2442+
2443+
/* if there is pending bd, the SW param next_to_clean has moved
2444+
* to next and the next is NULL
2445+
*/
2446+
if (pending) {
2447+
pre_bd = (ring->next_to_clean - 1 + ring->desc_num) %
2448+
ring->desc_num;
2449+
pre_desc = &ring->desc[pre_bd];
2450+
bd_base_info = le32_to_cpu(pre_desc->rx.bd_base_info);
2451+
} else {
2452+
bd_base_info = le32_to_cpu(desc->rx.bd_base_info);
2453+
}
2454+
2455+
while (!hnae3_get_bit(bd_base_info, HNS3_RXD_FE_B)) {
2456+
desc = &ring->desc[ring->next_to_clean];
2457+
desc_cb = &ring->desc_cb[ring->next_to_clean];
2458+
bd_base_info = le32_to_cpu(desc->rx.bd_base_info);
2459+
if (!hnae3_get_bit(bd_base_info, HNS3_RXD_VLD_B))
2460+
return -ENXIO;
2461+
2462+
hns3_nic_reuse_page(skb, ring->pending_buf, ring, 0, desc_cb);
2463+
ring_ptr_move_fw(ring, next_to_clean);
2464+
ring->pending_buf++;
2465+
}
2466+
2467+
return 0;
2468+
}
2469+
23862470
static void hns3_set_rx_skb_rss_type(struct hns3_enet_ring *ring,
23872471
struct sk_buff *skb)
23882472
{
@@ -2399,18 +2483,16 @@ static void hns3_set_rx_skb_rss_type(struct hns3_enet_ring *ring,
23992483
}
24002484

24012485
static int hns3_handle_rx_bd(struct hns3_enet_ring *ring,
2402-
struct sk_buff **out_skb, int *out_bnum)
2486+
struct sk_buff **out_skb)
24032487
{
24042488
struct net_device *netdev = ring->tqp->handle->kinfo.netdev;
2489+
struct sk_buff *skb = ring->skb;
24052490
struct hns3_desc_cb *desc_cb;
24062491
struct hns3_desc *desc;
2407-
struct sk_buff *skb;
2408-
unsigned char *va;
24092492
u32 bd_base_info;
2410-
int pull_len;
24112493
u32 l234info;
24122494
int length;
2413-
int bnum;
2495+
int ret;
24142496

24152497
desc = &ring->desc[ring->next_to_clean];
24162498
desc_cb = &ring->desc_cb[ring->next_to_clean];
@@ -2422,9 +2504,10 @@ static int hns3_handle_rx_bd(struct hns3_enet_ring *ring,
24222504

24232505
/* Check valid BD */
24242506
if (unlikely(!hnae3_get_bit(bd_base_info, HNS3_RXD_VLD_B)))
2425-
return -EFAULT;
2507+
return -ENXIO;
24262508

2427-
va = (unsigned char *)desc_cb->buf + desc_cb->page_offset;
2509+
if (!skb)
2510+
ring->va = (unsigned char *)desc_cb->buf + desc_cb->page_offset;
24282511

24292512
/* Prefetch first cache line of first page
24302513
* Idea is to cache few bytes of the header of the packet. Our L1 Cache
@@ -2433,62 +2516,42 @@ static int hns3_handle_rx_bd(struct hns3_enet_ring *ring,
24332516
* lines. In such a case, single fetch would suffice to cache in the
24342517
* relevant part of the header.
24352518
*/
2436-
prefetch(va);
2519+
prefetch(ring->va);
24372520
#if L1_CACHE_BYTES < 128
2438-
prefetch(va + L1_CACHE_BYTES);
2521+
prefetch(ring->va + L1_CACHE_BYTES);
24392522
#endif
24402523

2441-
skb = *out_skb = napi_alloc_skb(&ring->tqp_vector->napi,
2442-
HNS3_RX_HEAD_SIZE);
2443-
if (unlikely(!skb)) {
2444-
netdev_err(netdev, "alloc rx skb fail\n");
2524+
if (!skb) {
2525+
ret = hns3_alloc_skb(ring, length, ring->va);
2526+
*out_skb = skb = ring->skb;
24452527

2446-
u64_stats_update_begin(&ring->syncp);
2447-
ring->stats.sw_err_cnt++;
2448-
u64_stats_update_end(&ring->syncp);
2449-
2450-
return -ENOMEM;
2451-
}
2452-
2453-
prefetchw(skb->data);
2454-
2455-
bnum = 1;
2456-
if (length <= HNS3_RX_HEAD_SIZE) {
2457-
memcpy(__skb_put(skb, length), va, ALIGN(length, sizeof(long)));
2458-
2459-
/* We can reuse buffer as-is, just make sure it is local */
2460-
if (likely(page_to_nid(desc_cb->priv) == numa_node_id()))
2461-
desc_cb->reuse_flag = 1;
2462-
else /* This page cannot be reused so discard it */
2463-
put_page(desc_cb->priv);
2528+
if (ret < 0) /* alloc buffer fail */
2529+
return ret;
2530+
if (ret > 0) { /* need add frag */
2531+
ret = hns3_add_frag(ring, desc, &skb, false);
2532+
if (ret)
2533+
return ret;
24642534

2465-
ring_ptr_move_fw(ring, next_to_clean);
2535+
/* As the head data may be changed when GRO enable, copy
2536+
* the head data in after other data rx completed
2537+
*/
2538+
memcpy(skb->data, ring->va,
2539+
ALIGN(ring->pull_len, sizeof(long)));
2540+
}
24662541
} else {
2467-
u64_stats_update_begin(&ring->syncp);
2468-
ring->stats.seg_pkt_cnt++;
2469-
u64_stats_update_end(&ring->syncp);
2470-
2471-
pull_len = eth_get_headlen(va, HNS3_RX_HEAD_SIZE);
2472-
2473-
memcpy(__skb_put(skb, pull_len), va,
2474-
ALIGN(pull_len, sizeof(long)));
2475-
2476-
hns3_nic_reuse_page(skb, 0, ring, pull_len, desc_cb);
2477-
ring_ptr_move_fw(ring, next_to_clean);
2542+
ret = hns3_add_frag(ring, desc, &skb, true);
2543+
if (ret)
2544+
return ret;
24782545

2479-
while (!hnae3_get_bit(bd_base_info, HNS3_RXD_FE_B)) {
2480-
desc = &ring->desc[ring->next_to_clean];
2481-
desc_cb = &ring->desc_cb[ring->next_to_clean];
2482-
bd_base_info = le32_to_cpu(desc->rx.bd_base_info);
2483-
hns3_nic_reuse_page(skb, bnum, ring, 0, desc_cb);
2484-
ring_ptr_move_fw(ring, next_to_clean);
2485-
bnum++;
2486-
}
2546+
/* As the head data may be changed when GRO enable, copy
2547+
* the head data in after other data rx completed
2548+
*/
2549+
memcpy(skb->data, ring->va,
2550+
ALIGN(ring->pull_len, sizeof(long)));
24872551
}
24882552

2489-
*out_bnum = bnum;
2490-
24912553
l234info = le32_to_cpu(desc->rx.l234_info);
2554+
bd_base_info = le32_to_cpu(desc->rx.bd_base_info);
24922555

24932556
/* Based on hw strategy, the tag offloaded will be stored at
24942557
* ot_vlan_tag in two layer tag case, and stored at vlan_tag
@@ -2539,6 +2602,7 @@ static int hns3_handle_rx_bd(struct hns3_enet_ring *ring,
25392602
ring->tqp_vector->rx_group.total_bytes += skb->len;
25402603

25412604
hns3_rx_checksum(ring, skb, desc);
2605+
*out_skb = skb;
25422606
hns3_set_rx_skb_rss_type(ring, skb);
25432607

25442608
return 0;
@@ -2551,9 +2615,9 @@ int hns3_clean_rx_ring(
25512615
#define RCB_NOF_ALLOC_RX_BUFF_ONCE 16
25522616
struct net_device *netdev = ring->tqp->handle->kinfo.netdev;
25532617
int recv_pkts, recv_bds, clean_count, err;
2554-
int unused_count = hns3_desc_unused(ring);
2555-
struct sk_buff *skb = NULL;
2556-
int num, bnum = 0;
2618+
int unused_count = hns3_desc_unused(ring) - ring->pending_buf;
2619+
struct sk_buff *skb = ring->skb;
2620+
int num;
25572621

25582622
num = readl_relaxed(ring->tqp->io_base + HNS3_RING_RX_RING_FBDNUM_REG);
25592623
rmb(); /* Make sure num taken effect before the other data is touched */
@@ -2567,24 +2631,32 @@ int hns3_clean_rx_ring(
25672631
hns3_nic_alloc_rx_buffers(ring,
25682632
clean_count + unused_count);
25692633
clean_count = 0;
2570-
unused_count = hns3_desc_unused(ring);
2634+
unused_count = hns3_desc_unused(ring) -
2635+
ring->pending_buf;
25712636
}
25722637

25732638
/* Poll one pkt */
2574-
err = hns3_handle_rx_bd(ring, &skb, &bnum);
2639+
err = hns3_handle_rx_bd(ring, &skb);
25752640
if (unlikely(!skb)) /* This fault cannot be repaired */
25762641
goto out;
25772642

2578-
recv_bds += bnum;
2579-
clean_count += bnum;
2580-
if (unlikely(err)) { /* Do jump the err */
2581-
recv_pkts++;
2643+
if (err == -ENXIO) { /* Do not get FE for the packet */
2644+
goto out;
2645+
} else if (unlikely(err)) { /* Do jump the err */
2646+
recv_bds += ring->pending_buf;
2647+
clean_count += ring->pending_buf;
2648+
ring->skb = NULL;
2649+
ring->pending_buf = 0;
25822650
continue;
25832651
}
25842652

25852653
/* Do update ip stack process */
25862654
skb->protocol = eth_type_trans(skb, netdev);
25872655
rx_fn(ring, skb);
2656+
recv_bds += ring->pending_buf;
2657+
clean_count += ring->pending_buf;
2658+
ring->skb = NULL;
2659+
ring->pending_buf = 0;
25882660

25892661
recv_pkts++;
25902662
}

drivers/net/ethernet/hisilicon/hns3/hns3_enet.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,11 +401,17 @@ struct hns3_enet_ring {
401401
*/
402402
int next_to_clean;
403403

404+
int pull_len; /* head length for current packet */
405+
unsigned char *va; /* first buffer address for current packet */
406+
404407
u32 flag; /* ring attribute */
405408
int irq_init_flag;
406409

407410
int numa_node;
408411
cpumask_t affinity_mask;
412+
413+
int pending_buf;
414+
struct sk_buff *skb;
409415
};
410416

411417
struct hns_queue;

0 commit comments

Comments
 (0)