Re: [PATCH net-next v07 8/9] hinic3: Add netdev notifier interfaces
From: Paolo Abeni <pabeni@redhat.com>
Date: 2025-11-25 10:46:54
Also in:
linux-doc, lkml
On 11/19/25 1:43 PM, Fan Gong wrote:
Add netdev notifier interfaces. As we stipulate that netdevices with a vlan depth greater than 1 should disable the offload feature, Layer 1 vlan netdevices use notifier to modify vlan_features.
As mentioned by Jakub in the previous revision, the net stack can send packets with multiple stacked vlans. You need to implement ndo_features_check(), check for the problematic packet layout there and ev return a smaller features check excluding the relevant offloads.
+static u16 hinic3_get_vlan_depth(struct net_device *netdev)
+{
+ u16 vlan_depth = 0;
+
+#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
+ while (is_vlan_dev(netdev)) {
+ netdev = vlan_dev_priv(netdev)->real_dev;
+ vlan_depth++;
+ }
+#endif
+ return vlan_depth;AFAICS the above can return any number >= HINIC3_MAX_VLAN_DEPTH_OFFLOAD_SUPPORT ...
+}
+
+static int hinic3_netdev_event(struct notifier_block *notifier,
+ unsigned long event, void *ptr)
+{
+ struct net_device *ndev = netdev_notifier_info_to_dev(ptr);
+ struct hinic3_nic_dev *nic_dev = netdev_priv(ndev);
+ u16 vlan_depth;
+
+ if (!is_vlan_dev(ndev))
+ return NOTIFY_DONE;
+
+ netdev_hold(ndev, &nic_dev->tracker, GFP_ATOMIC);
+
+ switch (event) {
+ case NETDEV_REGISTER:
+ vlan_depth = hinic3_get_vlan_depth(ndev);
+ if (vlan_depth == HINIC3_MAX_VLAN_DEPTH_OFFLOAD_SUPPORT)... so here you should use '>='> + ndev->vlan_features &= (~HINIC3_VLAN_CLEAR_OFFLOAD);
quoted hunk ↗ jump to hunk
+ + break; + + default: + break; + } + + netdev_put(ndev, &nic_dev->tracker); + + return NOTIFY_DONE; +} + +static struct notifier_block hinic3_netdev_notifier = { + .notifier_call = hinic3_netdev_event, +}; + static void init_intr_coal_param(struct net_device *netdev) { struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);@@ -309,6 +364,36 @@ static int hinic3_set_default_hw_feature(struct net_device *netdev) return 0; } +static void hinic3_register_notifier(struct net_device *netdev) +{ + struct hinic3_nic_dev *nic_dev = netdev_priv(netdev); + int err; + + mutex_lock(&hinic3_netdev_notifiers_mutex); + hinic3_netdev_notifiers_ref_cnt++; + if (hinic3_netdev_notifiers_ref_cnt == 1) {
Why do you need this notifier accounting? Instead you should be able to call hinic3_register_notifier() only once. /P