Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'net-hibmcge-add-support-for-tracepoint-and-pagepool-on-hibmcge-driver'

Jijie Shao says:

====================
net: hibmcge: Add support for tracepoint and pagepool on hibmcge driver

In this patch set:
1: add support for tracepoint for rx descriptor
2: double the rx queue depth to reduce packet drop
3: add support for pagepool on rx
====================

Link: https://patch.msgid.link/20251122034657.3373143-1-shaojijie@huawei.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+273 -44
+1
drivers/net/ethernet/hisilicon/Kconfig
··· 151 151 select FIXED_PHY 152 152 select MOTORCOMM_PHY 153 153 select REALTEK_PHY 154 + select PAGE_POOL 154 155 help 155 156 If you wish to compile a kernel for a BMC with HIBMC-xx_gmac 156 157 then you should answer Y to this. This makes this driver suitable for use
+1
drivers/net/ethernet/hisilicon/hibmcge/Makefile
··· 3 3 # Makefile for the HISILICON BMC GE network device drivers. 4 4 # 5 5 6 + ccflags-y += -I$(src) 6 7 obj-$(CONFIG_HIBMCGE) += hibmcge.o 7 8 8 9 hibmcge-objs = hbg_main.o hbg_hw.o hbg_mdio.o hbg_irq.o hbg_txrx.o hbg_ethtool.o \
+8
drivers/net/ethernet/hisilicon/hibmcge/hbg_common.h
··· 7 7 #include <linux/ethtool.h> 8 8 #include <linux/netdevice.h> 9 9 #include <linux/pci.h> 10 + #include <net/page_pool/helpers.h> 10 11 #include "hbg_reg.h" 11 12 12 13 #define HBG_STATUS_DISABLE 0x0 ··· 56 55 dma_addr_t skb_dma; 57 56 u32 skb_len; 58 57 58 + struct page *page; 59 + void *page_addr; 60 + dma_addr_t page_dma; 61 + u32 page_size; 62 + u32 page_offset; 63 + 59 64 enum hbg_dir dir; 60 65 struct hbg_ring *ring; 61 66 struct hbg_priv *priv; ··· 85 78 struct hbg_priv *priv; 86 79 struct napi_struct napi; 87 80 char *tout_log_buf; /* tx timeout log buffer */ 81 + struct page_pool *page_pool; /* only for rx */ 88 82 }; 89 83 90 84 enum hbg_hw_event_type {
+4
drivers/net/ethernet/hisilicon/hibmcge/hbg_reg.h
··· 252 252 253 253 #define HBG_RX_DESC_W2_PKT_LEN_M GENMASK(31, 16) 254 254 #define HBG_RX_DESC_W2_PORT_NUM_M GENMASK(15, 12) 255 + #define HBG_RX_DESC_W3_IP_OFFSET_M GENMASK(23, 16) 256 + #define HBG_RX_DESC_W3_VLAN_M GENMASK(15, 0) 255 257 #define HBG_RX_DESC_W4_IP_TCP_UDP_M GENMASK(31, 30) 256 258 #define HBG_RX_DESC_W4_IPSEC_B BIT(29) 257 259 #define HBG_RX_DESC_W4_IP_VERSION_B BIT(28) ··· 271 269 #define HBG_RX_DESC_W4_L3_ERR_CODE_M GENMASK(12, 9) 272 270 #define HBG_RX_DESC_W4_L2_ERR_B BIT(8) 273 271 #define HBG_RX_DESC_W4_IDX_MATCH_B BIT(7) 272 + #define HBG_RX_DESC_W4_PARSE_MODE_M GENMASK(6, 5) 273 + #define HBG_RX_DESC_W5_VALID_SIZE_M GENMASK(15, 0) 274 274 275 275 enum hbg_l3_err_code { 276 276 HBG_L3_OK = 0,
+84
drivers/net/ethernet/hisilicon/hibmcge/hbg_trace.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0+ */ 2 + /* Copyright (c) 2025 Hisilicon Limited. */ 3 + 4 + /* This must be outside ifdef _HBG_TRACE_H */ 5 + #undef TRACE_SYSTEM 6 + #define TRACE_SYSTEM hibmcge 7 + 8 + #if !defined(_HBG_TRACE_H_) || defined(TRACE_HEADER_MULTI_READ) 9 + #define _HBG_TRACE_H_ 10 + 11 + #include <linux/bitfield.h> 12 + #include <linux/pci.h> 13 + #include <linux/tracepoint.h> 14 + #include <linux/types.h> 15 + #include "hbg_reg.h" 16 + 17 + TRACE_EVENT(hbg_rx_desc, 18 + TP_PROTO(struct hbg_priv *priv, u32 index, 19 + struct hbg_rx_desc *rx_desc), 20 + TP_ARGS(priv, index, rx_desc), 21 + 22 + TP_STRUCT__entry(__field(u32, index) 23 + __field(u8, port_num) 24 + __field(u8, ip_offset) 25 + __field(u8, parse_mode) 26 + __field(u8, l4_error_code) 27 + __field(u8, l3_error_code) 28 + __field(u8, l2_error_code) 29 + __field(u16, packet_len) 30 + __field(u16, valid_size) 31 + __field(u16, vlan) 32 + __string(pciname, pci_name(priv->pdev)) 33 + __string(devname, priv->netdev->name) 34 + ), 35 + 36 + TP_fast_assign(__entry->index = index, 37 + __entry->packet_len = 38 + FIELD_GET(HBG_RX_DESC_W2_PKT_LEN_M, 39 + rx_desc->word2); 40 + __entry->port_num = 41 + FIELD_GET(HBG_RX_DESC_W2_PORT_NUM_M, 42 + rx_desc->word2); 43 + __entry->ip_offset = 44 + FIELD_GET(HBG_RX_DESC_W3_IP_OFFSET_M, 45 + rx_desc->word3); 46 + __entry->vlan = 47 + FIELD_GET(HBG_RX_DESC_W3_VLAN_M, 48 + rx_desc->word3); 49 + __entry->parse_mode = 50 + FIELD_GET(HBG_RX_DESC_W4_PARSE_MODE_M, 51 + rx_desc->word4); 52 + __entry->l4_error_code = 53 + FIELD_GET(HBG_RX_DESC_W4_L4_ERR_CODE_M, 54 + rx_desc->word4); 55 + __entry->l3_error_code = 56 + FIELD_GET(HBG_RX_DESC_W4_L3_ERR_CODE_M, 57 + rx_desc->word4); 58 + __entry->l2_error_code = 59 + FIELD_GET(HBG_RX_DESC_W4_L2_ERR_B, 60 + rx_desc->word4); 61 + __entry->valid_size = 62 + FIELD_GET(HBG_RX_DESC_W5_VALID_SIZE_M, 63 + rx_desc->word5); 64 + __assign_str(pciname); 65 + __assign_str(devname); 66 + ), 67 + 68 + TP_printk("%s %s index:%u, port num:%u, len:%u, valid size:%u, ip_offset:%u, vlan:0x%04x, parse mode:%u, l4_err:0x%x, l3_err:0x%x, l2_err:0x%x", 69 + __get_str(pciname), __get_str(devname), __entry->index, 70 + __entry->port_num, __entry->packet_len, 71 + __entry->valid_size, __entry->ip_offset, __entry->vlan, 72 + __entry->parse_mode, __entry->l4_error_code, 73 + __entry->l3_error_code, __entry->l2_error_code 74 + ) 75 + ); 76 + 77 + #endif /* _HBG_TRACE_H_ */ 78 + 79 + /* This must be outside ifdef _HBG_TRACE_H */ 80 + #undef TRACE_INCLUDE_PATH 81 + #define TRACE_INCLUDE_PATH . 82 + #undef TRACE_INCLUDE_FILE 83 + #define TRACE_INCLUDE_FILE hbg_trace 84 + #include <trace/define_trace.h>
+175 -44
drivers/net/ethernet/hisilicon/hibmcge/hbg_txrx.c
··· 7 7 #include "hbg_reg.h" 8 8 #include "hbg_txrx.h" 9 9 10 + #define CREATE_TRACE_POINTS 11 + #include "hbg_trace.h" 12 + 10 13 #define netdev_get_tx_ring(netdev) \ 11 14 (&(((struct hbg_priv *)netdev_priv(netdev))->tx_ring)) 12 15 ··· 30 27 #define hbg_queue_move_next(p, ring) ({ \ 31 28 typeof(ring) _ring = (ring); \ 32 29 _ring->p = hbg_queue_next_prt(_ring->p, _ring); }) 30 + 31 + #define hbg_get_page_order(ring) ({ \ 32 + typeof(ring) _ring = (ring); \ 33 + get_order(hbg_spec_max_frame_len(_ring->priv, _ring->dir)); }) 34 + #define hbg_get_page_size(ring) (PAGE_SIZE << hbg_get_page_order((ring))) 33 35 34 36 #define HBG_TX_STOP_THRS 2 35 37 #define HBG_TX_START_THRS (2 * HBG_TX_STOP_THRS) ··· 68 60 dma_unmap_single(&priv->pdev->dev, buffer->skb_dma, buffer->skb_len, 69 61 buffer_to_dma_dir(buffer)); 70 62 buffer->skb_dma = 0; 63 + } 64 + 65 + static void hbg_buffer_free_page(struct hbg_buffer *buffer) 66 + { 67 + struct hbg_ring *ring = buffer->ring; 68 + 69 + if (unlikely(!buffer->page)) 70 + return; 71 + 72 + page_pool_put_full_page(ring->page_pool, buffer->page, false); 73 + 74 + buffer->page = NULL; 75 + buffer->page_dma = 0; 76 + buffer->page_addr = NULL; 77 + buffer->page_size = 0; 78 + buffer->page_offset = 0; 79 + } 80 + 81 + static int hbg_buffer_alloc_page(struct hbg_buffer *buffer) 82 + { 83 + struct hbg_ring *ring = buffer->ring; 84 + u32 len = hbg_get_page_size(ring); 85 + u32 offset; 86 + 87 + if (unlikely(!ring->page_pool)) 88 + return 0; 89 + 90 + buffer->page = page_pool_dev_alloc_frag(ring->page_pool, &offset, len); 91 + if (unlikely(!buffer->page)) 92 + return -ENOMEM; 93 + 94 + buffer->page_dma = page_pool_get_dma_addr(buffer->page) + offset; 95 + buffer->page_addr = page_address(buffer->page) + offset; 96 + buffer->page_size = len; 97 + buffer->page_offset = offset; 98 + 99 + return 0; 71 100 } 72 101 73 102 static void hbg_init_tx_desc(struct hbg_buffer *buffer, ··· 180 135 buffer->skb = NULL; 181 136 } 182 137 183 - static int hbg_buffer_alloc_skb(struct hbg_buffer *buffer) 184 - { 185 - u32 len = hbg_spec_max_frame_len(buffer->priv, buffer->dir); 186 - struct hbg_priv *priv = buffer->priv; 187 - 188 - buffer->skb = netdev_alloc_skb(priv->netdev, len); 189 - if (unlikely(!buffer->skb)) 190 - return -ENOMEM; 191 - 192 - buffer->skb_len = len; 193 - memset(buffer->skb->data, 0, HBG_PACKET_HEAD_SIZE); 194 - return 0; 195 - } 196 - 197 138 static void hbg_buffer_free(struct hbg_buffer *buffer) 198 139 { 199 - hbg_dma_unmap(buffer); 200 - hbg_buffer_free_skb(buffer); 140 + if (buffer->skb) { 141 + hbg_dma_unmap(buffer); 142 + return hbg_buffer_free_skb(buffer); 143 + } 144 + 145 + hbg_buffer_free_page(buffer); 201 146 } 202 147 203 148 static int hbg_napi_tx_recycle(struct napi_struct *napi, int budget) ··· 409 374 struct hbg_buffer *buffer; 410 375 int ret; 411 376 412 - if (hbg_queue_is_full(ring->ntc, ring->ntu, ring)) 377 + if (hbg_queue_is_full(ring->ntc, ring->ntu, ring) || 378 + hbg_fifo_is_full(priv, ring->dir)) 413 379 return 0; 414 380 415 381 buffer = &ring->queue[ring->ntu]; 416 - ret = hbg_buffer_alloc_skb(buffer); 382 + ret = hbg_buffer_alloc_page(buffer); 417 383 if (unlikely(ret)) 418 384 return ret; 419 385 420 - ret = hbg_dma_map(buffer); 421 - if (unlikely(ret)) { 422 - hbg_buffer_free_skb(buffer); 423 - return ret; 424 - } 386 + memset(buffer->page_addr, 0, HBG_PACKET_HEAD_SIZE); 387 + dma_sync_single_for_device(&priv->pdev->dev, buffer->page_dma, 388 + HBG_PACKET_HEAD_SIZE, DMA_TO_DEVICE); 425 389 426 - hbg_hw_fill_buffer(priv, buffer->skb_dma); 390 + hbg_hw_fill_buffer(priv, buffer->page_dma); 427 391 hbg_queue_move_next(ntu, ring); 428 392 return 0; 393 + } 394 + 395 + static int hbg_rx_fill_buffers(struct hbg_priv *priv) 396 + { 397 + u32 remained = hbg_hw_get_fifo_used_num(priv, HBG_DIR_RX); 398 + u32 max_count = priv->dev_specs.rx_fifo_num; 399 + u32 refill_count; 400 + int ret; 401 + 402 + if (unlikely(remained >= max_count)) 403 + return 0; 404 + 405 + refill_count = max_count - remained; 406 + while (refill_count--) { 407 + ret = hbg_rx_fill_one_buffer(priv); 408 + if (unlikely(ret)) 409 + break; 410 + } 411 + 412 + return ret; 429 413 } 430 414 431 415 static bool hbg_sync_data_from_hw(struct hbg_priv *priv, ··· 455 401 /* make sure HW write desc complete */ 456 402 dma_rmb(); 457 403 458 - dma_sync_single_for_cpu(&priv->pdev->dev, buffer->skb_dma, 459 - buffer->skb_len, DMA_FROM_DEVICE); 404 + dma_sync_single_for_cpu(&priv->pdev->dev, buffer->page_dma, 405 + buffer->page_size, DMA_FROM_DEVICE); 460 406 461 - rx_desc = (struct hbg_rx_desc *)buffer->skb->data; 407 + rx_desc = (struct hbg_rx_desc *)buffer->page_addr; 462 408 return FIELD_GET(HBG_RX_DESC_W2_PKT_LEN_M, rx_desc->word2) != 0; 409 + } 410 + 411 + static int hbg_build_skb(struct hbg_priv *priv, 412 + struct hbg_buffer *buffer, u32 pkt_len) 413 + { 414 + net_prefetch(buffer->page_addr); 415 + 416 + buffer->skb = napi_build_skb(buffer->page_addr, buffer->page_size); 417 + if (unlikely(!buffer->skb)) 418 + return -ENOMEM; 419 + skb_mark_for_recycle(buffer->skb); 420 + 421 + /* page will be freed together with the skb */ 422 + buffer->page = NULL; 423 + 424 + return 0; 463 425 } 464 426 465 427 static int hbg_napi_rx_poll(struct napi_struct *napi, int budget) ··· 487 417 u32 packet_done = 0; 488 418 u32 pkt_len; 489 419 420 + hbg_rx_fill_buffers(priv); 490 421 while (packet_done < budget) { 491 422 if (unlikely(hbg_queue_is_empty(ring->ntc, ring->ntu, ring))) 492 423 break; 493 424 494 425 buffer = &ring->queue[ring->ntc]; 495 - if (unlikely(!buffer->skb)) 426 + if (unlikely(!buffer->page)) 496 427 goto next_buffer; 497 428 498 429 if (unlikely(!hbg_sync_data_from_hw(priv, buffer))) 499 430 break; 500 - rx_desc = (struct hbg_rx_desc *)buffer->skb->data; 431 + rx_desc = (struct hbg_rx_desc *)buffer->page_addr; 501 432 pkt_len = FIELD_GET(HBG_RX_DESC_W2_PKT_LEN_M, rx_desc->word2); 433 + trace_hbg_rx_desc(priv, ring->ntc, rx_desc); 502 434 503 - if (unlikely(!hbg_rx_pkt_check(priv, rx_desc, buffer->skb))) { 504 - hbg_buffer_free(buffer); 435 + if (unlikely(hbg_build_skb(priv, buffer, pkt_len))) { 436 + hbg_buffer_free_page(buffer); 505 437 goto next_buffer; 506 438 } 507 439 508 - hbg_dma_unmap(buffer); 440 + if (unlikely(!hbg_rx_pkt_check(priv, rx_desc, buffer->skb))) { 441 + hbg_buffer_free_skb(buffer); 442 + goto next_buffer; 443 + } 444 + 509 445 skb_reserve(buffer->skb, HBG_PACKET_HEAD_SIZE + NET_IP_ALIGN); 510 446 skb_put(buffer->skb, pkt_len); 511 447 buffer->skb->protocol = eth_type_trans(buffer->skb, 512 448 priv->netdev); 513 - 514 449 dev_sw_netstats_rx_add(priv->netdev, pkt_len); 515 450 napi_gro_receive(napi, buffer->skb); 516 451 buffer->skb = NULL; 452 + buffer->page = NULL; 517 453 518 454 next_buffer: 519 455 hbg_rx_fill_one_buffer(priv); ··· 532 456 hbg_hw_irq_enable(priv, HBG_INT_MSK_RX_B, true); 533 457 534 458 return packet_done; 459 + } 460 + 461 + static void hbg_ring_page_pool_destory(struct hbg_ring *ring) 462 + { 463 + if (!ring->page_pool) 464 + return; 465 + 466 + page_pool_destroy(ring->page_pool); 467 + ring->page_pool = NULL; 468 + } 469 + 470 + static int hbg_ring_page_pool_init(struct hbg_priv *priv, struct hbg_ring *ring) 471 + { 472 + u32 buf_size = hbg_spec_max_frame_len(priv, ring->dir); 473 + struct page_pool_params pp_params = { 474 + .flags = PP_FLAG_DMA_MAP | PP_FLAG_DMA_SYNC_DEV, 475 + .order = hbg_get_page_order(ring), 476 + .pool_size = ring->len * buf_size / hbg_get_page_size(ring), 477 + .nid = dev_to_node(&priv->pdev->dev), 478 + .dev = &priv->pdev->dev, 479 + .napi = &ring->napi, 480 + .dma_dir = DMA_FROM_DEVICE, 481 + .offset = 0, 482 + .max_len = hbg_get_page_size(ring), 483 + }; 484 + int ret = 0; 485 + 486 + ring->page_pool = page_pool_create(&pp_params); 487 + if (IS_ERR(ring->page_pool)) { 488 + ret = PTR_ERR(ring->page_pool); 489 + dev_err(&priv->pdev->dev, 490 + "failed to create page pool, ret = %d\n", ret); 491 + ring->page_pool = NULL; 492 + } 493 + 494 + return ret; 535 495 } 536 496 537 497 static void hbg_ring_uninit(struct hbg_ring *ring) ··· 588 476 buffer->priv = NULL; 589 477 } 590 478 479 + hbg_ring_page_pool_destory(ring); 591 480 dma_free_coherent(&ring->priv->pdev->dev, 592 481 ring->len * sizeof(*ring->queue), 593 482 ring->queue, ring->queue_dma); ··· 604 491 { 605 492 struct hbg_buffer *buffer; 606 493 u32 i, len; 494 + int ret; 607 495 608 496 len = hbg_get_spec_fifo_max_num(priv, dir) + 1; 497 + /* To improve receiving performance under high-stress scenarios, 498 + * in the `hbg_napi_rx_poll()`, we first use the other half of 499 + * the buffer to receive packets from the hardware via the 500 + * `hbg_rx_fill_buffers()`, and then process the packets in the 501 + * original half of the buffer to avoid packet loss caused by 502 + * hardware overflow as much as possible. 503 + */ 504 + if (dir == HBG_DIR_RX) 505 + len += hbg_get_spec_fifo_max_num(priv, dir); 506 + 609 507 ring->queue = dma_alloc_coherent(&priv->pdev->dev, 610 508 len * sizeof(*ring->queue), 611 509 &ring->queue_dma, GFP_KERNEL); ··· 638 514 ring->ntu = 0; 639 515 ring->len = len; 640 516 641 - if (dir == HBG_DIR_TX) 517 + if (dir == HBG_DIR_TX) { 642 518 netif_napi_add_tx(priv->netdev, &ring->napi, napi_poll); 643 - else 519 + } else { 644 520 netif_napi_add(priv->netdev, &ring->napi, napi_poll); 521 + 522 + ret = hbg_ring_page_pool_init(priv, ring); 523 + if (ret) { 524 + netif_napi_del(&ring->napi); 525 + dma_free_coherent(&ring->priv->pdev->dev, 526 + ring->len * sizeof(*ring->queue), 527 + ring->queue, ring->queue_dma); 528 + ring->queue = NULL; 529 + ring->len = 0; 530 + return ret; 531 + } 532 + } 645 533 646 534 napi_enable(&ring->napi); 647 535 return 0; ··· 677 541 static int hbg_rx_ring_init(struct hbg_priv *priv) 678 542 { 679 543 int ret; 680 - u32 i; 681 544 682 545 ret = hbg_ring_init(priv, &priv->rx_ring, hbg_napi_rx_poll, HBG_DIR_RX); 683 546 if (ret) 684 547 return ret; 685 548 686 - for (i = 0; i < priv->rx_ring.len - 1; i++) { 687 - ret = hbg_rx_fill_one_buffer(priv); 688 - if (ret) { 689 - hbg_ring_uninit(&priv->rx_ring); 690 - return ret; 691 - } 692 - } 549 + ret = hbg_rx_fill_buffers(priv); 550 + if (ret) 551 + hbg_ring_uninit(&priv->rx_ring); 693 552 694 - return 0; 553 + return ret; 695 554 } 696 555 697 556 int hbg_txrx_init(struct hbg_priv *priv)