Commit Graph

11 Commits

Author SHA1 Message Date
Ivan Vecera df5de7ae75 mlxsw: spectrum_acl_erp: Fix object nesting warning
JIRA: https://issues.redhat.com/browse/RHEL-67125

commit 97d833ceb27dc19f8777d63f90be4a27b5daeedf
Author: Ido Schimmel <idosch@nvidia.com>
Date:   Thu Jun 6 16:49:42 2024 +0200

    mlxsw: spectrum_acl_erp: Fix object nesting warning

    ACLs in Spectrum-2 and newer ASICs can reside in the algorithmic TCAM
    (A-TCAM) or in the ordinary circuit TCAM (C-TCAM). The former can
    contain more ACLs (i.e., tc filters), but the number of masks in each
    region (i.e., tc chain) is limited.

    In order to mitigate the effects of the above limitation, the device
    allows filters to share a single mask if their masks only differ in up
    to 8 consecutive bits. For example, dst_ip/25 can be represented using
    dst_ip/24 with a delta of 1 bit. The C-TCAM does not have a limit on the
    number of masks being used (and therefore does not support mask
    aggregation), but can contain a limited number of filters.

    The driver uses the "objagg" library to perform the mask aggregation by
    passing it objects that consist of the filter's mask and whether the
    filter is to be inserted into the A-TCAM or the C-TCAM since filters in
    different TCAMs cannot share a mask.

    The set of created objects is dependent on the insertion order of the
    filters and is not necessarily optimal. Therefore, the driver will
    periodically ask the library to compute a more optimal set ("hints") by
    looking at all the existing objects.

    When the library asks the driver whether two objects can be aggregated
    the driver only compares the provided masks and ignores the A-TCAM /
    C-TCAM indication. This is the right thing to do since the goal is to
    move as many filters as possible to the A-TCAM. The driver also forbids
    two identical masks from being aggregated since this can only happen if
    one was intentionally put in the C-TCAM to avoid a conflict in the
    A-TCAM.

    The above can result in the following set of hints:

    H1: {mask X, A-TCAM} -> H2: {mask Y, A-TCAM} // X is Y + delta
    H3: {mask Y, C-TCAM} -> H4: {mask Z, A-TCAM} // Y is Z + delta

    After getting the hints from the library the driver will start migrating
    filters from one region to another while consulting the computed hints
    and instructing the device to perform a lookup in both regions during
    the transition.

    Assuming a filter with mask X is being migrated into the A-TCAM in the
    new region, the hints lookup will return H1. Since H2 is the parent of
    H1, the library will try to find the object associated with it and
    create it if necessary in which case another hints lookup (recursive)
    will be performed. This hints lookup for {mask Y, A-TCAM} will either
    return H2 or H3 since the driver passes the library an object comparison
    function that ignores the A-TCAM / C-TCAM indication.

    This can eventually lead to nested objects which are not supported by
    the library [1].

    Fix by removing the object comparison function from both the driver and
    the library as the driver was the only user. That way the lookup will
    only return exact matches.

    I do not have a reliable reproducer that can reproduce the issue in a
    timely manner, but before the fix the issue would reproduce in several
    minutes and with the fix it does not reproduce in over an hour.

    Note that the current usefulness of the hints is limited because they
    include the C-TCAM indication and represent aggregation that cannot
    actually happen. This will be addressed in net-next.

    [1]
    WARNING: CPU: 0 PID: 153 at lib/objagg.c:170 objagg_obj_parent_assign+0xb5/0xd0
    Modules linked in:
    CPU: 0 PID: 153 Comm: kworker/0:18 Not tainted 6.9.0-rc6-custom-g70fbc2c1c38b #42
    Hardware name: Mellanox Technologies Ltd. MSN3700C/VMOD0008, BIOS 5.11 10/10/2018
    Workqueue: mlxsw_core mlxsw_sp_acl_tcam_vregion_rehash_work
    RIP: 0010:objagg_obj_parent_assign+0xb5/0xd0
    [...]
    Call Trace:
     <TASK>
     __objagg_obj_get+0x2bb/0x580
     objagg_obj_get+0xe/0x80
     mlxsw_sp_acl_erp_mask_get+0xb5/0xf0
     mlxsw_sp_acl_atcam_entry_add+0xe8/0x3c0
     mlxsw_sp_acl_tcam_entry_create+0x5e/0xa0
     mlxsw_sp_acl_tcam_vchunk_migrate_one+0x16b/0x270
     mlxsw_sp_acl_tcam_vregion_rehash_work+0xbe/0x510
     process_one_work+0x151/0x370

    Fixes: 9069a3817d ("lib: objagg: implement optimization hints assembly and use hints for object creation")
    Signed-off-by: Ido Schimmel <idosch@nvidia.com>
    Reviewed-by: Amit Cohen <amcohen@nvidia.com>
    Tested-by: Alexander Zubkov <green@qrator.net>
    Signed-off-by: Petr Machata <petrm@nvidia.com>
    Reviewed-by: Simon Horman <horms@kernel.org>
    Signed-off-by: David S. Miller <davem@davemloft.net>

Signed-off-by: Ivan Vecera <ivecera@redhat.com>
2024-12-03 15:46:17 +01:00
Ivan Vecera 1e027dc989 lib: objagg: Fix spelling
JIRA: https://issues.redhat.com/browse/RHEL-67125

commit c1e156ae50ee520baf4e560b1284677ddfcea974
Author: Ido Schimmel <idosch@nvidia.com>
Date:   Thu Jun 6 16:49:38 2024 +0200

    lib: objagg: Fix spelling

    Fixes: 0a020d416d ("lib: introduce initial implementation of object aggregation manager")
    Signed-off-by: Ido Schimmel <idosch@nvidia.com>
    Reviewed-by: Amit Cohen <amcohen@nvidia.com>
    Tested-by: Alexander Zubkov <green@qrator.net>
    Signed-off-by: Petr Machata <petrm@nvidia.com>
    Reviewed-by: Simon Horman <horms@kernel.org>
    Signed-off-by: David S. Miller <davem@davemloft.net>

Signed-off-by: Ivan Vecera <ivecera@redhat.com>
2024-12-03 15:46:16 +01:00
Waiman Long 74e6153f64 lib: objagg: Fix general protection fault
JIRA: https://issues.redhat.com/browse/RHEL-54790
JIRA: https://issues.redhat.com/browse/RHEL-54793
CVE: CVE-2024-43846

commit b4a3a89fffcdf09702b1f161b914e52abca1894d
Author: Ido Schimmel <idosch@nvidia.com>
Date:   Thu, 6 Jun 2024 16:49:41 +0200

    lib: objagg: Fix general protection fault

    The library supports aggregation of objects into other objects only if
    the parent object does not have a parent itself. That is, nesting is not
    supported.

    Aggregation happens in two cases: Without and with hints, where hints
    are a pre-computed recommendation on how to aggregate the provided
    objects.

    Nesting is not possible in the first case due to a check that prevents
    it, but in the second case there is no check because the assumption is
    that nesting cannot happen when creating objects based on hints. The
    violation of this assumption leads to various warnings and eventually to
    a general protection fault [1].

    Before fixing the root cause, error out when nesting happens and warn.

    [1]
    general protection fault, probably for non-canonical address 0xdead000000000d90: 0000 [#1] PREEMPT SMP PTI
    CPU: 1 PID: 1083 Comm: kworker/1:9 Tainted: G        W          6.9.0-rc6-custom-gd9b4f1cca7fb #7
    Hardware name: Mellanox Technologies Ltd. MSN3700/VMOD0005, BIOS 5.11 01/06/2019
    Workqueue: mlxsw_core mlxsw_sp_acl_tcam_vregion_rehash_work
    RIP: 0010:mlxsw_sp_acl_erp_bf_insert+0x25/0x80
    [...]
    Call Trace:
     <TASK>
     mlxsw_sp_acl_atcam_entry_add+0x256/0x3c0
     mlxsw_sp_acl_tcam_entry_create+0x5e/0xa0
     mlxsw_sp_acl_tcam_vchunk_migrate_one+0x16b/0x270
     mlxsw_sp_acl_tcam_vregion_rehash_work+0xbe/0x510
     process_one_work+0x151/0x370
     worker_thread+0x2cb/0x3e0
     kthread+0xd0/0x100
     ret_from_fork+0x34/0x50
     ret_from_fork_asm+0x1a/0x30
     </TASK>

    Fixes: 9069a3817d ("lib: objagg: implement optimization hints assembly and use hints for object creation")
    Reported-by: Alexander Zubkov <green@qrator.net>
    Signed-off-by: Ido Schimmel <idosch@nvidia.com>
    Reviewed-by: Amit Cohen <amcohen@nvidia.com>
    Tested-by: Alexander Zubkov <green@qrator.net>
    Signed-off-by: Petr Machata <petrm@nvidia.com>
    Reviewed-by: Simon Horman <horms@kernel.org>
    Signed-off-by: David S. Miller <davem@davemloft.net>

Signed-off-by: Waiman Long <longman@redhat.com>
2024-08-21 20:50:48 -04:00
Gustavo A. R. Silva 1f4c51de33 lib: objagg: Replace zero-length arrays with flexible-array member
The current codebase makes use of the zero-length array language
extension to the C90 standard, but the preferred mechanism to declare
variable-length types such as these ones is a flexible array member[1][2],
introduced in C99:

struct foo {
        int stuff;
        struct boo array[];
};

By making use of the mechanism above, we will get a compiler warning
in case the flexible array does not occur last in the structure, which
will help us prevent some kind of undefined behavior bugs from being
inadvertenly introduced[3] to the codebase from now on.

This issue was found with the help of Coccinelle.

[1] https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html
[2] https://github.com/KSPP/linux/issues/21
[3] commit 7649773293 ("cxgb3/l2t: Fix undefined behaviour")

Signed-off-by: Gustavo A. R. Silva <gustavo@embeddedor.com>
Acked-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-02-16 18:33:00 -08:00
Gustavo A. R. Silva e736bf72af lib: objagg: Use struct_size() in kzalloc()
One of the more common cases of allocation size calculations is finding
the size of a structure that has a zero-sized array at the end, along
with memory for some number of elements for that array. For example:

struct objagg_stats {
	...
        struct objagg_obj_stats_info stats_info[];
};

size = sizeof(*objagg_stats) + sizeof(objagg_stats->stats_info[0]) * count;
instance = kzalloc(size, GFP_KERNEL);

Instead of leaving these open-coded and prone to type mistakes, we can
now use the new struct_size() helper:

instance = kzalloc(struct_size(instance, stats_info, count), GFP_KERNEL);

Notice that, in this case, variable alloc_size is not necessary, hence it
is removed.

This code was detected with the help of Coccinelle.

Signed-off-by: Gustavo A. R. Silva <gustavo@embeddedor.com>
Acked-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2019-06-05 19:03:39 -07:00
Jiri Pirko fa8ba2cba7 lib: objagg: fix handling of object with 0 users when assembling hints
It is possible that there might be an originally parent object with 0
direct users that is in hints no longer considered as parent. Then the
weight of this object is 0 and current code ignores him. That's why the
total amount of hint objects might be lower than for the original
objagg and WARN_ON is hit. Fix this be considering 0 weight valid.

Fixes: 9069a3817d ("lib: objagg: implement optimization hints assembly and use hints for object creation")
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
Reviewed-by: Ido Schimmel <idosch@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2019-02-14 12:41:54 -05:00
Dan Carpenter 4446eb8dbe lib: objagg: Fix an error code in objagg_hints_get()
We need to set the error code on this path otherwise we return
ERR_PTR(0) which would result in a NULL dereference in the caller.

Fixes: 9069a3817d ("lib: objagg: implement optimization hints assembly and use hints for object creation")
Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
Acked-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2019-02-13 22:13:29 -08:00
Jiri Pirko 204f6a8c41 lib: objagg: add root count to stats
Count number of roots and add it to stats. It is handy for the library
user to have this stats available as it can act upon it without
counting roots itself.

Signed-off-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: Ido Schimmel <idosch@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2019-02-08 15:02:49 -08:00
Jiri Pirko 9069a3817d lib: objagg: implement optimization hints assembly and use hints for object creation
Implement simple greedy algo to find more optimized root-delta tree for
a given objagg instance. This "hints" can be used by a driver to:
1) check if the hints are better (driver's choice) than the original
   objagg tree. Driver does comparison of objagg stats and hints stats.
2) use the hints to create a new objagg instance which will construct
   the root-delta tree according to the passed hints. Currently, only a
   simple greedy algorithm is implemented. Basically it finds the roots
   according to the maximal possible user count including deltas.

Signed-off-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: Ido Schimmel <idosch@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2019-02-08 15:02:49 -08:00
Jiri Pirko bb72e68bd1 lib: objagg: fix typo in objagg_stats_put() docstring
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: Ido Schimmel <idosch@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2019-02-08 15:02:49 -08:00
Jiri Pirko 0a020d416d lib: introduce initial implementation of object aggregation manager
This lib tracks objects which could be of two types:
1) root object
2) nested object - with a "delta" which differentiates it from
                   the associated root object
The objects are tracked by a hashtable and reference-counted. User is
responsible of implementing callbacks to create/destroy root entity
related to each root object and callback to create/destroy nested object
delta.

Signed-off-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: Ido Schimmel <idosch@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2018-11-15 14:43:43 -08:00