• Tejun Heo's avatar
    workqueue: Preserve OFFQ bits in cancel[_sync] paths · 1211f3b2
    Tejun Heo authored
    The cancel[_sync] paths acquire and release WORK_STRUCT_PENDING, and
    manipulate WORK_OFFQ_CANCELING. However, they assume that all the OFFQ bit
    values except for the pool ID are statically known and don't preserve them,
    which is not wrong in the current code as the pool ID and CANCELING are the
    only information carried. However, the planned disable/enable support will
    add more fields and need them to be preserved.
    
    This patch updates work data handling so that only the bits which need
    updating are updated.
    
    - struct work_offq_data is added along with work_offqd_unpack() and
      work_offqd_pack_flags() to help manipulating multiple fields contained in
      work->data. Note that the helpers look a bit silly right now as there
      isn't that much to pack. The next patch will add more.
    
    - mark_work_canceling() which is used only by __cancel_work_sync() is
      replaced by open-coded usage of work_offq_data and
      set_work_pool_and_keep_pending() in __cancel_work_sync().
    
    - __cancel_work[_sync]() uses offq_data helpers to preserve other OFFQ bits
      when clearing WORK_STRUCT_PENDING and WORK_OFFQ_CANCELING at the end.
    
    - This removes all users of get_work_pool_id() which is dropped. Note that
      get_work_pool_id() could handle both WORK_STRUCT_PWQ and !WORK_STRUCT_PWQ
      cases; however, it was only being called after try_to_grab_pending()
      succeeded, in which case WORK_STRUCT_PWQ is never set and thus it's safe
      to use work_offqd_unpack() instead.
    
    No behavior changes intended.
    Signed-off-by: default avatarTejun Heo <tj@kernel.org>
    Reviewed-by: default avatarLai Jiangshan <jiangshanlai@gmail.com>
    1211f3b2
workqueue.c 221 KB