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()
This commit is contained in:
commit
f9ed72dde3
2 changed files with 21 additions and 9 deletions
|
@ -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,
|
||||||
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,
|
||||||
{
|
{
|
||||||
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)
|
||||||
};
|
};
|
||||||
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));
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue