Commit f9ed72dd authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-linus' of git://git.kernel.dk/linux-block

Pull block fixes from Jens Axboe:
 "Two fixes in this pull request:

   - The writeback regression fix from Tejun, which has been weeks in
     the making.  This fixes a case where we would sometimes not issue
     writeback when we should have.

   - An older fix for a memory corruption issue in mtip32xx.  It was
     deferred since we wanted a better fix for this (driver should not
     have to handle that case), but given the timing, it's better to put
     the simple fix in for 4.2 release"

* 'for-linus' of git://git.kernel.dk/linux-block:
  mtip32x: fix regression introduced by blk-mq per-hctx flush
  writeback: sync_inodes_sb() must write out I_DIRTY_TIME inodes and always call wait_sb_inodes()
parents f5db4b31 74c9c913
...@@ -3756,6 +3756,14 @@ static int mtip_init_cmd(void *data, struct request *rq, unsigned int hctx_idx, ...@@ -3756,6 +3756,14 @@ static int mtip_init_cmd(void *data, struct request *rq, unsigned int hctx_idx,
struct mtip_cmd *cmd = blk_mq_rq_to_pdu(rq); struct mtip_cmd *cmd = blk_mq_rq_to_pdu(rq);
u32 host_cap_64 = readl(dd->mmio + HOST_CAP) & HOST_CAP_64; u32 host_cap_64 = readl(dd->mmio + HOST_CAP) & HOST_CAP_64;
/*
* For flush requests, request_idx starts at the end of the
* tag space. Since we don't support FLUSH/FUA, simply return
* 0 as there's nothing to be done.
*/
if (request_idx >= MTIP_MAX_COMMAND_SLOTS)
return 0;
cmd->command = dmam_alloc_coherent(&dd->pdev->dev, CMD_DMA_ALLOC_SZ, cmd->command = dmam_alloc_coherent(&dd->pdev->dev, CMD_DMA_ALLOC_SZ,
&cmd->command_dma, GFP_KERNEL); &cmd->command_dma, GFP_KERNEL);
if (!cmd->command) if (!cmd->command)
......
...@@ -844,14 +844,15 @@ static void bdi_split_work_to_wbs(struct backing_dev_info *bdi, ...@@ -844,14 +844,15 @@ static void bdi_split_work_to_wbs(struct backing_dev_info *bdi,
struct wb_iter iter; struct wb_iter iter;
might_sleep(); might_sleep();
if (!bdi_has_dirty_io(bdi))
return;
restart: restart:
rcu_read_lock(); rcu_read_lock();
bdi_for_each_wb(wb, bdi, &iter, next_blkcg_id) { bdi_for_each_wb(wb, bdi, &iter, next_blkcg_id) {
if (!wb_has_dirty_io(wb) || /* SYNC_ALL writes out I_DIRTY_TIME too */
(skip_if_busy && writeback_in_progress(wb))) if (!wb_has_dirty_io(wb) &&
(base_work->sync_mode == WB_SYNC_NONE ||
list_empty(&wb->b_dirty_time)))
continue;
if (skip_if_busy && writeback_in_progress(wb))
continue; continue;
base_work->nr_pages = wb_split_bdi_pages(wb, nr_pages); base_work->nr_pages = wb_split_bdi_pages(wb, nr_pages);
...@@ -899,8 +900,7 @@ static void bdi_split_work_to_wbs(struct backing_dev_info *bdi, ...@@ -899,8 +900,7 @@ static void bdi_split_work_to_wbs(struct backing_dev_info *bdi,
{ {
might_sleep(); might_sleep();
if (bdi_has_dirty_io(bdi) && if (!skip_if_busy || !writeback_in_progress(&bdi->wb)) {
(!skip_if_busy || !writeback_in_progress(&bdi->wb))) {
base_work->auto_free = 0; base_work->auto_free = 0;
base_work->single_wait = 0; base_work->single_wait = 0;
base_work->single_done = 0; base_work->single_done = 0;
...@@ -2275,8 +2275,12 @@ void sync_inodes_sb(struct super_block *sb) ...@@ -2275,8 +2275,12 @@ void sync_inodes_sb(struct super_block *sb)
}; };
struct backing_dev_info *bdi = sb->s_bdi; struct backing_dev_info *bdi = sb->s_bdi;
/* Nothing to do? */ /*
if (!bdi_has_dirty_io(bdi) || bdi == &noop_backing_dev_info) * Can't skip on !bdi_has_dirty() because we should wait for !dirty
* inodes under writeback and I_DIRTY_TIME inodes ignored by
* bdi_has_dirty() need to be written out too.
*/
if (bdi == &noop_backing_dev_info)
return; return;
WARN_ON(!rwsem_is_locked(&sb->s_umount)); WARN_ON(!rwsem_is_locked(&sb->s_umount));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment