• David Howells's avatar
    rxrpc: Don't hold a ref for call timer or workqueue · 3feda9d6
    David Howells authored
    Currently, rxrpc gives the call timer a ref on the call when it starts it
    and this is passed along to the workqueue by the timer expiration function.
    The problem comes when queue_work() fails (ie. the work item is already
    queued): the timer routine must put the ref - but this may cause the
    cleanup code to run.
    
    This has the unfortunate effect that the cleanup code may then be run in
    softirq context - which means that any spinlocks it might need to touch
    have to be guarded to disable softirqs (ie. they need a "_bh" suffix).
    
    Fix this by:
    
     (1) Don't give a ref to the timer.
    
     (2) Making the expiration function not do anything if the refcount is 0.
         Note that this is more of an optimisation.
    
     (3) Make sure that the cleanup routine waits for timer to complete.
    
    However, this has a consequence that timer cannot give a ref to the work
    item.  Therefore the following fixes are also necessary:
    
     (4) Don't give a ref to the work item.
    
     (5) Make the work item return asap if it sees the ref count is 0.
    
     (6) Make sure that the cleanup routine waits for the work item to
         complete.
    
    Unfortunately, neither the timer nor the work item can simply get around
    the problem by just using refcount_inc_not_zero() as the waits would still
    have to be done, and there would still be the possibility of having to put
    the ref in the expiration function.
    
    Note the call work item is going to go away with the work being transferred
    to the I/O thread, so the wait in (6) will become obsolete.
    Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
    cc: Marc Dionne <marc.dionne@auristor.com>
    cc: linux-afs@lists.infradead.org
    3feda9d6
rxrpc.h 52 KB