From: Vikas Gupta <vikas.gupta@broadcom.com>
To: davem@davemloft.net, edumazet@google.com, kuba@kernel.org,
pabeni@redhat.com, andrew+netdev@lunn.ch, horms@kernel.org
Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
bhargava.marreddy@broadcom.com, rahul-rg.gupta@broadcom.com,
vsrama-krishna.nemani@broadcom.com,
rajashekar.hudumula@broadcom.com, dharmender.garg@broadcom.com,
ajit.khaparde@broadcom.com,
Vikas Gupta <vikas.gupta@broadcom.com>
Subject: [net-next, v2 10/11] bnge: add aRFS flow steering ndo support
Date: Tue, 8 Sep 2026 15:00:52 +0530 [thread overview]
Message-ID: <20260908093053.2596020-11-vikas.gupta@broadcom.com> (raw)
In-Reply-To: <20260908093053.2596020-1-vikas.gupta@broadcom.com>
Introduce the ndo_rx_flow_steer callback (bnge_rx_flow_steer) to
support aRFS.
This callback creates an NTUPLE filter that steers matching packets
to the appropriate RX queue. The implementation dissects flow keys
from the SKB, creates an NTUPLE filter with the associated L2 filter,
inserts it into the NTUPLE hash table, and schedules the sp_task
workqueue via BNGE_RX_NTP_FLTR_SP_EVENT to program the filter
in the firmware.
Add bnge_cfg_ntp_filters() called from the periodic timer via sp_task
to handle deferred filter programming and expiration via
rps_may_expire_flow().
Signed-off-by: Vikas Gupta <vikas.gupta@broadcom.com>
Reviewed-by: Dharmender Garg <dharmender.garg@broadcom.com>
Signed-off-by: Vikas Gupta <vikas.gupta@broadcom.com>
---
.../net/ethernet/broadcom/bnge/bnge_filter.c | 45 ++++++++
.../net/ethernet/broadcom/bnge/bnge_filter.h | 1 +
.../net/ethernet/broadcom/bnge/bnge_netdev.c | 102 ++++++++++++++++++
.../net/ethernet/broadcom/bnge/bnge_netdev.h | 1 +
4 files changed, 149 insertions(+)
diff --git a/drivers/net/ethernet/broadcom/bnge/bnge_filter.c b/drivers/net/ethernet/broadcom/bnge/bnge_filter.c
index 9da3c976cf3a..a7844f364994 100644
--- a/drivers/net/ethernet/broadcom/bnge/bnge_filter.c
+++ b/drivers/net/ethernet/broadcom/bnge/bnge_filter.c
@@ -621,3 +621,48 @@ void bnge_clear_usr_fltrs(struct bnge_net *bn)
}
}
}
+
+void bnge_cfg_ntp_filters(struct bnge_net *bn)
+{
+#ifdef CONFIG_RFS_ACCEL
+ struct bnge_ntuple_filter *fltr, *tmp;
+ LIST_HEAD(install_list);
+ LIST_HEAD(expire_list);
+ int i, rc;
+
+ rcu_read_lock();
+ for (i = 0; i < BNGE_NTP_FLTR_HASH_SIZE; i++) {
+ hlist_for_each_entry_rcu(fltr, &bn->ntp_fltr_hash_tbl[i],
+ base.hlist) {
+ if (test_bit(BNGE_FLTR_VALID, &fltr->base.state)) {
+ if (fltr->base.flags & BNGE_ACT_NO_AGING)
+ continue;
+ if (rps_may_expire_flow(bn->netdev,
+ fltr->base.rxq,
+ fltr->flow_id,
+ fltr->base.sw_id))
+ list_add(&fltr->base.list_node,
+ &expire_list);
+ } else {
+ list_add(&fltr->base.list_node, &install_list);
+ }
+ }
+ }
+ rcu_read_unlock();
+
+ list_for_each_entry_safe(fltr, tmp, &install_list, base.list_node) {
+ list_del_init(&fltr->base.list_node);
+ rc = bnge_hwrm_cfa_ntuple_filter_alloc(bn->bd, fltr);
+ if (rc)
+ bnge_del_ntp_filter_rcu(bn, fltr);
+ else
+ set_bit(BNGE_FLTR_VALID, &fltr->base.state);
+ }
+
+ list_for_each_entry_safe(fltr, tmp, &expire_list, base.list_node) {
+ list_del_init(&fltr->base.list_node);
+ bnge_hwrm_cfa_ntuple_filter_free(bn->bd, fltr);
+ bnge_del_ntp_filter_rcu(bn, fltr);
+ }
+#endif
+}
diff --git a/drivers/net/ethernet/broadcom/bnge/bnge_filter.h b/drivers/net/ethernet/broadcom/bnge/bnge_filter.h
index 4e9a4e661017..e4447af7be69 100644
--- a/drivers/net/ethernet/broadcom/bnge/bnge_filter.h
+++ b/drivers/net/ethernet/broadcom/bnge/bnge_filter.h
@@ -119,4 +119,5 @@ void bnge_del_ntp_filter_rcu(struct bnge_net *bn,
struct bnge_ntuple_filter *fltr);
void bnge_cfg_usr_fltrs(struct bnge_net *bn);
void bnge_clear_usr_fltrs(struct bnge_net *bn);
+void bnge_cfg_ntp_filters(struct bnge_net *bn);
#endif /* _BNGE_FILTER_H_ */
diff --git a/drivers/net/ethernet/broadcom/bnge/bnge_netdev.c b/drivers/net/ethernet/broadcom/bnge/bnge_netdev.c
index 3ecbc95772cb..4354fbf438f7 100644
--- a/drivers/net/ethernet/broadcom/bnge/bnge_netdev.c
+++ b/drivers/net/ethernet/broadcom/bnge/bnge_netdev.c
@@ -303,6 +303,11 @@ static void bnge_timer(struct timer_list *t)
if (BNGE_LINK_IS_UP(bd) && bn->stats_coal_ticks)
bnge_queue_sp_work(bn, BNGE_PERIODIC_STATS_SP_EVENT);
+#ifdef CONFIG_RFS_ACCEL
+ if ((bn->priv_flags & BNGE_NET_EN_NTUPLE) && bn->ntp_fltr_count)
+ bnge_queue_sp_work(bn, BNGE_RX_NTP_FLTR_SP_EVENT);
+#endif
+
mod_timer(&bn->timer, jiffies + bn->current_interval);
}
@@ -444,6 +449,9 @@ static void bnge_sp_task(struct work_struct *work)
bnge_init_ethtool_link_settings(bn);
}
+ if (test_and_clear_bit(BNGE_RX_NTP_FLTR_SP_EVENT, &bn->sp_event))
+ bnge_cfg_ntp_filters(bn);
+
netdev_unlock(bn->netdev);
}
@@ -3165,6 +3173,97 @@ static int bnge_set_features(struct net_device *dev, netdev_features_t features)
return 0;
}
+#ifdef CONFIG_RFS_ACCEL
+static u64 bnge_lookup_l2_filter_from_key(struct bnge_net *bn,
+ struct bnge_l2_key *key)
+{
+ u32 idx;
+
+ idx = jhash2(&key->filter_key, BNGE_L2_KEY_SIZE, bn->hash_seed) &
+ BNGE_L2_FLTR_HASH_MASK;
+ return bnge_lookup_l2_filter_rcu(bn, key, idx);
+}
+
+static int bnge_rx_flow_steer(struct net_device *dev, const struct sk_buff *skb,
+ u16 rxq_index, u32 flow_id)
+{
+ struct ethhdr *eth = (struct ethhdr *)skb_mac_header(skb);
+ struct bnge_ntuple_filter *fltr, *new_fltr;
+ struct bnge_net *bn = netdev_priv(dev);
+ struct flow_keys *fkeys;
+ __le64 filter_id;
+ u32 flags, idx;
+ int rc = 0;
+
+ if (ether_addr_equal(dev->dev_addr, eth->h_dest)) {
+ struct bnge_l2_filter *l2_filter;
+
+ l2_filter = bn->vnic_info[BNGE_VNIC_DEFAULT].l2_filters[0];
+ filter_id = l2_filter->base.filter_id;
+
+ } else {
+ struct bnge_l2_key key;
+
+ ether_addr_copy(key.dst_mac_addr, eth->h_dest);
+ key.vlan = 0;
+
+ filter_id = bnge_lookup_l2_filter_from_key(bn, &key);
+ if (filter_id == BNGE_FLTR_ID_INVALID)
+ return -EINVAL;
+ }
+ new_fltr = kzalloc_obj(*new_fltr, GFP_ATOMIC);
+ if (!new_fltr)
+ return -ENOMEM;
+
+ fkeys = &new_fltr->fkeys;
+ if (!skb_flow_dissect_flow_keys(skb, fkeys, 0)) {
+ rc = -EPROTONOSUPPORT;
+ goto err_free;
+ }
+
+ if ((fkeys->basic.n_proto != htons(ETH_P_IP) &&
+ fkeys->basic.n_proto != htons(ETH_P_IPV6)) ||
+ ((fkeys->basic.ip_proto != IPPROTO_TCP) &&
+ (fkeys->basic.ip_proto != IPPROTO_UDP))) {
+ rc = -EPROTONOSUPPORT;
+ goto err_free;
+ }
+ new_fltr->fmasks = BNGE_FLOW_IPV4_MASK_ALL;
+ if (fkeys->basic.n_proto == htons(ETH_P_IPV6))
+ new_fltr->fmasks = BNGE_FLOW_IPV6_MASK_ALL;
+
+ flags = fkeys->control.flags;
+ if (flags & FLOW_DIS_IS_FRAGMENT) {
+ rc = -EPROTONOSUPPORT;
+ goto err_free;
+ }
+
+ new_fltr->l2_filter_id = filter_id;
+
+ idx = bnge_get_ntp_filter_idx(bn, fkeys, skb);
+ rcu_read_lock();
+ fltr = bnge_lookup_ntp_filter_from_idx(bn, new_fltr, idx);
+ if (fltr) {
+ rc = fltr->base.sw_id;
+ rcu_read_unlock();
+ goto err_free;
+ }
+ rcu_read_unlock();
+
+ new_fltr->flow_id = flow_id;
+ new_fltr->base.rxq = rxq_index;
+ rc = bnge_insert_ntp_filter(bn, new_fltr, idx);
+ if (!rc) {
+ bnge_queue_sp_work(bn, BNGE_RX_NTP_FLTR_SP_EVENT);
+ return new_fltr->base.sw_id;
+ }
+
+err_free:
+ kfree(new_fltr);
+ return rc;
+}
+#endif
+
static const struct net_device_ops bnge_netdev_ops = {
.ndo_open = bnge_open,
.ndo_stop = bnge_close,
@@ -3174,6 +3273,9 @@ static const struct net_device_ops bnge_netdev_ops = {
.ndo_features_check = bnge_features_check,
.ndo_fix_features = bnge_fix_features,
.ndo_set_features = bnge_set_features,
+#ifdef CONFIG_RFS_ACCEL
+ .ndo_rx_flow_steer = bnge_rx_flow_steer,
+#endif
};
static void bnge_init_mac_addr(struct bnge_dev *bd)
diff --git a/drivers/net/ethernet/broadcom/bnge/bnge_netdev.h b/drivers/net/ethernet/broadcom/bnge/bnge_netdev.h
index bfd0d9cb871f..3146023621a6 100644
--- a/drivers/net/ethernet/broadcom/bnge/bnge_netdev.h
+++ b/drivers/net/ethernet/broadcom/bnge/bnge_netdev.h
@@ -282,6 +282,7 @@ enum bnge_sp_event {
BNGE_LINK_CFG_CHANGE_SP_EVENT,
BNGE_UPDATE_PHY_SP_EVENT,
BNGE_PERIODIC_STATS_SP_EVENT,
+ BNGE_RX_NTP_FLTR_SP_EVENT,
};
#define BNGE_NTP_FLTR_HASH_SIZE 512
--
2.47.1
next prev parent reply other threads:[~2026-09-08 9:32 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-08 9:30 [net-next, v2 00/11] add features to bnge Vikas Gupta
2026-09-08 9:30 ` [net-next, v2 01/11] bnge: update HSI Vikas Gupta
2026-09-08 9:30 ` [net-next, v2 02/11] bnge: restructure VNIC and filter code Vikas Gupta
2026-09-08 9:30 ` [net-next, v2 03/11] bnge: add NTUPLE/ARFS VNIC Vikas Gupta
2026-09-08 9:30 ` [net-next, v2 04/11] bnge: add helper functions for multi RSS contexts Vikas Gupta
2026-09-08 9:30 ` [net-next, v2 05/11] bnge: add RXFH ethtool support Vikas Gupta
2026-09-08 9:30 ` [net-next, v2 06/11] bnge: add ethtool support to manage RSS contexts Vikas Gupta
2026-09-08 9:30 ` [net-next, v2 07/11] bnge: remove refcount from L2 filter Vikas Gupta
2026-09-08 9:30 ` [net-next, v2 08/11] bnge: add NTUPLE filter infrastructure Vikas Gupta
2026-09-10 23:59 ` Jakub Kicinski
2026-09-08 9:30 ` [net-next, v2 09/11] bnge: add NTUPLE filter support in ethtool Vikas Gupta
2026-09-08 9:30 ` Vikas Gupta [this message]
2026-09-08 9:30 ` [net-next, v2 11/11] bnge: add cpu_rmap support for IRQ affinity Vikas Gupta
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260908093053.2596020-11-vikas.gupta@broadcom.com \
--to=vikas.gupta@broadcom.com \
--cc=ajit.khaparde@broadcom.com \
--cc=andrew+netdev@lunn.ch \
--cc=bhargava.marreddy@broadcom.com \
--cc=davem@davemloft.net \
--cc=dharmender.garg@broadcom.com \
--cc=edumazet@google.com \
--cc=horms@kernel.org \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=rahul-rg.gupta@broadcom.com \
--cc=rajashekar.hudumula@broadcom.com \
--cc=vsrama-krishna.nemani@broadcom.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®