• Ying Xue's avatar
    rhashtable: Fix race in rhashtable_destroy() and use regular work_struct · 57699a40
    Ying Xue authored
    When we put our declared work task in the global workqueue with
    schedule_delayed_work(), its delay parameter is always zero.
    Therefore, we should define a regular work in rhashtable structure
    instead of a delayed work.
    By the way, we add a condition to check whether resizing functions
    are NULL before cancelling the work, avoiding to cancel an
    uninitialized work.
    Lastly, while we wait for all work items we submitted before to run
    to completion with cancel_delayed_work(), ht->mutex has been taken in
    rhashtable_destroy(). Moreover, cancel_delayed_work() doesn't return
    until all work items are accomplished, and when work items are
    scheduled, the work's function - rht_deferred_worker() will be called.
    However, as rht_deferred_worker() also needs to acquire the lock,
    deadlock might happen at the moment as the lock is already held before.
    So if the cancel work function is moved out of the lock covered scope,
    this will avoid the deadlock.
    Fixes: 97defe1e ("rhashtable: Per bucket locks & deferred expansion/shrinking")
    Signed-off-by: default avatarYing Xue <ying.xue@windriver.com>
    Cc: Thomas Graf <tgraf@suug.ch>
    Acked-by: default avatarThomas Graf <tgraf@suug.ch>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
rhashtable.c 30.1 KB