net: microchip: sparx5: Add VCAP admin locking in debugFS
authorSteen Hegelund <steen.hegelund@microchip.com>
Tue, 17 Jan 2023 08:55:42 +0000 (09:55 +0100)
committerDavid S. Miller <davem@davemloft.net>
Wed, 18 Jan 2023 14:31:43 +0000 (14:31 +0000)
This ensures that the admin lock is taken before the debugFS functions
starts iterating the VCAP rules.
It also adds a separate function to decode a rule, which expects the lock
to have been taken before it is called.

Signed-off-by: Steen Hegelund <steen.hegelund@microchip.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/microchip/vcap/vcap_api.c
drivers/net/ethernet/microchip/vcap/vcap_api_debugfs.c
drivers/net/ethernet/microchip/vcap/vcap_api_private.h

index f1dc4fd6bb96df12808d4d083dce877aabda160e..198c36627ba1cd0ff1b4b47219d6a3bc4f837d60 100644 (file)
@@ -2170,47 +2170,53 @@ void vcap_free_rule(struct vcap_rule *rule)
 }
 EXPORT_SYMBOL_GPL(vcap_free_rule);
 
-struct vcap_rule *vcap_get_rule(struct vcap_control *vctrl, u32 id)
+/* Decode a rule from the VCAP cache and return a copy */
+struct vcap_rule *vcap_decode_rule(struct vcap_rule_internal *elem)
 {
-       struct vcap_rule_internal *elem;
        struct vcap_rule_internal *ri;
        int err;
 
-       ri = NULL;
-
-       err = vcap_api_check(vctrl);
-       if (err)
-               return ERR_PTR(err);
-       elem = vcap_lookup_rule(vctrl, id);
-       if (!elem)
-               return NULL;
-       mutex_lock(&elem->admin->lock);
        ri = vcap_dup_rule(elem, elem->state == VCAP_RS_DISABLED);
        if (IS_ERR(ri))
-               goto unlock;
+               return ERR_PTR(PTR_ERR(ri));
 
        if (ri->state == VCAP_RS_DISABLED)
-               goto unlock;
+               goto out;
 
        err = vcap_read_rule(ri);
-       if (err) {
-               ri = ERR_PTR(err);
-               goto unlock;
-       }
+       if (err)
+               return ERR_PTR(err);
+
        err = vcap_decode_keyset(ri);
-       if (err) {
-               ri = ERR_PTR(err);
-               goto unlock;
-       }
+       if (err)
+               return ERR_PTR(err);
+
        err = vcap_decode_actionset(ri);
-       if (err) {
-               ri = ERR_PTR(err);
-               goto unlock;
-       }
+       if (err)
+               return ERR_PTR(err);
 
-unlock:
+out:
+       return &ri->data;
+}
+
+struct vcap_rule *vcap_get_rule(struct vcap_control *vctrl, u32 id)
+{
+       struct vcap_rule_internal *elem;
+       struct vcap_rule *rule;
+       int err;
+
+       err = vcap_api_check(vctrl);
+       if (err)
+               return ERR_PTR(err);
+
+       elem = vcap_lookup_rule(vctrl, id);
+       if (!elem)
+               return NULL;
+
+       mutex_lock(&elem->admin->lock);
+       rule = vcap_decode_rule(elem);
        mutex_unlock(&elem->admin->lock);
-       return (struct vcap_rule *)ri;
+       return rule;
 }
 EXPORT_SYMBOL_GPL(vcap_get_rule);
 
index dc06f6d4f513f49ca09306f6141f6e507aec742b..d49b1cf7712f94ba9ad9b0fada8ba9e900f49af0 100644 (file)
@@ -295,7 +295,7 @@ static int vcap_show_admin(struct vcap_control *vctrl,
 
        vcap_show_admin_info(vctrl, admin, out);
        list_for_each_entry(elem, &admin->rules, list) {
-               vrule = vcap_get_rule(vctrl, elem->data.id);
+               vrule = vcap_decode_rule(elem);
                if (IS_ERR_OR_NULL(vrule)) {
                        ret = PTR_ERR(vrule);
                        break;
@@ -404,8 +404,12 @@ static int vcap_debugfs_show(struct seq_file *m, void *unused)
                .prf = (void *)seq_printf,
                .dst = m,
        };
+       int ret;
 
-       return vcap_show_admin(info->vctrl, info->admin, &out);
+       mutex_lock(&info->admin->lock);
+       ret = vcap_show_admin(info->vctrl, info->admin, &out);
+       mutex_unlock(&info->admin->lock);
+       return ret;
 }
 DEFINE_SHOW_ATTRIBUTE(vcap_debugfs);
 
@@ -417,8 +421,12 @@ static int vcap_raw_debugfs_show(struct seq_file *m, void *unused)
                .prf = (void *)seq_printf,
                .dst = m,
        };
+       int ret;
 
-       return vcap_show_admin_raw(info->vctrl, info->admin, &out);
+       mutex_lock(&info->admin->lock);
+       ret = vcap_show_admin_raw(info->vctrl, info->admin, &out);
+       mutex_unlock(&info->admin->lock);
+       return ret;
 }
 DEFINE_SHOW_ATTRIBUTE(vcap_raw_debugfs);
 
index 86542accffe6bd2fe76450bcd494f5f14fb45399..df81d9ff502b31146e4284fec2ebb35023d57122 100644 (file)
@@ -118,4 +118,7 @@ int vcap_find_keystream_keysets(struct vcap_control *vctrl, enum vcap_type vt,
 /* Get the keysets that matches the rule key type/mask */
 int vcap_rule_get_keysets(struct vcap_rule_internal *ri,
                          struct vcap_keyset_list *matches);
+/* Decode a rule from the VCAP cache and return a copy */
+struct vcap_rule *vcap_decode_rule(struct vcap_rule_internal *elem);
+
 #endif /* __VCAP_API_PRIVATE__ */