mm: hide laptop_mode_wb_timer entirely behind the BDI API
authorChristoph Hellwig <hch@lst.de>
Mon, 9 Aug 2021 14:17:40 +0000 (16:17 +0200)
committerJens Axboe <axboe@kernel.dk>
Mon, 9 Aug 2021 17:52:28 +0000 (11:52 -0600)
Don't leak the detaŃ–ls of the timer into the block layer, instead
initialize the timer in bdi_alloc and delete it in bdi_unregister.
Note that this means the timer is initialized (but not armed) for
non-block queues as well now.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Jan Kara <jack@suse.cz>
Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Link: https://lore.kernel.org/r/20210809141744.1203023-2-hch@lst.de
Signed-off-by: Jens Axboe <axboe@kernel.dk>
block/blk-core.c
mm/backing-dev.c
mm/page-writeback.c

index 0447769..5897bc3 100644 (file)
@@ -394,10 +394,7 @@ void blk_cleanup_queue(struct request_queue *q)
        /* for synchronous bio-based driver finish in-flight integrity i/o */
        blk_flush_integrity();
 
-       /* @q won't process any more request, flush async actions */
-       del_timer_sync(&q->backing_dev_info->laptop_mode_wb_timer);
        blk_sync_queue(q);
-
        if (queue_is_mq(q))
                blk_mq_exit_queue(q);
 
@@ -546,8 +543,6 @@ struct request_queue *blk_alloc_queue(int node_id)
 
        atomic_set(&q->nr_active_requests_shared_sbitmap, 0);
 
-       timer_setup(&q->backing_dev_info->laptop_mode_wb_timer,
-                   laptop_mode_timer_fn, 0);
        timer_setup(&q->timeout, blk_rq_timed_out_timer, 0);
        INIT_WORK(&q->timeout_work, blk_timeout_work);
        INIT_LIST_HEAD(&q->icq_list);
index f5561ea..cd06dca 100644 (file)
@@ -807,6 +807,7 @@ struct backing_dev_info *bdi_alloc(int node_id)
        bdi->capabilities = BDI_CAP_WRITEBACK | BDI_CAP_WRITEBACK_ACCT;
        bdi->ra_pages = VM_READAHEAD_PAGES;
        bdi->io_pages = VM_READAHEAD_PAGES;
+       timer_setup(&bdi->laptop_mode_wb_timer, laptop_mode_timer_fn, 0);
        return bdi;
 }
 EXPORT_SYMBOL(bdi_alloc);
@@ -928,6 +929,8 @@ static void bdi_remove_from_list(struct backing_dev_info *bdi)
 
 void bdi_unregister(struct backing_dev_info *bdi)
 {
+       del_timer_sync(&bdi->laptop_mode_wb_timer);
+
        /* make sure nobody finds us on the bdi_list anymore */
        bdi_remove_from_list(bdi);
        wb_shutdown(&bdi->wb);
index 9f63548..c12f67c 100644 (file)
@@ -2010,7 +2010,6 @@ int dirty_writeback_centisecs_handler(struct ctl_table *table, int write,
        return ret;
 }
 
-#ifdef CONFIG_BLOCK
 void laptop_mode_timer_fn(struct timer_list *t)
 {
        struct backing_dev_info *backing_dev_info =
@@ -2045,7 +2044,6 @@ void laptop_sync_completion(void)
 
        rcu_read_unlock();
 }
-#endif
 
 /*
  * If ratelimit_pages is too high then we can get into dirty-data overload