Message ID | 20210402091145.80635-1-songmuchun@bytedance.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | [v3] writeback: fix obtain a reference to a freeing memcg css | expand |
On Fri, Apr 02, 2021 at 05:11:45PM +0800, Muchun Song wrote: > The caller of wb_get_create() should pin the memcg, because > wb_get_create() relies on this guarantee. The rcu read lock > only can guarantee that the memcg css returned by css_from_id() > cannot be released, but the reference of the memcg can be zero. > > rcu_read_lock() > memcg_css = css_from_id() > wb_get_create(memcg_css) > cgwb_create(memcg_css) > // css_get can change the ref counter from 0 back to 1 > css_get(memcg_css) > rcu_read_unlock() > > Fix it by holding a reference to the css before calling > wb_get_create(). This is not a problem I encountered in the > real world. Just the result of a code review. > > Fixes: 682aa8e1a6a1 ("writeback: implement unlocked_inode_to_wb transaction and use it for stat updates") > Signed-off-by: Muchun Song <songmuchun@bytedance.com> > Acked-by: Michal Hocko <mhocko@suse.com> Acked-by: Tejun Heo <tj@kernel.org> Thanks.
Hi, It seems like this patch has not been added to the linux-next tree. Can anyone help with this? Thanks. On Fri, Apr 2, 2021 at 5:13 PM Muchun Song <songmuchun@bytedance.com> wrote: > > The caller of wb_get_create() should pin the memcg, because > wb_get_create() relies on this guarantee. The rcu read lock > only can guarantee that the memcg css returned by css_from_id() > cannot be released, but the reference of the memcg can be zero. > > rcu_read_lock() > memcg_css = css_from_id() > wb_get_create(memcg_css) > cgwb_create(memcg_css) > // css_get can change the ref counter from 0 back to 1 > css_get(memcg_css) > rcu_read_unlock() > > Fix it by holding a reference to the css before calling > wb_get_create(). This is not a problem I encountered in the > real world. Just the result of a code review. > > Fixes: 682aa8e1a6a1 ("writeback: implement unlocked_inode_to_wb transaction and use it for stat updates") > Signed-off-by: Muchun Song <songmuchun@bytedance.com> > Acked-by: Michal Hocko <mhocko@suse.com> > --- > Changelog in v3: > 1. Do not change GFP_ATOMIC. > 2. Update commit log. > > Thanks for Michal's review and suggestions. > > Changelog in v2: > 1. Replace GFP_ATOMIC with GFP_NOIO suggested by Matthew. > > > fs/fs-writeback.c | 9 +++++++-- > 1 file changed, 7 insertions(+), 2 deletions(-) > > diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c > index 3ac002561327..dedde99da40d 100644 > --- a/fs/fs-writeback.c > +++ b/fs/fs-writeback.c > @@ -506,9 +506,14 @@ static void inode_switch_wbs(struct inode *inode, int new_wb_id) > /* find and pin the new wb */ > rcu_read_lock(); > memcg_css = css_from_id(new_wb_id, &memory_cgrp_subsys); > - if (memcg_css) > - isw->new_wb = wb_get_create(bdi, memcg_css, GFP_ATOMIC); > + if (memcg_css && !css_tryget(memcg_css)) > + memcg_css = NULL; > rcu_read_unlock(); > + if (!memcg_css) > + goto out_free; > + > + isw->new_wb = wb_get_create(bdi, memcg_css, GFP_ATOMIC); > + css_put(memcg_css); > if (!isw->new_wb) > goto out_free; > > -- > 2.11.0 >
Hi! On Thu 20-05-21 11:45:23, Muchun Song wrote: > It seems like this patch has not been added to the linux-next > tree. Can anyone help with this? Thanks. Muchun, did someone pickup this patch? I don't see it merged so unless somebody yells, I'll pick it up to my tree and send it to Linus for rc2. Honza > > On Fri, Apr 2, 2021 at 5:13 PM Muchun Song <songmuchun@bytedance.com> wrote: > > > > The caller of wb_get_create() should pin the memcg, because > > wb_get_create() relies on this guarantee. The rcu read lock > > only can guarantee that the memcg css returned by css_from_id() > > cannot be released, but the reference of the memcg can be zero. > > > > rcu_read_lock() > > memcg_css = css_from_id() > > wb_get_create(memcg_css) > > cgwb_create(memcg_css) > > // css_get can change the ref counter from 0 back to 1 > > css_get(memcg_css) > > rcu_read_unlock() > > > > Fix it by holding a reference to the css before calling > > wb_get_create(). This is not a problem I encountered in the > > real world. Just the result of a code review. > > > > Fixes: 682aa8e1a6a1 ("writeback: implement unlocked_inode_to_wb transaction and use it for stat updates") > > Signed-off-by: Muchun Song <songmuchun@bytedance.com> > > Acked-by: Michal Hocko <mhocko@suse.com> > > --- > > Changelog in v3: > > 1. Do not change GFP_ATOMIC. > > 2. Update commit log. > > > > Thanks for Michal's review and suggestions. > > > > Changelog in v2: > > 1. Replace GFP_ATOMIC with GFP_NOIO suggested by Matthew. > > > > > > fs/fs-writeback.c | 9 +++++++-- > > 1 file changed, 7 insertions(+), 2 deletions(-) > > > > diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c > > index 3ac002561327..dedde99da40d 100644 > > --- a/fs/fs-writeback.c > > +++ b/fs/fs-writeback.c > > @@ -506,9 +506,14 @@ static void inode_switch_wbs(struct inode *inode, int new_wb_id) > > /* find and pin the new wb */ > > rcu_read_lock(); > > memcg_css = css_from_id(new_wb_id, &memory_cgrp_subsys); > > - if (memcg_css) > > - isw->new_wb = wb_get_create(bdi, memcg_css, GFP_ATOMIC); > > + if (memcg_css && !css_tryget(memcg_css)) > > + memcg_css = NULL; > > rcu_read_unlock(); > > + if (!memcg_css) > > + goto out_free; > > + > > + isw->new_wb = wb_get_create(bdi, memcg_css, GFP_ATOMIC); > > + css_put(memcg_css); > > if (!isw->new_wb) > > goto out_free; > > > > -- > > 2.11.0 > >
On Tue, Jun 29, 2021 at 12:32 AM Jan Kara <jack@suse.cz> wrote: > > Hi! > > On Thu 20-05-21 11:45:23, Muchun Song wrote: > > It seems like this patch has not been added to the linux-next > > tree. Can anyone help with this? Thanks. > Hi, > Muchun, did someone pickup this patch? I don't see it merged so unless No, not yet. > somebody yells, I'll pick it up to my tree and send it to Linus for rc2. I'll be happy if you do that. Thanks. > > Honza > > > > > On Fri, Apr 2, 2021 at 5:13 PM Muchun Song <songmuchun@bytedance.com> wrote: > > > > > > The caller of wb_get_create() should pin the memcg, because > > > wb_get_create() relies on this guarantee. The rcu read lock > > > only can guarantee that the memcg css returned by css_from_id() > > > cannot be released, but the reference of the memcg can be zero. > > > > > > rcu_read_lock() > > > memcg_css = css_from_id() > > > wb_get_create(memcg_css) > > > cgwb_create(memcg_css) > > > // css_get can change the ref counter from 0 back to 1 > > > css_get(memcg_css) > > > rcu_read_unlock() > > > > > > Fix it by holding a reference to the css before calling > > > wb_get_create(). This is not a problem I encountered in the > > > real world. Just the result of a code review. > > > > > > Fixes: 682aa8e1a6a1 ("writeback: implement unlocked_inode_to_wb transaction and use it for stat updates") > > > Signed-off-by: Muchun Song <songmuchun@bytedance.com> > > > Acked-by: Michal Hocko <mhocko@suse.com> > > > --- > > > Changelog in v3: > > > 1. Do not change GFP_ATOMIC. > > > 2. Update commit log. > > > > > > Thanks for Michal's review and suggestions. > > > > > > Changelog in v2: > > > 1. Replace GFP_ATOMIC with GFP_NOIO suggested by Matthew. > > > > > > > > > fs/fs-writeback.c | 9 +++++++-- > > > 1 file changed, 7 insertions(+), 2 deletions(-) > > > > > > diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c > > > index 3ac002561327..dedde99da40d 100644 > > > --- a/fs/fs-writeback.c > > > +++ b/fs/fs-writeback.c > > > @@ -506,9 +506,14 @@ static void inode_switch_wbs(struct inode *inode, int new_wb_id) > > > /* find and pin the new wb */ > > > rcu_read_lock(); > > > memcg_css = css_from_id(new_wb_id, &memory_cgrp_subsys); > > > - if (memcg_css) > > > - isw->new_wb = wb_get_create(bdi, memcg_css, GFP_ATOMIC); > > > + if (memcg_css && !css_tryget(memcg_css)) > > > + memcg_css = NULL; > > > rcu_read_unlock(); > > > + if (!memcg_css) > > > + goto out_free; > > > + > > > + isw->new_wb = wb_get_create(bdi, memcg_css, GFP_ATOMIC); > > > + css_put(memcg_css); > > > if (!isw->new_wb) > > > goto out_free; > > > > > > -- > > > 2.11.0 > > > > -- > Jan Kara <jack@suse.com> > SUSE Labs, CR
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c index 3ac002561327..dedde99da40d 100644 --- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c @@ -506,9 +506,14 @@ static void inode_switch_wbs(struct inode *inode, int new_wb_id) /* find and pin the new wb */ rcu_read_lock(); memcg_css = css_from_id(new_wb_id, &memory_cgrp_subsys); - if (memcg_css) - isw->new_wb = wb_get_create(bdi, memcg_css, GFP_ATOMIC); + if (memcg_css && !css_tryget(memcg_css)) + memcg_css = NULL; rcu_read_unlock(); + if (!memcg_css) + goto out_free; + + isw->new_wb = wb_get_create(bdi, memcg_css, GFP_ATOMIC); + css_put(memcg_css); if (!isw->new_wb) goto out_free;