We should update the entry before we mark it as valid.

Fixes: 93954b40f6a4 ("net-shapers: implement NL set and delete operations")
Signed-off-by: Jakub Kicinski <[email protected]>
---
 net/shaper/shaper.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/net/shaper/shaper.c b/net/shaper/shaper.c
index d2b8f1f951b1..86319ddbf290 100644
--- a/net/shaper/shaper.c
+++ b/net/shaper/shaper.c
@@ -295,6 +295,10 @@ net_shaper_lookup(struct net_shaper_binding *binding,
                                       NET_SHAPER_VALID))
                return NULL;
 
+       /* Pairs with smp_wmb() in net_shaper_commit(): if the entry is
+        * valid, its contents must be visible too.
+        */
+       smp_rmb();
        return xa_load(&hierarchy->shapers, index);
 }
 
@@ -412,8 +416,9 @@ static void net_shaper_commit(struct net_shaper_binding 
*binding,
                /* Successful update: drop the tentative mark
                 * and update the hierarchy container.
                 */
-               __xa_set_mark(&hierarchy->shapers, index, NET_SHAPER_VALID);
                *cur = shapers[i];
+               smp_wmb();
+               __xa_set_mark(&hierarchy->shapers, index, NET_SHAPER_VALID);
        }
        xa_unlock(&hierarchy->shapers);
 }
@@ -837,6 +842,10 @@ int net_shaper_nl_get_dumpit(struct sk_buff *skb,
        for (; (shaper = xa_find(&hierarchy->shapers, &ctx->start_index,
                                 U32_MAX, NET_SHAPER_VALID));
             ctx->start_index++) {
+               /* Pairs with smp_wmb() in net_shaper_commit(): the entry
+                * is marked VALID, so its contents must be visible too.
+                */
+               smp_rmb();
                ret = net_shaper_fill_one(skb, binding, shaper, info);
                if (ret)
                        break;
-- 
2.54.0


Reply via email to