Skip to content

Commit 6a8788f

Browse files
CCX-Stingraydavem330
authored andcommitted
bnxt_en: add support for software dynamic interrupt moderation
This implements the changes needed for the bnxt_en driver to add support for dynamic interrupt moderation per ring. This does add additional counters in the receive path, but testing shows that any additional instructions are offset by throughput gain when the default configuration is for low latency. Signed-off-by: Andy Gospodarek <[email protected]> Acked-by: Michael Chan <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 8115b75 commit 6a8788f

File tree

5 files changed

+118
-12
lines changed

5 files changed

+118
-12
lines changed
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
obj-$(CONFIG_BNXT) += bnxt_en.o
22

3-
bnxt_en-y := bnxt.o bnxt_sriov.o bnxt_ethtool.o bnxt_dcb.o bnxt_ulp.o bnxt_xdp.o bnxt_vfr.o bnxt_devlink.o
3+
bnxt_en-y := bnxt.o bnxt_sriov.o bnxt_ethtool.o bnxt_dcb.o bnxt_ulp.o bnxt_xdp.o bnxt_vfr.o bnxt_devlink.o bnxt_dim.o
44
bnxt_en-$(CONFIG_BNXT_FLOWER_OFFLOAD) += bnxt_tc.o

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

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1645,6 +1645,8 @@ static int bnxt_rx_pkt(struct bnxt *bp, struct bnxt_napi *bnapi, u32 *raw_cons,
16451645
rxr->rx_next_cons = NEXT_RX(cons);
16461646

16471647
next_rx_no_prod:
1648+
cpr->rx_packets += 1;
1649+
cpr->rx_bytes += len;
16481650
*raw_cons = tmp_raw_cons;
16491651

16501652
return rc;
@@ -1802,6 +1804,7 @@ static irqreturn_t bnxt_msix(int irq, void *dev_instance)
18021804
struct bnxt_cp_ring_info *cpr = &bnapi->cp_ring;
18031805
u32 cons = RING_CMP(cpr->cp_raw_cons);
18041806

1807+
cpr->event_ctr++;
18051808
prefetch(&cpr->cp_desc_ring[CP_RING(cons)][CP_IDX(cons)]);
18061809
napi_schedule(&bnapi->napi);
18071810
return IRQ_HANDLED;
@@ -2025,6 +2028,15 @@ static int bnxt_poll(struct napi_struct *napi, int budget)
20252028
break;
20262029
}
20272030
}
2031+
if (bp->flags & BNXT_FLAG_DIM) {
2032+
struct net_dim_sample dim_sample;
2033+
2034+
net_dim_sample(cpr->event_ctr,
2035+
cpr->rx_packets,
2036+
cpr->rx_bytes,
2037+
&dim_sample);
2038+
net_dim(&cpr->dim, dim_sample);
2039+
}
20282040
mmiowb();
20292041
return work_done;
20302042
}
@@ -2617,6 +2629,8 @@ static void bnxt_init_cp_rings(struct bnxt *bp)
26172629
struct bnxt_ring_struct *ring = &cpr->cp_ring_struct;
26182630

26192631
ring->fw_ring_id = INVALID_HW_RING_ID;
2632+
cpr->rx_ring_coal.coal_ticks = bp->rx_coal.coal_ticks;
2633+
cpr->rx_ring_coal.coal_bufs = bp->rx_coal.coal_bufs;
26202634
}
26212635
}
26222636

@@ -4593,6 +4607,36 @@ static void bnxt_hwrm_set_coal_params(struct bnxt_coal *hw_coal,
45934607
req->flags = cpu_to_le16(flags);
45944608
}
45954609

4610+
int bnxt_hwrm_set_ring_coal(struct bnxt *bp, struct bnxt_napi *bnapi)
4611+
{
4612+
struct hwrm_ring_cmpl_ring_cfg_aggint_params_input req_rx = {0};
4613+
struct bnxt_cp_ring_info *cpr = &bnapi->cp_ring;
4614+
struct bnxt_coal coal;
4615+
unsigned int grp_idx;
4616+
4617+
/* Tick values in micro seconds.
4618+
* 1 coal_buf x bufs_per_record = 1 completion record.
4619+
*/
4620+
memcpy(&coal, &bp->rx_coal, sizeof(struct bnxt_coal));
4621+
4622+
coal.coal_ticks = cpr->rx_ring_coal.coal_ticks;
4623+
coal.coal_bufs = cpr->rx_ring_coal.coal_bufs;
4624+
4625+
if (!bnapi->rx_ring)
4626+
return -ENODEV;
4627+
4628+
bnxt_hwrm_cmd_hdr_init(bp, &req_rx,
4629+
HWRM_RING_CMPL_RING_CFG_AGGINT_PARAMS, -1, -1);
4630+
4631+
bnxt_hwrm_set_coal_params(&coal, &req_rx);
4632+
4633+
grp_idx = bnapi->index;
4634+
req_rx.ring_id = cpu_to_le16(bp->grp_info[grp_idx].cp_fw_ring_id);
4635+
4636+
return hwrm_send_message(bp, &req_rx, sizeof(req_rx),
4637+
HWRM_CMD_TIMEOUT);
4638+
}
4639+
45964640
int bnxt_hwrm_set_coal(struct bnxt *bp)
45974641
{
45984642
int i, rc = 0;
@@ -5715,7 +5759,13 @@ static void bnxt_enable_napi(struct bnxt *bp)
57155759
int i;
57165760

57175761
for (i = 0; i < bp->cp_nr_rings; i++) {
5762+
struct bnxt_cp_ring_info *cpr = &bp->bnapi[i]->cp_ring;
57185763
bp->bnapi[i]->in_reset = false;
5764+
5765+
if (bp->bnapi[i]->rx_ring) {
5766+
INIT_WORK(&cpr->dim.work, bnxt_dim_work);
5767+
cpr->dim.mode = NET_DIM_CQ_PERIOD_MODE_START_FROM_EQE;
5768+
}
57195769
napi_enable(&bp->bnapi[i]->napi);
57205770
}
57215771
}

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

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include <net/dst_metadata.h>
2525
#include <net/switchdev.h>
2626
#include <net/xdp.h>
27+
#include <linux/net_dim.h>
2728

2829
struct tx_bd {
2930
__le32 tx_bd_len_flags_type;
@@ -608,6 +609,17 @@ struct bnxt_tx_ring_info {
608609
struct bnxt_ring_struct tx_ring_struct;
609610
};
610611

612+
struct bnxt_coal {
613+
u16 coal_ticks;
614+
u16 coal_ticks_irq;
615+
u16 coal_bufs;
616+
u16 coal_bufs_irq;
617+
/* RING_IDLE enabled when coal ticks < idle_thresh */
618+
u16 idle_thresh;
619+
u8 bufs_per_record;
620+
u8 budget;
621+
};
622+
611623
struct bnxt_tpa_info {
612624
void *data;
613625
u8 *data_ptr;
@@ -672,6 +684,13 @@ struct bnxt_cp_ring_info {
672684
u32 cp_raw_cons;
673685
void __iomem *cp_doorbell;
674686

687+
struct bnxt_coal rx_ring_coal;
688+
u64 rx_packets;
689+
u64 rx_bytes;
690+
u64 event_ctr;
691+
692+
struct net_dim dim;
693+
675694
struct tx_cmp *cp_desc_ring[MAX_CP_PAGES];
676695

677696
dma_addr_t cp_desc_mapping[MAX_CP_PAGES];
@@ -946,17 +965,6 @@ struct bnxt_test_info {
946965
#define BNXT_CAG_REG_LEGACY_INT_STATUS 0x4014
947966
#define BNXT_CAG_REG_BASE 0x300000
948967

949-
struct bnxt_coal {
950-
u16 coal_ticks;
951-
u16 coal_ticks_irq;
952-
u16 coal_bufs;
953-
u16 coal_bufs_irq;
954-
/* RING_IDLE enabled when coal ticks < idle_thresh */
955-
u16 idle_thresh;
956-
u8 bufs_per_record;
957-
u8 budget;
958-
};
959-
960968
struct bnxt_tc_flow_stats {
961969
u64 packets;
962970
u64 bytes;
@@ -1128,6 +1136,7 @@ struct bnxt {
11281136
#define BNXT_FLAG_DOUBLE_DB 0x400000
11291137
#define BNXT_FLAG_FW_DCBX_AGENT 0x800000
11301138
#define BNXT_FLAG_CHIP_NITRO_A0 0x1000000
1139+
#define BNXT_FLAG_DIM 0x2000000
11311140

11321141
#define BNXT_FLAG_ALL_CONFIG_FEATS (BNXT_FLAG_TPA | \
11331142
BNXT_FLAG_RFS | \
@@ -1425,4 +1434,7 @@ int bnxt_setup_mq_tc(struct net_device *dev, u8 tc);
14251434
int bnxt_get_max_rings(struct bnxt *, int *, int *, bool);
14261435
void bnxt_restore_pf_fw_resources(struct bnxt *bp);
14271436
int bnxt_port_attr_get(struct bnxt *bp, struct switchdev_attr *attr);
1437+
void bnxt_dim_work(struct work_struct *work);
1438+
int bnxt_hwrm_set_ring_coal(struct bnxt *bp, struct bnxt_napi *bnapi);
1439+
14281440
#endif
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/* Broadcom NetXtreme-C/E network driver.
2+
*
3+
* Copyright (c) 2017-2018 Broadcom Limited
4+
*
5+
* This program is free software; you can redistribute it and/or modify
6+
* it under the terms of the GNU General Public License as published by
7+
* the Free Software Foundation.
8+
*/
9+
10+
#include <linux/net_dim.h>
11+
#include "bnxt_hsi.h"
12+
#include "bnxt.h"
13+
14+
void bnxt_dim_work(struct work_struct *work)
15+
{
16+
struct net_dim *dim = container_of(work, struct net_dim,
17+
work);
18+
struct bnxt_cp_ring_info *cpr = container_of(dim,
19+
struct bnxt_cp_ring_info,
20+
dim);
21+
struct bnxt_napi *bnapi = container_of(cpr,
22+
struct bnxt_napi,
23+
cp_ring);
24+
struct net_dim_cq_moder cur_profile = net_dim_get_profile(dim->mode,
25+
dim->profile_ix);
26+
27+
cpr->rx_ring_coal.coal_ticks = cur_profile.usec;
28+
cpr->rx_ring_coal.coal_bufs = cur_profile.pkts;
29+
30+
bnxt_hwrm_set_ring_coal(bnapi->bp, bnapi);
31+
dim->state = NET_DIM_START_MEASURE;
32+
}

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ static int bnxt_get_coalesce(struct net_device *dev,
4949

5050
memset(coal, 0, sizeof(*coal));
5151

52+
coal->use_adaptive_rx_coalesce = bp->flags & BNXT_FLAG_DIM;
53+
5254
hw_coal = &bp->rx_coal;
5355
mult = hw_coal->bufs_per_record;
5456
coal->rx_coalesce_usecs = hw_coal->coal_ticks;
@@ -77,6 +79,15 @@ static int bnxt_set_coalesce(struct net_device *dev,
7779
int rc = 0;
7880
u16 mult;
7981

82+
if (coal->use_adaptive_rx_coalesce) {
83+
bp->flags |= BNXT_FLAG_DIM;
84+
} else {
85+
if (bp->flags & BNXT_FLAG_DIM) {
86+
bp->flags &= ~(BNXT_FLAG_DIM);
87+
goto reset_coalesce;
88+
}
89+
}
90+
8091
hw_coal = &bp->rx_coal;
8192
mult = hw_coal->bufs_per_record;
8293
hw_coal->coal_ticks = coal->rx_coalesce_usecs;
@@ -104,6 +115,7 @@ static int bnxt_set_coalesce(struct net_device *dev,
104115
update_stats = true;
105116
}
106117

118+
reset_coalesce:
107119
if (netif_running(dev)) {
108120
if (update_stats) {
109121
rc = bnxt_close_nic(bp, true, false);

0 commit comments

Comments
 (0)