|
@@ -631,11 +631,13 @@ static int madvise_inject_error(int behavior,
|
|
|
|
|
|
|
|
|
|
for (; start < end; start += PAGE_SIZE << order) {
|
|
for (; start < end; start += PAGE_SIZE << order) {
|
|
|
|
+ unsigned long pfn;
|
|
int ret;
|
|
int ret;
|
|
|
|
|
|
ret = get_user_pages_fast(start, 1, 0, &page);
|
|
ret = get_user_pages_fast(start, 1, 0, &page);
|
|
if (ret != 1)
|
|
if (ret != 1)
|
|
return ret;
|
|
return ret;
|
|
|
|
+ pfn = page_to_pfn(page);
|
|
|
|
|
|
/*
|
|
/*
|
|
* When soft offlining hugepages, after migrating the page
|
|
* When soft offlining hugepages, after migrating the page
|
|
@@ -651,17 +653,25 @@ static int madvise_inject_error(int behavior,
|
|
|
|
|
|
if (behavior == MADV_SOFT_OFFLINE) {
|
|
if (behavior == MADV_SOFT_OFFLINE) {
|
|
pr_info("Soft offlining pfn %#lx at process virtual address %#lx\n",
|
|
pr_info("Soft offlining pfn %#lx at process virtual address %#lx\n",
|
|
- page_to_pfn(page), start);
|
|
|
|
|
|
+ pfn, start);
|
|
|
|
|
|
ret = soft_offline_page(page, MF_COUNT_INCREASED);
|
|
ret = soft_offline_page(page, MF_COUNT_INCREASED);
|
|
if (ret)
|
|
if (ret)
|
|
return ret;
|
|
return ret;
|
|
continue;
|
|
continue;
|
|
}
|
|
}
|
|
|
|
+
|
|
pr_info("Injecting memory failure for pfn %#lx at process virtual address %#lx\n",
|
|
pr_info("Injecting memory failure for pfn %#lx at process virtual address %#lx\n",
|
|
- page_to_pfn(page), start);
|
|
|
|
|
|
+ pfn, start);
|
|
|
|
|
|
- ret = memory_failure(page_to_pfn(page), MF_COUNT_INCREASED);
|
|
|
|
|
|
+ /*
|
|
|
|
+ * Drop the page reference taken by get_user_pages_fast(). In
|
|
|
|
+ * the absence of MF_COUNT_INCREASED the memory_failure()
|
|
|
|
+ * routine is responsible for pinning the page to prevent it
|
|
|
|
+ * from being released back to the page allocator.
|
|
|
|
+ */
|
|
|
|
+ put_page(page);
|
|
|
|
+ ret = memory_failure(pfn, 0);
|
|
if (ret)
|
|
if (ret)
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|