• Jason Gunthorpe's avatar
    RDMA/cm: Simplify establishing a listen cm_id · 98f67156
    Jason Gunthorpe authored
    Any manipulation of cm_id->state must be done under the cm_id_priv->lock,
    the two routines that added listens did not follow this rule, because they
    never participate in any concurrent access around the state.
    
    However, since this exception makes the code hard to understand, simplify
    the flow so that it can be fully locked:
     - Move manipulation of listen_sharecount into cm_insert_listen() so it is
       trivially under the cm.lock without having to expose the cm.lock to the
       caller.
     - Push the cm.lock down into cm_insert_listen() and have the function
       increment the reference count before returning an existing pointer.
     - Split ib_cm_listen() into an cm_init_listen() and do not call
       ib_cm_listen() from ib_cm_insert_listen()
     - Make both ib_cm_listen() and ib_cm_insert_listen() directly call
       cm_insert_listen() under their cm_id_priv->lock which does both a
       collision detect and, if needed, the insert (atomically)
     - Enclose all state manipulation within the cm_id_priv->lock, notice this
       set can be done safely after cm_insert_listen() as no reader is allowed
       to read the state without holding the lock.
     - Do not set the listen cm_id in the xarray, as it is never correct to
       look it up. This makes the concurrency simpler to understand.
    
    Many needless error unwinds are removed in the process.
    
    Link: https://lore.kernel.org/r/20200310092545.251365-6-leon@kernel.orgSigned-off-by: default avatarLeon Romanovsky <leonro@mellanox.com>
    Signed-off-by: default avatarJason Gunthorpe <jgg@mellanox.com>
    98f67156
cm.c 128 KB