Skip to content

Commit

Permalink
net: dsa: document the existing switch tree notifiers and add a new one
Browse files Browse the repository at this point in the history
The existence of dsa_broadcast has generated some confusion in the past:
https://www.mail-archive.com/netdev@vger.kernel.org/msg365042.html

So let's document the existing dsa_port_notify and dsa_broadcast
functions and explain when each of them should be used.

Also, in fact, the in-between function has always been there but was
lacking a name, and is the main reason for this patch: dsa_tree_notify.
Refactor dsa_broadcast to use it.

This patch also moves dsa_broadcast (a top-level function) to dsa2.c,
where it really belonged in the first place, but had no companion so it
stood with dsa_port_notify.

Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
  • Loading branch information
Vladimir Oltean authored and Jakub Kicinski committed Jan 30, 2021
1 parent cacea62 commit 886f8e2
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 23 deletions.
43 changes: 43 additions & 0 deletions net/dsa/dsa2.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,49 @@
static DEFINE_MUTEX(dsa2_mutex);
LIST_HEAD(dsa_tree_list);

/**
* dsa_tree_notify - Execute code for all switches in a DSA switch tree.
* @dst: collection of struct dsa_switch devices to notify.
* @e: event, must be of type DSA_NOTIFIER_*
* @v: event-specific value.
*
* Given a struct dsa_switch_tree, this can be used to run a function once for
* each member DSA switch. The other alternative of traversing the tree is only
* through its ports list, which does not uniquely list the switches.
*/
int dsa_tree_notify(struct dsa_switch_tree *dst, unsigned long e, void *v)
{
struct raw_notifier_head *nh = &dst->nh;
int err;

err = raw_notifier_call_chain(nh, e, v);

return notifier_to_errno(err);
}

/**
* dsa_broadcast - Notify all DSA trees in the system.
* @e: event, must be of type DSA_NOTIFIER_*
* @v: event-specific value.
*
* Can be used to notify the switching fabric of events such as cross-chip
* bridging between disjoint trees (such as islands of tagger-compatible
* switches bridged by an incompatible middle switch).
*/
int dsa_broadcast(unsigned long e, void *v)
{
struct dsa_switch_tree *dst;
int err = 0;

list_for_each_entry(dst, &dsa_tree_list, list) {
err = dsa_tree_notify(dst, e, v);
if (err)
break;
}

return err;
}

/**
* dsa_lag_map() - Map LAG netdev to a linear LAG ID
* @dst: Tree in which to record the mapping.
Expand Down
2 changes: 2 additions & 0 deletions net/dsa/dsa_priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,8 @@ void dsa_switch_unregister_notifier(struct dsa_switch *ds);
/* dsa2.c */
void dsa_lag_map(struct dsa_switch_tree *dst, struct net_device *lag);
void dsa_lag_unmap(struct dsa_switch_tree *dst, struct net_device *lag);
int dsa_tree_notify(struct dsa_switch_tree *dst, unsigned long e, void *v);
int dsa_broadcast(unsigned long e, void *v);

extern struct list_head dsa_tree_list;

Expand Down
36 changes: 13 additions & 23 deletions net/dsa/port.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,31 +13,21 @@

#include "dsa_priv.h"

static int dsa_broadcast(unsigned long e, void *v)
{
struct dsa_switch_tree *dst;
int err = 0;

list_for_each_entry(dst, &dsa_tree_list, list) {
struct raw_notifier_head *nh = &dst->nh;

err = raw_notifier_call_chain(nh, e, v);
err = notifier_to_errno(err);
if (err)
break;
}

return err;
}

/**
* dsa_port_notify - Notify the switching fabric of changes to a port
* @dp: port on which change occurred
* @e: event, must be of type DSA_NOTIFIER_*
* @v: event-specific value.
*
* Notify all switches in the DSA tree that this port's switch belongs to,
* including this switch itself, of an event. Allows the other switches to
* reconfigure themselves for cross-chip operations. Can also be used to
* reconfigure ports without net_devices (CPU ports, DSA links) whenever
* a user port's state changes.
*/
static int dsa_port_notify(const struct dsa_port *dp, unsigned long e, void *v)
{
struct raw_notifier_head *nh = &dp->ds->dst->nh;
int err;

err = raw_notifier_call_chain(nh, e, v);

return notifier_to_errno(err);
return dsa_tree_notify(dp->ds->dst, e, v);
}

int dsa_port_set_state(struct dsa_port *dp, u8 state)
Expand Down

0 comments on commit 886f8e2

Please sign in to comment.