• Tejun Heo's avatar
    RDMAVT: Fix synchronization around percpu_ref · 95da6e96
    Tejun Heo authored
    rvt_mregion uses percpu_ref for reference counting and RCU to protect
    accesses from lkey_table.  When a rvt_mregion needs to be freed, it
    first gets unregistered from lkey_table and then rvt_check_refs() is
    called to wait for in-flight usages before the rvt_mregion is freed.
    
    rvt_check_refs() seems to have a couple issues.
    
    * It has a fast exit path which tests percpu_ref_is_zero().  However,
      a percpu_ref reading zero doesn't mean that the object can be
      released.  In fact, the ->release() callback might not even have
      started executing yet.  Proceeding with freeing can lead to
      use-after-free.
    
    * lkey_table is RCU protected but there is no RCU grace period in the
      free path.  percpu_ref uses RCU internally but it's sched-RCU whose
      grace periods are different from regular RCU.  Also, it generally
      isn't a good idea to depend on internal behaviors like this.
    
    To address the above issues, this patch removes the fast exit and adds
    an explicit synchronize_rcu().
    Signed-off-by: default avatarTejun Heo <tj@kernel.org>
    Acked-by: default avatarDennis Dalessandro <dennis.dalessandro@intel.com>
    Cc: Mike Marciniszyn <mike.marciniszyn@intel.com>
    Cc: linux-rdma@vger.kernel.org
    Cc: Linus Torvalds <torvalds@linux-foundation.org>
    Signed-off-by: default avatarJason Gunthorpe <jgg@mellanox.com>
    95da6e96
mr.c 26.3 KB