Skip to content

Commit a96857a

Browse files
author
Herton R. Krzesinski
committed
Merge: bnxt: Driver update for RHEL9.2
MR: https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-9/-/merge_requests/1931 Bugzilla: http://bugzilla.redhat.com/2112187 Depends: !1690 Update bnxt driver with latest upstream commits v2: Add missing fixes bnxt_en: fix memory leak in bnxt_nvm_test() bnxt: make sure we return pages to the pool v3: Only apply bnxt portion of patches Ken Cox (21): bnxt_en: Use struct_group_attr() for memcpy() region bnxt_en: Add compression flags information in coredump segment header bnxt_en: extract coredump command line from current task bnxt: adding bnxt_rx_agg_pages_xdp for aggregated xdp bnxt: set xdp_buff pfmemalloc flag if needed bnxt: adding bnxt_xdp_build_skb to build skb from multibuffer xdp_buff bnxt: support transmit and free of aggregation buffers bnxt: XDP multibuffer enablement ethernet: Remove vf rate limit check for drivers bnxt: Fix typo in comments bnxt: Use the bitmap API to allocate bitmaps bnxt_en: Fix and simplify XDP transmit path bnxt_en: implement callbacks for devlink selftests bnxt_en: Remove duplicated include bnxt_devlink.c bnxt_en: Use PAGE_SIZE to init buffer when multi buffer XDP is not in use bnxt_en: set missing reload flag in devlink features bnxt_en: fix NQ resource accounting during vf creation on 57500 chips bnxt_en: fix LRO/GRO_HW features in ndo_fix_features callback net: ethernet: move from strlcpy with unused retval to strscpy bnxt_en: fix memory leak in bnxt_nvm_test() bnxt: make sure we return pages to the pool drivers/net/ethernet/broadcom/bnxt/bnxt.c | 136 +++++++++++++--- drivers/net/ethernet/broadcom/bnxt/bnxt.h | 8 +- .../ethernet/broadcom/bnxt/bnxt_coredump.c | 27 +++- drivers/net/ethernet/broadcom/bnxt/bnxt_dcb.c | 4 +- drivers/net/ethernet/broadcom/bnxt/bnxt_dcb.h | 14 +- .../net/ethernet/broadcom/bnxt/bnxt_devlink.c | 62 +++++++ .../net/ethernet/broadcom/bnxt/bnxt_ethtool.c | 34 ++-- .../net/ethernet/broadcom/bnxt/bnxt_ethtool.h | 12 ++ .../net/ethernet/broadcom/bnxt/bnxt_sriov.c | 4 +- drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.c | 2 +- drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c | 151 ++++++++++++++++-- drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.h | 9 +- 12 files changed, 391 insertions(+), 72 deletions(-) Signed-off-by: Ken Cox <jkc@redhat.com> Approved-by: Kamal Heib <kheib@redhat.com> Approved-by: Jonathan Toppins <jtoppins@redhat.com> Signed-off-by: Herton R. Krzesinski <herton@redhat.com>
2 parents e319482 + 2ece429 commit a96857a

File tree

12 files changed

+391
-72
lines changed

12 files changed

+391
-72
lines changed

drivers/net/ethernet/broadcom/bnxt/bnxt.c

Lines changed: 112 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -968,6 +968,39 @@ static void bnxt_reuse_rx_agg_bufs(struct bnxt_cp_ring_info *cpr, u16 idx,
968968
rxr->rx_sw_agg_prod = sw_prod;
969969
}
970970

971+
static struct sk_buff *bnxt_rx_multi_page_skb(struct bnxt *bp,
972+
struct bnxt_rx_ring_info *rxr,
973+
u16 cons, void *data, u8 *data_ptr,
974+
dma_addr_t dma_addr,
975+
unsigned int offset_and_len)
976+
{
977+
unsigned int len = offset_and_len & 0xffff;
978+
struct page *page = data;
979+
u16 prod = rxr->rx_prod;
980+
struct sk_buff *skb;
981+
int err;
982+
983+
err = bnxt_alloc_rx_data(bp, rxr, prod, GFP_ATOMIC);
984+
if (unlikely(err)) {
985+
bnxt_reuse_rx_data(rxr, cons, data);
986+
return NULL;
987+
}
988+
dma_addr -= bp->rx_dma_offset;
989+
dma_unmap_page_attrs(&bp->pdev->dev, dma_addr, PAGE_SIZE, bp->rx_dir,
990+
DMA_ATTR_WEAK_ORDERING);
991+
skb = build_skb(page_address(page), BNXT_PAGE_MODE_BUF_SIZE +
992+
bp->rx_dma_offset);
993+
if (!skb) {
994+
page_pool_recycle_direct(rxr->page_pool, page);
995+
return NULL;
996+
}
997+
skb_mark_for_recycle(skb);
998+
skb_reserve(skb, bp->rx_dma_offset);
999+
__skb_put(skb, len);
1000+
1001+
return skb;
1002+
}
1003+
9711004
static struct sk_buff *bnxt_rx_page_skb(struct bnxt *bp,
9721005
struct bnxt_rx_ring_info *rxr,
9731006
u16 cons, void *data, u8 *data_ptr,
@@ -990,17 +1023,17 @@ static struct sk_buff *bnxt_rx_page_skb(struct bnxt *bp,
9901023
dma_addr -= bp->rx_dma_offset;
9911024
dma_unmap_page_attrs(&bp->pdev->dev, dma_addr, PAGE_SIZE, bp->rx_dir,
9921025
DMA_ATTR_WEAK_ORDERING);
993-
page_pool_release_page(rxr->page_pool, page);
9941026

9951027
if (unlikely(!payload))
9961028
payload = eth_get_headlen(bp->dev, data_ptr, len);
9971029

9981030
skb = napi_alloc_skb(&rxr->bnapi->napi, payload);
9991031
if (!skb) {
1000-
__free_page(page);
1032+
page_pool_recycle_direct(rxr->page_pool, page);
10011033
return NULL;
10021034
}
10031035

1036+
skb_mark_for_recycle(skb);
10041037
off = (void *)data_ptr - page_address(page);
10051038
skb_add_rx_frag(skb, 0, page, off, len, PAGE_SIZE);
10061039
memcpy(skb->data - NET_IP_ALIGN, data_ptr - NET_IP_ALIGN,
@@ -1047,7 +1080,8 @@ static struct sk_buff *bnxt_rx_skb(struct bnxt *bp,
10471080
static u32 __bnxt_rx_agg_pages(struct bnxt *bp,
10481081
struct bnxt_cp_ring_info *cpr,
10491082
struct skb_shared_info *shinfo,
1050-
u16 idx, u32 agg_bufs, bool tpa)
1083+
u16 idx, u32 agg_bufs, bool tpa,
1084+
struct xdp_buff *xdp)
10511085
{
10521086
struct bnxt_napi *bnapi = cpr->bnapi;
10531087
struct pci_dev *pdev = bp->pdev;
@@ -1090,6 +1124,9 @@ static u32 __bnxt_rx_agg_pages(struct bnxt *bp,
10901124
page = cons_rx_buf->page;
10911125
cons_rx_buf->page = NULL;
10921126

1127+
if (xdp && page_is_pfmemalloc(page))
1128+
xdp_buff_set_frag_pfmemalloc(xdp);
1129+
10931130
if (bnxt_alloc_rx_page(bp, rxr, prod, GFP_ATOMIC) != 0) {
10941131
unsigned int nr_frags;
10951132

@@ -1124,8 +1161,8 @@ static struct sk_buff *bnxt_rx_agg_pages_skb(struct bnxt *bp,
11241161
struct skb_shared_info *shinfo = skb_shinfo(skb);
11251162
u32 total_frag_len = 0;
11261163

1127-
total_frag_len = __bnxt_rx_agg_pages(bp, cpr, shinfo, idx, agg_bufs, tpa);
1128-
1164+
total_frag_len = __bnxt_rx_agg_pages(bp, cpr, shinfo, idx,
1165+
agg_bufs, tpa, NULL);
11291166
if (!total_frag_len) {
11301167
dev_kfree_skb(skb);
11311168
return NULL;
@@ -1137,6 +1174,27 @@ static struct sk_buff *bnxt_rx_agg_pages_skb(struct bnxt *bp,
11371174
return skb;
11381175
}
11391176

1177+
static u32 bnxt_rx_agg_pages_xdp(struct bnxt *bp,
1178+
struct bnxt_cp_ring_info *cpr,
1179+
struct xdp_buff *xdp, u16 idx,
1180+
u32 agg_bufs, bool tpa)
1181+
{
1182+
struct skb_shared_info *shinfo = xdp_get_shared_info_from_buff(xdp);
1183+
u32 total_frag_len = 0;
1184+
1185+
if (!xdp_buff_has_frags(xdp))
1186+
shinfo->nr_frags = 0;
1187+
1188+
total_frag_len = __bnxt_rx_agg_pages(bp, cpr, shinfo,
1189+
idx, agg_bufs, tpa, xdp);
1190+
if (total_frag_len) {
1191+
xdp_buff_set_frags_flag(xdp);
1192+
shinfo->nr_frags = agg_bufs;
1193+
shinfo->xdp_frags_size = total_frag_len;
1194+
}
1195+
return total_frag_len;
1196+
}
1197+
11401198
static int bnxt_agg_bufs_valid(struct bnxt *bp, struct bnxt_cp_ring_info *cpr,
11411199
u8 agg_bufs, u32 *raw_cons)
11421200
{
@@ -1865,11 +1923,20 @@ static int bnxt_rx_pkt(struct bnxt *bp, struct bnxt_cp_ring_info *cpr,
18651923

18661924
if (bnxt_xdp_attached(bp, rxr)) {
18671925
bnxt_xdp_buff_init(bp, rxr, cons, &data_ptr, &len, &xdp);
1926+
if (agg_bufs) {
1927+
u32 frag_len = bnxt_rx_agg_pages_xdp(bp, cpr, &xdp,
1928+
cp_cons, agg_bufs,
1929+
false);
1930+
if (!frag_len) {
1931+
cpr->sw_stats.rx.rx_oom_discards += 1;
1932+
rc = -ENOMEM;
1933+
goto next_rx;
1934+
}
1935+
}
18681936
xdp_active = true;
18691937
}
18701938

1871-
/* skip running XDP prog if there are aggregation bufs */
1872-
if (!agg_bufs && xdp_active) {
1939+
if (xdp_active) {
18731940
if (bnxt_rx_xdp(bp, rxr, cons, xdp, data, &len, event)) {
18741941
rc = 1;
18751942
goto next_rx;
@@ -1880,9 +1947,13 @@ static int bnxt_rx_pkt(struct bnxt *bp, struct bnxt_cp_ring_info *cpr,
18801947
skb = bnxt_copy_skb(bnapi, data_ptr, len, dma_addr);
18811948
bnxt_reuse_rx_data(rxr, cons, data);
18821949
if (!skb) {
1883-
if (agg_bufs)
1884-
bnxt_reuse_rx_agg_bufs(cpr, cp_cons, 0,
1885-
agg_bufs, false);
1950+
if (agg_bufs) {
1951+
if (!xdp_active)
1952+
bnxt_reuse_rx_agg_bufs(cpr, cp_cons, 0,
1953+
agg_bufs, false);
1954+
else
1955+
bnxt_xdp_buff_frags_free(rxr, &xdp);
1956+
}
18861957
cpr->sw_stats.rx.rx_oom_discards += 1;
18871958
rc = -ENOMEM;
18881959
goto next_rx;
@@ -1911,6 +1982,15 @@ static int bnxt_rx_pkt(struct bnxt *bp, struct bnxt_cp_ring_info *cpr,
19111982
rc = -ENOMEM;
19121983
goto next_rx;
19131984
}
1985+
} else {
1986+
skb = bnxt_xdp_build_skb(bp, skb, agg_bufs, rxr->page_pool, &xdp, rxcmp1);
1987+
if (!skb) {
1988+
/* we should be able to free the old skb here */
1989+
bnxt_xdp_buff_frags_free(rxr, &xdp);
1990+
cpr->sw_stats.rx.rx_oom_discards += 1;
1991+
rc = -ENOMEM;
1992+
goto next_rx;
1993+
}
19141994
}
19151995
}
19161996

@@ -2526,10 +2606,13 @@ static void __bnxt_poll_work_done(struct bnxt *bp, struct bnxt_napi *bnapi)
25262606
if ((bnapi->events & BNXT_RX_EVENT) && !(bnapi->in_reset)) {
25272607
struct bnxt_rx_ring_info *rxr = bnapi->rx_ring;
25282608

2529-
if (bnapi->events & BNXT_AGG_EVENT)
2530-
bnxt_db_write(bp, &rxr->rx_agg_db, rxr->rx_agg_prod);
25312609
bnxt_db_write(bp, &rxr->rx_db, rxr->rx_prod);
25322610
}
2611+
if (bnapi->events & BNXT_AGG_EVENT) {
2612+
struct bnxt_rx_ring_info *rxr = bnapi->rx_ring;
2613+
2614+
bnxt_db_write(bp, &rxr->rx_agg_db, rxr->rx_agg_prod);
2615+
}
25332616
bnapi->events = 0;
25342617
}
25352618

@@ -3930,14 +4013,21 @@ void bnxt_set_ring_params(struct bnxt *bp)
39304013
int bnxt_set_rx_skb_mode(struct bnxt *bp, bool page_mode)
39314014
{
39324015
if (page_mode) {
3933-
if (bp->dev->mtu > BNXT_MAX_PAGE_MODE_MTU)
3934-
return -EOPNOTSUPP;
3935-
bp->dev->max_mtu =
3936-
min_t(u16, bp->max_mtu, BNXT_MAX_PAGE_MODE_MTU);
39374016
bp->flags &= ~BNXT_FLAG_AGG_RINGS;
3938-
bp->flags |= BNXT_FLAG_NO_AGG_RINGS | BNXT_FLAG_RX_PAGE_MODE;
4017+
bp->flags |= BNXT_FLAG_RX_PAGE_MODE;
4018+
4019+
if (bp->dev->mtu > BNXT_MAX_PAGE_MODE_MTU) {
4020+
bp->flags |= BNXT_FLAG_JUMBO;
4021+
bp->rx_skb_func = bnxt_rx_multi_page_skb;
4022+
bp->dev->max_mtu =
4023+
min_t(u16, bp->max_mtu, BNXT_MAX_MTU);
4024+
} else {
4025+
bp->flags |= BNXT_FLAG_NO_AGG_RINGS;
4026+
bp->rx_skb_func = bnxt_rx_page_skb;
4027+
bp->dev->max_mtu =
4028+
min_t(u16, bp->max_mtu, BNXT_MAX_PAGE_MODE_MTU);
4029+
}
39394030
bp->rx_dir = DMA_BIDIRECTIONAL;
3940-
bp->rx_skb_func = bnxt_rx_page_skb;
39414031
/* Disable LRO or GRO_HW */
39424032
netdev_update_features(bp->dev);
39434033
} else {
@@ -4387,7 +4477,7 @@ static void bnxt_free_ntp_fltrs(struct bnxt *bp, bool irq_reinit)
43874477
}
43884478
}
43894479
if (irq_reinit) {
4390-
kfree(bp->ntp_fltr_bmap);
4480+
bitmap_free(bp->ntp_fltr_bmap);
43914481
bp->ntp_fltr_bmap = NULL;
43924482
}
43934483
bp->ntp_fltr_count = 0;
@@ -4406,9 +4496,7 @@ static int bnxt_alloc_ntp_fltrs(struct bnxt *bp)
44064496
INIT_HLIST_HEAD(&bp->ntp_fltr_hash_tbl[i]);
44074497

44084498
bp->ntp_fltr_count = 0;
4409-
bp->ntp_fltr_bmap = kcalloc(BITS_TO_LONGS(BNXT_NTP_FLTR_MAX_FLTR),
4410-
sizeof(long),
4411-
GFP_KERNEL);
4499+
bp->ntp_fltr_bmap = bitmap_zalloc(BNXT_NTP_FLTR_MAX_FLTR, GFP_KERNEL);
44124500

44134501
if (!bp->ntp_fltr_bmap)
44144502
rc = -ENOMEM;
@@ -10566,7 +10654,7 @@ static void __bnxt_close_nic(struct bnxt *bp, bool irq_re_init,
1056610654
while (bnxt_drv_busy(bp))
1056710655
msleep(20);
1056810656

10569-
/* Flush rings and and disable interrupts */
10657+
/* Flush rings and disable interrupts */
1057010658
bnxt_shutdown_nic(bp, irq_re_init);
1057110659

1057210660
/* TODO CHIMP_FW: Link/PHY related cleanup if (link_re_init) */
@@ -11090,7 +11178,7 @@ static netdev_features_t bnxt_fix_features(struct net_device *dev,
1109011178
if ((features & NETIF_F_NTUPLE) && !bnxt_rfs_capable(bp))
1109111179
features &= ~NETIF_F_NTUPLE;
1109211180

11093-
if (bp->flags & BNXT_FLAG_NO_AGG_RINGS)
11181+
if ((bp->flags & BNXT_FLAG_NO_AGG_RINGS) || bp->xdp_prog)
1109411182
features &= ~(NETIF_F_LRO | NETIF_F_GRO_HW);
1109511183

1109611184
if (!(features & NETIF_F_GRO))

drivers/net/ethernet/broadcom/bnxt/bnxt.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -701,13 +701,12 @@ struct bnxt_sw_tx_bd {
701701
};
702702
DEFINE_DMA_UNMAP_ADDR(mapping);
703703
DEFINE_DMA_UNMAP_LEN(len);
704+
struct page *page;
704705
u8 is_gso;
705706
u8 is_push;
706707
u8 action;
707-
union {
708-
unsigned short nr_frags;
709-
u16 rx_prod;
710-
};
708+
unsigned short nr_frags;
709+
u16 rx_prod;
711710
};
712711

713712
struct bnxt_sw_rx_bd {
@@ -2131,6 +2130,7 @@ struct bnxt {
21312130
#define BNXT_DUMP_CRASH 1
21322131

21332132
struct bpf_prog *xdp_prog;
2133+
u8 xdp_has_frags;
21342134

21352135
struct bnxt_ptp_cfg *ptp_cfg;
21362136
u8 ptp_all_rx_tstamp;

drivers/net/ethernet/broadcom/bnxt/bnxt_coredump.c

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,7 @@ bnxt_fill_coredump_seg_hdr(struct bnxt *bp,
178178
seg_hdr->segment_id = (__force __le32)seg_rec->segment_id;
179179
seg_hdr->low_version = seg_rec->version_low;
180180
seg_hdr->high_version = seg_rec->version_hi;
181+
seg_hdr->flags = cpu_to_le32(seg_rec->compress_flags);
181182
} else {
182183
/* For hwrm_ver_get response Component id = 2
183184
* and Segment id = 0
@@ -193,6 +194,30 @@ bnxt_fill_coredump_seg_hdr(struct bnxt *bp,
193194
seg_hdr->instance = cpu_to_le32(instance);
194195
}
195196

197+
static void bnxt_fill_cmdline(struct bnxt_coredump_record *record)
198+
{
199+
struct mm_struct *mm = current->mm;
200+
int i, len, last = 0;
201+
202+
if (mm) {
203+
len = min_t(int, mm->arg_end - mm->arg_start,
204+
sizeof(record->commandline) - 1);
205+
if (len && !copy_from_user(record->commandline,
206+
(char __user *)mm->arg_start, len)) {
207+
for (i = 0; i < len; i++) {
208+
if (record->commandline[i])
209+
last = i;
210+
else
211+
record->commandline[i] = ' ';
212+
}
213+
record->commandline[last + 1] = 0;
214+
return;
215+
}
216+
}
217+
218+
strscpy(record->commandline, current->comm, TASK_COMM_LEN);
219+
}
220+
196221
static void
197222
bnxt_fill_coredump_record(struct bnxt *bp, struct bnxt_coredump_record *record,
198223
time64_t start, s16 start_utc, u16 total_segs,
@@ -218,7 +243,7 @@ bnxt_fill_coredump_record(struct bnxt *bp, struct bnxt_coredump_record *record,
218243
record->minute = cpu_to_le16(tm.tm_min);
219244
record->second = cpu_to_le16(tm.tm_sec);
220245
record->utc_bias = cpu_to_le16(start_utc);
221-
strcpy(record->commandline, "ethtool -w");
246+
bnxt_fill_cmdline(record);
222247
record->total_segments = cpu_to_le32(total_segs);
223248

224249
if (sscanf(utsname()->release, "%u.%u", &os_ver_major, &os_ver_minor) != 2)

drivers/net/ethernet/broadcom/bnxt/bnxt_dcb.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -159,10 +159,10 @@ static int bnxt_hwrm_queue_cos2bw_qcfg(struct bnxt *bp, struct ieee_ets *ets)
159159
}
160160

161161
data = &resp->queue_id0 + offsetof(struct bnxt_cos2bw_cfg, queue_id);
162-
for (i = 0; i < bp->max_tc; i++, data += sizeof(cos2bw) - 4) {
162+
for (i = 0; i < bp->max_tc; i++, data += sizeof(cos2bw.cfg)) {
163163
int tc;
164164

165-
memcpy(&cos2bw.queue_id, data, sizeof(cos2bw) - 4);
165+
memcpy(&cos2bw.cfg, data, sizeof(cos2bw.cfg));
166166
if (i == 0)
167167
cos2bw.queue_id = resp->queue_id0;
168168

drivers/net/ethernet/broadcom/bnxt/bnxt_dcb.h

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,15 @@ struct bnxt_dcb {
2323

2424
struct bnxt_cos2bw_cfg {
2525
u8 pad[3];
26-
u8 queue_id;
27-
__le32 min_bw;
28-
__le32 max_bw;
26+
struct_group_attr(cfg, __packed,
27+
u8 queue_id;
28+
__le32 min_bw;
29+
__le32 max_bw;
2930
#define BW_VALUE_UNIT_PERCENT1_100 (0x1UL << 29)
30-
u8 tsa;
31-
u8 pri_lvl;
32-
u8 bw_weight;
31+
u8 tsa;
32+
u8 pri_lvl;
33+
u8 bw_weight;
34+
);
3335
u8 unused;
3436
};
3537

0 commit comments

Comments
 (0)