diff mbox series

[ovs-dev] dpif-netlink: avoid netlink modify flow put op failed after tc modify flow put op failed.

Message ID 1583905174-3232-1-git-send-email-wenxu@ucloud.cn
State Accepted
Commit 65b84d4a32bdcb6ed8605988f4cedb58a753e184
Headers show
Series [ovs-dev] dpif-netlink: avoid netlink modify flow put op failed after tc modify flow put op failed. | expand

Commit Message

wenxu March 11, 2020, 5:39 a.m. UTC
From: wenxu <wenxu@ucloud.cn>

The tc modify flow put always delete the original flow first and
then add the new flow. If the modfiy flow put operation failed,
the flow put operation will change from modify to create if success
to delete the original flow in tc (which will be always failed with
ENOENT, the flow is already be deleted before add the new flow in tc).
Finally, the modify flow put will failed to add in kernel datapath.

Signed-off-by: wenxu <wenxu@ucloud.cn>
---
 lib/dpif-netlink.c      | 7 ++++++-
 lib/netdev-offload-tc.c | 2 +-
 lib/netdev-offload.h    | 3 +++
 3 files changed, 10 insertions(+), 2 deletions(-)

Comments

Roi Dayan March 19, 2020, 9:28 a.m. UTC | #1
On 2020-03-11 7:39 AM, wenxu@ucloud.cn wrote:
> From: wenxu <wenxu@ucloud.cn>
> 
> The tc modify flow put always delete the original flow first and
> then add the new flow. If the modfiy flow put operation failed,
> the flow put operation will change from modify to create if success
> to delete the original flow in tc (which will be always failed with
> ENOENT, the flow is already be deleted before add the new flow in tc).
> Finally, the modify flow put will failed to add in kernel datapath.
> 
> Signed-off-by: wenxu <wenxu@ucloud.cn>
> ---
>  lib/dpif-netlink.c      | 7 ++++++-
>  lib/netdev-offload-tc.c | 2 +-
>  lib/netdev-offload.h    | 3 +++
>  3 files changed, 10 insertions(+), 2 deletions(-)
> 
> diff --git a/lib/dpif-netlink.c b/lib/dpif-netlink.c
> index 5b5c96d..b8d08a6 100644
> --- a/lib/dpif-netlink.c
> +++ b/lib/dpif-netlink.c
> @@ -2091,6 +2091,7 @@ parse_flow_put(struct dpif_netlink *dpif, struct dpif_flow_put *put)
>      info.tunnel_csum_on = csum_on;
>      info.recirc_id_shared_with_tc = (dpif->user_features
>                                       & OVS_DP_F_TC_RECIRC_SHARING);
> +    info.tc_modify_flow_deleted = false;
>      err = netdev_flow_put(dev, &match,
>                            CONST_CAST(struct nlattr *, put->actions),
>                            put->actions_len,
> @@ -2141,7 +2142,11 @@ parse_flow_put(struct dpif_netlink *dpif, struct dpif_flow_put *put)
>  out:
>      if (err && err != EEXIST && (put->flags & DPIF_FP_MODIFY)) {
>          /* Modified rule can't be offloaded, try and delete from HW */
> -        int del_err = netdev_flow_del(dev, put->ufid, put->stats);
> +        int del_err = 0;
> +
> +        if (!info.tc_modify_flow_deleted) {
> +            del_err = netdev_flow_del(dev, put->ufid, put->stats);
> +        }
>  
>          if (!del_err) {
>              /* Delete from hw success, so old flow was offloaded.
> diff --git a/lib/netdev-offload-tc.c b/lib/netdev-offload-tc.c
> index 550e440..5e7b873 100644
> --- a/lib/netdev-offload-tc.c
> +++ b/lib/netdev-offload-tc.c
> @@ -1727,7 +1727,7 @@ netdev_tc_flow_put(struct netdev *netdev, struct match *match,
>      if (get_ufid_tc_mapping(ufid, &id) == 0) {
>          VLOG_DBG_RL(&rl, "updating old handle: %d prio: %d",
>                      id.handle, id.prio);
> -        del_filter_and_ufid_mapping(&id, ufid);
> +        info->tc_modify_flow_deleted = !del_filter_and_ufid_mapping(&id, ufid);
>      }
>  
>      prio = get_prio_for_tc_flower(&flower);
> diff --git a/lib/netdev-offload.h b/lib/netdev-offload.h
> index cd6dfdf..b4b882a 100644
> --- a/lib/netdev-offload.h
> +++ b/lib/netdev-offload.h
> @@ -74,6 +74,9 @@ struct offload_info {
>       * it will be in the pkt meta data.
>       */
>      uint32_t flow_mark;
> +
> +    bool tc_modify_flow_deleted; /* Indicate the tc modify flow put success
> +                                  * to delete the original flow. */
>  };
>  
>  int netdev_flow_flush(struct netdev *);
> 

Acked-by: Roi Dayan <roid@mellanox.com>
Simon Horman March 19, 2020, 11:04 a.m. UTC | #2
On Thu, Mar 19, 2020 at 11:28:00AM +0200, Roi Dayan wrote:
> 
> 
> On 2020-03-11 7:39 AM, wenxu@ucloud.cn wrote:
> > From: wenxu <wenxu@ucloud.cn>
> > 
> > The tc modify flow put always delete the original flow first and
> > then add the new flow. If the modfiy flow put operation failed,
> > the flow put operation will change from modify to create if success
> > to delete the original flow in tc (which will be always failed with
> > ENOENT, the flow is already be deleted before add the new flow in tc).
> > Finally, the modify flow put will failed to add in kernel datapath.
> > 
> > Signed-off-by: wenxu <wenxu@ucloud.cn>

...

> Acked-by: Roi Dayan <roid@mellanox.com>

Thanks,

this looks good to me.

I am exercising the patch applied on top of master and branch-2.13
using Travis CI. And I plan to push the patch to those branches if
that succeeds.

The patch does not apply cleanly on branch-2.12. Please consider
posting a backport to that and earlier branches if the change
is appropriate there.
Simon Horman March 19, 2020, 1:44 p.m. UTC | #3
On Thu, Mar 19, 2020 at 12:04:40PM +0100, Simon Horman wrote:
> On Thu, Mar 19, 2020 at 11:28:00AM +0200, Roi Dayan wrote:
> > 
> > 
> > On 2020-03-11 7:39 AM, wenxu@ucloud.cn wrote:
> > > From: wenxu <wenxu@ucloud.cn>
> > > 
> > > The tc modify flow put always delete the original flow first and
> > > then add the new flow. If the modfiy flow put operation failed,
> > > the flow put operation will change from modify to create if success
> > > to delete the original flow in tc (which will be always failed with
> > > ENOENT, the flow is already be deleted before add the new flow in tc).
> > > Finally, the modify flow put will failed to add in kernel datapath.
> > > 
> > > Signed-off-by: wenxu <wenxu@ucloud.cn>
> 
> ...
> 
> > Acked-by: Roi Dayan <roid@mellanox.com>
> 
> Thanks,
> 
> this looks good to me.
> 
> I am exercising the patch applied on top of master and branch-2.13
> using Travis CI. And I plan to push the patch to those branches if
> that succeeds.
> 
> The patch does not apply cleanly on branch-2.12. Please consider
> posting a backport to that and earlier branches if the change
> is appropriate there.

Thanks again, pushed to master and branch-2.13.
diff mbox series

Patch

diff --git a/lib/dpif-netlink.c b/lib/dpif-netlink.c
index 5b5c96d..b8d08a6 100644
--- a/lib/dpif-netlink.c
+++ b/lib/dpif-netlink.c
@@ -2091,6 +2091,7 @@  parse_flow_put(struct dpif_netlink *dpif, struct dpif_flow_put *put)
     info.tunnel_csum_on = csum_on;
     info.recirc_id_shared_with_tc = (dpif->user_features
                                      & OVS_DP_F_TC_RECIRC_SHARING);
+    info.tc_modify_flow_deleted = false;
     err = netdev_flow_put(dev, &match,
                           CONST_CAST(struct nlattr *, put->actions),
                           put->actions_len,
@@ -2141,7 +2142,11 @@  parse_flow_put(struct dpif_netlink *dpif, struct dpif_flow_put *put)
 out:
     if (err && err != EEXIST && (put->flags & DPIF_FP_MODIFY)) {
         /* Modified rule can't be offloaded, try and delete from HW */
-        int del_err = netdev_flow_del(dev, put->ufid, put->stats);
+        int del_err = 0;
+
+        if (!info.tc_modify_flow_deleted) {
+            del_err = netdev_flow_del(dev, put->ufid, put->stats);
+        }
 
         if (!del_err) {
             /* Delete from hw success, so old flow was offloaded.
diff --git a/lib/netdev-offload-tc.c b/lib/netdev-offload-tc.c
index 550e440..5e7b873 100644
--- a/lib/netdev-offload-tc.c
+++ b/lib/netdev-offload-tc.c
@@ -1727,7 +1727,7 @@  netdev_tc_flow_put(struct netdev *netdev, struct match *match,
     if (get_ufid_tc_mapping(ufid, &id) == 0) {
         VLOG_DBG_RL(&rl, "updating old handle: %d prio: %d",
                     id.handle, id.prio);
-        del_filter_and_ufid_mapping(&id, ufid);
+        info->tc_modify_flow_deleted = !del_filter_and_ufid_mapping(&id, ufid);
     }
 
     prio = get_prio_for_tc_flower(&flower);
diff --git a/lib/netdev-offload.h b/lib/netdev-offload.h
index cd6dfdf..b4b882a 100644
--- a/lib/netdev-offload.h
+++ b/lib/netdev-offload.h
@@ -74,6 +74,9 @@  struct offload_info {
      * it will be in the pkt meta data.
      */
     uint32_t flow_mark;
+
+    bool tc_modify_flow_deleted; /* Indicate the tc modify flow put success
+                                  * to delete the original flow. */
 };
 
 int netdev_flow_flush(struct netdev *);