diff options
author | Florian Fainelli <f.fainelli@gmail.com> | 2019-02-27 14:44:31 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2019-02-27 15:39:56 -0500 |
commit | d45224d604c5ba6ac5f9d6fddbe1d058c81dee80 (patch) | |
tree | 1708ef76a424c823156c36c563a242dadcb35c37 /net/switchdev/switchdev.c | |
parent | 570b68c8dddea16b96730f7d5d732e270b6a9189 (diff) |
net: switchdev: Replace port attr set SDO with a notification
Drop switchdev_ops.switchdev_port_attr_set. Drop the uses of this field
from all clients, which were migrated to use switchdev notification in
the previous patches.
Add a new function switchdev_port_attr_notify() that sends the switchdev
notifications SWITCHDEV_PORT_ATTR_SET and calls the blocking (process)
notifier chain.
We have one odd case within net/bridge/br_switchdev.c with the
SWITCHDEV_ATTR_ID_PORT_PRE_BRIDGE_FLAGS attribute identifier that
requires executing from atomic context, we deal with that one
specifically.
Drop __switchdev_port_attr_set() and update switchdev_port_attr_set()
likewise.
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
Reviewed-by: Ido Schimmel <idosch@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/switchdev/switchdev.c')
-rw-r--r-- | net/switchdev/switchdev.c | 53 |
1 files changed, 24 insertions, 29 deletions
diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c index 3560c19aa7e2..d81cfcee9ad9 100644 --- a/net/switchdev/switchdev.c +++ b/net/switchdev/switchdev.c | |||
@@ -174,39 +174,32 @@ static int switchdev_deferred_enqueue(struct net_device *dev, | |||
174 | return 0; | 174 | return 0; |
175 | } | 175 | } |
176 | 176 | ||
177 | static int __switchdev_port_attr_set(struct net_device *dev, | 177 | static int switchdev_port_attr_notify(enum switchdev_notifier_type nt, |
178 | const struct switchdev_attr *attr, | 178 | struct net_device *dev, |
179 | struct switchdev_trans *trans) | 179 | const struct switchdev_attr *attr, |
180 | struct switchdev_trans *trans) | ||
180 | { | 181 | { |
181 | const struct switchdev_ops *ops = dev->switchdev_ops; | 182 | int err; |
182 | struct net_device *lower_dev; | 183 | int rc; |
183 | struct list_head *iter; | ||
184 | int err = -EOPNOTSUPP; | ||
185 | |||
186 | if (ops && ops->switchdev_port_attr_set) { | ||
187 | err = ops->switchdev_port_attr_set(dev, attr, trans); | ||
188 | goto done; | ||
189 | } | ||
190 | |||
191 | if (attr->flags & SWITCHDEV_F_NO_RECURSE) | ||
192 | goto done; | ||
193 | 184 | ||
194 | /* Switch device port(s) may be stacked under | 185 | struct switchdev_notifier_port_attr_info attr_info = { |
195 | * bond/team/vlan dev, so recurse down to set attr on | 186 | .attr = attr, |
196 | * each port. | 187 | .trans = trans, |
197 | */ | 188 | .handled = false, |
189 | }; | ||
198 | 190 | ||
199 | netdev_for_each_lower_dev(dev, lower_dev, iter) { | 191 | rc = call_switchdev_blocking_notifiers(nt, dev, |
200 | err = __switchdev_port_attr_set(lower_dev, attr, trans); | 192 | &attr_info.info, NULL); |
201 | if (err) | 193 | err = notifier_to_errno(rc); |
202 | break; | 194 | if (err) { |
195 | WARN_ON(!attr_info.handled); | ||
196 | return err; | ||
203 | } | 197 | } |
204 | 198 | ||
205 | done: | 199 | if (!attr_info.handled) |
206 | if (err == -EOPNOTSUPP && attr->flags & SWITCHDEV_F_SKIP_EOPNOTSUPP) | 200 | return -EOPNOTSUPP; |
207 | err = 0; | ||
208 | 201 | ||
209 | return err; | 202 | return 0; |
210 | } | 203 | } |
211 | 204 | ||
212 | static int switchdev_port_attr_set_now(struct net_device *dev, | 205 | static int switchdev_port_attr_set_now(struct net_device *dev, |
@@ -225,7 +218,8 @@ static int switchdev_port_attr_set_now(struct net_device *dev, | |||
225 | */ | 218 | */ |
226 | 219 | ||
227 | trans.ph_prepare = true; | 220 | trans.ph_prepare = true; |
228 | err = __switchdev_port_attr_set(dev, attr, &trans); | 221 | err = switchdev_port_attr_notify(SWITCHDEV_PORT_ATTR_SET, dev, attr, |
222 | &trans); | ||
229 | if (err) { | 223 | if (err) { |
230 | /* Prepare phase failed: abort the transaction. Any | 224 | /* Prepare phase failed: abort the transaction. Any |
231 | * resources reserved in the prepare phase are | 225 | * resources reserved in the prepare phase are |
@@ -244,7 +238,8 @@ static int switchdev_port_attr_set_now(struct net_device *dev, | |||
244 | */ | 238 | */ |
245 | 239 | ||
246 | trans.ph_prepare = false; | 240 | trans.ph_prepare = false; |
247 | err = __switchdev_port_attr_set(dev, attr, &trans); | 241 | err = switchdev_port_attr_notify(SWITCHDEV_PORT_ATTR_SET, dev, attr, |
242 | &trans); | ||
248 | WARN(err, "%s: Commit of attribute (id=%d) failed.\n", | 243 | WARN(err, "%s: Commit of attribute (id=%d) failed.\n", |
249 | dev->name, attr->id); | 244 | dev->name, attr->id); |
250 | switchdev_trans_items_warn_destroy(dev, &trans); | 245 | switchdev_trans_items_warn_destroy(dev, &trans); |