aboutsummaryrefslogtreecommitdiffstats
path: root/include/net/switchdev.h
diff options
context:
space:
mode:
authorPetr Machata <petrm@mellanox.com>2018-11-22 18:28:25 -0500
committerDavid S. Miller <davem@davemloft.net>2018-11-23 21:02:23 -0500
commita93e3b17227ed8b0db7e44d0302b4da7d07f9a35 (patch)
tree668db99bc01b59b8a3da2d19003f0a5843aaa0ae /include/net/switchdev.h
parentec394af5ea1d8ee62681815d167115ac618bcb42 (diff)
switchdev: Add a blocking notifier chain
In general one can't assume that a switchdev notifier is called in a non-atomic context, and correspondingly, the switchdev notifier chain is an atomic one. However, port object addition and deletion messages are delivered from a process context. Even the MDB addition messages, whose delivery is scheduled from atomic context, are queued and the delivery itself takes place in blocking context. For VLAN messages in particular, keeping the blocking nature is important for error reporting. Therefore introduce a blocking notifier chain and related service functions to distribute the notifications for which a blocking context can be assumed. Signed-off-by: Petr Machata <petrm@mellanox.com> Reviewed-by: Jiri Pirko <jiri@mellanox.com> Reviewed-by: Ido Schimmel <idosch@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/net/switchdev.h')
-rw-r--r--include/net/switchdev.h27
1 files changed, 27 insertions, 0 deletions
diff --git a/include/net/switchdev.h b/include/net/switchdev.h
index dd969224a9b9..e021b67b9b32 100644
--- a/include/net/switchdev.h
+++ b/include/net/switchdev.h
@@ -182,10 +182,17 @@ int switchdev_port_obj_add(struct net_device *dev,
182 const struct switchdev_obj *obj); 182 const struct switchdev_obj *obj);
183int switchdev_port_obj_del(struct net_device *dev, 183int switchdev_port_obj_del(struct net_device *dev,
184 const struct switchdev_obj *obj); 184 const struct switchdev_obj *obj);
185
185int register_switchdev_notifier(struct notifier_block *nb); 186int register_switchdev_notifier(struct notifier_block *nb);
186int unregister_switchdev_notifier(struct notifier_block *nb); 187int unregister_switchdev_notifier(struct notifier_block *nb);
187int call_switchdev_notifiers(unsigned long val, struct net_device *dev, 188int call_switchdev_notifiers(unsigned long val, struct net_device *dev,
188 struct switchdev_notifier_info *info); 189 struct switchdev_notifier_info *info);
190
191int register_switchdev_blocking_notifier(struct notifier_block *nb);
192int unregister_switchdev_blocking_notifier(struct notifier_block *nb);
193int call_switchdev_blocking_notifiers(unsigned long val, struct net_device *dev,
194 struct switchdev_notifier_info *info);
195
189void switchdev_port_fwd_mark_set(struct net_device *dev, 196void switchdev_port_fwd_mark_set(struct net_device *dev,
190 struct net_device *group_dev, 197 struct net_device *group_dev,
191 bool joining); 198 bool joining);
@@ -241,6 +248,26 @@ static inline int call_switchdev_notifiers(unsigned long val,
241 return NOTIFY_DONE; 248 return NOTIFY_DONE;
242} 249}
243 250
251static inline int
252register_switchdev_blocking_notifier(struct notifier_block *nb)
253{
254 return 0;
255}
256
257static inline int
258unregister_switchdev_blocking_notifier(struct notifier_block *nb)
259{
260 return 0;
261}
262
263static inline int
264call_switchdev_blocking_notifiers(unsigned long val,
265 struct net_device *dev,
266 struct switchdev_notifier_info *info)
267{
268 return NOTIFY_DONE;
269}
270
244static inline bool switchdev_port_same_parent_id(struct net_device *a, 271static inline bool switchdev_port_same_parent_id(struct net_device *a,
245 struct net_device *b) 272 struct net_device *b)
246{ 273{