2023-05-24 06:17:03

by Yang Yang

[permalink] [raw]
Subject: [PATCH v9 3/5] ksm: add ksm zero pages for each process

From: xu xin <[email protected]>

As the number of ksm zero pages is not included in ksm_merging_pages per
process when enabling use_zero_pages, it's unclear of how many actual
pages are merged by KSM. To let users accurately estimate their memory
demands when unsharing KSM zero-pages, it's necessary to show KSM zero-
pages per process. In addition, it help users to know the actual KSM
profit because KSM-placed zero pages are also benefit from KSM.

since unsharing zero pages placed by KSM accurately is achieved, then
tracking empty pages merging and unmerging is not a difficult thing any
longer.

Since we already have /proc/<pid>/ksm_stat, just add the information of
'ksm_zero_pages' in it.

Signed-off-by: xu xin <[email protected]>
Cc: Claudio Imbrenda <[email protected]>
Cc: David Hildenbrand <[email protected]>
Cc: Xuexin Jiang <[email protected]>
Cc: Xiaokai Ran <[email protected]>
Cc: Yang Yang <[email protected]>
---
fs/proc/base.c | 1 +
include/linux/ksm.h | 6 ++++--
include/linux/mm_types.h | 9 +++++++--
mm/khugepaged.c | 2 +-
mm/ksm.c | 1 +
mm/memory.c | 4 ++--
6 files changed, 16 insertions(+), 7 deletions(-)

diff --git a/fs/proc/base.c b/fs/proc/base.c
index 05452c3b9872..e407a34a46e8 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -3209,6 +3209,7 @@ static int proc_pid_ksm_stat(struct seq_file *m, struct pid_namespace *ns,
seq_printf(m, "ksm_rmap_items %lu\n", mm->ksm_rmap_items);
seq_printf(m, "ksm_merging_pages %lu\n", mm->ksm_merging_pages);
seq_printf(m, "ksm_process_profit %ld\n", ksm_process_profit(mm));
+ seq_printf(m, "ksm_zero_pages %lu\n", mm->ksm_zero_pages);
mmput(mm);
}

diff --git a/include/linux/ksm.h b/include/linux/ksm.h
index f2d98c53cfec..0e6f04ac3f2b 100644
--- a/include/linux/ksm.h
+++ b/include/linux/ksm.h
@@ -35,10 +35,12 @@ void __ksm_exit(struct mm_struct *mm);

extern unsigned long ksm_zero_pages;

-static inline void ksm_notify_unmap_zero_page(pte_t pte)
+static inline void ksm_notify_unmap_zero_page(struct mm_struct *mm, pte_t pte)
{
- if (is_ksm_zero_pte(pte))
+ if (is_ksm_zero_pte(pte)) {
ksm_zero_pages--;
+ mm->ksm_zero_pages--;
+ }
}

static inline int ksm_fork(struct mm_struct *mm, struct mm_struct *oldmm)
diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
index 306a3d1a0fa6..14f781509812 100644
--- a/include/linux/mm_types.h
+++ b/include/linux/mm_types.h
@@ -777,7 +777,7 @@ struct mm_struct {
#ifdef CONFIG_KSM
/*
* Represent how many pages of this process are involved in KSM
- * merging.
+ * merging (not including ksm_zero_pages).
*/
unsigned long ksm_merging_pages;
/*
@@ -785,7 +785,12 @@ struct mm_struct {
* including merged and not merged.
*/
unsigned long ksm_rmap_items;
-#endif
+ /*
+ * Represent how many empty pages are merged with kernel zero
+ * pages when enabling KSM use_zero_pages.
+ */
+ unsigned long ksm_zero_pages;
+#endif /* CONFIG_KSM */
#ifdef CONFIG_LRU_GEN
struct {
/* this mm_struct is on lru_gen_mm_list */
diff --git a/mm/khugepaged.c b/mm/khugepaged.c
index e417a928ef8d..85dc2e922f64 100644
--- a/mm/khugepaged.c
+++ b/mm/khugepaged.c
@@ -712,7 +712,7 @@ static void __collapse_huge_page_copy_succeeded(pte_t *pte,
spin_lock(ptl);
ptep_clear(vma->vm_mm, address, _pte);
spin_unlock(ptl);
- ksm_notify_unmap_zero_page(pteval);
+ ksm_notify_unmap_zero_page(vma->vm_mm, pteval);
}
} else {
src_page = pte_page(pteval);
diff --git a/mm/ksm.c b/mm/ksm.c
index d3ed90159322..07a6fe7d7c99 100644
--- a/mm/ksm.c
+++ b/mm/ksm.c
@@ -1231,6 +1231,7 @@ static int replace_page(struct vm_area_struct *vma, struct page *page,
*/
newpte = pte_mkdirty(pte_mkspecial(pfn_pte(page_to_pfn(kpage), vma->vm_page_prot)));
ksm_zero_pages++;
+ mm->ksm_zero_pages++;
/*
* We're replacing an anonymous page with a zero page, which is
* not anonymous. We need to do proper accounting otherwise we
diff --git a/mm/memory.c b/mm/memory.c
index 09c31160af4e..26bb291c1c72 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -1416,7 +1416,7 @@ static unsigned long zap_pte_range(struct mmu_gather *tlb,
zap_install_uffd_wp_if_needed(vma, addr, pte, details,
ptent);
if (unlikely(!page)) {
- ksm_notify_unmap_zero_page(ptent);
+ ksm_notify_unmap_zero_page(mm, ptent);
continue;
}

@@ -3122,7 +3122,7 @@ static vm_fault_t wp_page_copy(struct vm_fault *vmf)
inc_mm_counter(mm, MM_ANONPAGES);
}
} else {
- ksm_notify_unmap_zero_page(vmf->orig_pte);
+ ksm_notify_unmap_zero_page(mm, vmf->orig_pte);
inc_mm_counter(mm, MM_ANONPAGES);
}
flush_cache_page(vma, vmf->address, pte_pfn(vmf->orig_pte));
--
2.15.2


2023-05-24 07:38:29

by David Hildenbrand

[permalink] [raw]
Subject: Re: [PATCH v9 3/5] ksm: add ksm zero pages for each process

On 24.05.23 07:58, Yang Yang wrote:
> From: xu xin <[email protected]>
>
> As the number of ksm zero pages is not included in ksm_merging_pages per
> process when enabling use_zero_pages, it's unclear of how many actual
> pages are merged by KSM. To let users accurately estimate their memory
> demands when unsharing KSM zero-pages, it's necessary to show KSM zero-
> pages per process. In addition, it help users to know the actual KSM
> profit because KSM-placed zero pages are also benefit from KSM.
>
> since unsharing zero pages placed by KSM accurately is achieved, then
> tracking empty pages merging and unmerging is not a difficult thing any
> longer.
>
> Since we already have /proc/<pid>/ksm_stat, just add the information of
> 'ksm_zero_pages' in it.
>
> Signed-off-by: xu xin <[email protected]>
> Cc: Claudio Imbrenda <[email protected]>
> Cc: David Hildenbrand <[email protected]>
> Cc: Xuexin Jiang <[email protected]>
> Cc: Xiaokai Ran <[email protected]>
> Cc: Yang Yang <[email protected]>
> ---

[...]

> static inline int ksm_fork(struct mm_struct *mm, struct mm_struct *oldmm)
> diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
> index 306a3d1a0fa6..14f781509812 100644
> --- a/include/linux/mm_types.h
> +++ b/include/linux/mm_types.h
> @@ -777,7 +777,7 @@ struct mm_struct {
> #ifdef CONFIG_KSM
> /*
> * Represent how many pages of this process are involved in KSM
> - * merging.
> + * merging (not including ksm_zero_pages).
> */
> unsigned long ksm_merging_pages;
> /*
> @@ -785,7 +785,12 @@ struct mm_struct {
> * including merged and not merged.
> */
> unsigned long ksm_rmap_items;
> -#endif
> + /*
> + * Represent how many empty pages are merged with kernel zero
> + * pages when enabling KSM use_zero_pages.

"zero page" ? Only some archs have multiple ones, and it's rather an
implementation detail.

> + */
> + unsigned long ksm_zero_pages;
> +#endif /* CONFIG_KSM */
> #ifdef CONFIG_LRU_GEN
> struct {

Reviewed-by: David Hildenbrand <[email protected]>

--
Thanks,

David / dhildenb


2023-05-25 03:57:25

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH v9 3/5] ksm: add ksm zero pages for each process

Hi Yang,

kernel test robot noticed the following build errors:

[auto build test ERROR on akpm-mm/mm-everything]
[also build test ERROR on linus/master v6.4-rc3 next-20230524]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url: https://github.com/intel-lab-lkp/linux/commits/Yang-Yang/ksm-count-all-zero-pages-placed-by-KSM/20230524-153333
base: https://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm.git mm-everything
patch link: https://lore.kernel.org/r/20230524055800.20498-1-yang.yang29%40zte.com.cn
patch subject: [PATCH v9 3/5] ksm: add ksm zero pages for each process
config: powerpc-allnoconfig
compiler: powerpc-linux-gcc (GCC) 12.1.0
reproduce (this is a W=1 build):
mkdir -p ~/bin
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# https://github.com/intel-lab-lkp/linux/commit/c9da8338fa8f95db948cd4d826053d8f6cbcf19c
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review Yang-Yang/ksm-count-all-zero-pages-placed-by-KSM/20230524-153333
git checkout c9da8338fa8f95db948cd4d826053d8f6cbcf19c
# save the config file
mkdir build_dir && cp config build_dir/.config
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 ~/bin/make.cross W=1 O=build_dir ARCH=powerpc olddefconfig
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 ~/bin/make.cross W=1 O=build_dir ARCH=powerpc SHELL=/bin/bash

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <[email protected]>
| Closes: https://lore.kernel.org/oe-kbuild-all/[email protected]/

All error/warnings (new ones prefixed by >>):

mm/memory.c: In function 'zap_pte_range':
>> mm/memory.c:1419:60: warning: passing argument 1 of 'ksm_notify_unmap_zero_page' makes integer from pointer without a cast [-Wint-conversion]
1419 | ksm_notify_unmap_zero_page(mm, ptent);
| ^~
| |
| struct mm_struct *
In file included from mm/memory.c:56:
include/linux/ksm.h:116:53: note: expected 'pte_t' {aka 'long unsigned int'} but argument is of type 'struct mm_struct *'
116 | static inline void ksm_notify_unmap_zero_page(pte_t pte)
| ~~~~~~^~~
>> mm/memory.c:1419:33: error: too many arguments to function 'ksm_notify_unmap_zero_page'
1419 | ksm_notify_unmap_zero_page(mm, ptent);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/ksm.h:116:20: note: declared here
116 | static inline void ksm_notify_unmap_zero_page(pte_t pte)
| ^~~~~~~~~~~~~~~~~~~~~~~~~~
mm/memory.c: In function 'wp_page_copy':
mm/memory.c:3125:52: warning: passing argument 1 of 'ksm_notify_unmap_zero_page' makes integer from pointer without a cast [-Wint-conversion]
3125 | ksm_notify_unmap_zero_page(mm, vmf->orig_pte);
| ^~
| |
| struct mm_struct *
include/linux/ksm.h:116:53: note: expected 'pte_t' {aka 'long unsigned int'} but argument is of type 'struct mm_struct *'
116 | static inline void ksm_notify_unmap_zero_page(pte_t pte)
| ~~~~~~^~~
mm/memory.c:3125:25: error: too many arguments to function 'ksm_notify_unmap_zero_page'
3125 | ksm_notify_unmap_zero_page(mm, vmf->orig_pte);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/ksm.h:116:20: note: declared here
116 | static inline void ksm_notify_unmap_zero_page(pte_t pte)
| ^~~~~~~~~~~~~~~~~~~~~~~~~~


vim +/ksm_notify_unmap_zero_page +1419 mm/memory.c

1376
1377 static unsigned long zap_pte_range(struct mmu_gather *tlb,
1378 struct vm_area_struct *vma, pmd_t *pmd,
1379 unsigned long addr, unsigned long end,
1380 struct zap_details *details)
1381 {
1382 struct mm_struct *mm = tlb->mm;
1383 int force_flush = 0;
1384 int rss[NR_MM_COUNTERS];
1385 spinlock_t *ptl;
1386 pte_t *start_pte;
1387 pte_t *pte;
1388 swp_entry_t entry;
1389
1390 tlb_change_page_size(tlb, PAGE_SIZE);
1391 again:
1392 init_rss_vec(rss);
1393 start_pte = pte_offset_map_lock(mm, pmd, addr, &ptl);
1394 pte = start_pte;
1395 flush_tlb_batched_pending(mm);
1396 arch_enter_lazy_mmu_mode();
1397 do {
1398 pte_t ptent = *pte;
1399 struct page *page;
1400
1401 if (pte_none(ptent))
1402 continue;
1403
1404 if (need_resched())
1405 break;
1406
1407 if (pte_present(ptent)) {
1408 unsigned int delay_rmap;
1409
1410 page = vm_normal_page(vma, addr, ptent);
1411 if (unlikely(!should_zap_page(details, page)))
1412 continue;
1413 ptent = ptep_get_and_clear_full(mm, addr, pte,
1414 tlb->fullmm);
1415 tlb_remove_tlb_entry(tlb, pte, addr);
1416 zap_install_uffd_wp_if_needed(vma, addr, pte, details,
1417 ptent);
1418 if (unlikely(!page)) {
> 1419 ksm_notify_unmap_zero_page(mm, ptent);
1420 continue;
1421 }
1422
1423 delay_rmap = 0;
1424 if (!PageAnon(page)) {
1425 if (pte_dirty(ptent)) {
1426 set_page_dirty(page);
1427 if (tlb_delay_rmap(tlb)) {
1428 delay_rmap = 1;
1429 force_flush = 1;
1430 }
1431 }
1432 if (pte_young(ptent) && likely(vma_has_recency(vma)))
1433 mark_page_accessed(page);
1434 }
1435 rss[mm_counter(page)]--;
1436 if (!delay_rmap) {
1437 page_remove_rmap(page, vma, false);
1438 if (unlikely(page_mapcount(page) < 0))
1439 print_bad_pte(vma, addr, ptent, page);
1440 }
1441 if (unlikely(__tlb_remove_page(tlb, page, delay_rmap))) {
1442 force_flush = 1;
1443 addr += PAGE_SIZE;
1444 break;
1445 }
1446 continue;
1447 }
1448
1449 entry = pte_to_swp_entry(ptent);
1450 if (is_device_private_entry(entry) ||
1451 is_device_exclusive_entry(entry)) {
1452 page = pfn_swap_entry_to_page(entry);
1453 if (unlikely(!should_zap_page(details, page)))
1454 continue;
1455 /*
1456 * Both device private/exclusive mappings should only
1457 * work with anonymous page so far, so we don't need to
1458 * consider uffd-wp bit when zap. For more information,
1459 * see zap_install_uffd_wp_if_needed().
1460 */
1461 WARN_ON_ONCE(!vma_is_anonymous(vma));
1462 rss[mm_counter(page)]--;
1463 if (is_device_private_entry(entry))
1464 page_remove_rmap(page, vma, false);
1465 put_page(page);
1466 } else if (!non_swap_entry(entry)) {
1467 /* Genuine swap entry, hence a private anon page */
1468 if (!should_zap_cows(details))
1469 continue;
1470 rss[MM_SWAPENTS]--;
1471 if (unlikely(!free_swap_and_cache(entry)))
1472 print_bad_pte(vma, addr, ptent, NULL);
1473 } else if (is_migration_entry(entry)) {
1474 page = pfn_swap_entry_to_page(entry);
1475 if (!should_zap_page(details, page))
1476 continue;
1477 rss[mm_counter(page)]--;
1478 } else if (pte_marker_entry_uffd_wp(entry)) {
1479 /*
1480 * For anon: always drop the marker; for file: only
1481 * drop the marker if explicitly requested.
1482 */
1483 if (!vma_is_anonymous(vma) &&
1484 !zap_drop_file_uffd_wp(details))
1485 continue;
1486 } else if (is_hwpoison_entry(entry) ||
1487 is_swapin_error_entry(entry)) {
1488 if (!should_zap_cows(details))
1489 continue;
1490 } else {
1491 /* We should have covered all the swap entry types */
1492 WARN_ON_ONCE(1);
1493 }
1494 pte_clear_not_present_full(mm, addr, pte, tlb->fullmm);
1495 zap_install_uffd_wp_if_needed(vma, addr, pte, details, ptent);
1496 } while (pte++, addr += PAGE_SIZE, addr != end);
1497
1498 add_mm_rss_vec(mm, rss);
1499 arch_leave_lazy_mmu_mode();
1500
1501 /* Do the actual TLB flush before dropping ptl */
1502 if (force_flush) {
1503 tlb_flush_mmu_tlbonly(tlb);
1504 tlb_flush_rmaps(tlb, vma);
1505 }
1506 pte_unmap_unlock(start_pte, ptl);
1507
1508 /*
1509 * If we forced a TLB flush (either due to running out of
1510 * batch buffers or because we needed to flush dirty TLB
1511 * entries before releasing the ptl), free the batched
1512 * memory too. Restart if we didn't do everything.
1513 */
1514 if (force_flush) {
1515 force_flush = 0;
1516 tlb_flush_mmu(tlb);
1517 }
1518
1519 if (addr != end) {
1520 cond_resched();
1521 goto again;
1522 }
1523
1524 return addr;
1525 }
1526

--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


Attachments:
(No filename) (9.47 kB)
config (31.63 kB)
Download all attachments

2023-05-25 07:13:23

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH v9 3/5] ksm: add ksm zero pages for each process

Hi Yang,

kernel test robot noticed the following build errors:

[auto build test ERROR on akpm-mm/mm-everything]
[also build test ERROR on linus/master v6.4-rc3 next-20230525]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url: https://github.com/intel-lab-lkp/linux/commits/Yang-Yang/ksm-count-all-zero-pages-placed-by-KSM/20230524-153333
base: https://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm.git mm-everything
patch link: https://lore.kernel.org/r/20230524055800.20498-1-yang.yang29%40zte.com.cn
patch subject: [PATCH v9 3/5] ksm: add ksm zero pages for each process
config: nios2-defconfig
compiler: nios2-linux-gcc (GCC) 12.1.0
reproduce (this is a W=1 build):
mkdir -p ~/bin
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# https://github.com/intel-lab-lkp/linux/commit/c9da8338fa8f95db948cd4d826053d8f6cbcf19c
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review Yang-Yang/ksm-count-all-zero-pages-placed-by-KSM/20230524-153333
git checkout c9da8338fa8f95db948cd4d826053d8f6cbcf19c
# save the config file
mkdir build_dir && cp config build_dir/.config
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 ~/bin/make.cross W=1 O=build_dir ARCH=nios2 olddefconfig
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 ~/bin/make.cross W=1 O=build_dir ARCH=nios2 SHELL=/bin/bash

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <[email protected]>
| Closes: https://lore.kernel.org/oe-kbuild-all/[email protected]/

All errors (new ones prefixed by >>):

mm/memory.c: In function 'zap_pte_range':
>> mm/memory.c:1419:60: error: incompatible type for argument 1 of 'ksm_notify_unmap_zero_page'
1419 | ksm_notify_unmap_zero_page(mm, ptent);
| ^~
| |
| struct mm_struct *
In file included from mm/memory.c:56:
include/linux/ksm.h:116:53: note: expected 'pte_t' but argument is of type 'struct mm_struct *'
116 | static inline void ksm_notify_unmap_zero_page(pte_t pte)
| ~~~~~~^~~
mm/memory.c:1419:33: error: too many arguments to function 'ksm_notify_unmap_zero_page'
1419 | ksm_notify_unmap_zero_page(mm, ptent);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/ksm.h:116:20: note: declared here
116 | static inline void ksm_notify_unmap_zero_page(pte_t pte)
| ^~~~~~~~~~~~~~~~~~~~~~~~~~
mm/memory.c: In function 'wp_page_copy':
mm/memory.c:3125:52: error: incompatible type for argument 1 of 'ksm_notify_unmap_zero_page'
3125 | ksm_notify_unmap_zero_page(mm, vmf->orig_pte);
| ^~
| |
| struct mm_struct *
include/linux/ksm.h:116:53: note: expected 'pte_t' but argument is of type 'struct mm_struct *'
116 | static inline void ksm_notify_unmap_zero_page(pte_t pte)
| ~~~~~~^~~
mm/memory.c:3125:25: error: too many arguments to function 'ksm_notify_unmap_zero_page'
3125 | ksm_notify_unmap_zero_page(mm, vmf->orig_pte);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/ksm.h:116:20: note: declared here
116 | static inline void ksm_notify_unmap_zero_page(pte_t pte)
| ^~~~~~~~~~~~~~~~~~~~~~~~~~


vim +/ksm_notify_unmap_zero_page +1419 mm/memory.c

1376
1377 static unsigned long zap_pte_range(struct mmu_gather *tlb,
1378 struct vm_area_struct *vma, pmd_t *pmd,
1379 unsigned long addr, unsigned long end,
1380 struct zap_details *details)
1381 {
1382 struct mm_struct *mm = tlb->mm;
1383 int force_flush = 0;
1384 int rss[NR_MM_COUNTERS];
1385 spinlock_t *ptl;
1386 pte_t *start_pte;
1387 pte_t *pte;
1388 swp_entry_t entry;
1389
1390 tlb_change_page_size(tlb, PAGE_SIZE);
1391 again:
1392 init_rss_vec(rss);
1393 start_pte = pte_offset_map_lock(mm, pmd, addr, &ptl);
1394 pte = start_pte;
1395 flush_tlb_batched_pending(mm);
1396 arch_enter_lazy_mmu_mode();
1397 do {
1398 pte_t ptent = *pte;
1399 struct page *page;
1400
1401 if (pte_none(ptent))
1402 continue;
1403
1404 if (need_resched())
1405 break;
1406
1407 if (pte_present(ptent)) {
1408 unsigned int delay_rmap;
1409
1410 page = vm_normal_page(vma, addr, ptent);
1411 if (unlikely(!should_zap_page(details, page)))
1412 continue;
1413 ptent = ptep_get_and_clear_full(mm, addr, pte,
1414 tlb->fullmm);
1415 tlb_remove_tlb_entry(tlb, pte, addr);
1416 zap_install_uffd_wp_if_needed(vma, addr, pte, details,
1417 ptent);
1418 if (unlikely(!page)) {
> 1419 ksm_notify_unmap_zero_page(mm, ptent);
1420 continue;
1421 }
1422
1423 delay_rmap = 0;
1424 if (!PageAnon(page)) {
1425 if (pte_dirty(ptent)) {
1426 set_page_dirty(page);
1427 if (tlb_delay_rmap(tlb)) {
1428 delay_rmap = 1;
1429 force_flush = 1;
1430 }
1431 }
1432 if (pte_young(ptent) && likely(vma_has_recency(vma)))
1433 mark_page_accessed(page);
1434 }
1435 rss[mm_counter(page)]--;
1436 if (!delay_rmap) {
1437 page_remove_rmap(page, vma, false);
1438 if (unlikely(page_mapcount(page) < 0))
1439 print_bad_pte(vma, addr, ptent, page);
1440 }
1441 if (unlikely(__tlb_remove_page(tlb, page, delay_rmap))) {
1442 force_flush = 1;
1443 addr += PAGE_SIZE;
1444 break;
1445 }
1446 continue;
1447 }
1448
1449 entry = pte_to_swp_entry(ptent);
1450 if (is_device_private_entry(entry) ||
1451 is_device_exclusive_entry(entry)) {
1452 page = pfn_swap_entry_to_page(entry);
1453 if (unlikely(!should_zap_page(details, page)))
1454 continue;
1455 /*
1456 * Both device private/exclusive mappings should only
1457 * work with anonymous page so far, so we don't need to
1458 * consider uffd-wp bit when zap. For more information,
1459 * see zap_install_uffd_wp_if_needed().
1460 */
1461 WARN_ON_ONCE(!vma_is_anonymous(vma));
1462 rss[mm_counter(page)]--;
1463 if (is_device_private_entry(entry))
1464 page_remove_rmap(page, vma, false);
1465 put_page(page);
1466 } else if (!non_swap_entry(entry)) {
1467 /* Genuine swap entry, hence a private anon page */
1468 if (!should_zap_cows(details))
1469 continue;
1470 rss[MM_SWAPENTS]--;
1471 if (unlikely(!free_swap_and_cache(entry)))
1472 print_bad_pte(vma, addr, ptent, NULL);
1473 } else if (is_migration_entry(entry)) {
1474 page = pfn_swap_entry_to_page(entry);
1475 if (!should_zap_page(details, page))
1476 continue;
1477 rss[mm_counter(page)]--;
1478 } else if (pte_marker_entry_uffd_wp(entry)) {
1479 /*
1480 * For anon: always drop the marker; for file: only
1481 * drop the marker if explicitly requested.
1482 */
1483 if (!vma_is_anonymous(vma) &&
1484 !zap_drop_file_uffd_wp(details))
1485 continue;
1486 } else if (is_hwpoison_entry(entry) ||
1487 is_swapin_error_entry(entry)) {
1488 if (!should_zap_cows(details))
1489 continue;
1490 } else {
1491 /* We should have covered all the swap entry types */
1492 WARN_ON_ONCE(1);
1493 }
1494 pte_clear_not_present_full(mm, addr, pte, tlb->fullmm);
1495 zap_install_uffd_wp_if_needed(vma, addr, pte, details, ptent);
1496 } while (pte++, addr += PAGE_SIZE, addr != end);
1497
1498 add_mm_rss_vec(mm, rss);
1499 arch_leave_lazy_mmu_mode();
1500
1501 /* Do the actual TLB flush before dropping ptl */
1502 if (force_flush) {
1503 tlb_flush_mmu_tlbonly(tlb);
1504 tlb_flush_rmaps(tlb, vma);
1505 }
1506 pte_unmap_unlock(start_pte, ptl);
1507
1508 /*
1509 * If we forced a TLB flush (either due to running out of
1510 * batch buffers or because we needed to flush dirty TLB
1511 * entries before releasing the ptl), free the batched
1512 * memory too. Restart if we didn't do everything.
1513 */
1514 if (force_flush) {
1515 force_flush = 0;
1516 tlb_flush_mmu(tlb);
1517 }
1518
1519 if (addr != end) {
1520 cond_resched();
1521 goto again;
1522 }
1523
1524 return addr;
1525 }
1526

--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


Attachments:
(No filename) (9.31 kB)
config (44.01 kB)
Download all attachments

2023-05-29 02:09:29

by xu

[permalink] [raw]
Subject: Re: [PATCH v9 3/5] ksm: add ksm zero pages for each process


Already fixed in PACTH v10.

>Hi Yang,
>
>kernel test robot noticed the following build errors:
>
>[auto build test ERROR on akpm-mm/mm-everything]
>[also build test ERROR on linus/master v6.4-rc3 next-20230525]
>[If your patch is applied to the wrong git tree, kindly drop us a note.
>And when submitting patch, we suggest to use '--base' as documented in
>https://git-scm.com/docs/git-format-patch#_base_tree_information]
>
>url: https://github.com/intel-lab-lkp/linux/commits/Yang-Yang/ksm-count-all-zero-pages-placed-by-KSM/20230524-153333
>base: https://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm.git mm-everything
>patch link: https://lore.kernel.org/r/20230524055800.20498-1-yang.yang29%40zte.com.cn
>patch subject: [PATCH v9 3/5] ksm: add ksm zero pages for each process
>config: nios2-defconfig
>compiler: nios2-linux-gcc (GCC) 12.1.0
>reproduce (this is a W=1 build):
> mkdir -p ~/bin
> wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
> chmod +x ~/bin/make.cross
> # https://github.com/intel-lab-lkp/linux/commit/c9da8338fa8f95db948cd4d826053d8f6cbcf19c
> git remote add linux-review https://github.com/intel-lab-lkp/linux
> git fetch --no-tags linux-review Yang-Yang/ksm-count-all-zero-pages-placed-by-KSM/20230524-153333
> git checkout c9da8338fa8f95db948cd4d826053d8f6cbcf19c
> # save the config file
> mkdir build_dir && cp config build_dir/.config
> COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 ~/bin/make.cross W=1 O=build_dir ARCH=nios2 olddefconfig
> COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 ~/bin/make.cross W=1 O=build_dir ARCH=nios2 SHELL=/bin/bash
>
>If you fix the issue, kindly add following tag where applicable
>| Reported-by: kernel test robot <[email protected]>
>| Closes: https://lore.kernel.org/oe-kbuild-all/[email protected]/
>
>All errors (new ones prefixed by >>):
>
> mm/memory.c: In function 'zap_pte_range':
>>> mm/memory.c:1419:60: error: incompatible type for argument 1 of 'ksm_notify_unmap_zero_page'
> 1419 | ksm_notify_unmap_zero_page(mm, ptent);
> | ^~
> | |
> | struct mm_struct *
> In file included from mm/memory.c:56:
> include/linux/ksm.h:116:53: note: expected 'pte_t' but argument is of type 'struct mm_struct *'
> 116 | static inline void ksm_notify_unmap_zero_page(pte_t pte)
> | ~~~~~~^~~
> mm/memory.c:1419:33: error: too many arguments to function 'ksm_notify_unmap_zero_page'
> 1419 | ksm_notify_unmap_zero_page(mm, ptent);
> | ^~~~~~~~~~~~~~~~~~~~~~~~~~
> include/linux/ksm.h:116:20: note: declared here
> 116 | static inline void ksm_notify_unmap_zero_page(pte_t pte)
> | ^~~~~~~~~~~~~~~~~~~~~~~~~~