1. 14 Dec, 2023 3 commits
    • Jakub Kicinski's avatar
      Merge branch 'net-sched-optimizations-around-action-binding-and-init' · a25ebbf3
      Jakub Kicinski authored
      Pedro Tammela says:
      
      ====================
      net/sched: optimizations around action binding and init
      
      Scaling optimizations for action binding in rtnl-less filters.
      We saw a noticeable lock contention around idrinfo->lock when
      testing in a 56 core system, which disappeared after the patches.
      ====================
      
      Link: https://lore.kernel.org/r/20231211181807.96028-1-pctammela@mojatatu.comSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
      a25ebbf3
    • Pedro Tammela's avatar
      net/sched: act_api: skip idr replace on bound actions · 1dd7f18f
      Pedro Tammela authored
      tcf_idr_insert_many will replace the allocated -EBUSY pointer in
      tcf_idr_check_alloc with the real action pointer, exposing it
      to all operations. This operation is only needed when the action pointer
      is created (ACT_P_CREATED). For actions which are bound to (returned 0),
      the pointer already resides in the idr making such operation a nop.
      
      Even though it's a nop, it's still not a cheap operation as internally
      the idr code walks the idr and then does a replace on the appropriate slot.
      So if the action was bound, better skip the idr replace entirely.
      Signed-off-by: default avatarPedro Tammela <pctammela@mojatatu.com>
      Acked-by: default avatarJamal Hadi Salim <jhs@mojatatu.com>
      Reviewed-by: default avatarVlad Buslov <vladbu@nvidia.com>
      Link: https://lore.kernel.org/r/20231211181807.96028-3-pctammela@mojatatu.comSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
      1dd7f18f
    • Pedro Tammela's avatar
      net/sched: act_api: rely on rcu in tcf_idr_check_alloc · 4b55e867
      Pedro Tammela authored
      Instead of relying only on the idrinfo->lock mutex for
      bind/alloc logic, rely on a combination of rcu + mutex + atomics
      to better scale the case where multiple rtnl-less filters are
      binding to the same action object.
      
      Action binding happens when an action index is specified explicitly and
      an action exists which such index exists. Example:
        tc actions add action drop index 1
        tc filter add ... matchall action drop index 1
        tc filter add ... matchall action drop index 1
        tc filter add ... matchall action drop index 1
        tc filter ls ...
           filter protocol all pref 49150 matchall chain 0 filter protocol all pref 49150 matchall chain 0 handle 0x1
           not_in_hw
                 action order 1: gact action drop
                  random type none pass val 0
                  index 1 ref 4 bind 3
      
         filter protocol all pref 49151 matchall chain 0 filter protocol all pref 49151 matchall chain 0 handle 0x1
           not_in_hw
                 action order 1: gact action drop
                  random type none pass val 0
                  index 1 ref 4 bind 3
      
         filter protocol all pref 49152 matchall chain 0 filter protocol all pref 49152 matchall chain 0 handle 0x1
           not_in_hw
                 action order 1: gact action drop
                  random type none pass val 0
                  index 1 ref 4 bind 3
      
      When no index is specified, as before, grab the mutex and allocate
      in the idr the next available id. In this version, as opposed to before,
      it's simplified to store the -EBUSY pointer instead of the previous
      alloc + replace combination.
      
      When an index is specified, rely on rcu to find if there's an object in
      such index. If there's none, fallback to the above, serializing on the
      mutex and reserving the specified id. If there's one, it can be an -EBUSY
      pointer, in which case we just try again until it's an action, or an action.
      Given the rcu guarantees, the action found could be dead and therefore
      we need to bump the refcount if it's not 0, handling the case it's
      in fact 0.
      
      As bind and the action refcount are already atomics, these increments can
      happen without the mutex protection while many tcf_idr_check_alloc race
      to bind to the same action instance.
      
      In case binding encounters a parallel delete or add, it will return
      -EAGAIN in order to try again. Both filter and action apis already
      have the retry machinery in-place. In case it's an unlocked filter it
      retries under the rtnl lock.
      Signed-off-by: default avatarPedro Tammela <pctammela@mojatatu.com>
      Acked-by: default avatarJamal Hadi Salim <jhs@mojatatu.com>
      Reviewed-by: default avatarVlad Buslov <vladbu@nvidia.com>
      Link: https://lore.kernel.org/r/20231211181807.96028-2-pctammela@mojatatu.comSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
      4b55e867
  2. 13 Dec, 2023 37 commits