Patch "writeback: keep superblock pinned during cgroup writeback association switches" has been added to the 4.4-stable tree
Subsystems (2)
This is a note to let you know that I've just added the patch titled
writeback: keep superblock pinned during cgroup writeback association switches
to the 4.4-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
writeback-keep-superblock-pinned-during-cgroup-writeback-association-switches.patch
and it can be found in the queue-4.4 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
5ff8eaac1636bf6deae86491f4818c4c69d1a9acMon Sep 17 00:00:00 2001
From: Tejun Heo <[email protected]>
Date: Tue, 16 Feb 2016 11:34:07 -0700
Subject: writeback: keep superblock pinned during cgroup writeback association switches
From: Tejun Heo <[email protected]>
commit 5ff8eaac1636bf6deae86491f4818c4c69d1a9ac upstream.
If cgroup writeback is in use, an inode is associated with a cgroup for writeback. If the inode's main dirtier changes to another cgroup, the association gets updated asynchronously. Nothing was pinning the superblock while such switches are in progress and superblock could go away while async switching is pending or in progress leading to crashes like the following.
kernel BUG at fs/jbd2/transaction.c:319!
invalid opcode: 0000 [#1] SMP DEBUG_PAGEALLOC
CPU: 1 PID: 29158 Comm: kworker/1:10 Not tainted 4.5.0-rc3 #51 Hardware name: Google Google, BIOS Google 01/01/2011 Workqueue: events inode_switch_wbs_work_fn task: ffff880213dbbd40 ti: ffff880209264000 task.ti: ffff880209264000 RIP: 0010:[<ffffffff803e6922>] [<ffffffff803e6922>] start_this_handle+0x382/0x3e0 RSP: 0018:ffff880209267c30 EFLAGS: 00010202 ... Call Trace: [<ffffffff803e6be4>] jbd2__journal_start+0xf4/0x190 [<ffffffff803cfc7e>] __ext4_journal_start_sb+0x4e/0x70 [<ffffffff803b31ec>] ext4_evict_inode+0x12c/0x3d0 [<ffffffff8035338b>] evict+0xbb/0x190 [<ffffffff80354190>] iput+0x130/0x190 [<ffffffff80360223>] inode_switch_wbs_work_fn+0x343/0x4c0 [<ffffffff80279819>] process_one_work+0x129/0x300 [<ffffffff80279b16>] worker_thread+0x126/0x480 [<ffffffff8027ed14>] kthread+0xc4/0xe0 [<ffffffff809771df>] ret_from_fork+0x3f/0x70
Fix it by bumping s_active while cgroup association switching is in flight.
fs/fs-writeback.c +11 -4
@@ -317,6 +317,7 @@ static void inode_switch_wbs_work_fn(struct work_struct *work)struct inode_switch_wbs_context *isw = container_of(work, struct inode_switch_wbs_context, work);struct inode *inode = isw->inode; +struct super_block *sb = inode->i_sb;struct address_space *mapping = inode->i_mapping;struct bdi_writeback *old_wb = inode->i_wb;struct bdi_writeback *new_wb = isw->new_wb;
@@ -423,6 +424,7 @@ skip_switch:wb_put (new_wb);iput (inode); +deactivate_super (sb);kfree (isw); }
@@ -469,11 +471,14 @@ static void inode_switch_wbs(struct inode *inode, int new_wb_id)/* while holding I_WB_SWITCH, no one else can update the association */ spin_lock (&inode->i_lock); +if (inode->i_state & (I_WB_SWITCH |I_FREEING ) || -inode_to_wb (inode) == isw->new_wb) { -spin_unlock (&inode->i_lock); - goto out_free; - } +inode_to_wb (inode) == isw->new_wb) + goto out_unlock; + +if (!atomic_inc_not_zero (&inode->i_sb->s_active)) + goto out_unlock; + inode->i_state |=I_WB_SWITCH ;spin_unlock (&inode->i_lock);
@@ -489,6 +494,8 @@ static void inode_switch_wbs(struct inode *inode, int new_wb_id)call_rcu (&isw->rcu_head, inode_switch_wbs_rcu_fn);return ; +out_unlock: +spin_unlock (&inode->i_lock); out_free:if (isw->new_wb)wb_put (isw->new_wb);
Patches currently in stable-queue which might be from [email protected] are
queue-4.4/writeback-keep-superblock-pinned-during-cgroup-writeback-association-switches.patch queue-4.4/workqueue-handle-numa_no_node-for-unbound-pool_workqueue-lookup.patch queue-4.4/cgroup-make-sure-a-parent-css-isn-t-offlined-before-its-children.patch queue-4.4/cpuset-make-mm-migration-asynchronous.patch queue-4.4/libata-fix-sff-host-state-machine-locking-while-polling.patch queue-4.4/revert-workqueue-make-sure-delayed-work-run-in-local-cpu.patch