Patch "writeback: fix memory leak in wb_queue_work()" has been added to the 4.9-stable tree
Subsystems (2)
This is a note to let you know that I've just added the patch titled
writeback: fix memory leak in wb_queue_work()
to the 4.9-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-fix-memory-leak-in-wb_queue_work.patch
and it can be found in the queue-4.9 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 foo@baz Mon Dec 18 14:12:34 CET 2017
From: Tahsin Erdogan <[email protected]>
Date: Fri, 10 Mar 2017 12:09:49 -0800
Subject: writeback: fix memory leak in wb_queue_work()
From: Tahsin Erdogan <[email protected]>
[ Upstream commit 4a3a485b1ed0e109718cc8c9d094fa0f552de9b2 ]
When WB_registered flag is not set, wb_queue_work() skips queuing the work, but does not perform the necessary clean up. In particular, if work->auto_free is true, it should free the memory.
The leak condition can be reprouced by following these steps:
mount /dev/sdb /mnt/sdb
/* In qemu console: device_del sdb */
umount /dev/sdb
Above will result in a wb_queue_work() call on an unregistered wb and thus leak memory.
--- fs/fs-writeback.c | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-)
fs/fs-writeback.c +21 -14
@@ -173,19 +173,33 @@ static void wb_wakeup(struct bdi_writebaspin_unlock_bh (&wb->work_lock); } +static void finish_writeback_work (struct bdi_writeback *wb, +struct wb_writeback_work *work) +{ +struct wb_completion *done = work->done; + +if (work->auto_free) +kfree (work); +if (done &&atomic_dec_and_test (&done->cnt)) +wake_up_all (&wb->bdi->wb_waitq); +} +static void wb_queue_work (struct bdi_writeback *wb,struct wb_writeback_work *work) {trace_writeback_queue (wb, work); -spin_lock_bh (&wb->work_lock); -if (!test_bit (WB_registered, &wb->state)) - goto out_unlock;if (work->done)atomic_inc (&work->done->cnt); -list_add_tail (&work->list, &wb->work_list); -mod_delayed_work (bdi_wq, &wb->dwork,0 ); -out_unlock: + +spin_lock_bh (&wb->work_lock); + +if (test_bit (WB_registered, &wb->state)) { +list_add_tail (&work->list, &wb->work_list); +mod_delayed_work (bdi_wq, &wb->dwork,0 ); + }else +finish_writeback_work (wb, work); +spin_unlock_bh (&wb->work_lock); }
@@ -1875,16 +1889,9 @@ static long wb_do_writeback(struct bdi_wset_bit (WB_writeback_running, &wb->state);while ((work =get_next_work_item (wb)) !=NULL ) { -struct wb_completion *done = work->done; -trace_writeback_exec (wb, work); - wrote +=wb_writeback (wb, work); - -if (work->auto_free) -kfree (work); -if (done &&atomic_dec_and_test (&done->cnt)) -wake_up_all (&wb->bdi->wb_waitq); +finish_writeback_work (wb, work); }/*
Patches currently in stable-queue which might be from [email protected] are
queue-4.9/writeback-fix-memory-leak-in-wb_queue_work.patch