* [PATCH net-next 00/10] eth: fbnic: support basic RSS config and setting channel count
@ 2024-12-20 2:52 Jakub Kicinski
2024-12-20 2:52 ` [PATCH net-next 01/10] eth: fbnic: reorder ethtool code Jakub Kicinski
` (10 more replies)
0 siblings, 11 replies; 20+ messages in thread
From: Jakub Kicinski @ 2024-12-20 2:52 UTC (permalink / raw)
To: davem; +Cc: netdev, edumazet, pabeni, Jakub Kicinski
Add support for basic RSS config (indirection table, key get and set),
and changing the number of channels.
# ./ksft-net-drv/run_kselftest.sh -t drivers/net/hw:rss_ctx.py
TAP version 13
1..1
# timeout set to 0
# selftests: drivers/net/hw: rss_ctx.py
# KTAP version 1
# 1..15
# ok 1 rss_ctx.test_rss_key_indir
# ok 2 rss_ctx.test_rss_queue_reconfigure
# ok 3 rss_ctx.test_rss_resize
# ok 4 rss_ctx.test_hitless_key_update
.. the rest of the tests are for additional contexts so they
get skipped..
The slicing of the patches (and bugs) are mine, but I'm keeping
Alex as the author on the patches where he wrote 100% of the code.
Alexander Duyck (4):
eth: fbnic: support querying RSS config
eth: fbnic: support setting RSS configuration
eth: fbnic: let user control the RSS hash fields
eth: fbnic: centralize the queue count and NAPI<>queue setting
Jakub Kicinski (6):
eth: fbnic: reorder ethtool code
eth: fbnic: don't reset the secondary RSS indir table
eth: fbnic: store NAPIs in an array instead of the list
eth: fbnic: add IRQ reuse support
eth: fbnic: support ring channel get and set while down
eth: fbnic: support ring channel set while up
drivers/net/ethernet/meta/fbnic/fbnic.h | 15 +
.../net/ethernet/meta/fbnic/fbnic_ethtool.c | 551 +++++++++++++++---
drivers/net/ethernet/meta/fbnic/fbnic_irq.c | 53 ++
.../net/ethernet/meta/fbnic/fbnic_netdev.c | 12 +-
.../net/ethernet/meta/fbnic/fbnic_netdev.h | 7 +-
drivers/net/ethernet/meta/fbnic/fbnic_pci.c | 2 +-
drivers/net/ethernet/meta/fbnic/fbnic_rpc.c | 7 +-
drivers/net/ethernet/meta/fbnic/fbnic_txrx.c | 236 ++++----
drivers/net/ethernet/meta/fbnic/fbnic_txrx.h | 16 +-
9 files changed, 699 insertions(+), 200 deletions(-)
--
2.47.1
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH net-next 01/10] eth: fbnic: reorder ethtool code
2024-12-20 2:52 [PATCH net-next 00/10] eth: fbnic: support basic RSS config and setting channel count Jakub Kicinski
@ 2024-12-20 2:52 ` Jakub Kicinski
2024-12-20 14:53 ` Larysa Zaremba
2024-12-20 2:52 ` [PATCH net-next 02/10] eth: fbnic: support querying RSS config Jakub Kicinski
` (9 subsequent siblings)
10 siblings, 1 reply; 20+ messages in thread
From: Jakub Kicinski @ 2024-12-20 2:52 UTC (permalink / raw)
To: davem; +Cc: netdev, edumazet, pabeni, Jakub Kicinski
Define ethtool callback handlers in order in which they are defined
in the ops struct. It doesn't really matter what the order is,
but it's good to have an order.
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
.../net/ethernet/meta/fbnic/fbnic_ethtool.c | 160 +++++++++---------
1 file changed, 80 insertions(+), 80 deletions(-)
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c b/drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c
index cc8ca94529ca..777e083acae9 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c
@@ -40,6 +40,68 @@ static const struct fbnic_stat fbnic_gstrings_hw_stats[] = {
#define FBNIC_HW_FIXED_STATS_LEN ARRAY_SIZE(fbnic_gstrings_hw_stats)
#define FBNIC_HW_STATS_LEN FBNIC_HW_FIXED_STATS_LEN
+static void
+fbnic_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo)
+{
+ struct fbnic_net *fbn = netdev_priv(netdev);
+ struct fbnic_dev *fbd = fbn->fbd;
+
+ fbnic_get_fw_ver_commit_str(fbd, drvinfo->fw_version,
+ sizeof(drvinfo->fw_version));
+}
+
+static int fbnic_get_regs_len(struct net_device *netdev)
+{
+ struct fbnic_net *fbn = netdev_priv(netdev);
+
+ return fbnic_csr_regs_len(fbn->fbd) * sizeof(u32);
+}
+
+static void fbnic_get_regs(struct net_device *netdev,
+ struct ethtool_regs *regs, void *data)
+{
+ struct fbnic_net *fbn = netdev_priv(netdev);
+
+ fbnic_csr_get_regs(fbn->fbd, data, ®s->version);
+}
+
+static void fbnic_get_strings(struct net_device *dev, u32 sset, u8 *data)
+{
+ int i;
+
+ switch (sset) {
+ case ETH_SS_STATS:
+ for (i = 0; i < FBNIC_HW_STATS_LEN; i++)
+ ethtool_puts(&data, fbnic_gstrings_hw_stats[i].string);
+ break;
+ }
+}
+
+static void fbnic_get_ethtool_stats(struct net_device *dev,
+ struct ethtool_stats *stats, u64 *data)
+{
+ struct fbnic_net *fbn = netdev_priv(dev);
+ const struct fbnic_stat *stat;
+ int i;
+
+ fbnic_get_hw_stats(fbn->fbd);
+
+ for (i = 0; i < FBNIC_HW_STATS_LEN; i++) {
+ stat = &fbnic_gstrings_hw_stats[i];
+ data[i] = *(u64 *)((u8 *)&fbn->fbd->hw_stats + stat->offset);
+ }
+}
+
+static int fbnic_get_sset_count(struct net_device *dev, int sset)
+{
+ switch (sset) {
+ case ETH_SS_STATS:
+ return FBNIC_HW_STATS_LEN;
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
static int
fbnic_get_ts_info(struct net_device *netdev,
struct kernel_ethtool_ts_info *tsinfo)
@@ -69,14 +131,27 @@ fbnic_get_ts_info(struct net_device *netdev,
return 0;
}
-static void
-fbnic_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo)
+static void fbnic_get_ts_stats(struct net_device *netdev,
+ struct ethtool_ts_stats *ts_stats)
{
struct fbnic_net *fbn = netdev_priv(netdev);
- struct fbnic_dev *fbd = fbn->fbd;
+ u64 ts_packets, ts_lost;
+ struct fbnic_ring *ring;
+ unsigned int start;
+ int i;
- fbnic_get_fw_ver_commit_str(fbd, drvinfo->fw_version,
- sizeof(drvinfo->fw_version));
+ ts_stats->pkts = fbn->tx_stats.ts_packets;
+ ts_stats->lost = fbn->tx_stats.ts_lost;
+ for (i = 0; i < fbn->num_tx_queues; i++) {
+ ring = fbn->tx[i];
+ do {
+ start = u64_stats_fetch_begin(&ring->stats.syncp);
+ ts_packets = ring->stats.ts_packets;
+ ts_lost = ring->stats.ts_lost;
+ } while (u64_stats_fetch_retry(&ring->stats.syncp, start));
+ ts_stats->pkts += ts_packets;
+ ts_stats->lost += ts_lost;
+ }
}
static void fbnic_set_counter(u64 *stat, struct fbnic_stat_counter *counter)
@@ -85,43 +160,6 @@ static void fbnic_set_counter(u64 *stat, struct fbnic_stat_counter *counter)
*stat = counter->value;
}
-static void fbnic_get_strings(struct net_device *dev, u32 sset, u8 *data)
-{
- int i;
-
- switch (sset) {
- case ETH_SS_STATS:
- for (i = 0; i < FBNIC_HW_STATS_LEN; i++)
- ethtool_puts(&data, fbnic_gstrings_hw_stats[i].string);
- break;
- }
-}
-
-static int fbnic_get_sset_count(struct net_device *dev, int sset)
-{
- switch (sset) {
- case ETH_SS_STATS:
- return FBNIC_HW_STATS_LEN;
- default:
- return -EOPNOTSUPP;
- }
-}
-
-static void fbnic_get_ethtool_stats(struct net_device *dev,
- struct ethtool_stats *stats, u64 *data)
-{
- struct fbnic_net *fbn = netdev_priv(dev);
- const struct fbnic_stat *stat;
- int i;
-
- fbnic_get_hw_stats(fbn->fbd);
-
- for (i = 0; i < FBNIC_HW_STATS_LEN; i++) {
- stat = &fbnic_gstrings_hw_stats[i];
- data[i] = *(u64 *)((u8 *)&fbn->fbd->hw_stats + stat->offset);
- }
-}
-
static void
fbnic_get_eth_mac_stats(struct net_device *netdev,
struct ethtool_eth_mac_stats *eth_mac_stats)
@@ -164,44 +202,6 @@ fbnic_get_eth_mac_stats(struct net_device *netdev,
&mac_stats->eth_mac.FrameTooLongErrors);
}
-static void fbnic_get_ts_stats(struct net_device *netdev,
- struct ethtool_ts_stats *ts_stats)
-{
- struct fbnic_net *fbn = netdev_priv(netdev);
- u64 ts_packets, ts_lost;
- struct fbnic_ring *ring;
- unsigned int start;
- int i;
-
- ts_stats->pkts = fbn->tx_stats.ts_packets;
- ts_stats->lost = fbn->tx_stats.ts_lost;
- for (i = 0; i < fbn->num_tx_queues; i++) {
- ring = fbn->tx[i];
- do {
- start = u64_stats_fetch_begin(&ring->stats.syncp);
- ts_packets = ring->stats.ts_packets;
- ts_lost = ring->stats.ts_lost;
- } while (u64_stats_fetch_retry(&ring->stats.syncp, start));
- ts_stats->pkts += ts_packets;
- ts_stats->lost += ts_lost;
- }
-}
-
-static void fbnic_get_regs(struct net_device *netdev,
- struct ethtool_regs *regs, void *data)
-{
- struct fbnic_net *fbn = netdev_priv(netdev);
-
- fbnic_csr_get_regs(fbn->fbd, data, ®s->version);
-}
-
-static int fbnic_get_regs_len(struct net_device *netdev)
-{
- struct fbnic_net *fbn = netdev_priv(netdev);
-
- return fbnic_csr_regs_len(fbn->fbd) * sizeof(u32);
-}
-
static const struct ethtool_ops fbnic_ethtool_ops = {
.get_drvinfo = fbnic_get_drvinfo,
.get_regs_len = fbnic_get_regs_len,
--
2.47.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH net-next 02/10] eth: fbnic: support querying RSS config
2024-12-20 2:52 [PATCH net-next 00/10] eth: fbnic: support basic RSS config and setting channel count Jakub Kicinski
2024-12-20 2:52 ` [PATCH net-next 01/10] eth: fbnic: reorder ethtool code Jakub Kicinski
@ 2024-12-20 2:52 ` Jakub Kicinski
2024-12-20 11:42 ` Przemek Kitszel
2024-12-20 2:52 ` [PATCH net-next 03/10] eth: fbnic: don't reset the secondary RSS indir table Jakub Kicinski
` (8 subsequent siblings)
10 siblings, 1 reply; 20+ messages in thread
From: Jakub Kicinski @ 2024-12-20 2:52 UTC (permalink / raw)
To: davem; +Cc: netdev, edumazet, pabeni, Alexander Duyck, Jakub Kicinski
From: Alexander Duyck <alexanderduyck@fb.com>
The initial driver submission already added all the RSS state,
as part of multi-queue support. Expose the configuration via
the ethtool APIs.
Signed-off-by: Alexander Duyck <alexanderduyck@fb.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
.../net/ethernet/meta/fbnic/fbnic_ethtool.c | 103 ++++++++++++++++++
1 file changed, 103 insertions(+)
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c b/drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c
index 777e083acae9..e71ae6abb0f5 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c
@@ -102,6 +102,105 @@ static int fbnic_get_sset_count(struct net_device *dev, int sset)
}
}
+static int fbnic_get_rss_hash_idx(u32 flow_type)
+{
+ switch (flow_type & ~(FLOW_EXT | FLOW_MAC_EXT | FLOW_RSS)) {
+ case TCP_V4_FLOW:
+ return FBNIC_TCP4_HASH_OPT;
+ case TCP_V6_FLOW:
+ return FBNIC_TCP6_HASH_OPT;
+ case UDP_V4_FLOW:
+ return FBNIC_UDP4_HASH_OPT;
+ case UDP_V6_FLOW:
+ return FBNIC_UDP6_HASH_OPT;
+ case AH_V4_FLOW:
+ case ESP_V4_FLOW:
+ case AH_ESP_V4_FLOW:
+ case SCTP_V4_FLOW:
+ case IPV4_FLOW:
+ case IPV4_USER_FLOW:
+ return FBNIC_IPV4_HASH_OPT;
+ case AH_V6_FLOW:
+ case ESP_V6_FLOW:
+ case AH_ESP_V6_FLOW:
+ case SCTP_V6_FLOW:
+ case IPV6_FLOW:
+ case IPV6_USER_FLOW:
+ return FBNIC_IPV6_HASH_OPT;
+ case ETHER_FLOW:
+ return FBNIC_ETHER_HASH_OPT;
+ }
+
+ return -1;
+}
+
+static int
+fbnic_get_rss_hash_opts(struct fbnic_net *fbn, struct ethtool_rxnfc *cmd)
+{
+ int hash_opt_idx = fbnic_get_rss_hash_idx(cmd->flow_type);
+
+ if (hash_opt_idx < 0)
+ return -EINVAL;
+
+ /* Report options from rss_en table in fbn */
+ cmd->data = fbn->rss_flow_hash[hash_opt_idx];
+
+ return 0;
+}
+
+static int fbnic_get_rxnfc(struct net_device *netdev,
+ struct ethtool_rxnfc *cmd, u32 *rule_locs)
+{
+ struct fbnic_net *fbn = netdev_priv(netdev);
+ int ret = -EOPNOTSUPP;
+
+ switch (cmd->cmd) {
+ case ETHTOOL_GRXRINGS:
+ cmd->data = fbn->num_rx_queues;
+ ret = 0;
+ break;
+ case ETHTOOL_GRXFH:
+ ret = fbnic_get_rss_hash_opts(fbn, cmd);
+ break;
+ }
+
+ return ret;
+}
+
+static u32 fbnic_get_rxfh_key_size(struct net_device *netdev)
+{
+ return FBNIC_RPC_RSS_KEY_BYTE_LEN;
+}
+
+static u32 fbnic_get_rxfh_indir_size(struct net_device *netdev)
+{
+ return FBNIC_RPC_RSS_TBL_SIZE;
+}
+
+static int
+fbnic_get_rxfh(struct net_device *netdev, struct ethtool_rxfh_param *rxfh)
+{
+ struct fbnic_net *fbn = netdev_priv(netdev);
+ unsigned int i;
+
+ rxfh->hfunc = ETH_RSS_HASH_TOP;
+
+ if (rxfh->key) {
+ for (i = 0; i < FBNIC_RPC_RSS_KEY_BYTE_LEN; i++) {
+ u32 rss_key = fbn->rss_key[i / 4] << ((i % 4) * 8);
+
+ rxfh->key[i] = rss_key >> 24;
+ }
+ }
+
+ if (rxfh->indir) {
+ for (i = 0; i < FBNIC_RPC_RSS_TBL_SIZE; i++)
+ rxfh->indir[i] = fbn->indir_tbl[0][i];
+ }
+
+ return 0;
+}
+
static int
fbnic_get_ts_info(struct net_device *netdev,
struct kernel_ethtool_ts_info *tsinfo)
@@ -209,6 +308,10 @@ static const struct ethtool_ops fbnic_ethtool_ops = {
.get_strings = fbnic_get_strings,
.get_ethtool_stats = fbnic_get_ethtool_stats,
.get_sset_count = fbnic_get_sset_count,
+ .get_rxnfc = fbnic_get_rxnfc,
+ .get_rxfh_key_size = fbnic_get_rxfh_key_size,
+ .get_rxfh_indir_size = fbnic_get_rxfh_indir_size,
+ .get_rxfh = fbnic_get_rxfh,
.get_ts_info = fbnic_get_ts_info,
.get_ts_stats = fbnic_get_ts_stats,
.get_eth_mac_stats = fbnic_get_eth_mac_stats,
--
2.47.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH net-next 03/10] eth: fbnic: don't reset the secondary RSS indir table
2024-12-20 2:52 [PATCH net-next 00/10] eth: fbnic: support basic RSS config and setting channel count Jakub Kicinski
2024-12-20 2:52 ` [PATCH net-next 01/10] eth: fbnic: reorder ethtool code Jakub Kicinski
2024-12-20 2:52 ` [PATCH net-next 02/10] eth: fbnic: support querying RSS config Jakub Kicinski
@ 2024-12-20 2:52 ` Jakub Kicinski
2024-12-20 2:52 ` [PATCH net-next 04/10] eth: fbnic: support setting RSS configuration Jakub Kicinski
` (7 subsequent siblings)
10 siblings, 0 replies; 20+ messages in thread
From: Jakub Kicinski @ 2024-12-20 2:52 UTC (permalink / raw)
To: davem; +Cc: netdev, edumazet, pabeni, Jakub Kicinski
Secondary RSS indirection table is for additional contexts.
It can / should be initialized when such context is created.
Since we don't support creating RSS contexts, yet, this change
has no user visible effect.
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
drivers/net/ethernet/meta/fbnic/fbnic_rpc.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_rpc.c b/drivers/net/ethernet/meta/fbnic/fbnic_rpc.c
index 908c098cd59e..b99c890ac43f 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_rpc.c
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_rpc.c
@@ -13,10 +13,8 @@ void fbnic_reset_indir_tbl(struct fbnic_net *fbn)
unsigned int num_rx = fbn->num_rx_queues;
unsigned int i;
- for (i = 0; i < FBNIC_RPC_RSS_TBL_SIZE; i++) {
+ for (i = 0; i < FBNIC_RPC_RSS_TBL_SIZE; i++)
fbn->indir_tbl[0][i] = ethtool_rxfh_indir_default(i, num_rx);
- fbn->indir_tbl[1][i] = ethtool_rxfh_indir_default(i, num_rx);
- }
}
void fbnic_rss_key_fill(u32 *buffer)
--
2.47.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH net-next 04/10] eth: fbnic: support setting RSS configuration
2024-12-20 2:52 [PATCH net-next 00/10] eth: fbnic: support basic RSS config and setting channel count Jakub Kicinski
` (2 preceding siblings ...)
2024-12-20 2:52 ` [PATCH net-next 03/10] eth: fbnic: don't reset the secondary RSS indir table Jakub Kicinski
@ 2024-12-20 2:52 ` Jakub Kicinski
2024-12-20 2:52 ` [PATCH net-next 05/10] eth: fbnic: let user control the RSS hash fields Jakub Kicinski
` (6 subsequent siblings)
10 siblings, 0 replies; 20+ messages in thread
From: Jakub Kicinski @ 2024-12-20 2:52 UTC (permalink / raw)
To: davem; +Cc: netdev, edumazet, pabeni, Alexander Duyck, Jakub Kicinski
From: Alexander Duyck <alexanderduyck@fb.com>
Let the user program the RSS indirection table and the RSS key.
Straightforward implementation. Track the changes and don't bother
poking the HW if user asked for a config identical to what's already
programmed. The device only supports Toeplitz hash.
Similarly to the GET support - all the real code that does the programming
was part of initial driver submission, already.
Signed-off-by: Alexander Duyck <alexanderduyck@fb.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
.../net/ethernet/meta/fbnic/fbnic_ethtool.c | 55 +++++++++++++++++++
1 file changed, 55 insertions(+)
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c b/drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c
index e71ae6abb0f5..5523803c8edd 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c
@@ -201,6 +201,60 @@ fbnic_get_rxfh(struct net_device *netdev, struct ethtool_rxfh_param *rxfh)
return 0;
}
+static unsigned int
+fbnic_set_indir(struct fbnic_net *fbn, unsigned int idx, const u32 *indir)
+{
+ unsigned int i, changes = 0;
+
+ for (i = 0; i < FBNIC_RPC_RSS_TBL_SIZE; i++) {
+ if (fbn->indir_tbl[idx][i] == indir[i])
+ continue;
+
+ fbn->indir_tbl[idx][i] = indir[i];
+ changes++;
+ }
+
+ return changes;
+}
+
+static int
+fbnic_set_rxfh(struct net_device *netdev, struct ethtool_rxfh_param *rxfh,
+ struct netlink_ext_ack *extack)
+{
+ struct fbnic_net *fbn = netdev_priv(netdev);
+ unsigned int i, changes = 0;
+
+ if (rxfh->hfunc != ETH_RSS_HASH_NO_CHANGE &&
+ rxfh->hfunc != ETH_RSS_HASH_TOP)
+ return -EINVAL;
+
+ if (rxfh->key) {
+ u32 rss_key = 0;
+
+ for (i = FBNIC_RPC_RSS_KEY_BYTE_LEN; i--;) {
+ rss_key >>= 8;
+ rss_key |= (u32)(rxfh->key[i]) << 24;
+
+ if (i % 4)
+ continue;
+
+ if (fbn->rss_key[i / 4] == rss_key)
+ continue;
+
+ fbn->rss_key[i / 4] = rss_key;
+ changes++;
+ }
+ }
+
+ if (rxfh->indir)
+ changes += fbnic_set_indir(fbn, 0, rxfh->indir);
+
+ if (changes && netif_running(netdev))
+ fbnic_rss_reinit_hw(fbn->fbd, fbn);
+
+ return 0;
+}
+
static int
fbnic_get_ts_info(struct net_device *netdev,
struct kernel_ethtool_ts_info *tsinfo)
@@ -312,6 +366,7 @@ static const struct ethtool_ops fbnic_ethtool_ops = {
.get_rxfh_key_size = fbnic_get_rxfh_key_size,
.get_rxfh_indir_size = fbnic_get_rxfh_indir_size,
.get_rxfh = fbnic_get_rxfh,
+ .set_rxfh = fbnic_set_rxfh,
.get_ts_info = fbnic_get_ts_info,
.get_ts_stats = fbnic_get_ts_stats,
.get_eth_mac_stats = fbnic_get_eth_mac_stats,
--
2.47.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH net-next 05/10] eth: fbnic: let user control the RSS hash fields
2024-12-20 2:52 [PATCH net-next 00/10] eth: fbnic: support basic RSS config and setting channel count Jakub Kicinski
` (3 preceding siblings ...)
2024-12-20 2:52 ` [PATCH net-next 04/10] eth: fbnic: support setting RSS configuration Jakub Kicinski
@ 2024-12-20 2:52 ` Jakub Kicinski
2024-12-20 2:52 ` [PATCH net-next 06/10] eth: fbnic: store NAPIs in an array instead of the list Jakub Kicinski
` (5 subsequent siblings)
10 siblings, 0 replies; 20+ messages in thread
From: Jakub Kicinski @ 2024-12-20 2:52 UTC (permalink / raw)
To: davem; +Cc: netdev, edumazet, pabeni, Alexander Duyck, Jakub Kicinski
From: Alexander Duyck <alexanderduyck@fb.com>
Support setting the fields over which RSS computes its hash.
Signed-off-by: Alexander Duyck <alexanderduyck@fb.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
.../net/ethernet/meta/fbnic/fbnic_ethtool.c | 50 +++++++++++++++++++
1 file changed, 50 insertions(+)
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c b/drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c
index 5523803c8edd..d1be8fc30404 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c
@@ -167,6 +167,55 @@ static int fbnic_get_rxnfc(struct net_device *netdev,
return ret;
}
+#define FBNIC_L2_HASH_OPTIONS \
+ (RXH_L2DA | RXH_DISCARD)
+#define FBNIC_L3_HASH_OPTIONS \
+ (FBNIC_L2_HASH_OPTIONS | RXH_IP_SRC | RXH_IP_DST)
+#define FBNIC_L4_HASH_OPTIONS \
+ (FBNIC_L3_HASH_OPTIONS | RXH_L4_B_0_1 | RXH_L4_B_2_3)
+
+static int
+fbnic_set_rss_hash_opts(struct fbnic_net *fbn, const struct ethtool_rxnfc *cmd)
+{
+ int hash_opt_idx;
+
+ /* Verify the type requested is correct */
+ hash_opt_idx = fbnic_get_rss_hash_idx(cmd->flow_type);
+ if (hash_opt_idx < 0)
+ return -EINVAL;
+
+ /* Verify the fields asked for can actually be assigned based on type */
+ if (cmd->data & ~FBNIC_L4_HASH_OPTIONS ||
+ (hash_opt_idx > FBNIC_L4_HASH_OPT &&
+ cmd->data & ~FBNIC_L3_HASH_OPTIONS) ||
+ (hash_opt_idx > FBNIC_IP_HASH_OPT &&
+ cmd->data & ~FBNIC_L2_HASH_OPTIONS))
+ return -EINVAL;
+
+ fbn->rss_flow_hash[hash_opt_idx] = cmd->data;
+
+ if (netif_running(fbn->netdev)) {
+ fbnic_rss_reinit(fbn->fbd, fbn);
+ fbnic_write_rules(fbn->fbd);
+ }
+
+ return 0;
+}
+
+static int fbnic_set_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *cmd)
+{
+ struct fbnic_net *fbn = netdev_priv(netdev);
+ int ret = -EOPNOTSUPP;
+
+ switch (cmd->cmd) {
+ case ETHTOOL_SRXFH:
+ ret = fbnic_set_rss_hash_opts(fbn, cmd);
+ break;
+ }
+
+ return ret;
+}
+
static u32 fbnic_get_rxfh_key_size(struct net_device *netdev)
{
return FBNIC_RPC_RSS_KEY_BYTE_LEN;
@@ -363,6 +412,7 @@ static const struct ethtool_ops fbnic_ethtool_ops = {
.get_ethtool_stats = fbnic_get_ethtool_stats,
.get_sset_count = fbnic_get_sset_count,
.get_rxnfc = fbnic_get_rxnfc,
+ .set_rxnfc = fbnic_set_rxnfc,
.get_rxfh_key_size = fbnic_get_rxfh_key_size,
.get_rxfh_indir_size = fbnic_get_rxfh_indir_size,
.get_rxfh = fbnic_get_rxfh,
--
2.47.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH net-next 06/10] eth: fbnic: store NAPIs in an array instead of the list
2024-12-20 2:52 [PATCH net-next 00/10] eth: fbnic: support basic RSS config and setting channel count Jakub Kicinski
` (4 preceding siblings ...)
2024-12-20 2:52 ` [PATCH net-next 05/10] eth: fbnic: let user control the RSS hash fields Jakub Kicinski
@ 2024-12-20 2:52 ` Jakub Kicinski
2024-12-20 2:52 ` [PATCH net-next 07/10] eth: fbnic: add IRQ reuse support Jakub Kicinski
` (4 subsequent siblings)
10 siblings, 0 replies; 20+ messages in thread
From: Jakub Kicinski @ 2024-12-20 2:52 UTC (permalink / raw)
To: davem; +Cc: netdev, edumazet, pabeni, Jakub Kicinski
We will need an array for storing NAPIs in the upcoming IRQ handler
reuse rework. Replace the current list we have, so that we are able
to reuse it later.
In a few places replace i as the iterator with t when we iterate
over triads, this seems slightly less confusing than having
i, j, k variables.
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
.../net/ethernet/meta/fbnic/fbnic_netdev.c | 1 -
.../net/ethernet/meta/fbnic/fbnic_netdev.h | 6 +-
drivers/net/ethernet/meta/fbnic/fbnic_txrx.c | 117 ++++++++++--------
drivers/net/ethernet/meta/fbnic/fbnic_txrx.h | 7 +-
4 files changed, 71 insertions(+), 60 deletions(-)
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c b/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c
index fc7d80db5fa6..558644c49a4b 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c
@@ -615,7 +615,6 @@ struct net_device *fbnic_netdev_alloc(struct fbnic_dev *fbd)
fbn->netdev = netdev;
fbn->fbd = fbd;
- INIT_LIST_HEAD(&fbn->napis);
fbn->txq_size = FBNIC_TXQ_SIZE_DEFAULT;
fbn->hpq_size = FBNIC_HPQ_SIZE_DEFAULT;
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_netdev.h b/drivers/net/ethernet/meta/fbnic/fbnic_netdev.h
index b8417b300778..0986c8f120a8 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_netdev.h
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_netdev.h
@@ -11,10 +11,14 @@
#include "fbnic_rpc.h"
#include "fbnic_txrx.h"
+#define FBNIC_MAX_NAPI_VECTORS 128u
+
struct fbnic_net {
struct fbnic_ring *tx[FBNIC_MAX_TXQS];
struct fbnic_ring *rx[FBNIC_MAX_RXQS];
+ struct fbnic_napi_vector *napi[FBNIC_MAX_NAPI_VECTORS];
+
struct net_device *netdev;
struct fbnic_dev *fbd;
@@ -56,8 +60,6 @@ struct fbnic_net {
/* Time stampinn filter config */
struct kernel_hwtstamp_config hwtstamp_config;
-
- struct list_head napis;
};
int __fbnic_open(struct fbnic_net *fbn);
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_txrx.c b/drivers/net/ethernet/meta/fbnic/fbnic_txrx.c
index b5050fabe8fe..87e4eb03d991 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_txrx.c
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_txrx.c
@@ -1116,16 +1116,17 @@ static void fbnic_free_napi_vector(struct fbnic_net *fbn,
fbnic_free_irq(fbd, v_idx, nv);
page_pool_destroy(nv->page_pool);
netif_napi_del(&nv->napi);
- list_del(&nv->napis);
+ fbn->napi[fbnic_napi_idx(nv)] = NULL;
kfree(nv);
}
void fbnic_free_napi_vectors(struct fbnic_net *fbn)
{
- struct fbnic_napi_vector *nv, *temp;
+ int i;
- list_for_each_entry_safe(nv, temp, &fbn->napis, napis)
- fbnic_free_napi_vector(fbn, nv);
+ for (i = 0; i < fbn->num_napi; i++)
+ if (fbn->napi[i])
+ fbnic_free_napi_vector(fbn, fbn->napi[i]);
}
static void fbnic_name_napi_vector(struct fbnic_napi_vector *nv)
@@ -1222,7 +1223,7 @@ static int fbnic_alloc_napi_vector(struct fbnic_dev *fbd, struct fbnic_net *fbn,
nv->v_idx = v_idx;
/* Tie napi to netdev */
- list_add(&nv->napis, &fbn->napis);
+ fbn->napi[fbnic_napi_idx(nv)] = nv;
netif_napi_add(fbn->netdev, &nv->napi, fbnic_poll);
/* Record IRQ to NAPI struct */
@@ -1307,7 +1308,7 @@ static int fbnic_alloc_napi_vector(struct fbnic_dev *fbd, struct fbnic_net *fbn,
page_pool_destroy(nv->page_pool);
napi_del:
netif_napi_del(&nv->napi);
- list_del(&nv->napis);
+ fbn->napi[fbnic_napi_idx(nv)] = NULL;
kfree(nv);
return err;
}
@@ -1612,19 +1613,18 @@ static int fbnic_alloc_nv_resources(struct fbnic_net *fbn,
void fbnic_free_resources(struct fbnic_net *fbn)
{
- struct fbnic_napi_vector *nv;
+ int i;
- list_for_each_entry(nv, &fbn->napis, napis)
- fbnic_free_nv_resources(fbn, nv);
+ for (i = 0; i < fbn->num_napi; i++)
+ fbnic_free_nv_resources(fbn, fbn->napi[i]);
}
int fbnic_alloc_resources(struct fbnic_net *fbn)
{
- struct fbnic_napi_vector *nv;
- int err = -ENODEV;
+ int i, err = -ENODEV;
- list_for_each_entry(nv, &fbn->napis, napis) {
- err = fbnic_alloc_nv_resources(fbn, nv);
+ for (i = 0; i < fbn->num_napi; i++) {
+ err = fbnic_alloc_nv_resources(fbn, fbn->napi[i]);
if (err)
goto free_resources;
}
@@ -1632,8 +1632,8 @@ int fbnic_alloc_resources(struct fbnic_net *fbn)
return 0;
free_resources:
- list_for_each_entry_continue_reverse(nv, &fbn->napis, napis)
- fbnic_free_nv_resources(fbn, nv);
+ while (i--)
+ fbnic_free_nv_resources(fbn, fbn->napi[i]);
return err;
}
@@ -1670,33 +1670,34 @@ static void fbnic_disable_rcq(struct fbnic_ring *rxr)
void fbnic_napi_disable(struct fbnic_net *fbn)
{
- struct fbnic_napi_vector *nv;
+ int i;
- list_for_each_entry(nv, &fbn->napis, napis) {
- napi_disable(&nv->napi);
+ for (i = 0; i < fbn->num_napi; i++) {
+ napi_disable(&fbn->napi[i]->napi);
- fbnic_nv_irq_disable(nv);
+ fbnic_nv_irq_disable(fbn->napi[i]);
}
}
void fbnic_disable(struct fbnic_net *fbn)
{
struct fbnic_dev *fbd = fbn->fbd;
- struct fbnic_napi_vector *nv;
- int i, j;
+ int i, j, t;
+
+ for (i = 0; i < fbn->num_napi; i++) {
+ struct fbnic_napi_vector *nv = fbn->napi[i];
- list_for_each_entry(nv, &fbn->napis, napis) {
/* Disable Tx queue triads */
- for (i = 0; i < nv->txt_count; i++) {
- struct fbnic_q_triad *qt = &nv->qt[i];
+ for (t = 0; t < nv->txt_count; t++) {
+ struct fbnic_q_triad *qt = &nv->qt[t];
fbnic_disable_twq0(&qt->sub0);
fbnic_disable_tcq(&qt->cmpl);
}
/* Disable Rx queue triads */
- for (j = 0; j < nv->rxt_count; j++, i++) {
- struct fbnic_q_triad *qt = &nv->qt[i];
+ for (j = 0; j < nv->rxt_count; j++, t++) {
+ struct fbnic_q_triad *qt = &nv->qt[t];
fbnic_disable_bdq(&qt->sub0, &qt->sub1);
fbnic_disable_rcq(&qt->cmpl);
@@ -1792,14 +1793,15 @@ int fbnic_wait_all_queues_idle(struct fbnic_dev *fbd, bool may_fail)
void fbnic_flush(struct fbnic_net *fbn)
{
- struct fbnic_napi_vector *nv;
+ int i;
- list_for_each_entry(nv, &fbn->napis, napis) {
- int i, j;
+ for (i = 0; i < fbn->num_napi; i++) {
+ struct fbnic_napi_vector *nv = fbn->napi[i];
+ int j, t;
/* Flush any processed Tx Queue Triads and drop the rest */
- for (i = 0; i < nv->txt_count; i++) {
- struct fbnic_q_triad *qt = &nv->qt[i];
+ for (t = 0; t < nv->txt_count; t++) {
+ struct fbnic_q_triad *qt = &nv->qt[t];
struct netdev_queue *tx_queue;
/* Clean the work queues of unprocessed work */
@@ -1823,8 +1825,8 @@ void fbnic_flush(struct fbnic_net *fbn)
}
/* Flush any processed Rx Queue Triads and drop the rest */
- for (j = 0; j < nv->rxt_count; j++, i++) {
- struct fbnic_q_triad *qt = &nv->qt[i];
+ for (j = 0; j < nv->rxt_count; j++, t++) {
+ struct fbnic_q_triad *qt = &nv->qt[t];
/* Clean the work queues of unprocessed work */
fbnic_clean_bdq(nv, 0, &qt->sub0, qt->sub0.tail);
@@ -1845,14 +1847,15 @@ void fbnic_flush(struct fbnic_net *fbn)
void fbnic_fill(struct fbnic_net *fbn)
{
- struct fbnic_napi_vector *nv;
+ int i;
- list_for_each_entry(nv, &fbn->napis, napis) {
- int i, j;
+ for (i = 0; i < fbn->num_napi; i++) {
+ struct fbnic_napi_vector *nv = fbn->napi[i];
+ int j, t;
/* Configure NAPI mapping for Tx */
- for (i = 0; i < nv->txt_count; i++) {
- struct fbnic_q_triad *qt = &nv->qt[i];
+ for (t = 0; t < nv->txt_count; t++) {
+ struct fbnic_q_triad *qt = &nv->qt[t];
/* Nothing to do if Tx queue is disabled */
if (qt->sub0.flags & FBNIC_RING_F_DISABLED)
@@ -1866,8 +1869,8 @@ void fbnic_fill(struct fbnic_net *fbn)
/* Configure NAPI mapping and populate pages
* in the BDQ rings to use for Rx
*/
- for (j = 0; j < nv->rxt_count; j++, i++) {
- struct fbnic_q_triad *qt = &nv->qt[i];
+ for (j = 0; j < nv->rxt_count; j++, t++) {
+ struct fbnic_q_triad *qt = &nv->qt[t];
/* Associate Rx queue with NAPI */
netif_queue_set_napi(nv->napi.dev, qt->cmpl.q_idx,
@@ -2025,21 +2028,23 @@ static void fbnic_enable_rcq(struct fbnic_napi_vector *nv,
void fbnic_enable(struct fbnic_net *fbn)
{
struct fbnic_dev *fbd = fbn->fbd;
- struct fbnic_napi_vector *nv;
- int i, j;
+ int i;
+
+ for (i = 0; i < fbn->num_napi; i++) {
+ struct fbnic_napi_vector *nv = fbn->napi[i];
+ int j, t;
- list_for_each_entry(nv, &fbn->napis, napis) {
/* Setup Tx Queue Triads */
- for (i = 0; i < nv->txt_count; i++) {
- struct fbnic_q_triad *qt = &nv->qt[i];
+ for (t = 0; t < nv->txt_count; t++) {
+ struct fbnic_q_triad *qt = &nv->qt[t];
fbnic_enable_twq0(&qt->sub0);
fbnic_enable_tcq(nv, &qt->cmpl);
}
/* Setup Rx Queue Triads */
- for (j = 0; j < nv->rxt_count; j++, i++) {
- struct fbnic_q_triad *qt = &nv->qt[i];
+ for (j = 0; j < nv->rxt_count; j++, t++) {
+ struct fbnic_q_triad *qt = &nv->qt[t];
fbnic_enable_bdq(&qt->sub0, &qt->sub1);
fbnic_config_drop_mode_rcq(nv, &qt->cmpl);
@@ -2064,10 +2069,11 @@ void fbnic_napi_enable(struct fbnic_net *fbn)
{
u32 irqs[FBNIC_MAX_MSIX_VECS / 32] = {};
struct fbnic_dev *fbd = fbn->fbd;
- struct fbnic_napi_vector *nv;
int i;
- list_for_each_entry(nv, &fbn->napis, napis) {
+ for (i = 0; i < fbn->num_napi; i++) {
+ struct fbnic_napi_vector *nv = fbn->napi[i];
+
napi_enable(&nv->napi);
fbnic_nv_irq_enable(nv);
@@ -2096,17 +2102,18 @@ void fbnic_napi_depletion_check(struct net_device *netdev)
struct fbnic_net *fbn = netdev_priv(netdev);
u32 irqs[FBNIC_MAX_MSIX_VECS / 32] = {};
struct fbnic_dev *fbd = fbn->fbd;
- struct fbnic_napi_vector *nv;
- int i, j;
+ int i, j, t;
+
+ for (i = 0; i < fbn->num_napi; i++) {
+ struct fbnic_napi_vector *nv = fbn->napi[i];
- list_for_each_entry(nv, &fbn->napis, napis) {
/* Find RQs which are completely out of pages */
- for (i = nv->txt_count, j = 0; j < nv->rxt_count; j++, i++) {
+ for (t = nv->txt_count, j = 0; j < nv->rxt_count; j++, t++) {
/* Assume 4 pages is always enough to fit a packet
* and therefore generate a completion and an IRQ.
*/
- if (fbnic_desc_used(&nv->qt[i].sub0) < 4 ||
- fbnic_desc_used(&nv->qt[i].sub1) < 4)
+ if (fbnic_desc_used(&nv->qt[t].sub0) < 4 ||
+ fbnic_desc_used(&nv->qt[t].sub1) < 4)
irqs[nv->v_idx / 32] |= BIT(nv->v_idx % 32);
}
}
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_txrx.h b/drivers/net/ethernet/meta/fbnic/fbnic_txrx.h
index 8d626287c3f4..1965d1fa38a2 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_txrx.h
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_txrx.h
@@ -110,8 +110,6 @@ struct fbnic_napi_vector {
u8 txt_count;
u8 rxt_count;
- struct list_head napis;
-
struct fbnic_q_triad qt[];
};
@@ -137,4 +135,9 @@ void fbnic_fill(struct fbnic_net *fbn);
void fbnic_napi_depletion_check(struct net_device *netdev);
int fbnic_wait_all_queues_idle(struct fbnic_dev *fbd, bool may_fail);
+static inline int fbnic_napi_idx(const struct fbnic_napi_vector *nv)
+{
+ return nv->v_idx - FBNIC_NON_NAPI_VECTORS;
+}
+
#endif /* _FBNIC_TXRX_H_ */
--
2.47.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH net-next 07/10] eth: fbnic: add IRQ reuse support
2024-12-20 2:52 [PATCH net-next 00/10] eth: fbnic: support basic RSS config and setting channel count Jakub Kicinski
` (5 preceding siblings ...)
2024-12-20 2:52 ` [PATCH net-next 06/10] eth: fbnic: store NAPIs in an array instead of the list Jakub Kicinski
@ 2024-12-20 2:52 ` Jakub Kicinski
2024-12-20 2:52 ` [PATCH net-next 08/10] eth: fbnic: centralize the queue count and NAPI<>queue setting Jakub Kicinski
` (3 subsequent siblings)
10 siblings, 0 replies; 20+ messages in thread
From: Jakub Kicinski @ 2024-12-20 2:52 UTC (permalink / raw)
To: davem; +Cc: netdev, edumazet, pabeni, Jakub Kicinski
Change our method of swapping NAPIs without disturbing existing config.
This is primarily needed for "live reconfiguration" such as changing
the channel count when interface is already up.
Previously we were planning to use a trick of using shared interrupts.
We would install a second IRQ handler for the new NAPI, and make it
return IRQ_NONE until we were ready for it to take over. This works fine
functionally but breaks IRQ naming. The IRQ subsystem uses the IRQ name
to create the procfs entry, since both handlers used the same name
the second handler wouldn't get a proc directory registered.
When first one gets removed on success full ring count change
it would remove its directory and we would be left with none.
New approach uses a double pointer to the NAPI. The IRQ handler needs
to know how to locate the NAPI to schedule. We register a single IRQ handler
and give it a pointer to a pointer. We can then change what it points to
without re-registering. This may have a tiny perf impact, but really
really negligible.
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
drivers/net/ethernet/meta/fbnic/fbnic.h | 14 +++++++
drivers/net/ethernet/meta/fbnic/fbnic_irq.c | 42 +++++++++++++++++++
.../net/ethernet/meta/fbnic/fbnic_netdev.c | 2 +
drivers/net/ethernet/meta/fbnic/fbnic_txrx.c | 25 ++---------
drivers/net/ethernet/meta/fbnic/fbnic_txrx.h | 2 +-
5 files changed, 63 insertions(+), 22 deletions(-)
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic.h b/drivers/net/ethernet/meta/fbnic/fbnic.h
index 706ae6104c8e..ed527209b30c 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic.h
+++ b/drivers/net/ethernet/meta/fbnic/fbnic.h
@@ -16,6 +16,10 @@
#include "fbnic_mac.h"
#include "fbnic_rpc.h"
+struct fbnic_napi_vector;
+
+#define FBNIC_MAX_NAPI_VECTORS 128u
+
struct fbnic_dev {
struct device *dev;
struct net_device *netdev;
@@ -29,6 +33,11 @@ struct fbnic_dev {
unsigned int pcs_msix_vector;
unsigned short num_irqs;
+ struct {
+ u8 users;
+ char name[IFNAMSIZ + 9];
+ } napi_irq[FBNIC_MAX_NAPI_VECTORS];
+
struct delayed_work service_task;
struct fbnic_fw_mbx mbx[FBNIC_IPC_MBX_INDICES];
@@ -148,6 +157,11 @@ void fbnic_hwmon_unregister(struct fbnic_dev *fbd);
int fbnic_pcs_irq_enable(struct fbnic_dev *fbd);
void fbnic_pcs_irq_disable(struct fbnic_dev *fbd);
+void fbnic_napi_name_irqs(struct fbnic_dev *fbd);
+int fbnic_napi_request_irq(struct fbnic_dev *fbd,
+ struct fbnic_napi_vector *nv);
+void fbnic_napi_free_irq(struct fbnic_dev *fbd,
+ struct fbnic_napi_vector *nv);
int fbnic_request_irq(struct fbnic_dev *dev, int nr, irq_handler_t handler,
unsigned long flags, const char *name, void *data);
void fbnic_free_irq(struct fbnic_dev *dev, int nr, void *data);
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_irq.c b/drivers/net/ethernet/meta/fbnic/fbnic_irq.c
index 914362195920..a8ea7b6774a8 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_irq.c
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_irq.c
@@ -169,6 +169,48 @@ void fbnic_free_irq(struct fbnic_dev *fbd, int nr, void *data)
free_irq(irq, data);
}
+void fbnic_napi_name_irqs(struct fbnic_dev *fbd)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(fbd->napi_irq); i++)
+ snprintf(fbd->napi_irq[i].name,
+ sizeof(fbd->napi_irq[i].name),
+ "%s-TxRx-%u", fbd->netdev->name, i);
+}
+
+int fbnic_napi_request_irq(struct fbnic_dev *fbd,
+ struct fbnic_napi_vector *nv)
+{
+ struct fbnic_net *fbn = netdev_priv(fbd->netdev);
+ int i = fbnic_napi_idx(nv);
+ int err;
+
+ if (!fbd->napi_irq[i].users) {
+ err = fbnic_request_irq(fbd, nv->v_idx,
+ fbnic_msix_clean_rings, 0,
+ fbd->napi_irq[i].name,
+ &fbn->napi[i]);
+ if (err)
+ return err;
+ }
+
+ fbd->napi_irq[i].users++;
+ return 0;
+}
+
+void fbnic_napi_free_irq(struct fbnic_dev *fbd,
+ struct fbnic_napi_vector *nv)
+{
+ struct fbnic_net *fbn = netdev_priv(fbd->netdev);
+ int i = fbnic_napi_idx(nv);
+
+ if (--fbd->napi_irq[i].users)
+ return;
+
+ fbnic_free_irq(fbd, nv->v_idx, &fbn->napi[i]);
+}
+
void fbnic_free_irqs(struct fbnic_dev *fbd)
{
struct pci_dev *pdev = to_pci_dev(fbd->dev);
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c b/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c
index 558644c49a4b..2f19144e4410 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c
@@ -74,6 +74,8 @@ static int fbnic_open(struct net_device *netdev)
struct fbnic_net *fbn = netdev_priv(netdev);
int err;
+ fbnic_napi_name_irqs(fbn->fbd);
+
err = __fbnic_open(fbn);
if (!err)
fbnic_up(fbn);
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_txrx.c b/drivers/net/ethernet/meta/fbnic/fbnic_txrx.c
index 87e4eb03d991..75b491b8e1ca 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_txrx.c
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_txrx.c
@@ -1036,9 +1036,9 @@ static int fbnic_poll(struct napi_struct *napi, int budget)
return 0;
}
-static irqreturn_t fbnic_msix_clean_rings(int __always_unused irq, void *data)
+irqreturn_t fbnic_msix_clean_rings(int __always_unused irq, void *data)
{
- struct fbnic_napi_vector *nv = data;
+ struct fbnic_napi_vector *nv = *(void **)data;
napi_schedule_irqoff(&nv->napi);
@@ -1099,7 +1099,6 @@ static void fbnic_free_napi_vector(struct fbnic_net *fbn,
struct fbnic_napi_vector *nv)
{
struct fbnic_dev *fbd = nv->fbd;
- u32 v_idx = nv->v_idx;
int i, j;
for (i = 0; i < nv->txt_count; i++) {
@@ -1113,7 +1112,7 @@ static void fbnic_free_napi_vector(struct fbnic_net *fbn,
fbnic_remove_rx_ring(fbn, &nv->qt[i].cmpl);
}
- fbnic_free_irq(fbd, v_idx, nv);
+ fbnic_napi_free_irq(fbd, nv);
page_pool_destroy(nv->page_pool);
netif_napi_del(&nv->napi);
fbn->napi[fbnic_napi_idx(nv)] = NULL;
@@ -1129,18 +1128,6 @@ void fbnic_free_napi_vectors(struct fbnic_net *fbn)
fbnic_free_napi_vector(fbn, fbn->napi[i]);
}
-static void fbnic_name_napi_vector(struct fbnic_napi_vector *nv)
-{
- unsigned char *dev_name = nv->napi.dev->name;
-
- if (!nv->rxt_count)
- snprintf(nv->name, sizeof(nv->name), "%s-Tx-%u", dev_name,
- nv->v_idx - FBNIC_NON_NAPI_VECTORS);
- else
- snprintf(nv->name, sizeof(nv->name), "%s-TxRx-%u", dev_name,
- nv->v_idx - FBNIC_NON_NAPI_VECTORS);
-}
-
#define FBNIC_PAGE_POOL_FLAGS \
(PP_FLAG_DMA_MAP | PP_FLAG_DMA_SYNC_DEV)
@@ -1240,12 +1227,8 @@ static int fbnic_alloc_napi_vector(struct fbnic_dev *fbd, struct fbnic_net *fbn,
goto napi_del;
}
- /* Initialize vector name */
- fbnic_name_napi_vector(nv);
-
/* Request the IRQ for napi vector */
- err = fbnic_request_irq(fbd, v_idx, &fbnic_msix_clean_rings,
- IRQF_SHARED, nv->name, nv);
+ err = fbnic_napi_request_irq(fbd, nv);
if (err)
goto pp_destroy;
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_txrx.h b/drivers/net/ethernet/meta/fbnic/fbnic_txrx.h
index 1965d1fa38a2..c8d908860ab0 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_txrx.h
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_txrx.h
@@ -104,7 +104,6 @@ struct fbnic_napi_vector {
struct device *dev; /* Device for DMA unmapping */
struct page_pool *page_pool;
struct fbnic_dev *fbd;
- char name[IFNAMSIZ + 9];
u16 v_idx;
u8 txt_count;
@@ -125,6 +124,7 @@ int fbnic_alloc_napi_vectors(struct fbnic_net *fbn);
void fbnic_free_napi_vectors(struct fbnic_net *fbn);
int fbnic_alloc_resources(struct fbnic_net *fbn);
void fbnic_free_resources(struct fbnic_net *fbn);
+irqreturn_t fbnic_msix_clean_rings(int irq, void *data);
void fbnic_napi_enable(struct fbnic_net *fbn);
void fbnic_napi_disable(struct fbnic_net *fbn);
void fbnic_enable(struct fbnic_net *fbn);
--
2.47.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH net-next 08/10] eth: fbnic: centralize the queue count and NAPI<>queue setting
2024-12-20 2:52 [PATCH net-next 00/10] eth: fbnic: support basic RSS config and setting channel count Jakub Kicinski
` (6 preceding siblings ...)
2024-12-20 2:52 ` [PATCH net-next 07/10] eth: fbnic: add IRQ reuse support Jakub Kicinski
@ 2024-12-20 2:52 ` Jakub Kicinski
2024-12-20 2:52 ` [PATCH net-next 09/10] eth: fbnic: support ring channel get and set while down Jakub Kicinski
` (2 subsequent siblings)
10 siblings, 0 replies; 20+ messages in thread
From: Jakub Kicinski @ 2024-12-20 2:52 UTC (permalink / raw)
To: davem; +Cc: netdev, edumazet, pabeni, Alexander Duyck, Jakub Kicinski
From: Alexander Duyck <alexanderduyck@fb.com>
To simplify dealing with RTNL_ASSERT() requirements further
down the line, move setting queue count and NAPI<>queue
association to their own helpers.
Signed-off-by: Alexander Duyck <alexanderduyck@fb.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
.../net/ethernet/meta/fbnic/fbnic_netdev.c | 9 +-
drivers/net/ethernet/meta/fbnic/fbnic_txrx.c | 92 +++++++++++++------
drivers/net/ethernet/meta/fbnic/fbnic_txrx.h | 2 +
3 files changed, 70 insertions(+), 33 deletions(-)
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c b/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c
index 2f19144e4410..7a96b6ee773f 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c
@@ -23,13 +23,7 @@ int __fbnic_open(struct fbnic_net *fbn)
if (err)
goto free_napi_vectors;
- err = netif_set_real_num_tx_queues(fbn->netdev,
- fbn->num_tx_queues);
- if (err)
- goto free_resources;
-
- err = netif_set_real_num_rx_queues(fbn->netdev,
- fbn->num_rx_queues);
+ err = fbnic_set_netif_queues(fbn);
if (err)
goto free_resources;
@@ -93,6 +87,7 @@ static int fbnic_stop(struct net_device *netdev)
fbnic_time_stop(fbn);
fbnic_fw_xmit_ownership_msg(fbn->fbd, false);
+ fbnic_reset_netif_queues(fbn);
fbnic_free_resources(fbn);
fbnic_free_napi_vectors(fbn);
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_txrx.c b/drivers/net/ethernet/meta/fbnic/fbnic_txrx.c
index 75b491b8e1ca..92fc1ad6ed6f 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_txrx.c
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_txrx.c
@@ -1621,6 +1621,71 @@ int fbnic_alloc_resources(struct fbnic_net *fbn)
return err;
}
+static void fbnic_set_netif_napi(struct fbnic_napi_vector *nv)
+{
+ int i, j;
+
+ /* Associate Tx queue with NAPI */
+ for (i = 0; i < nv->txt_count; i++) {
+ struct fbnic_q_triad *qt = &nv->qt[i];
+
+ netif_queue_set_napi(nv->napi.dev, qt->sub0.q_idx,
+ NETDEV_QUEUE_TYPE_TX, &nv->napi);
+ }
+
+ /* Associate Rx queue with NAPI */
+ for (j = 0; j < nv->rxt_count; j++, i++) {
+ struct fbnic_q_triad *qt = &nv->qt[i];
+
+ netif_queue_set_napi(nv->napi.dev, qt->cmpl.q_idx,
+ NETDEV_QUEUE_TYPE_RX, &nv->napi);
+ }
+}
+
+static void fbnic_reset_netif_napi(struct fbnic_napi_vector *nv)
+{
+ int i, j;
+
+ /* Disassociate Tx queue from NAPI */
+ for (i = 0; i < nv->txt_count; i++) {
+ struct fbnic_q_triad *qt = &nv->qt[i];
+
+ netif_queue_set_napi(nv->napi.dev, qt->sub0.q_idx,
+ NETDEV_QUEUE_TYPE_TX, NULL);
+ }
+
+ /* Disassociate Rx queue from NAPI */
+ for (j = 0; j < nv->rxt_count; j++, i++) {
+ struct fbnic_q_triad *qt = &nv->qt[i];
+
+ netif_queue_set_napi(nv->napi.dev, qt->cmpl.q_idx,
+ NETDEV_QUEUE_TYPE_RX, NULL);
+ }
+}
+
+int fbnic_set_netif_queues(struct fbnic_net *fbn)
+{
+ int i, err;
+
+ err = netif_set_real_num_queues(fbn->netdev, fbn->num_tx_queues,
+ fbn->num_rx_queues);
+ if (err)
+ return err;
+
+ for (i = 0; i < fbn->num_napi; i++)
+ fbnic_set_netif_napi(fbn->napi[i]);
+
+ return 0;
+}
+
+void fbnic_reset_netif_queues(struct fbnic_net *fbn)
+{
+ int i;
+
+ for (i = 0; i < fbn->num_napi; i++)
+ fbnic_reset_netif_napi(fbn->napi[i]);
+}
+
static void fbnic_disable_twq0(struct fbnic_ring *txr)
{
u32 twq_ctl = fbnic_ring_rd32(txr, FBNIC_QUEUE_TWQ0_CTL);
@@ -1801,10 +1866,6 @@ void fbnic_flush(struct fbnic_net *fbn)
tx_queue = netdev_get_tx_queue(nv->napi.dev,
qt->sub0.q_idx);
netdev_tx_reset_queue(tx_queue);
-
- /* Disassociate Tx queue from NAPI */
- netif_queue_set_napi(nv->napi.dev, qt->sub0.q_idx,
- NETDEV_QUEUE_TYPE_TX, NULL);
}
/* Flush any processed Rx Queue Triads and drop the rest */
@@ -1820,10 +1881,6 @@ void fbnic_flush(struct fbnic_net *fbn)
fbnic_put_pkt_buff(nv, qt->cmpl.pkt, 0);
qt->cmpl.pkt->buff.data_hard_start = NULL;
-
- /* Disassociate Rx queue from NAPI */
- netif_queue_set_napi(nv->napi.dev, qt->cmpl.q_idx,
- NETDEV_QUEUE_TYPE_RX, NULL);
}
}
}
@@ -1836,29 +1893,12 @@ void fbnic_fill(struct fbnic_net *fbn)
struct fbnic_napi_vector *nv = fbn->napi[i];
int j, t;
- /* Configure NAPI mapping for Tx */
- for (t = 0; t < nv->txt_count; t++) {
- struct fbnic_q_triad *qt = &nv->qt[t];
-
- /* Nothing to do if Tx queue is disabled */
- if (qt->sub0.flags & FBNIC_RING_F_DISABLED)
- continue;
-
- /* Associate Tx queue with NAPI */
- netif_queue_set_napi(nv->napi.dev, qt->sub0.q_idx,
- NETDEV_QUEUE_TYPE_TX, &nv->napi);
- }
-
/* Configure NAPI mapping and populate pages
* in the BDQ rings to use for Rx
*/
- for (j = 0; j < nv->rxt_count; j++, t++) {
+ for (j = 0, t = nv->txt_count; j < nv->rxt_count; j++, t++) {
struct fbnic_q_triad *qt = &nv->qt[t];
- /* Associate Rx queue with NAPI */
- netif_queue_set_napi(nv->napi.dev, qt->cmpl.q_idx,
- NETDEV_QUEUE_TYPE_RX, &nv->napi);
-
/* Populate the header and payload BDQs */
fbnic_fill_bdq(nv, &qt->sub0);
fbnic_fill_bdq(nv, &qt->sub1);
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_txrx.h b/drivers/net/ethernet/meta/fbnic/fbnic_txrx.h
index c8d908860ab0..92c671135ad7 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_txrx.h
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_txrx.h
@@ -124,6 +124,8 @@ int fbnic_alloc_napi_vectors(struct fbnic_net *fbn);
void fbnic_free_napi_vectors(struct fbnic_net *fbn);
int fbnic_alloc_resources(struct fbnic_net *fbn);
void fbnic_free_resources(struct fbnic_net *fbn);
+int fbnic_set_netif_queues(struct fbnic_net *fbn);
+void fbnic_reset_netif_queues(struct fbnic_net *fbn);
irqreturn_t fbnic_msix_clean_rings(int irq, void *data);
void fbnic_napi_enable(struct fbnic_net *fbn);
void fbnic_napi_disable(struct fbnic_net *fbn);
--
2.47.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH net-next 09/10] eth: fbnic: support ring channel get and set while down
2024-12-20 2:52 [PATCH net-next 00/10] eth: fbnic: support basic RSS config and setting channel count Jakub Kicinski
` (7 preceding siblings ...)
2024-12-20 2:52 ` [PATCH net-next 08/10] eth: fbnic: centralize the queue count and NAPI<>queue setting Jakub Kicinski
@ 2024-12-20 2:52 ` Jakub Kicinski
2024-12-20 2:52 ` [PATCH net-next 10/10] eth: fbnic: support ring channel set while up Jakub Kicinski
2024-12-23 18:50 ` [PATCH net-next 00/10] eth: fbnic: support basic RSS config and setting channel count patchwork-bot+netdevbpf
10 siblings, 0 replies; 20+ messages in thread
From: Jakub Kicinski @ 2024-12-20 2:52 UTC (permalink / raw)
To: davem; +Cc: netdev, edumazet, pabeni, Jakub Kicinski
Trivial implementation of ethtool channel get and set. Set is only
supported when device is closed, next patch will add code for
live reconfig.
Asymmetric configurations are supported (combined + extra Tx or Rx),
so are configurations with independent IRQs for Rx and Tx.
Having all 3 NAPI types (combined, Tx, Rx) is not supported.
We used to only call fbnic_reset_indir_tbl() during init.
Now that we call it after device had been register must
be careful not to override user config.
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
.../net/ethernet/meta/fbnic/fbnic_ethtool.c | 64 +++++++++++++++++++
drivers/net/ethernet/meta/fbnic/fbnic_rpc.c | 3 +
2 files changed, 67 insertions(+)
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c b/drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c
index d1be8fc30404..d2fe97ae6a71 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c
@@ -304,6 +304,68 @@ fbnic_set_rxfh(struct net_device *netdev, struct ethtool_rxfh_param *rxfh,
return 0;
}
+static void fbnic_get_channels(struct net_device *netdev,
+ struct ethtool_channels *ch)
+{
+ struct fbnic_net *fbn = netdev_priv(netdev);
+ struct fbnic_dev *fbd = fbn->fbd;
+
+ ch->max_rx = fbd->max_num_queues;
+ ch->max_tx = fbd->max_num_queues;
+ ch->max_combined = min(ch->max_rx, ch->max_tx);
+ ch->max_other = FBNIC_NON_NAPI_VECTORS;
+
+ if (fbn->num_rx_queues > fbn->num_napi ||
+ fbn->num_tx_queues > fbn->num_napi)
+ ch->combined_count = min(fbn->num_rx_queues,
+ fbn->num_tx_queues);
+ else
+ ch->combined_count =
+ fbn->num_rx_queues + fbn->num_tx_queues - fbn->num_napi;
+ ch->rx_count = fbn->num_rx_queues - ch->combined_count;
+ ch->tx_count = fbn->num_tx_queues - ch->combined_count;
+ ch->other_count = FBNIC_NON_NAPI_VECTORS;
+}
+
+static void fbnic_set_queues(struct fbnic_net *fbn, struct ethtool_channels *ch,
+ unsigned int max_napis)
+{
+ fbn->num_rx_queues = ch->rx_count + ch->combined_count;
+ fbn->num_tx_queues = ch->tx_count + ch->combined_count;
+ fbn->num_napi = min(ch->rx_count + ch->tx_count + ch->combined_count,
+ max_napis);
+}
+
+static int fbnic_set_channels(struct net_device *netdev,
+ struct ethtool_channels *ch)
+{
+ struct fbnic_net *fbn = netdev_priv(netdev);
+ unsigned int max_napis, standalone;
+ struct fbnic_dev *fbd = fbn->fbd;
+
+ max_napis = fbd->num_irqs - FBNIC_NON_NAPI_VECTORS;
+ standalone = ch->rx_count + ch->tx_count;
+
+ /* Limits for standalone queues:
+ * - each queue has it's own NAPI (num_napi >= rx + tx + combined)
+ * - combining queues (combined not 0, rx or tx must be 0)
+ */
+ if ((ch->rx_count && ch->tx_count && ch->combined_count) ||
+ (standalone && standalone + ch->combined_count > max_napis) ||
+ ch->rx_count + ch->combined_count > fbd->max_num_queues ||
+ ch->tx_count + ch->combined_count > fbd->max_num_queues ||
+ ch->other_count != FBNIC_NON_NAPI_VECTORS)
+ return -EINVAL;
+
+ if (!netif_running(netdev)) {
+ fbnic_set_queues(fbn, ch, max_napis);
+ fbnic_reset_indir_tbl(fbn);
+ return 0;
+ }
+
+ return -EBUSY;
+}
+
static int
fbnic_get_ts_info(struct net_device *netdev,
struct kernel_ethtool_ts_info *tsinfo)
@@ -417,6 +479,8 @@ static const struct ethtool_ops fbnic_ethtool_ops = {
.get_rxfh_indir_size = fbnic_get_rxfh_indir_size,
.get_rxfh = fbnic_get_rxfh,
.set_rxfh = fbnic_set_rxfh,
+ .get_channels = fbnic_get_channels,
+ .set_channels = fbnic_set_channels,
.get_ts_info = fbnic_get_ts_info,
.get_ts_stats = fbnic_get_ts_stats,
.get_eth_mac_stats = fbnic_get_eth_mac_stats,
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_rpc.c b/drivers/net/ethernet/meta/fbnic/fbnic_rpc.c
index b99c890ac43f..c25bd300b902 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_rpc.c
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_rpc.c
@@ -13,6 +13,9 @@ void fbnic_reset_indir_tbl(struct fbnic_net *fbn)
unsigned int num_rx = fbn->num_rx_queues;
unsigned int i;
+ if (netif_is_rxfh_configured(fbn->netdev))
+ return;
+
for (i = 0; i < FBNIC_RPC_RSS_TBL_SIZE; i++)
fbn->indir_tbl[0][i] = ethtool_rxfh_indir_default(i, num_rx);
}
--
2.47.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH net-next 10/10] eth: fbnic: support ring channel set while up
2024-12-20 2:52 [PATCH net-next 00/10] eth: fbnic: support basic RSS config and setting channel count Jakub Kicinski
` (8 preceding siblings ...)
2024-12-20 2:52 ` [PATCH net-next 09/10] eth: fbnic: support ring channel get and set while down Jakub Kicinski
@ 2024-12-20 2:52 ` Jakub Kicinski
2024-12-20 13:49 ` Przemek Kitszel
2024-12-23 18:50 ` [PATCH net-next 00/10] eth: fbnic: support basic RSS config and setting channel count patchwork-bot+netdevbpf
10 siblings, 1 reply; 20+ messages in thread
From: Jakub Kicinski @ 2024-12-20 2:52 UTC (permalink / raw)
To: davem; +Cc: netdev, edumazet, pabeni, Jakub Kicinski
Implement the channel count changes. Copy the netdev priv,
allocate new channels using it. Stop, swap, start.
Then free the copy of the priv along with the channels it
holds, which are now the channels that used to be on the
real priv.
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
drivers/net/ethernet/meta/fbnic/fbnic.h | 1 +
.../net/ethernet/meta/fbnic/fbnic_ethtool.c | 121 +++++++++++++++++-
drivers/net/ethernet/meta/fbnic/fbnic_irq.c | 11 ++
.../net/ethernet/meta/fbnic/fbnic_netdev.h | 1 +
drivers/net/ethernet/meta/fbnic/fbnic_pci.c | 2 +-
drivers/net/ethernet/meta/fbnic/fbnic_txrx.c | 8 +-
drivers/net/ethernet/meta/fbnic/fbnic_txrx.h | 5 +
7 files changed, 143 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic.h b/drivers/net/ethernet/meta/fbnic/fbnic.h
index ed527209b30c..14751f16e125 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic.h
+++ b/drivers/net/ethernet/meta/fbnic/fbnic.h
@@ -162,6 +162,7 @@ int fbnic_napi_request_irq(struct fbnic_dev *fbd,
struct fbnic_napi_vector *nv);
void fbnic_napi_free_irq(struct fbnic_dev *fbd,
struct fbnic_napi_vector *nv);
+void fbnic_synchronize_irq(struct fbnic_dev *fbd, int nr);
int fbnic_request_irq(struct fbnic_dev *dev, int nr, irq_handler_t handler,
unsigned long flags, const char *name, void *data);
void fbnic_free_irq(struct fbnic_dev *dev, int nr, void *data);
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c b/drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c
index d2fe97ae6a71..20cd9f5f89e2 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c
@@ -65,6 +65,76 @@ static void fbnic_get_regs(struct net_device *netdev,
fbnic_csr_get_regs(fbn->fbd, data, ®s->version);
}
+static struct fbnic_net *fbnic_clone_create(struct fbnic_net *orig)
+{
+ struct fbnic_net *clone;
+
+ clone = kmemdup(orig, sizeof(*orig), GFP_KERNEL);
+ if (!clone)
+ return NULL;
+
+ memset(clone->tx, 0, sizeof(clone->tx));
+ memset(clone->rx, 0, sizeof(clone->rx));
+ memset(clone->napi, 0, sizeof(clone->napi));
+ return clone;
+}
+
+static void fbnic_clone_swap_cfg(struct fbnic_net *orig,
+ struct fbnic_net *clone)
+{
+ swap(clone->rcq_size, orig->rcq_size);
+ swap(clone->hpq_size, orig->hpq_size);
+ swap(clone->ppq_size, orig->ppq_size);
+ swap(clone->txq_size, orig->txq_size);
+ swap(clone->num_rx_queues, orig->num_rx_queues);
+ swap(clone->num_tx_queues, orig->num_tx_queues);
+ swap(clone->num_napi, orig->num_napi);
+}
+
+static void fbnic_aggregate_vector_counters(struct fbnic_net *fbn,
+ struct fbnic_napi_vector *nv)
+{
+ int i, j;
+
+ for (i = 0; i < nv->txt_count; i++) {
+ fbnic_aggregate_ring_tx_counters(fbn, &nv->qt[i].sub0);
+ fbnic_aggregate_ring_tx_counters(fbn, &nv->qt[i].sub1);
+ fbnic_aggregate_ring_tx_counters(fbn, &nv->qt[i].cmpl);
+ }
+
+ for (j = 0; j < nv->rxt_count; j++, i++) {
+ fbnic_aggregate_ring_rx_counters(fbn, &nv->qt[i].sub0);
+ fbnic_aggregate_ring_rx_counters(fbn, &nv->qt[i].sub1);
+ fbnic_aggregate_ring_rx_counters(fbn, &nv->qt[i].cmpl);
+ }
+}
+
+static void fbnic_clone_swap(struct fbnic_net *orig,
+ struct fbnic_net *clone)
+{
+ struct fbnic_dev *fbd = orig->fbd;
+ unsigned int i;
+
+ for (i = 0; i < max(clone->num_napi, orig->num_napi); i++)
+ fbnic_synchronize_irq(fbd, FBNIC_NON_NAPI_VECTORS + i);
+ for (i = 0; i < orig->num_napi; i++)
+ fbnic_aggregate_vector_counters(orig, orig->napi[i]);
+
+ fbnic_clone_swap_cfg(orig, clone);
+
+ for (i = 0; i < ARRAY_SIZE(orig->napi); i++)
+ swap(clone->napi[i], orig->napi[i]);
+ for (i = 0; i < ARRAY_SIZE(orig->tx); i++)
+ swap(clone->tx[i], orig->tx[i]);
+ for (i = 0; i < ARRAY_SIZE(orig->rx); i++)
+ swap(clone->rx[i], orig->rx[i]);
+}
+
+static void fbnic_clone_free(struct fbnic_net *clone)
+{
+ kfree(clone);
+}
+
static void fbnic_get_strings(struct net_device *dev, u32 sset, u8 *data)
{
int i;
@@ -342,6 +412,8 @@ static int fbnic_set_channels(struct net_device *netdev,
struct fbnic_net *fbn = netdev_priv(netdev);
unsigned int max_napis, standalone;
struct fbnic_dev *fbd = fbn->fbd;
+ struct fbnic_net *clone;
+ int err;
max_napis = fbd->num_irqs - FBNIC_NON_NAPI_VECTORS;
standalone = ch->rx_count + ch->tx_count;
@@ -363,7 +435,54 @@ static int fbnic_set_channels(struct net_device *netdev,
return 0;
}
- return -EBUSY;
+ clone = fbnic_clone_create(fbn);
+ if (!clone)
+ return -ENOMEM;
+
+ fbnic_set_queues(clone, ch, max_napis);
+
+ err = fbnic_alloc_napi_vectors(clone);
+ if (err)
+ goto err_free_clone;
+
+ err = fbnic_alloc_resources(clone);
+ if (err)
+ goto err_free_napis;
+
+ fbnic_down_noidle(fbn);
+ err = fbnic_wait_all_queues_idle(fbn->fbd, true);
+ if (err)
+ goto err_start_stack;
+
+ err = fbnic_set_netif_queues(clone);
+ if (err)
+ goto err_start_stack;
+
+ /* Nothing can fail past this point */
+ fbnic_flush(fbn);
+
+ fbnic_clone_swap(fbn, clone);
+
+ /* Reset RSS indirection table */
+ fbnic_reset_indir_tbl(fbn);
+
+ fbnic_up(fbn);
+
+ fbnic_free_resources(clone);
+ fbnic_free_napi_vectors(clone);
+ fbnic_clone_free(clone);
+
+ return 0;
+
+err_start_stack:
+ fbnic_flush(fbn);
+ fbnic_up(fbn);
+ fbnic_free_resources(clone);
+err_free_napis:
+ fbnic_free_napi_vectors(clone);
+err_free_clone:
+ fbnic_clone_free(clone);
+ return err;
}
static int
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_irq.c b/drivers/net/ethernet/meta/fbnic/fbnic_irq.c
index a8ea7b6774a8..1bbc0e56f3a0 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_irq.c
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_irq.c
@@ -146,6 +146,17 @@ void fbnic_pcs_irq_disable(struct fbnic_dev *fbd)
free_irq(fbd->pcs_msix_vector, fbd);
}
+void fbnic_synchronize_irq(struct fbnic_dev *fbd, int nr)
+{
+ struct pci_dev *pdev = to_pci_dev(fbd->dev);
+ int irq = pci_irq_vector(pdev, nr);
+
+ if (irq < 0)
+ return;
+
+ synchronize_irq(irq);
+}
+
int fbnic_request_irq(struct fbnic_dev *fbd, int nr, irq_handler_t handler,
unsigned long flags, const char *name, void *data)
{
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_netdev.h b/drivers/net/ethernet/meta/fbnic/fbnic_netdev.h
index 0986c8f120a8..a392ac1cc4f2 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_netdev.h
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_netdev.h
@@ -65,6 +65,7 @@ struct fbnic_net {
int __fbnic_open(struct fbnic_net *fbn);
void fbnic_up(struct fbnic_net *fbn);
void fbnic_down(struct fbnic_net *fbn);
+void fbnic_down_noidle(struct fbnic_net *fbn);
struct net_device *fbnic_netdev_alloc(struct fbnic_dev *fbd);
void fbnic_netdev_free(struct fbnic_dev *fbd);
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_pci.c b/drivers/net/ethernet/meta/fbnic/fbnic_pci.c
index 32702dc4a066..6cbbc2ee3e1f 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_pci.c
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_pci.c
@@ -145,7 +145,7 @@ void fbnic_up(struct fbnic_net *fbn)
fbnic_service_task_start(fbn);
}
-static void fbnic_down_noidle(struct fbnic_net *fbn)
+void fbnic_down_noidle(struct fbnic_net *fbn)
{
fbnic_service_task_stop(fbn);
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_txrx.c b/drivers/net/ethernet/meta/fbnic/fbnic_txrx.c
index 92fc1ad6ed6f..bb54ce5f5787 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_txrx.c
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_txrx.c
@@ -1045,8 +1045,8 @@ irqreturn_t fbnic_msix_clean_rings(int __always_unused irq, void *data)
return IRQ_HANDLED;
}
-static void fbnic_aggregate_ring_rx_counters(struct fbnic_net *fbn,
- struct fbnic_ring *rxr)
+void fbnic_aggregate_ring_rx_counters(struct fbnic_net *fbn,
+ struct fbnic_ring *rxr)
{
struct fbnic_queue_stats *stats = &rxr->stats;
@@ -1056,8 +1056,8 @@ static void fbnic_aggregate_ring_rx_counters(struct fbnic_net *fbn,
fbn->rx_stats.dropped += stats->dropped;
}
-static void fbnic_aggregate_ring_tx_counters(struct fbnic_net *fbn,
- struct fbnic_ring *txr)
+void fbnic_aggregate_ring_tx_counters(struct fbnic_net *fbn,
+ struct fbnic_ring *txr)
{
struct fbnic_queue_stats *stats = &txr->stats;
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_txrx.h b/drivers/net/ethernet/meta/fbnic/fbnic_txrx.h
index 92c671135ad7..c2a94f31f71b 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_txrx.h
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_txrx.h
@@ -120,6 +120,11 @@ netdev_features_t
fbnic_features_check(struct sk_buff *skb, struct net_device *dev,
netdev_features_t features);
+void fbnic_aggregate_ring_rx_counters(struct fbnic_net *fbn,
+ struct fbnic_ring *rxr);
+void fbnic_aggregate_ring_tx_counters(struct fbnic_net *fbn,
+ struct fbnic_ring *txr);
+
int fbnic_alloc_napi_vectors(struct fbnic_net *fbn);
void fbnic_free_napi_vectors(struct fbnic_net *fbn);
int fbnic_alloc_resources(struct fbnic_net *fbn);
--
2.47.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* Re: [PATCH net-next 02/10] eth: fbnic: support querying RSS config
2024-12-20 2:52 ` [PATCH net-next 02/10] eth: fbnic: support querying RSS config Jakub Kicinski
@ 2024-12-20 11:42 ` Przemek Kitszel
2024-12-20 14:08 ` Jakub Kicinski
0 siblings, 1 reply; 20+ messages in thread
From: Przemek Kitszel @ 2024-12-20 11:42 UTC (permalink / raw)
To: Jakub Kicinski, Alexander Duyck; +Cc: netdev, edumazet, davem, pabeni
On 12/20/24 03:52, Jakub Kicinski wrote:
> From: Alexander Duyck <alexanderduyck@fb.com>
>
> The initial driver submission already added all the RSS state,
> as part of multi-queue support. Expose the configuration via
> the ethtool APIs.
>
> Signed-off-by: Alexander Duyck <alexanderduyck@fb.com>
> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
> ---
> .../net/ethernet/meta/fbnic/fbnic_ethtool.c | 103 ++++++++++++++++++
> 1 file changed, 103 insertions(+)
>
> +static int
> +fbnic_get_rxfh(struct net_device *netdev, struct ethtool_rxfh_param *rxfh)
> +{
> + struct fbnic_net *fbn = netdev_priv(netdev);
> + unsigned int i;
AFAIK index type should be spelled as u32
And will be best declared in the first clause of the for()
> +
> + rxfh->hfunc = ETH_RSS_HASH_TOP;
> +
> + if (rxfh->key) {
> + for (i = 0; i < FBNIC_RPC_RSS_KEY_BYTE_LEN; i++) {
> + u32 rss_key = fbn->rss_key[i / 4] << ((i % 4) * 8);
are you dropping 75% of entropy provided in fbn->rss_key?
> +
> + rxfh->key[i] = rss_key >> 24;
> + }
> + }
> +
> + if (rxfh->indir) {
> + for (i = 0; i < FBNIC_RPC_RSS_TBL_SIZE; i++)
> + rxfh->indir[i] = fbn->indir_tbl[0][i];
> + }
> +
> + return 0;
> +}
> +
> static int
> fbnic_get_ts_info(struct net_device *netdev,
> struct kernel_ethtool_ts_info *tsinfo)
> @@ -209,6 +308,10 @@ static const struct ethtool_ops fbnic_ethtool_ops = {
> .get_strings = fbnic_get_strings,
> .get_ethtool_stats = fbnic_get_ethtool_stats,
> .get_sset_count = fbnic_get_sset_count,
> + .get_rxnfc = fbnic_get_rxnfc,
> + .get_rxfh_key_size = fbnic_get_rxfh_key_size,
> + .get_rxfh_indir_size = fbnic_get_rxfh_indir_size,
> + .get_rxfh = fbnic_get_rxfh,
> .get_ts_info = fbnic_get_ts_info,
> .get_ts_stats = fbnic_get_ts_stats,
> .get_eth_mac_stats = fbnic_get_eth_mac_stats,
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH net-next 10/10] eth: fbnic: support ring channel set while up
2024-12-20 2:52 ` [PATCH net-next 10/10] eth: fbnic: support ring channel set while up Jakub Kicinski
@ 2024-12-20 13:49 ` Przemek Kitszel
2024-12-20 14:10 ` Jakub Kicinski
0 siblings, 1 reply; 20+ messages in thread
From: Przemek Kitszel @ 2024-12-20 13:49 UTC (permalink / raw)
To: Jakub Kicinski; +Cc: netdev, edumazet, pabeni, davem
On 12/20/24 03:52, Jakub Kicinski wrote:
> Implement the channel count changes. Copy the netdev priv,
> allocate new channels using it. Stop, swap, start.
> Then free the copy of the priv along with the channels it
> holds, which are now the channels that used to be on the
> real priv.
>
> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
> ---
> drivers/net/ethernet/meta/fbnic/fbnic.h | 1 +
> .../net/ethernet/meta/fbnic/fbnic_ethtool.c | 121 +++++++++++++++++-
> drivers/net/ethernet/meta/fbnic/fbnic_irq.c | 11 ++
> .../net/ethernet/meta/fbnic/fbnic_netdev.h | 1 +
> drivers/net/ethernet/meta/fbnic/fbnic_pci.c | 2 +-
> drivers/net/ethernet/meta/fbnic/fbnic_txrx.c | 8 +-
> drivers/net/ethernet/meta/fbnic/fbnic_txrx.h | 5 +
> 7 files changed, 143 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/net/ethernet/meta/fbnic/fbnic.h b/drivers/net/ethernet/meta/fbnic/fbnic.h
Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
very nice, refreshing and inspirational design
> +static struct fbnic_net *fbnic_clone_create(struct fbnic_net *orig)
> +{
> + struct fbnic_net *clone;
> +
> + clone = kmemdup(orig, sizeof(*orig), GFP_KERNEL);
> + if (!clone)
> + return NULL;
> +
> + memset(clone->tx, 0, sizeof(clone->tx));
> + memset(clone->rx, 0, sizeof(clone->rx));
> + memset(clone->napi, 0, sizeof(clone->napi));
> + return clone;
> +}
> +
> +static void fbnic_clone_swap_cfg(struct fbnic_net *orig,
> + struct fbnic_net *clone)
> +{
> + swap(clone->rcq_size, orig->rcq_size);
> + swap(clone->hpq_size, orig->hpq_size);
> + swap(clone->ppq_size, orig->ppq_size);
> + swap(clone->txq_size, orig->txq_size);
> + swap(clone->num_rx_queues, orig->num_rx_queues);
> + swap(clone->num_tx_queues, orig->num_tx_queues);
> + swap(clone->num_napi, orig->num_napi);
> +}
> +static void fbnic_clone_swap(struct fbnic_net *orig,
> + struct fbnic_net *clone)
> +{
> + struct fbnic_dev *fbd = orig->fbd;
> + unsigned int i;
> +
> + for (i = 0; i < max(clone->num_napi, orig->num_napi); i++)
> + fbnic_synchronize_irq(fbd, FBNIC_NON_NAPI_VECTORS + i);
> + for (i = 0; i < orig->num_napi; i++)
> + fbnic_aggregate_vector_counters(orig, orig->napi[i]);
> +
> + fbnic_clone_swap_cfg(orig, clone);
> +
> + for (i = 0; i < ARRAY_SIZE(orig->napi); i++)
> + swap(clone->napi[i], orig->napi[i]);
> + for (i = 0; i < ARRAY_SIZE(orig->tx); i++)
> + swap(clone->tx[i], orig->tx[i]);
> + for (i = 0; i < ARRAY_SIZE(orig->rx); i++)
> + swap(clone->rx[i], orig->rx[i]);
I would perhaps move the above 6 lines to fbnic_clone_swap_cfg()
> +}
> +
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH net-next 02/10] eth: fbnic: support querying RSS config
2024-12-20 11:42 ` Przemek Kitszel
@ 2024-12-20 14:08 ` Jakub Kicinski
2024-12-20 14:23 ` Przemek Kitszel
0 siblings, 1 reply; 20+ messages in thread
From: Jakub Kicinski @ 2024-12-20 14:08 UTC (permalink / raw)
To: Przemek Kitszel; +Cc: Alexander Duyck, netdev, edumazet, davem, pabeni
On Fri, 20 Dec 2024 12:42:42 +0100 Przemek Kitszel wrote:
> > +static int
> > +fbnic_get_rxfh(struct net_device *netdev, struct ethtool_rxfh_param *rxfh)
> > +{
> > + struct fbnic_net *fbn = netdev_priv(netdev);
> > + unsigned int i;
>
> AFAIK index type should be spelled as u32
Does it matter? I have a weak preference for not using explicitly sized
types unless the bit width is itself meaningful.
> And will be best declared in the first clause of the for()
I don't see woohaii.
> > +
> > + rxfh->hfunc = ETH_RSS_HASH_TOP;
> > +
> > + if (rxfh->key) {
> > + for (i = 0; i < FBNIC_RPC_RSS_KEY_BYTE_LEN; i++) {
> > + u32 rss_key = fbn->rss_key[i / 4] << ((i % 4) * 8);
>
> are you dropping 75% of entropy provided in fbn->rss_key?
Nope, it's shifting out the unused bits. And below we shift back
down to the lowest byte.
We store the key as u32 (register width) while the uAPI is in u8.
> > +
> > + rxfh->key[i] = rss_key >> 24;
> > + }
> > + }
> > +
> > + if (rxfh->indir) {
> > + for (i = 0; i < FBNIC_RPC_RSS_TBL_SIZE; i++)
> > + rxfh->indir[i] = fbn->indir_tbl[0][i];
> > + }
> > +
> > + return 0;
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH net-next 10/10] eth: fbnic: support ring channel set while up
2024-12-20 13:49 ` Przemek Kitszel
@ 2024-12-20 14:10 ` Jakub Kicinski
2024-12-20 15:02 ` Przemek Kitszel
0 siblings, 1 reply; 20+ messages in thread
From: Jakub Kicinski @ 2024-12-20 14:10 UTC (permalink / raw)
To: Przemek Kitszel; +Cc: netdev, edumazet, pabeni, davem
On Fri, 20 Dec 2024 14:49:02 +0100 Przemek Kitszel wrote:
> > + fbnic_clone_swap_cfg(orig, clone);
> > +
> > + for (i = 0; i < ARRAY_SIZE(orig->napi); i++)
> > + swap(clone->napi[i], orig->napi[i]);
> > + for (i = 0; i < ARRAY_SIZE(orig->tx); i++)
> > + swap(clone->tx[i], orig->tx[i]);
> > + for (i = 0; i < ARRAY_SIZE(orig->rx); i++)
> > + swap(clone->rx[i], orig->rx[i]);
>
> I would perhaps move the above 6 lines to fbnic_clone_swap_cfg()
Hm, it's here because of how we implemented ringparam changes.
They reuse some of the clone stuff but not all. Can we revisit
once that's sent?
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH net-next 02/10] eth: fbnic: support querying RSS config
2024-12-20 14:08 ` Jakub Kicinski
@ 2024-12-20 14:23 ` Przemek Kitszel
0 siblings, 0 replies; 20+ messages in thread
From: Przemek Kitszel @ 2024-12-20 14:23 UTC (permalink / raw)
To: Jakub Kicinski; +Cc: Alexander Duyck, netdev, edumazet, davem, pabeni
On 12/20/24 15:08, Jakub Kicinski wrote:
> On Fri, 20 Dec 2024 12:42:42 +0100 Przemek Kitszel wrote:
with [1] this patch looks good to me, thank you for explanation:
Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
the rest of the series is also fine for me, but I didn't spend that
much time to inflate my RB count
>>> +static int
>>> +fbnic_get_rxfh(struct net_device *netdev, struct ethtool_rxfh_param *rxfh)
>>> +{
>>> + struct fbnic_net *fbn = netdev_priv(netdev);
>>> + unsigned int i;
>>
>> AFAIK index type should be spelled as u32
>
> Does it matter? I have a weak preference for not using explicitly sized
> types unless the bit width is itself meaningful.
me too, unless it is "unsiged int", but I', not gonna fight for it
I would say that plain int is fine for iterator unless you want to
explicitly get the non-UB wrap-around (or count more than 31 bit wide).
But again, does not matter
>
>> And will be best declared in the first clause of the for()
>
> I don't see woohaii.
with such long to type types, it would be inconvenient, but the usual
argument about the proper scope of the variable
>
>>> +
>>> + rxfh->hfunc = ETH_RSS_HASH_TOP;
>>> +
>>> + if (rxfh->key) {
>>> + for (i = 0; i < FBNIC_RPC_RSS_KEY_BYTE_LEN; i++) {
>>> + u32 rss_key = fbn->rss_key[i / 4] << ((i % 4) * 8);
>>
>> are you dropping 75% of entropy provided in fbn->rss_key?
>
> Nope, it's shifting out the unused bits. And below we shift back
> down to the lowest byte.
> We store the key as u32 (register width) while the uAPI is in u8.
[1]
OK, I've double checked and the fbn->rss_key array has indeed
FBNIC_RPC_RSS_KEY_BYTE_LEN/4 entries
>
>>> +
>>> + rxfh->key[i] = rss_key >> 24;
>>> + }
>>> + }
>>> +
>>> + if (rxfh->indir) {
>>> + for (i = 0; i < FBNIC_RPC_RSS_TBL_SIZE; i++)
>>> + rxfh->indir[i] = fbn->indir_tbl[0][i];
>>> + }
>>> +
>>> + return 0;
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH net-next 01/10] eth: fbnic: reorder ethtool code
2024-12-20 2:52 ` [PATCH net-next 01/10] eth: fbnic: reorder ethtool code Jakub Kicinski
@ 2024-12-20 14:53 ` Larysa Zaremba
2024-12-20 17:38 ` Jakub Kicinski
0 siblings, 1 reply; 20+ messages in thread
From: Larysa Zaremba @ 2024-12-20 14:53 UTC (permalink / raw)
To: Jakub Kicinski; +Cc: davem, netdev, edumazet, pabeni
On Thu, Dec 19, 2024 at 06:52:32PM -0800, Jakub Kicinski wrote:
> Define ethtool callback handlers in order in which they are defined
> in the ops struct. It doesn't really matter what the order is,
> but it's good to have an order.
>
> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
> ---
> .../net/ethernet/meta/fbnic/fbnic_ethtool.c | 160 +++++++++---------
> 1 file changed, 80 insertions(+), 80 deletions(-)
>
> diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c b/drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c
> index cc8ca94529ca..777e083acae9 100644
> --- a/drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c
> +++ b/drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c
> @@ -40,6 +40,68 @@ static const struct fbnic_stat fbnic_gstrings_hw_stats[] = {
> #define FBNIC_HW_FIXED_STATS_LEN ARRAY_SIZE(fbnic_gstrings_hw_stats)
> #define FBNIC_HW_STATS_LEN FBNIC_HW_FIXED_STATS_LEN
>
> +static void
I thought type and name on separate lines are not desirable, it could be moved
to a single line in this commit. Assuming such adjustment,
Reviewed-by: Larysa Zaremba <larysa.zaremba@intel.com>
Also, this would be a little bit out of scope for this commit, but seeing
relatively new code that does not use `for (int i = 0,...)` is surprising.
> +fbnic_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo)
> +{
> + struct fbnic_net *fbn = netdev_priv(netdev);
> + struct fbnic_dev *fbd = fbn->fbd;
> +
> + fbnic_get_fw_ver_commit_str(fbd, drvinfo->fw_version,
> + sizeof(drvinfo->fw_version));
> +}
> +
> +static int fbnic_get_regs_len(struct net_device *netdev)
> +{
> + struct fbnic_net *fbn = netdev_priv(netdev);
> +
> + return fbnic_csr_regs_len(fbn->fbd) * sizeof(u32);
> +}
> +
> +static void fbnic_get_regs(struct net_device *netdev,
> + struct ethtool_regs *regs, void *data)
> +{
> + struct fbnic_net *fbn = netdev_priv(netdev);
> +
> + fbnic_csr_get_regs(fbn->fbd, data, ®s->version);
> +}
> +
> +static void fbnic_get_strings(struct net_device *dev, u32 sset, u8 *data)
> +{
> + int i;
> +
> + switch (sset) {
> + case ETH_SS_STATS:
> + for (i = 0; i < FBNIC_HW_STATS_LEN; i++)
> + ethtool_puts(&data, fbnic_gstrings_hw_stats[i].string);
> + break;
> + }
> +}
> +
> +static void fbnic_get_ethtool_stats(struct net_device *dev,
> + struct ethtool_stats *stats, u64 *data)
> +{
> + struct fbnic_net *fbn = netdev_priv(dev);
> + const struct fbnic_stat *stat;
> + int i;
> +
> + fbnic_get_hw_stats(fbn->fbd);
> +
> + for (i = 0; i < FBNIC_HW_STATS_LEN; i++) {
> + stat = &fbnic_gstrings_hw_stats[i];
> + data[i] = *(u64 *)((u8 *)&fbn->fbd->hw_stats + stat->offset);
> + }
> +}
> +
> +static int fbnic_get_sset_count(struct net_device *dev, int sset)
> +{
> + switch (sset) {
> + case ETH_SS_STATS:
> + return FBNIC_HW_STATS_LEN;
> + default:
> + return -EOPNOTSUPP;
> + }
> +}
> +
> static int
> fbnic_get_ts_info(struct net_device *netdev,
> struct kernel_ethtool_ts_info *tsinfo)
> @@ -69,14 +131,27 @@ fbnic_get_ts_info(struct net_device *netdev,
> return 0;
> }
>
> -static void
> -fbnic_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo)
> +static void fbnic_get_ts_stats(struct net_device *netdev,
> + struct ethtool_ts_stats *ts_stats)
> {
> struct fbnic_net *fbn = netdev_priv(netdev);
> - struct fbnic_dev *fbd = fbn->fbd;
> + u64 ts_packets, ts_lost;
> + struct fbnic_ring *ring;
> + unsigned int start;
> + int i;
>
> - fbnic_get_fw_ver_commit_str(fbd, drvinfo->fw_version,
> - sizeof(drvinfo->fw_version));
> + ts_stats->pkts = fbn->tx_stats.ts_packets;
> + ts_stats->lost = fbn->tx_stats.ts_lost;
> + for (i = 0; i < fbn->num_tx_queues; i++) {
> + ring = fbn->tx[i];
> + do {
> + start = u64_stats_fetch_begin(&ring->stats.syncp);
> + ts_packets = ring->stats.ts_packets;
> + ts_lost = ring->stats.ts_lost;
> + } while (u64_stats_fetch_retry(&ring->stats.syncp, start));
> + ts_stats->pkts += ts_packets;
> + ts_stats->lost += ts_lost;
> + }
> }
>
> static void fbnic_set_counter(u64 *stat, struct fbnic_stat_counter *counter)
> @@ -85,43 +160,6 @@ static void fbnic_set_counter(u64 *stat, struct fbnic_stat_counter *counter)
> *stat = counter->value;
> }
>
> -static void fbnic_get_strings(struct net_device *dev, u32 sset, u8 *data)
> -{
> - int i;
> -
> - switch (sset) {
> - case ETH_SS_STATS:
> - for (i = 0; i < FBNIC_HW_STATS_LEN; i++)
> - ethtool_puts(&data, fbnic_gstrings_hw_stats[i].string);
> - break;
> - }
> -}
> -
> -static int fbnic_get_sset_count(struct net_device *dev, int sset)
> -{
> - switch (sset) {
> - case ETH_SS_STATS:
> - return FBNIC_HW_STATS_LEN;
> - default:
> - return -EOPNOTSUPP;
> - }
> -}
> -
> -static void fbnic_get_ethtool_stats(struct net_device *dev,
> - struct ethtool_stats *stats, u64 *data)
> -{
> - struct fbnic_net *fbn = netdev_priv(dev);
> - const struct fbnic_stat *stat;
> - int i;
> -
> - fbnic_get_hw_stats(fbn->fbd);
> -
> - for (i = 0; i < FBNIC_HW_STATS_LEN; i++) {
> - stat = &fbnic_gstrings_hw_stats[i];
> - data[i] = *(u64 *)((u8 *)&fbn->fbd->hw_stats + stat->offset);
> - }
> -}
> -
> static void
> fbnic_get_eth_mac_stats(struct net_device *netdev,
> struct ethtool_eth_mac_stats *eth_mac_stats)
> @@ -164,44 +202,6 @@ fbnic_get_eth_mac_stats(struct net_device *netdev,
> &mac_stats->eth_mac.FrameTooLongErrors);
> }
>
> -static void fbnic_get_ts_stats(struct net_device *netdev,
> - struct ethtool_ts_stats *ts_stats)
> -{
> - struct fbnic_net *fbn = netdev_priv(netdev);
> - u64 ts_packets, ts_lost;
> - struct fbnic_ring *ring;
> - unsigned int start;
> - int i;
> -
> - ts_stats->pkts = fbn->tx_stats.ts_packets;
> - ts_stats->lost = fbn->tx_stats.ts_lost;
> - for (i = 0; i < fbn->num_tx_queues; i++) {
> - ring = fbn->tx[i];
> - do {
> - start = u64_stats_fetch_begin(&ring->stats.syncp);
> - ts_packets = ring->stats.ts_packets;
> - ts_lost = ring->stats.ts_lost;
> - } while (u64_stats_fetch_retry(&ring->stats.syncp, start));
> - ts_stats->pkts += ts_packets;
> - ts_stats->lost += ts_lost;
> - }
> -}
> -
> -static void fbnic_get_regs(struct net_device *netdev,
> - struct ethtool_regs *regs, void *data)
> -{
> - struct fbnic_net *fbn = netdev_priv(netdev);
> -
> - fbnic_csr_get_regs(fbn->fbd, data, ®s->version);
> -}
> -
> -static int fbnic_get_regs_len(struct net_device *netdev)
> -{
> - struct fbnic_net *fbn = netdev_priv(netdev);
> -
> - return fbnic_csr_regs_len(fbn->fbd) * sizeof(u32);
> -}
> -
> static const struct ethtool_ops fbnic_ethtool_ops = {
> .get_drvinfo = fbnic_get_drvinfo,
> .get_regs_len = fbnic_get_regs_len,
> --
> 2.47.1
>
>
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH net-next 10/10] eth: fbnic: support ring channel set while up
2024-12-20 14:10 ` Jakub Kicinski
@ 2024-12-20 15:02 ` Przemek Kitszel
0 siblings, 0 replies; 20+ messages in thread
From: Przemek Kitszel @ 2024-12-20 15:02 UTC (permalink / raw)
To: Jakub Kicinski; +Cc: netdev, edumazet, pabeni, davem
On 12/20/24 15:10, Jakub Kicinski wrote:
> On Fri, 20 Dec 2024 14:49:02 +0100 Przemek Kitszel wrote:
>>> + fbnic_clone_swap_cfg(orig, clone);
>>> +
>>> + for (i = 0; i < ARRAY_SIZE(orig->napi); i++)
>>> + swap(clone->napi[i], orig->napi[i]);
>>> + for (i = 0; i < ARRAY_SIZE(orig->tx); i++)
>>> + swap(clone->tx[i], orig->tx[i]);
>>> + for (i = 0; i < ARRAY_SIZE(orig->rx); i++)
>>> + swap(clone->rx[i], orig->rx[i]);
>>
>> I would perhaps move the above 6 lines to fbnic_clone_swap_cfg()
>
> Hm, it's here because of how we implemented ringparam changes.
> They reuse some of the clone stuff but not all. Can we revisit
> once that's sent?
This could stay as is here, it's in the fbnic_clone_swap() so does also
belong.
The "would+perhaps" + my RB tag meant that I'm fine as-is with this :)
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH net-next 01/10] eth: fbnic: reorder ethtool code
2024-12-20 14:53 ` Larysa Zaremba
@ 2024-12-20 17:38 ` Jakub Kicinski
0 siblings, 0 replies; 20+ messages in thread
From: Jakub Kicinski @ 2024-12-20 17:38 UTC (permalink / raw)
To: Larysa Zaremba; +Cc: davem, netdev, edumazet, pabeni
On Fri, 20 Dec 2024 15:53:18 +0100 Larysa Zaremba wrote:
> I thought type and name on separate lines are not desirable, it could be moved
> to a single line in this commit. Assuming such adjustment,
I find this style more readable, TBH. I tend to break the line after
return type if the function declaration doesn't fit on a line and the
type is longer than 3 chars (IOW int/u32/u8 are exceptions).
Functions which end up looking like:
static struct some_type_struct *some_function_name_here(struct another *ptr,
int argument);
are really ugly. And break if > 3 chars is a simple rule to follow.
You will find that most of fbnic does not follow this style, because
I didn't write most of it. But most of the nfp driver does.
I think I learned the breaking after return type from Felix Fietkau.
Not that he specified the 3 character thing as pedantically as I do.
> Reviewed-by: Larysa Zaremba <larysa.zaremba@intel.com>
>
> Also, this would be a little bit out of scope for this commit, but seeing
> relatively new code that does not use `for (int i = 0,...)` is surprising.
I think you at Intel try to adopt the novelties much more than the rest of us.
Let us old timers be, please.
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH net-next 00/10] eth: fbnic: support basic RSS config and setting channel count
2024-12-20 2:52 [PATCH net-next 00/10] eth: fbnic: support basic RSS config and setting channel count Jakub Kicinski
` (9 preceding siblings ...)
2024-12-20 2:52 ` [PATCH net-next 10/10] eth: fbnic: support ring channel set while up Jakub Kicinski
@ 2024-12-23 18:50 ` patchwork-bot+netdevbpf
10 siblings, 0 replies; 20+ messages in thread
From: patchwork-bot+netdevbpf @ 2024-12-23 18:50 UTC (permalink / raw)
To: Jakub Kicinski; +Cc: davem, netdev, edumazet, pabeni
Hello:
This series was applied to netdev/net-next.git (main)
by Jakub Kicinski <kuba@kernel.org>:
On Thu, 19 Dec 2024 18:52:31 -0800 you wrote:
> Add support for basic RSS config (indirection table, key get and set),
> and changing the number of channels.
>
> # ./ksft-net-drv/run_kselftest.sh -t drivers/net/hw:rss_ctx.py
> TAP version 13
> 1..1
> # timeout set to 0
> # selftests: drivers/net/hw: rss_ctx.py
> # KTAP version 1
> # 1..15
> # ok 1 rss_ctx.test_rss_key_indir
> # ok 2 rss_ctx.test_rss_queue_reconfigure
> # ok 3 rss_ctx.test_rss_resize
> # ok 4 rss_ctx.test_hitless_key_update
>
> [...]
Here is the summary with links:
- [net-next,01/10] eth: fbnic: reorder ethtool code
https://git.kernel.org/netdev/net-next/c/7d0bf493b135
- [net-next,02/10] eth: fbnic: support querying RSS config
https://git.kernel.org/netdev/net-next/c/7cb06a6a777c
- [net-next,03/10] eth: fbnic: don't reset the secondary RSS indir table
https://git.kernel.org/netdev/net-next/c/ef1c28817bf9
- [net-next,04/10] eth: fbnic: support setting RSS configuration
https://git.kernel.org/netdev/net-next/c/31ab733e999e
- [net-next,05/10] eth: fbnic: let user control the RSS hash fields
https://git.kernel.org/netdev/net-next/c/c23a1461bfee
- [net-next,06/10] eth: fbnic: store NAPIs in an array instead of the list
https://git.kernel.org/netdev/net-next/c/db7159c400ff
- [net-next,07/10] eth: fbnic: add IRQ reuse support
https://git.kernel.org/netdev/net-next/c/3a856ab34726
- [net-next,08/10] eth: fbnic: centralize the queue count and NAPI<>queue setting
https://git.kernel.org/netdev/net-next/c/557d02238e05
- [net-next,09/10] eth: fbnic: support ring channel get and set while down
https://git.kernel.org/netdev/net-next/c/3a481cc72673
- [net-next,10/10] eth: fbnic: support ring channel set while up
https://git.kernel.org/netdev/net-next/c/52dc722db0d9
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply [flat|nested] 20+ messages in thread
end of thread, other threads:[~2024-12-23 18:50 UTC | newest]
Thread overview: 20+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-12-20 2:52 [PATCH net-next 00/10] eth: fbnic: support basic RSS config and setting channel count Jakub Kicinski
2024-12-20 2:52 ` [PATCH net-next 01/10] eth: fbnic: reorder ethtool code Jakub Kicinski
2024-12-20 14:53 ` Larysa Zaremba
2024-12-20 17:38 ` Jakub Kicinski
2024-12-20 2:52 ` [PATCH net-next 02/10] eth: fbnic: support querying RSS config Jakub Kicinski
2024-12-20 11:42 ` Przemek Kitszel
2024-12-20 14:08 ` Jakub Kicinski
2024-12-20 14:23 ` Przemek Kitszel
2024-12-20 2:52 ` [PATCH net-next 03/10] eth: fbnic: don't reset the secondary RSS indir table Jakub Kicinski
2024-12-20 2:52 ` [PATCH net-next 04/10] eth: fbnic: support setting RSS configuration Jakub Kicinski
2024-12-20 2:52 ` [PATCH net-next 05/10] eth: fbnic: let user control the RSS hash fields Jakub Kicinski
2024-12-20 2:52 ` [PATCH net-next 06/10] eth: fbnic: store NAPIs in an array instead of the list Jakub Kicinski
2024-12-20 2:52 ` [PATCH net-next 07/10] eth: fbnic: add IRQ reuse support Jakub Kicinski
2024-12-20 2:52 ` [PATCH net-next 08/10] eth: fbnic: centralize the queue count and NAPI<>queue setting Jakub Kicinski
2024-12-20 2:52 ` [PATCH net-next 09/10] eth: fbnic: support ring channel get and set while down Jakub Kicinski
2024-12-20 2:52 ` [PATCH net-next 10/10] eth: fbnic: support ring channel set while up Jakub Kicinski
2024-12-20 13:49 ` Przemek Kitszel
2024-12-20 14:10 ` Jakub Kicinski
2024-12-20 15:02 ` Przemek Kitszel
2024-12-23 18:50 ` [PATCH net-next 00/10] eth: fbnic: support basic RSS config and setting channel count patchwork-bot+netdevbpf
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).