Message ID | 20230522090542.45679-10-wojciech.drewek@intel.com (mailing list archive) |
---|---|
State | Superseded |
Delegated to: | Netdev Maintainers |
Headers | show |
Series | ice: switchdev bridge offload | expand |
Context | Check | Description |
---|---|---|
netdev/tree_selection | success | Guessing tree name failed - patch did not apply |
Dear Wojciech, dear Michal, Am 22.05.23 um 11:05 schrieb Wojciech Drewek: > From: Michal Swiatkowski <michal.swiatkowski@linux.intel.com> > > Remove fdb entries always when ageing time expired. Why is that a good thing to do? > Allow user to set ageing time using port object attribute. Maybe add the comment how to do it too? Kind regards, Paul > Signed-off-by: Michal Swiatkowski <michal.swiatkowski@linux.intel.com> > Signed-off-by: Wojciech Drewek <wojciech.drewek@intel.com> > --- > v2: use msecs_to_jiffies upon definition of > ICE_ESW_BRIDGE_UPDATE_INTERVAL > --- > .../net/ethernet/intel/ice/ice_eswitch_br.c | 48 +++++++++++++++++++ > .../net/ethernet/intel/ice/ice_eswitch_br.h | 10 ++++ > 2 files changed, 58 insertions(+) > > diff --git a/drivers/net/ethernet/intel/ice/ice_eswitch_br.c b/drivers/net/ethernet/intel/ice/ice_eswitch_br.c > index 74857da6be9f..af3465b9699c 100644 > --- a/drivers/net/ethernet/intel/ice/ice_eswitch_br.c > +++ b/drivers/net/ethernet/intel/ice/ice_eswitch_br.c > @@ -8,6 +8,8 @@ > #include "ice_vlan.h" > #include "ice_vf_vsi_vlan_ops.h" > > +#define ICE_ESW_BRIDGE_UPDATE_INTERVAL msecs_to_jiffies(1000) > + > static const struct rhashtable_params ice_fdb_ht_params = { > .key_offset = offsetof(struct ice_esw_br_fdb_entry, data), > .key_len = sizeof(struct ice_esw_br_fdb_data), > @@ -443,6 +445,7 @@ ice_eswitch_br_fdb_entry_create(struct net_device *netdev, > fdb_entry->br_port = br_port; > fdb_entry->flow = flow; > fdb_entry->dev = netdev; > + fdb_entry->last_use = jiffies; > event = SWITCHDEV_FDB_ADD_TO_BRIDGE; > > if (added_by_user) { > @@ -836,6 +839,10 @@ ice_eswitch_br_port_obj_attr_set(struct net_device *netdev, const void *ctx, > ice_eswitch_br_vlan_filtering_set(br_port->bridge, > attr->u.vlan_filtering); > return 0; > + case SWITCHDEV_ATTR_ID_BRIDGE_AGEING_TIME: > + br_port->bridge->ageing_time = > + clock_t_to_jiffies(attr->u.ageing_time); > + return 0; > default: > return -EOPNOTSUPP; > } > @@ -1007,6 +1014,7 @@ ice_eswitch_br_init(struct ice_esw_br_offloads *br_offloads, int ifindex) > INIT_LIST_HEAD(&bridge->fdb_list); > bridge->br_offloads = br_offloads; > bridge->ifindex = ifindex; > + bridge->ageing_time = clock_t_to_jiffies(BR_DEFAULT_AGEING_TIME); > xa_init(&bridge->ports); > br_offloads->bridge = bridge; > > @@ -1210,6 +1218,7 @@ ice_eswitch_br_offloads_deinit(struct ice_pf *pf) > if (!br_offloads) > return; > > + cancel_delayed_work_sync(&br_offloads->update_work); > unregister_netdevice_notifier(&br_offloads->netdev_nb); > unregister_switchdev_blocking_notifier(&br_offloads->switchdev_blk); > unregister_switchdev_notifier(&br_offloads->switchdev_nb); > @@ -1224,6 +1233,40 @@ ice_eswitch_br_offloads_deinit(struct ice_pf *pf) > rtnl_unlock(); > } > > +static void ice_eswitch_br_update(struct ice_esw_br_offloads *br_offloads) > +{ > + struct ice_esw_br *bridge = br_offloads->bridge; > + struct ice_esw_br_fdb_entry *entry, *tmp; > + > + if (!bridge) > + return; > + > + rtnl_lock(); > + list_for_each_entry_safe(entry, tmp, &bridge->fdb_list, list) { > + if (entry->flags & ICE_ESWITCH_BR_FDB_ADDED_BY_USER) > + continue; > + > + if (time_is_after_eq_jiffies(entry->last_use + > + bridge->ageing_time)) > + continue; > + > + ice_eswitch_br_fdb_entry_notify_and_cleanup(bridge, entry); > + } > + rtnl_unlock(); > +} > + > +static void ice_eswitch_br_update_work(struct work_struct *work) > +{ > + struct ice_esw_br_offloads *br_offloads; > + > + br_offloads = ice_work_to_br_offloads(work); > + > + ice_eswitch_br_update(br_offloads); > + > + queue_delayed_work(br_offloads->wq, &br_offloads->update_work, > + ICE_ESW_BRIDGE_UPDATE_INTERVAL); > +} > + > int > ice_eswitch_br_offloads_init(struct ice_pf *pf) > { > @@ -1272,6 +1315,11 @@ ice_eswitch_br_offloads_init(struct ice_pf *pf) > goto err_reg_netdev_nb; > } > > + INIT_DELAYED_WORK(&br_offloads->update_work, > + ice_eswitch_br_update_work); > + queue_delayed_work(br_offloads->wq, &br_offloads->update_work, > + ICE_ESW_BRIDGE_UPDATE_INTERVAL); > + > return 0; > > err_reg_netdev_nb: > diff --git a/drivers/net/ethernet/intel/ice/ice_eswitch_br.h b/drivers/net/ethernet/intel/ice/ice_eswitch_br.h > index 72316ba8ff4d..93a8c23aa089 100644 > --- a/drivers/net/ethernet/intel/ice/ice_eswitch_br.h > +++ b/drivers/net/ethernet/intel/ice/ice_eswitch_br.h > @@ -5,6 +5,7 @@ > #define _ICE_ESWITCH_BR_H_ > > #include <linux/rhashtable.h> > +#include <linux/workqueue.h> > > struct ice_esw_br_fdb_data { > unsigned char addr[ETH_ALEN]; > @@ -30,6 +31,8 @@ struct ice_esw_br_fdb_entry { > struct net_device *dev; > struct ice_esw_br_port *br_port; > struct ice_esw_br_flow *flow; > + > + unsigned long last_use; > }; > > enum ice_esw_br_port_type { > @@ -59,6 +62,7 @@ struct ice_esw_br { > > int ifindex; > u32 flags; > + unsigned long ageing_time; > }; > > struct ice_esw_br_offloads { > @@ -69,6 +73,7 @@ struct ice_esw_br_offloads { > struct notifier_block switchdev_nb; > > struct workqueue_struct *wq; > + struct delayed_work update_work; > }; > > struct ice_esw_br_fdb_work { > @@ -89,6 +94,11 @@ struct ice_esw_br_vlan { > struct ice_esw_br_offloads, \ > nb_name) > > +#define ice_work_to_br_offloads(w) \ > + container_of(w, \ > + struct ice_esw_br_offloads, \ > + update_work.work) > + > #define ice_work_to_fdb_work(w) \ > container_of(w, \ > struct ice_esw_br_fdb_work, \
> -----Original Message----- > From: Paul Menzel <pmenzel@molgen.mpg.de> > Sent: poniedziałek, 22 maja 2023 12:14 > To: Drewek, Wojciech <wojciech.drewek@intel.com> > Cc: intel-wired-lan@lists.osuosl.org; Michal Swiatkowski <michal.swiatkowski@linux.intel.com>; netdev@vger.kernel.org > Subject: Re: [Intel-wired-lan] [PATCH iwl-next v3 09/10] ice: implement static version of ageing > > Dear Wojciech, dear Michal, > > > Am 22.05.23 um 11:05 schrieb Wojciech Drewek: > > From: Michal Swiatkowski <michal.swiatkowski@linux.intel.com> > > > > Remove fdb entries always when ageing time expired. > > Why is that a good thing to do? I agree that it is not a good solution. For proper aging we would need counter support in sw which is not in place yet. > > > Allow user to set ageing time using port object attribute. > > Maybe add the comment how to do it too? Sure thing > > > Kind regards, > > Paul > > > > Signed-off-by: Michal Swiatkowski <michal.swiatkowski@linux.intel.com> > > Signed-off-by: Wojciech Drewek <wojciech.drewek@intel.com> > > --- > > v2: use msecs_to_jiffies upon definition of > > ICE_ESW_BRIDGE_UPDATE_INTERVAL > > --- > > .../net/ethernet/intel/ice/ice_eswitch_br.c | 48 +++++++++++++++++++ > > .../net/ethernet/intel/ice/ice_eswitch_br.h | 10 ++++ > > 2 files changed, 58 insertions(+) > > > > diff --git a/drivers/net/ethernet/intel/ice/ice_eswitch_br.c b/drivers/net/ethernet/intel/ice/ice_eswitch_br.c > > index 74857da6be9f..af3465b9699c 100644 > > --- a/drivers/net/ethernet/intel/ice/ice_eswitch_br.c > > +++ b/drivers/net/ethernet/intel/ice/ice_eswitch_br.c > > @@ -8,6 +8,8 @@ > > #include "ice_vlan.h" > > #include "ice_vf_vsi_vlan_ops.h" > > > > +#define ICE_ESW_BRIDGE_UPDATE_INTERVAL msecs_to_jiffies(1000) > > + > > static const struct rhashtable_params ice_fdb_ht_params = { > > .key_offset = offsetof(struct ice_esw_br_fdb_entry, data), > > .key_len = sizeof(struct ice_esw_br_fdb_data), > > @@ -443,6 +445,7 @@ ice_eswitch_br_fdb_entry_create(struct net_device *netdev, > > fdb_entry->br_port = br_port; > > fdb_entry->flow = flow; > > fdb_entry->dev = netdev; > > + fdb_entry->last_use = jiffies; > > event = SWITCHDEV_FDB_ADD_TO_BRIDGE; > > > > if (added_by_user) { > > @@ -836,6 +839,10 @@ ice_eswitch_br_port_obj_attr_set(struct net_device *netdev, const void *ctx, > > ice_eswitch_br_vlan_filtering_set(br_port->bridge, > > attr->u.vlan_filtering); > > return 0; > > + case SWITCHDEV_ATTR_ID_BRIDGE_AGEING_TIME: > > + br_port->bridge->ageing_time = > > + clock_t_to_jiffies(attr->u.ageing_time); > > + return 0; > > default: > > return -EOPNOTSUPP; > > } > > @@ -1007,6 +1014,7 @@ ice_eswitch_br_init(struct ice_esw_br_offloads *br_offloads, int ifindex) > > INIT_LIST_HEAD(&bridge->fdb_list); > > bridge->br_offloads = br_offloads; > > bridge->ifindex = ifindex; > > + bridge->ageing_time = clock_t_to_jiffies(BR_DEFAULT_AGEING_TIME); > > xa_init(&bridge->ports); > > br_offloads->bridge = bridge; > > > > @@ -1210,6 +1218,7 @@ ice_eswitch_br_offloads_deinit(struct ice_pf *pf) > > if (!br_offloads) > > return; > > > > + cancel_delayed_work_sync(&br_offloads->update_work); > > unregister_netdevice_notifier(&br_offloads->netdev_nb); > > unregister_switchdev_blocking_notifier(&br_offloads->switchdev_blk); > > unregister_switchdev_notifier(&br_offloads->switchdev_nb); > > @@ -1224,6 +1233,40 @@ ice_eswitch_br_offloads_deinit(struct ice_pf *pf) > > rtnl_unlock(); > > } > > > > +static void ice_eswitch_br_update(struct ice_esw_br_offloads *br_offloads) > > +{ > > + struct ice_esw_br *bridge = br_offloads->bridge; > > + struct ice_esw_br_fdb_entry *entry, *tmp; > > + > > + if (!bridge) > > + return; > > + > > + rtnl_lock(); > > + list_for_each_entry_safe(entry, tmp, &bridge->fdb_list, list) { > > + if (entry->flags & ICE_ESWITCH_BR_FDB_ADDED_BY_USER) > > + continue; > > + > > + if (time_is_after_eq_jiffies(entry->last_use + > > + bridge->ageing_time)) > > + continue; > > + > > + ice_eswitch_br_fdb_entry_notify_and_cleanup(bridge, entry); > > + } > > + rtnl_unlock(); > > +} > > + > > +static void ice_eswitch_br_update_work(struct work_struct *work) > > +{ > > + struct ice_esw_br_offloads *br_offloads; > > + > > + br_offloads = ice_work_to_br_offloads(work); > > + > > + ice_eswitch_br_update(br_offloads); > > + > > + queue_delayed_work(br_offloads->wq, &br_offloads->update_work, > > + ICE_ESW_BRIDGE_UPDATE_INTERVAL); > > +} > > + > > int > > ice_eswitch_br_offloads_init(struct ice_pf *pf) > > { > > @@ -1272,6 +1315,11 @@ ice_eswitch_br_offloads_init(struct ice_pf *pf) > > goto err_reg_netdev_nb; > > } > > > > + INIT_DELAYED_WORK(&br_offloads->update_work, > > + ice_eswitch_br_update_work); > > + queue_delayed_work(br_offloads->wq, &br_offloads->update_work, > > + ICE_ESW_BRIDGE_UPDATE_INTERVAL); > > + > > return 0; > > > > err_reg_netdev_nb: > > diff --git a/drivers/net/ethernet/intel/ice/ice_eswitch_br.h b/drivers/net/ethernet/intel/ice/ice_eswitch_br.h > > index 72316ba8ff4d..93a8c23aa089 100644 > > --- a/drivers/net/ethernet/intel/ice/ice_eswitch_br.h > > +++ b/drivers/net/ethernet/intel/ice/ice_eswitch_br.h > > @@ -5,6 +5,7 @@ > > #define _ICE_ESWITCH_BR_H_ > > > > #include <linux/rhashtable.h> > > +#include <linux/workqueue.h> > > > > struct ice_esw_br_fdb_data { > > unsigned char addr[ETH_ALEN]; > > @@ -30,6 +31,8 @@ struct ice_esw_br_fdb_entry { > > struct net_device *dev; > > struct ice_esw_br_port *br_port; > > struct ice_esw_br_flow *flow; > > + > > + unsigned long last_use; > > }; > > > > enum ice_esw_br_port_type { > > @@ -59,6 +62,7 @@ struct ice_esw_br { > > > > int ifindex; > > u32 flags; > > + unsigned long ageing_time; > > }; > > > > struct ice_esw_br_offloads { > > @@ -69,6 +73,7 @@ struct ice_esw_br_offloads { > > struct notifier_block switchdev_nb; > > > > struct workqueue_struct *wq; > > + struct delayed_work update_work; > > }; > > > > struct ice_esw_br_fdb_work { > > @@ -89,6 +94,11 @@ struct ice_esw_br_vlan { > > struct ice_esw_br_offloads, \ > > nb_name) > > > > +#define ice_work_to_br_offloads(w) \ > > + container_of(w, \ > > + struct ice_esw_br_offloads, \ > > + update_work.work) > > + > > #define ice_work_to_fdb_work(w) \ > > container_of(w, \ > > struct ice_esw_br_fdb_work, \
diff --git a/drivers/net/ethernet/intel/ice/ice_eswitch_br.c b/drivers/net/ethernet/intel/ice/ice_eswitch_br.c index 74857da6be9f..af3465b9699c 100644 --- a/drivers/net/ethernet/intel/ice/ice_eswitch_br.c +++ b/drivers/net/ethernet/intel/ice/ice_eswitch_br.c @@ -8,6 +8,8 @@ #include "ice_vlan.h" #include "ice_vf_vsi_vlan_ops.h" +#define ICE_ESW_BRIDGE_UPDATE_INTERVAL msecs_to_jiffies(1000) + static const struct rhashtable_params ice_fdb_ht_params = { .key_offset = offsetof(struct ice_esw_br_fdb_entry, data), .key_len = sizeof(struct ice_esw_br_fdb_data), @@ -443,6 +445,7 @@ ice_eswitch_br_fdb_entry_create(struct net_device *netdev, fdb_entry->br_port = br_port; fdb_entry->flow = flow; fdb_entry->dev = netdev; + fdb_entry->last_use = jiffies; event = SWITCHDEV_FDB_ADD_TO_BRIDGE; if (added_by_user) { @@ -836,6 +839,10 @@ ice_eswitch_br_port_obj_attr_set(struct net_device *netdev, const void *ctx, ice_eswitch_br_vlan_filtering_set(br_port->bridge, attr->u.vlan_filtering); return 0; + case SWITCHDEV_ATTR_ID_BRIDGE_AGEING_TIME: + br_port->bridge->ageing_time = + clock_t_to_jiffies(attr->u.ageing_time); + return 0; default: return -EOPNOTSUPP; } @@ -1007,6 +1014,7 @@ ice_eswitch_br_init(struct ice_esw_br_offloads *br_offloads, int ifindex) INIT_LIST_HEAD(&bridge->fdb_list); bridge->br_offloads = br_offloads; bridge->ifindex = ifindex; + bridge->ageing_time = clock_t_to_jiffies(BR_DEFAULT_AGEING_TIME); xa_init(&bridge->ports); br_offloads->bridge = bridge; @@ -1210,6 +1218,7 @@ ice_eswitch_br_offloads_deinit(struct ice_pf *pf) if (!br_offloads) return; + cancel_delayed_work_sync(&br_offloads->update_work); unregister_netdevice_notifier(&br_offloads->netdev_nb); unregister_switchdev_blocking_notifier(&br_offloads->switchdev_blk); unregister_switchdev_notifier(&br_offloads->switchdev_nb); @@ -1224,6 +1233,40 @@ ice_eswitch_br_offloads_deinit(struct ice_pf *pf) rtnl_unlock(); } +static void ice_eswitch_br_update(struct ice_esw_br_offloads *br_offloads) +{ + struct ice_esw_br *bridge = br_offloads->bridge; + struct ice_esw_br_fdb_entry *entry, *tmp; + + if (!bridge) + return; + + rtnl_lock(); + list_for_each_entry_safe(entry, tmp, &bridge->fdb_list, list) { + if (entry->flags & ICE_ESWITCH_BR_FDB_ADDED_BY_USER) + continue; + + if (time_is_after_eq_jiffies(entry->last_use + + bridge->ageing_time)) + continue; + + ice_eswitch_br_fdb_entry_notify_and_cleanup(bridge, entry); + } + rtnl_unlock(); +} + +static void ice_eswitch_br_update_work(struct work_struct *work) +{ + struct ice_esw_br_offloads *br_offloads; + + br_offloads = ice_work_to_br_offloads(work); + + ice_eswitch_br_update(br_offloads); + + queue_delayed_work(br_offloads->wq, &br_offloads->update_work, + ICE_ESW_BRIDGE_UPDATE_INTERVAL); +} + int ice_eswitch_br_offloads_init(struct ice_pf *pf) { @@ -1272,6 +1315,11 @@ ice_eswitch_br_offloads_init(struct ice_pf *pf) goto err_reg_netdev_nb; } + INIT_DELAYED_WORK(&br_offloads->update_work, + ice_eswitch_br_update_work); + queue_delayed_work(br_offloads->wq, &br_offloads->update_work, + ICE_ESW_BRIDGE_UPDATE_INTERVAL); + return 0; err_reg_netdev_nb: diff --git a/drivers/net/ethernet/intel/ice/ice_eswitch_br.h b/drivers/net/ethernet/intel/ice/ice_eswitch_br.h index 72316ba8ff4d..93a8c23aa089 100644 --- a/drivers/net/ethernet/intel/ice/ice_eswitch_br.h +++ b/drivers/net/ethernet/intel/ice/ice_eswitch_br.h @@ -5,6 +5,7 @@ #define _ICE_ESWITCH_BR_H_ #include <linux/rhashtable.h> +#include <linux/workqueue.h> struct ice_esw_br_fdb_data { unsigned char addr[ETH_ALEN]; @@ -30,6 +31,8 @@ struct ice_esw_br_fdb_entry { struct net_device *dev; struct ice_esw_br_port *br_port; struct ice_esw_br_flow *flow; + + unsigned long last_use; }; enum ice_esw_br_port_type { @@ -59,6 +62,7 @@ struct ice_esw_br { int ifindex; u32 flags; + unsigned long ageing_time; }; struct ice_esw_br_offloads { @@ -69,6 +73,7 @@ struct ice_esw_br_offloads { struct notifier_block switchdev_nb; struct workqueue_struct *wq; + struct delayed_work update_work; }; struct ice_esw_br_fdb_work { @@ -89,6 +94,11 @@ struct ice_esw_br_vlan { struct ice_esw_br_offloads, \ nb_name) +#define ice_work_to_br_offloads(w) \ + container_of(w, \ + struct ice_esw_br_offloads, \ + update_work.work) + #define ice_work_to_fdb_work(w) \ container_of(w, \ struct ice_esw_br_fdb_work, \