1. 14 Dec, 2023 1 commit
    • 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 39 commits