Message ID | CAJtqMcZVQFp8U0aFqrMDD2-UGuLkWYvg3rytcCswnOT_ZMSzjQ@mail.gmail.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | mm/hwpoison: fix incorrect call put_hwpoison_page() when isolate_huge_page() return false | expand |
On Tue, Nov 13, 2018 at 03:00:09PM +0800, Yongkai Wu wrote: > when isolate_huge_page() return false,it won't takes a refcount of page, > if we call put_hwpoison_page() in that case,we may hit the VM_BUG_ON_PAGE! > > Signed-off-by: Yongkai Wu <nic_w@163.com> > --- > mm/memory-failure.c | 13 +++++++------ > 1 file changed, 7 insertions(+), 6 deletions(-) > > diff --git a/mm/memory-failure.c b/mm/memory-failure.c > index 0cd3de3..ed09f56 100644 > --- a/mm/memory-failure.c > +++ b/mm/memory-failure.c > @@ -1699,12 +1699,13 @@ static int soft_offline_huge_page(struct page *page, > int flags) > unlock_page(hpage); > > ret = isolate_huge_page(hpage, &pagelist); > - /* > - * get_any_page() and isolate_huge_page() takes a refcount each, > - * so need to drop one here. > - */ > - put_hwpoison_page(hpage); > - if (!ret) { > + if (ret) { > + /* > + * get_any_page() and isolate_huge_page() takes a refcount each, > + * so need to drop one here. > + */ > + put_hwpoison_page(hpage); > + } else { Hi Yongkai, Although the current code might look odd, it's OK. We have to release one refcount whether this isolate_huge_page() succeeds or not, because the put_hwpoison_page() is cancelling the refcount from get_any_page() which always succeeds when we enter soft_offline_huge_page(). Let's consider that the isolate_huge_page() fails with your patch applied, then the refcount taken by get_any_page() is never released after returning from soft_offline_page(). That will lead to memory leak. I think that current code comment doesn't explaing it well, so if you like, you can fix the comment. (If you do that, please check coding style. scripts/checkpatch.pl will help you.) Thanks, Naoya Horiguchi
Dear Naoya, Thank you for your kind reply. You are right.The current code is ok and I am sorry for wasting your time. Best Regards. On Tue, Nov 13, 2018 at 3:47 PM Naoya Horiguchi <n-horiguchi@ah.jp.nec.com> wrote: > On Tue, Nov 13, 2018 at 03:00:09PM +0800, Yongkai Wu wrote: > > when isolate_huge_page() return false,it won't takes a refcount of page, > > if we call put_hwpoison_page() in that case,we may hit the > VM_BUG_ON_PAGE! > > > > Signed-off-by: Yongkai Wu <nic_w@163.com> > > --- > > mm/memory-failure.c | 13 +++++++------ > > 1 file changed, 7 insertions(+), 6 deletions(-) > > > > diff --git a/mm/memory-failure.c b/mm/memory-failure.c > > index 0cd3de3..ed09f56 100644 > > --- a/mm/memory-failure.c > > +++ b/mm/memory-failure.c > > @@ -1699,12 +1699,13 @@ static int soft_offline_huge_page(struct page > *page, > > int flags) > > unlock_page(hpage); > > > > ret = isolate_huge_page(hpage, &pagelist); > > - /* > > - * get_any_page() and isolate_huge_page() takes a refcount each, > > - * so need to drop one here. > > - */ > > - put_hwpoison_page(hpage); > > - if (!ret) { > > + if (ret) { > > + /* > > + * get_any_page() and isolate_huge_page() takes a refcount > each, > > + * so need to drop one here. > > + */ > > + put_hwpoison_page(hpage); > > + } else { > > Hi Yongkai, > > Although the current code might look odd, it's OK. We have to release > one refcount whether this isolate_huge_page() succeeds or not, because > the put_hwpoison_page() is cancelling the refcount from get_any_page() > which always succeeds when we enter soft_offline_huge_page(). > > Let's consider that the isolate_huge_page() fails with your patch applied, > then the refcount taken by get_any_page() is never released after returning > from soft_offline_page(). That will lead to memory leak. > > I think that current code comment doesn't explaing it well, so if you > like, you can fix the comment. (If you do that, please check coding style. > scripts/checkpatch.pl will help you.) > > Thanks, > Naoya Horiguchi > <div dir="ltr"><div dir="ltr"><div dir="ltr">Dear Naoya,<div>Thank you for your kind reply.</div><div>You are right.The current code is ok and I am sorry for wasting your time.</div><div><br></div><div>Best Regards.</div><div> </div></div></div></div><br><div class="gmail_quote"><div dir="ltr">On Tue, Nov 13, 2018 at 3:47 PM Naoya Horiguchi <<a href="mailto:n-horiguchi@ah.jp.nec.com" target="_blank">n-horiguchi@ah.jp.nec.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">On Tue, Nov 13, 2018 at 03:00:09PM +0800, Yongkai Wu wrote:<br> > when isolate_huge_page() return false,it won't takes a refcount of page,<br> > if we call put_hwpoison_page() in that case,we may hit the VM_BUG_ON_PAGE!<br> > <br> > Signed-off-by: Yongkai Wu <<a href="mailto:nic_w@163.com" target="_blank">nic_w@163.com</a>><br> > ---<br> > mm/memory-failure.c | 13 +++++++------<br> > 1 file changed, 7 insertions(+), 6 deletions(-)<br> > <br> > diff --git a/mm/memory-failure.c b/mm/memory-failure.c<br> > index 0cd3de3..ed09f56 100644<br> > --- a/mm/memory-failure.c<br> > +++ b/mm/memory-failure.c<br> > @@ -1699,12 +1699,13 @@ static int soft_offline_huge_page(struct page *page,<br> > int flags)<br> > unlock_page(hpage);<br> > <br> > ret = isolate_huge_page(hpage, &pagelist);<br> > - /*<br> > - * get_any_page() and isolate_huge_page() takes a refcount each,<br> > - * so need to drop one here.<br> > - */<br> > - put_hwpoison_page(hpage);<br> > - if (!ret) {<br> > + if (ret) {<br> > + /*<br> > + * get_any_page() and isolate_huge_page() takes a refcount each,<br> > + * so need to drop one here.<br> > + */<br> > + put_hwpoison_page(hpage);<br> > + } else {<br> <br> Hi Yongkai,<br> <br> Although the current code might look odd, it's OK. We have to release<br> one refcount whether this isolate_huge_page() succeeds or not, because<br> the put_hwpoison_page() is cancelling the refcount from get_any_page()<br> which always succeeds when we enter soft_offline_huge_page().<br> <br> Let's consider that the isolate_huge_page() fails with your patch applied,<br> then the refcount taken by get_any_page() is never released after returning<br> from soft_offline_page(). That will lead to memory leak.<br> <br> I think that current code comment doesn't explaing it well, so if you<br> like, you can fix the comment. (If you do that, please check coding style.<br> scripts/<a href="http://checkpatch.pl" rel="noreferrer" target="_blank">checkpatch.pl</a> will help you.)<br> <br> Thanks,<br> Naoya Horiguchi<br> </blockquote></div>
diff --git a/mm/memory-failure.c b/mm/memory-failure.c index 0cd3de3..ed09f56 100644 --- a/mm/memory-failure.c +++ b/mm/memory-failure.c @@ -1699,12 +1699,13 @@ static int soft_offline_huge_page(struct page *page, int flags) unlock_page(hpage); ret = isolate_huge_page(hpage, &pagelist); - /* - * get_any_page() and isolate_huge_page() takes a refcount each, - * so need to drop one here. - */ - put_hwpoison_page(hpage); - if (!ret) { + if (ret) { + /* + * get_any_page() and isolate_huge_page() takes a refcount each, + * so need to drop one here. + */ + put_hwpoison_page(hpage); + } else { pr_info("soft offline: %#lx hugepage failed to isolate\n", pfn); return -EBUSY;
when isolate_huge_page() return false,it won't takes a refcount of page, if we call put_hwpoison_page() in that case,we may hit the VM_BUG_ON_PAGE! Signed-off-by: Yongkai Wu <nic_w@163.com> --- mm/memory-failure.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) }