aboutsummaryrefslogtreecommitdiffstats
path: root/net/switchdev/switchdev.c
diff options
context:
space:
mode:
authorFlorian Fainelli <f.fainelli@gmail.com>2019-02-27 14:44:31 -0500
committerDavid S. Miller <davem@davemloft.net>2019-02-27 15:39:56 -0500
commitd45224d604c5ba6ac5f9d6fddbe1d058c81dee80 (patch)
tree1708ef76a424c823156c36c563a242dadcb35c37 /net/switchdev/switchdev.c
parent570b68c8dddea16b96730f7d5d732e270b6a9189 (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.c53
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
177static int __switchdev_port_attr_set(struct net_device *dev, 177static 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
205done: 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
212static int switchdev_port_attr_set_now(struct net_device *dev, 205static 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);