Skip to content
  • Tejun Heo's avatar
    writeback: replace custom worker pool implementation with unbound workqueue · 839a8e86
    Tejun Heo authored
    
    
    Writeback implements its own worker pool - each bdi can be associated
    with a worker thread which is created and destroyed dynamically.  The
    worker thread for the default bdi is always present and serves as the
    "forker" thread which forks off worker threads for other bdis.
    
    there's no reason for writeback to implement its own worker pool when
    using unbound workqueue instead is much simpler and more efficient.
    This patch replaces custom worker pool implementation in writeback
    with an unbound workqueue.
    
    The conversion isn't too complicated but the followings are worth
    mentioning.
    
    * bdi_writeback->last_active, task and wakeup_timer are removed.
      delayed_work ->dwork is added instead.  Explicit timer handling is
      no longer necessary.  Everything works by either queueing / modding
      / flushing / canceling the delayed_work item.
    
    * bdi_writeback_thread() becomes bdi_writeback_workfn() which runs off
      bdi_writeback->dwork.  On each execution, it processes
      bdi->work_list and reschedules itself if there are more things to
      do.
    
      The function also handles low-mem condition, which used to be
      handled by the forker thread.  If the function is running off a
      rescuer thread, it only writes out limited number of pages so that
      the rescuer can serve other bdis too.  This preserves the flusher
      creation failure behavior of the forker thread.
    
    * INIT_LIST_HEAD(&bdi->bdi_list) is used to tell
      bdi_writeback_workfn() about on-going bdi unregistration so that it
      always drains work_list even if it's running off the rescuer.  Note
      that the original code was broken in this regard.  Under memory
      pressure, a bdi could finish unregistration with non-empty
      work_list.
    
    * The default bdi is no longer special.  It now is treated the same as
      any other bdi and bdi_cap_flush_forker() is removed.
    
    * BDI_pending is no longer used.  Removed.
    
    * Some tracepoints become non-applicable.  The following TPs are
      removed - writeback_nothread, writeback_wake_thread,
      writeback_wake_forker_thread, writeback_thread_start,
      writeback_thread_stop.
    
    Everything, including devices coming and going away and rescuer
    operation under simulated memory pressure, seems to work fine in my
    test setup.
    
    Signed-off-by: default avatarTejun Heo <tj@kernel.org>
    Reviewed-by: default avatarJan Kara <jack@suse.cz>
    Cc: Jens Axboe <axboe@kernel.dk>
    Cc: Fengguang Wu <fengguang.wu@intel.com>
    Cc: Jeff Moyer <jmoyer@redhat.com>
    839a8e86