Thread (7 messages) 7 messages, 2 authors, 2021-01-27

Re: [PATCH net-next 3/4] bridge: mrp: Extend br_mrp_switchdev to detect better the errors

From: Horatiu Vultur <horatiu.vultur@microchip.com>
Date: 2021-01-27 03:18:15
Also in: bridge, lkml

The 01/25/2021 19:06, Willem de Bruijn wrote:
On Sat, Jan 23, 2021 at 11:23 AM Horatiu Vultur
[off-list ref] wrote:
Hi Willem,
quoted
This patch extends the br_mrp_switchdev functions to be able to have a
better understanding what cause the issue and if the SW needs to be used
as a backup.

There are the following cases:
- when the code is compiled without CONFIG_NET_SWITCHDEV. In this case
  return success so the SW can continue with the protocol. Depending on
  the function it returns 0 or BR_MRP_SW.
- when code is compiled with CONFIG_NET_SWITCHDEV and the driver doesn't
  implement any MRP callbacks, then the HW can't run MRP so it just
  returns -EOPNOTSUPP. So the SW will stop further to configure the
  node.
- when code is compiled with CONFIG_NET_SWITCHDEV and the driver fully
  supports any MRP functionality then the SW doesn't need to do
  anything.  The functions will return 0 or BR_MRP_HW.
- when code is compiled with CONFIG_NET_SWITCHDEV and the HW can't run
  completely the protocol but it can help the SW to run it.  For
  example, the HW can't support completely MRM role(can't detect when it
  stops receiving MRP Test frames) but it can redirect these frames to
  CPU. In this case it is possible to have a SW fallback. The SW will
  try initially to call the driver with sw_backup set to false, meaning
  that the HW can implement completely the role. If the driver returns
  -EOPNOTSUPP, the SW will try again with sw_backup set to false,
  meaning that the SW will detect when it stops receiving the frames. In
  case the driver returns 0 then the SW will continue to configure the
  node accordingly.

In this way is more clear when the SW needs to stop configuring the
node, or when the SW is used as a backup or the HW can implement the
functionality.

Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com>
quoted
-int br_mrp_switchdev_set_ring_role(struct net_bridge *br,
-                                  struct br_mrp *mrp,
-                                  enum br_mrp_ring_role_type role)
+enum br_mrp_hw_support
+br_mrp_switchdev_set_ring_role(struct net_bridge *br, struct br_mrp *mrp,
+                              enum br_mrp_ring_role_type role)
 {
        struct switchdev_obj_ring_role_mrp mrp_role = {
                .obj.orig_dev = br->dev,
                .obj.id = SWITCHDEV_OBJ_ID_RING_ROLE_MRP,
                .ring_role = role,
                .ring_id = mrp->ring_id,
+               .sw_backup = false,
        };
        int err;

+       /* If switchdev is not enabled then just run in SW */
+       if (!IS_ENABLED(CONFIG_NET_SWITCHDEV))
+               return BR_MRP_SW;
+
+       /* First try to see if HW can implement comptletly the role in HW */
typo: completely
quoted
        if (role == BR_MRP_RING_ROLE_DISABLED)
                err = switchdev_port_obj_del(br->dev, &mrp_role.obj);
        else
                err = switchdev_port_obj_add(br->dev, &mrp_role.obj, NULL);

-       return err;
+       /* In case of success then just return and notify the SW that doesn't
+        * need to do anything
+        */
+       if (!err)
+               return BR_MRP_HW;
+
+       /* There was some issue then is not possible at all to have this role so
+        * just return failire
typo: failure
quoted
+        */
+       if (err != -EOPNOTSUPP)
+               return BR_MRP_NONE;
+
+       /* In case the HW can't run complety in HW the protocol, we try again
typo: completely. Please proofread your comments closely. I saw at
least one typo in the commit messages too.
Sorry for that. I will fix those in the next version.
More in general comments that say what the code does can generally be eschewed.
quoted
+        * and this time to allow the SW to help, but the HW needs to redirect
+        * the frames to CPU.
+        */
+       mrp_role.sw_backup = true;
+       err = switchdev_port_obj_add(br->dev, &mrp_role.obj, NULL);
This calls the same function. I did not see code that changes behavior
based on sw_backup. Will this not give the same result?
No, because is the driver responsibility to check that flag and
implement what it can support. If the sw_backup is false, then it is
expected the driver to implement completely the functionality in HW. If
sw_backup is true it just needs to help the SW to run. So the driver can
check this flag and decide what to do.
Also, this lacks the role test (add or del). Is that because if
falling back onto SW mode during add, this code does not get called at
all on delete?
Good catch!. It should have the check.
quoted
+
+       /* In case of success then notify the SW that it needs to help with the
+        * protocol
+        */
+       if (!err)
+               return BR_MRP_SW;
+
+       return BR_MRP_NONE;
 }

-int br_mrp_switchdev_send_ring_test(struct net_bridge *br,
-                                   struct br_mrp *mrp, u32 interval,
-                                   u8 max_miss, u32 period,
-                                   bool monitor)
+enum br_mrp_hw_support
+br_mrp_switchdev_send_ring_test(struct net_bridge *br, struct br_mrp *mrp,
+                               u32 interval, u8 max_miss, u32 period,
+                               bool monitor)
 {
        struct switchdev_obj_ring_test_mrp test = {
                .obj.orig_dev = br->dev,
@@ -79,12 +106,29 @@ int br_mrp_switchdev_send_ring_test(struct net_bridge *br,
        };
        int err;

+       /* If switchdev is not enabled then just run in SW */
+       if (!IS_ENABLED(CONFIG_NET_SWITCHDEV))
+               return BR_MRP_SW;
+
        if (interval == 0)
                err = switchdev_port_obj_del(br->dev, &test.obj);
        else
                err = switchdev_port_obj_add(br->dev, &test.obj, NULL);

-       return err;
+       /* If everything succeed then the HW can send this frames, so the SW
+        * doesn't need to generate them
+        */
+       if (!err)
+               return BR_MRP_HW;
+
+       /* There was an error when the HW was configured so the SW return
+        * failure
+        */
+       if (err != -EOPNOTSUPP)
+               return BR_MRP_NONE;
+
+       /* So the HW can't generate these frames so allow the SW to do that */
+       return BR_MRP_SW;
This is the same ternary test as above. It recurs a few times. Perhaps
it can use a helper.
Yes, I will try to have a look.

-- 
/Horatiu
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help