zhenwei pi
2022-May-06 13:38 UTC
[PATCH 3/4] mm/memofy-failure.c: optimize hwpoison_filter
On 5/6/22 16:59, Naoya Horiguchi wrote:> On Fri, Apr 29, 2022 at 10:22:05PM +0800, zhenwei pi wrote: >> In the memory failure procedure, hwpoison_filter has higher priority, >> if memory_filter() filters the error event, there is no need to do >> the further work. > > Could you clarify what problem you are trying to solve (what does > "optimize" mean in this context or what is the benefit)? >OK. The background of this work: As well known, the memory failure mechanism handles memory corrupted event, and try to send SIGBUS to the user process which uses this corrupted page. For the virtualization case, QEMU catches SIGBUS and tries to inject MCE into the guest, and the guest handles memory failure again. Thus the guest gets the minimal effect from hardware memory corruption. The further step I'm working on: 1, try to modify code to decrease poisoned pages in a single place (mm/memofy-failure.c: simplify num_poisoned_pages_dec in this series). 2, try to use page_handle_poison() to handle SetPageHWPoison() and num_poisoned_pages_inc() together. It would be best to call num_poisoned_pages_inc() in a single place too. I'm not sure if this is possible or not, please correct me if I misunderstand. 3, introduce memory failure notifier list in memory-failure.c: notify the corrupted PFN to someone who registers this list. If I can complete [1] and [2] part, [3] will be quite easy(just call notifier list after increasing poisoned page). 4, introduce memory recover VQ for memory balloon device, and registers memory failure notifier list. During the guest kernel handles memory failure, balloon device gets notified by memory failure notifier list, and tells the host to recover the corrupted PFN(GPA) by the new VQ. 5, host side remaps the corrupted page(HVA), and tells the guest side to unpoison the PFN(GPA). Then the guest fixes the corrupted page(GPA) dynamically. Because [4] and [5] are related to balloon device, also CC Michael, David and Jason.> Now hwpoison_filter() can be called both with *and* without taking page refcount. > It's mainly called *with* taking page refcount in order to make sure that the > actual handling process is executed only for pages that meet a given condition. > IOW, it's important to prevent pages which do not meet the condition from going > ahead to further steps (false-positive is not permitted). So this type of > callsite should not be omittable. > > As for the other case, hwpoison_filter() is also called in hwpoison_inject() > *without* taking page refcount. This actually has a different nuance and > intended to speculatively filter the injection events before setting > PageHWPoison flag to reduce the noise due to setting PG_hwpoison temporary. > The point is that it's not intended here to filter precisely and this callsite > is omittable. > > So in my understanding, we need keep hwpoison_filter() after taking page > refcount as we do now. Maybe optionally and additionally calling > hwpoison_filter() at the beginning of memory_failure() might be possible, > but I'm not sure yet how helpful... > > Thanks, > Naoya Horiguchi > >> >> Cc: Wu Fengguang <fengguang.wu at intel.com> >> Signed-off-by: zhenwei pi <pizhenwei at bytedance.com> >> --- >> mm/memory-failure.c | 14 +++++--------- >> 1 file changed, 5 insertions(+), 9 deletions(-) >> >> diff --git a/mm/memory-failure.c b/mm/memory-failure.c >> index ece05858568f..a6a27c8b800f 100644 >> --- a/mm/memory-failure.c >> +++ b/mm/memory-failure.c >> @@ -1800,6 +1800,11 @@ int memory_failure(unsigned long pfn, int flags) >> goto unlock_mutex; >> } >> >> + if (hwpoison_filter(p)) { >> + res = -EOPNOTSUPP; >> + goto unlock_mutex; >> + } >> + >> try_again: >> res = try_memory_failure_hugetlb(pfn, flags, &hugetlb); >> if (hugetlb) >> @@ -1937,15 +1942,6 @@ int memory_failure(unsigned long pfn, int flags) >> */ >> page_flags = p->flags; >> >> - if (hwpoison_filter(p)) { >> - if (TestClearPageHWPoison(p)) >> - num_poisoned_pages_dec(); >> - unlock_page(p); >> - put_page(p); >> - res = -EOPNOTSUPP; >> - goto unlock_mutex; >> - } >> - >> /* >> * __munlock_pagevec may clear a writeback page's LRU flag without >> * page_lock. We need wait writeback completion for this page or it >> -- >> 2.20.1 >>-- zhenwei pi
David Hildenbrand
2022-May-06 16:28 UTC
[PATCH 3/4] mm/memofy-failure.c: optimize hwpoison_filter
On 06.05.22 15:38, zhenwei pi wrote:> > > On 5/6/22 16:59, Naoya Horiguchi wrote: >> On Fri, Apr 29, 2022 at 10:22:05PM +0800, zhenwei pi wrote: >>> In the memory failure procedure, hwpoison_filter has higher priority, >>> if memory_filter() filters the error event, there is no need to do >>> the further work. >> >> Could you clarify what problem you are trying to solve (what does >> "optimize" mean in this context or what is the benefit)? >> > > OK. The background of this work: > As well known, the memory failure mechanism handles memory corrupted > event, and try to send SIGBUS to the user process which uses this > corrupted page. > > For the virtualization case, QEMU catches SIGBUS and tries to inject MCE > into the guest, and the guest handles memory failure again. Thus the > guest gets the minimal effect from hardware memory corruption. > > The further step I'm working on: > 1, try to modify code to decrease poisoned pages in a single place > (mm/memofy-failure.c: simplify num_poisoned_pages_dec in this series). > > 2, try to use page_handle_poison() to handle SetPageHWPoison() and > num_poisoned_pages_inc() together. It would be best to call > num_poisoned_pages_inc() in a single place too. I'm not sure if this is > possible or not, please correct me if I misunderstand. > > 3, introduce memory failure notifier list in memory-failure.c: notify > the corrupted PFN to someone who registers this list. > If I can complete [1] and [2] part, [3] will be quite easy(just call > notifier list after increasing poisoned page). > > 4, introduce memory recover VQ for memory balloon device, and registers > memory failure notifier list. During the guest kernel handles memory > failure, balloon device gets notified by memory failure notifier list, > and tells the host to recover the corrupted PFN(GPA) by the new VQ.Most probably you might want to do that asynchronously, and once the callback succeeds, un-poison the page.> > 5, host side remaps the corrupted page(HVA), and tells the guest side to > unpoison the PFN(GPA). Then the guest fixes the corrupted page(GPA) > dynamically.I think QEMU already does that during reboots. Now it would be triggered by the guest for individual pages.> > Because [4] and [5] are related to balloon device, also CC Michael, > David and Jason.Doesn't sound too crazy for me, although it's a shame that we always have to use virtio-balloon for such fairly balloon-unrelated things. -- Thanks, David / dhildenb