linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/1] writeback fix bdi thread race in mark_inode_dirty
@ 2013-07-19 18:05 Srinivas Eeda
  2013-07-22 13:32 ` Jan Kara
  2013-07-22 15:41 ` Jens Axboe
  0 siblings, 2 replies; 5+ messages in thread
From: Srinivas Eeda @ 2013-07-19 18:05 UTC (permalink / raw)
  To: linux-fsdevel; +Cc: jack, axboe

In __mark_inode_dirty, a process checks !wb_has_dirty_io outside of list_lock
spinlock. This could cause a race, where process sees that list has dirty io
and decides not wake up bdi thread and waits for spinlock to add to dirty list.
Right at this time bdi_writeback_workfn finished write-back on last inode.
It sees the list is empty and ends. Process could now get the spinlock and
add inode to dirty list and doesn't wakeup bdi thread. Future calls to
__mark_inode_dirty also do not wake up the thread because list is not empty
any more.

Fix is to get wb.list_lock spinlock before checking the dirty list

Signed-off-by: Srinivas Eeda <srinivas.eeda@oracle.com>
---
 fs/fs-writeback.c |    5 +++--
 1 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
index 68851ff..a5abc6c 100644
--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -1173,6 +1173,9 @@ void __mark_inode_dirty(struct inode *inode, int flags)
 			bool wakeup_bdi = false;
 			bdi = inode_to_bdi(inode);
 
+			spin_unlock(&inode->i_lock);
+			spin_lock(&bdi->wb.list_lock);
+
 			if (bdi_cap_writeback_dirty(bdi)) {
 				WARN(!test_bit(BDI_registered, &bdi->state),
 				     "bdi-%s not registered\n", bdi->name);
@@ -1187,8 +1190,6 @@ void __mark_inode_dirty(struct inode *inode, int flags)
 					wakeup_bdi = true;
 			}
 
-			spin_unlock(&inode->i_lock);
-			spin_lock(&bdi->wb.list_lock);
 			inode->dirtied_when = jiffies;
 			list_move(&inode->i_wb_list, &bdi->wb.b_dirty);
 			spin_unlock(&bdi->wb.list_lock);
-- 
1.5.6.5


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH 1/1] writeback fix bdi thread race in mark_inode_dirty
  2013-07-19 18:05 [PATCH 1/1] writeback fix bdi thread race in mark_inode_dirty Srinivas Eeda
@ 2013-07-22 13:32 ` Jan Kara
  2013-07-22 15:41 ` Jens Axboe
  1 sibling, 0 replies; 5+ messages in thread
From: Jan Kara @ 2013-07-22 13:32 UTC (permalink / raw)
  To: Srinivas Eeda; +Cc: linux-fsdevel, jack, axboe

On Fri 19-07-13 11:05:40, Srinivas Eeda wrote:
> In __mark_inode_dirty, a process checks !wb_has_dirty_io outside of list_lock
> spinlock. This could cause a race, where process sees that list has dirty io
> and decides not wake up bdi thread and waits for spinlock to add to dirty list.
> Right at this time bdi_writeback_workfn finished write-back on last inode.
> It sees the list is empty and ends. Process could now get the spinlock and
> add inode to dirty list and doesn't wakeup bdi thread. Future calls to
> __mark_inode_dirty also do not wake up the thread because list is not empty
> any more.
> 
> Fix is to get wb.list_lock spinlock before checking the dirty list
> 
> Signed-off-by: Srinivas Eeda <srinivas.eeda@oracle.com>
  Good catch! The patch looks good. You can add:
Reviewed-by: Jan Kara <jack@suse.cz>

								Honza
> ---
>  fs/fs-writeback.c |    5 +++--
>  1 files changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
> index 68851ff..a5abc6c 100644
> --- a/fs/fs-writeback.c
> +++ b/fs/fs-writeback.c
> @@ -1173,6 +1173,9 @@ void __mark_inode_dirty(struct inode *inode, int flags)
>  			bool wakeup_bdi = false;
>  			bdi = inode_to_bdi(inode);
>  
> +			spin_unlock(&inode->i_lock);
> +			spin_lock(&bdi->wb.list_lock);
> +
>  			if (bdi_cap_writeback_dirty(bdi)) {
>  				WARN(!test_bit(BDI_registered, &bdi->state),
>  				     "bdi-%s not registered\n", bdi->name);
> @@ -1187,8 +1190,6 @@ void __mark_inode_dirty(struct inode *inode, int flags)
>  					wakeup_bdi = true;
>  			}
>  
> -			spin_unlock(&inode->i_lock);
> -			spin_lock(&bdi->wb.list_lock);
>  			inode->dirtied_when = jiffies;
>  			list_move(&inode->i_wb_list, &bdi->wb.b_dirty);
>  			spin_unlock(&bdi->wb.list_lock);
> -- 
> 1.5.6.5
> 
-- 
Jan Kara <jack@suse.cz>
SUSE Labs, CR

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH 1/1] writeback fix bdi thread race in mark_inode_dirty
  2013-07-19 18:05 [PATCH 1/1] writeback fix bdi thread race in mark_inode_dirty Srinivas Eeda
  2013-07-22 13:32 ` Jan Kara
@ 2013-07-22 15:41 ` Jens Axboe
  2013-07-22 17:06   ` Srinivas Eeda
  1 sibling, 1 reply; 5+ messages in thread
From: Jens Axboe @ 2013-07-22 15:41 UTC (permalink / raw)
  To: Srinivas Eeda; +Cc: linux-fsdevel, jack

On Fri, Jul 19 2013, Srinivas Eeda wrote:
> In __mark_inode_dirty, a process checks !wb_has_dirty_io outside of list_lock
> spinlock. This could cause a race, where process sees that list has dirty io
> and decides not wake up bdi thread and waits for spinlock to add to dirty list.
> Right at this time bdi_writeback_workfn finished write-back on last inode.
> It sees the list is empty and ends. Process could now get the spinlock and
> add inode to dirty list and doesn't wakeup bdi thread. Future calls to
> __mark_inode_dirty also do not wake up the thread because list is not empty
> any more.
> 
> Fix is to get wb.list_lock spinlock before checking the dirty list

With Jan's ack, lets add this for the current cycle. Should go into
stable as well, imho.

-- 
Jens Axboe


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH 1/1] writeback fix bdi thread race in mark_inode_dirty
  2013-07-22 15:41 ` Jens Axboe
@ 2013-07-22 17:06   ` Srinivas Eeda
  2013-07-22 18:12     ` Jens Axboe
  0 siblings, 1 reply; 5+ messages in thread
From: Srinivas Eeda @ 2013-07-22 17:06 UTC (permalink / raw)
  To: Jens Axboe; +Cc: linux-fsdevel, jack

Hi Jens,

Thanks!

I am new to submitting patches to linux-fsdevel. Is there a mailing list 
I should submit this patch or someone will pick this patch for mainline 
and stable branch?

Thanks,
--Srini

On 07/22/2013 08:41 AM, Jens Axboe wrote:
> On Fri, Jul 19 2013, Srinivas Eeda wrote:
>> In __mark_inode_dirty, a process checks !wb_has_dirty_io outside of list_lock
>> spinlock. This could cause a race, where process sees that list has dirty io
>> and decides not wake up bdi thread and waits for spinlock to add to dirty list.
>> Right at this time bdi_writeback_workfn finished write-back on last inode.
>> It sees the list is empty and ends. Process could now get the spinlock and
>> add inode to dirty list and doesn't wakeup bdi thread. Future calls to
>> __mark_inode_dirty also do not wake up the thread because list is not empty
>> any more.
>>
>> Fix is to get wb.list_lock spinlock before checking the dirty list
> With Jan's ack, lets add this for the current cycle. Should go into
> stable as well, imho.
>


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH 1/1] writeback fix bdi thread race in mark_inode_dirty
  2013-07-22 17:06   ` Srinivas Eeda
@ 2013-07-22 18:12     ` Jens Axboe
  0 siblings, 0 replies; 5+ messages in thread
From: Jens Axboe @ 2013-07-22 18:12 UTC (permalink / raw)
  To: Srinivas Eeda; +Cc: linux-fsdevel, jack

On Mon, Jul 22 2013, Srinivas Eeda wrote:
> Hi Jens,
> 
> Thanks!
> 
> I am new to submitting patches to linux-fsdevel. Is there a mailing list I
> should submit this patch or someone will pick this patch for mainline and
> stable branch?

No that's fine. What is needed is a stable@kernel.org CC, but that can
easily be added after the fact.

-- 
Jens Axboe


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2013-07-22 18:13 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-07-19 18:05 [PATCH 1/1] writeback fix bdi thread race in mark_inode_dirty Srinivas Eeda
2013-07-22 13:32 ` Jan Kara
2013-07-22 15:41 ` Jens Axboe
2013-07-22 17:06   ` Srinivas Eeda
2013-07-22 18:12     ` Jens Axboe

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).