* Re: [RFC PATCH 4/6] mm: Add COW PTE fallback function
@ 2022-05-20 10:16 kernel test robot
0 siblings, 0 replies; 5+ messages in thread
From: kernel test robot @ 2022-05-20 10:16 UTC (permalink / raw)
To: kbuild
[-- Attachment #1: Type: text/plain, Size: 18844 bytes --]
CC: llvm(a)lists.linux.dev
CC: kbuild-all(a)lists.01.org
BCC: lkp(a)intel.com
In-Reply-To: <20220519183127.3909598-5-shiyn.lin@gmail.com>
References: <20220519183127.3909598-5-shiyn.lin@gmail.com>
TO: "Chih-En Lin" <shiyn.lin@gmail.com>
Hi Chih-En,
[FYI, it's a private test report for your RFC patch.]
[auto build test WARNING on tip/sched/core]
[also build test WARNING on soc/for-next linus/master v5.18-rc7 next-20220519]
[cannot apply to akpm-mm/mm-everything]
[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]
url: https://github.com/intel-lab-lkp/linux/commits/Chih-En-Lin/Introduce-Copy-On-Write-to-Page-Table/20220520-023243
base: https://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git 734387ec2f9d77b00276042b1fa7c95f48ee879d
:::::: branch date: 16 hours ago
:::::: commit date: 16 hours ago
config: x86_64-randconfig-c007 (https://download.01.org/0day-ci/archive/20220520/202205201842.2VF5TMYq-lkp(a)intel.com/config)
compiler: clang version 15.0.0 (https://github.com/llvm/llvm-project e00cbbec06c08dc616a0d52a20f678b8fbd4e304)
reproduce (this is a W=1 build):
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/e4e2e178c5a43b37925972bc0eab9976d41d35c7
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review Chih-En-Lin/Introduce-Copy-On-Write-to-Page-Table/20220520-023243
git checkout e4e2e178c5a43b37925972bc0eab9976d41d35c7
# save the config file
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=x86_64 clang-analyzer
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
clang-analyzer warnings: (new ones prefixed by >>)
include/linux/fortify-string.h:369:26: note: expanded from macro 'memcpy'
#define memcpy(p, q, s) __fortify_memcpy_chk(p, q, s, \
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/fortify-string.h:362:2: note: expanded from macro '__fortify_memcpy_chk'
__underlying_##op(p, q, __fortify_size); \
^~~~~~~~~~~~~~~~~
note: expanded from here
include/linux/fortify-string.h:45:29: note: expanded from macro '__underlying_memcpy'
#define __underlying_memcpy __builtin_memcpy
^~~~~~~~~~~~~~~~
Suppressed 47 warnings (46 in non-user code, 1 with check filters).
Use -header-filter=.* to display errors from all non-system headers. Use -system-headers to display errors from system headers as well.
81 warnings generated.
net/atm/mpoa_proc.c:152:3: warning: Call to function 'sprintf' is insecure as it does not provide security checks introduced in the C11 standard. Replace with analogous functions that support length arguments or provides boundary checks such as 'sprintf_s' in case of C11 [clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling]
sprintf(ip_string, "%pI4", &in_entry->ctrl_info.in_dst_ip);
^~~~~~~
net/atm/mpoa_proc.c:152:3: note: Call to function 'sprintf' is insecure as it does not provide security checks introduced in the C11 standard. Replace with analogous functions that support length arguments or provides boundary checks such as 'sprintf_s' in case of C11
sprintf(ip_string, "%pI4", &in_entry->ctrl_info.in_dst_ip);
^~~~~~~
net/atm/mpoa_proc.c:181:3: warning: Call to function 'sprintf' is insecure as it does not provide security checks introduced in the C11 standard. Replace with analogous functions that support length arguments or provides boundary checks such as 'sprintf_s' in case of C11 [clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling]
sprintf(ip_string, "%pI4", &eg_entry->latest_ip_addr);
^~~~~~~
net/atm/mpoa_proc.c:181:3: note: Call to function 'sprintf' is insecure as it does not provide security checks introduced in the C11 standard. Replace with analogous functions that support length arguments or provides boundary checks such as 'sprintf_s' in case of C11
sprintf(ip_string, "%pI4", &eg_entry->latest_ip_addr);
^~~~~~~
net/atm/mpoa_proc.c:251:2: warning: Call to function 'memset' is insecure as it does not provide security checks introduced in the C11 standard. Replace with analogous functions that support length arguments or provides boundary checks such as 'memset_s' in case of C11 [clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling]
memset(&qos, 0, sizeof(struct atm_qos));
^
include/linux/fortify-string.h:272:25: note: expanded from macro 'memset'
#define memset(p, c, s) __fortify_memset_chk(p, c, s, \
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/fortify-string.h:265:2: note: expanded from macro '__fortify_memset_chk'
__underlying_memset(p, c, __fortify_size); \
^~~~~~~~~~~~~~~~~~~
include/linux/fortify-string.h:47:29: note: expanded from macro '__underlying_memset'
#define __underlying_memset __builtin_memset
^~~~~~~~~~~~~~~~
net/atm/mpoa_proc.c:251:2: note: Call to function 'memset' is insecure as it does not provide security checks introduced in the C11 standard. Replace with analogous functions that support length arguments or provides boundary checks such as 'memset_s' in case of C11
memset(&qos, 0, sizeof(struct atm_qos));
^
include/linux/fortify-string.h:272:25: note: expanded from macro 'memset'
#define memset(p, c, s) __fortify_memset_chk(p, c, s, \
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/fortify-string.h:265:2: note: expanded from macro '__fortify_memset_chk'
__underlying_memset(p, c, __fortify_size); \
^~~~~~~~~~~~~~~~~~~
include/linux/fortify-string.h:47:29: note: expanded from macro '__underlying_memset'
#define __underlying_memset __builtin_memset
^~~~~~~~~~~~~~~~
net/atm/mpoa_proc.c:253:6: warning: Call to function 'sscanf' is insecure as it does not provide security checks introduced in the C11 standard. Replace with analogous functions that support length arguments or provides boundary checks such as 'sscanf_s' in case of C11 [clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling]
if (sscanf(buff, "del %hhu.%hhu.%hhu.%hhu",
^~~~~~
net/atm/mpoa_proc.c:253:6: note: Call to function 'sscanf' is insecure as it does not provide security checks introduced in the C11 standard. Replace with analogous functions that support length arguments or provides boundary checks such as 'sscanf_s' in case of C11
if (sscanf(buff, "del %hhu.%hhu.%hhu.%hhu",
^~~~~~
net/atm/mpoa_proc.c:259:6: warning: Call to function 'sscanf' is insecure as it does not provide security checks introduced in the C11 standard. Replace with analogous functions that support length arguments or provides boundary checks such as 'sscanf_s' in case of C11 [clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling]
if (sscanf(buff, "add %hhu.%hhu.%hhu.%hhu tx=%d,%d rx=tx",
^~~~~~
net/atm/mpoa_proc.c:259:6: note: Call to function 'sscanf' is insecure as it does not provide security checks introduced in the C11 standard. Replace with analogous functions that support length arguments or provides boundary checks such as 'sscanf_s' in case of C11
if (sscanf(buff, "add %hhu.%hhu.%hhu.%hhu tx=%d,%d rx=tx",
^~~~~~
net/atm/mpoa_proc.c:263:13: warning: Call to function 'sscanf' is insecure as it does not provide security checks introduced in the C11 standard. Replace with analogous functions that support length arguments or provides boundary checks such as 'sscanf_s' in case of C11 [clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling]
} else if (sscanf(buff, "add %hhu.%hhu.%hhu.%hhu tx=%d,%d rx=%d,%d",
^~~~~~
net/atm/mpoa_proc.c:263:13: note: Call to function 'sscanf' is insecure as it does not provide security checks introduced in the C11 standard. Replace with analogous functions that support length arguments or provides boundary checks such as 'sscanf_s' in case of C11
} else if (sscanf(buff, "add %hhu.%hhu.%hhu.%hhu tx=%d,%d rx=%d,%d",
^~~~~~
Suppressed 75 warnings (75 in non-user code).
Use -header-filter=.* to display errors from all non-system headers. Use -system-headers to display errors from system headers as well.
59 warnings generated.
mm/memory.c:332:2: warning: Value stored to 'p4d' is never read [clang-analyzer-deadcode.DeadStores]
p4d = p4d_offset(pgd, start);
^ ~~~~~~~~~~~~~~~~~~~~~~
mm/memory.c:332:2: note: Value stored to 'p4d' is never read
p4d = p4d_offset(pgd, start);
^ ~~~~~~~~~~~~~~~~~~~~~~
mm/memory.c:495:2: warning: Call to function 'memset' is insecure as it does not provide security checks introduced in the C11 standard. Replace with analogous functions that support length arguments or provides boundary checks such as 'memset_s' in case of C11 [clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling]
memset(rss, 0, sizeof(int) * NR_MM_COUNTERS);
^
include/linux/fortify-string.h:272:25: note: expanded from macro 'memset'
#define memset(p, c, s) __fortify_memset_chk(p, c, s, \
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/fortify-string.h:265:2: note: expanded from macro '__fortify_memset_chk'
__underlying_memset(p, c, __fortify_size); \
^~~~~~~~~~~~~~~~~~~
include/linux/fortify-string.h:47:29: note: expanded from macro '__underlying_memset'
#define __underlying_memset __builtin_memset
^~~~~~~~~~~~~~~~
mm/memory.c:495:2: note: Call to function 'memset' is insecure as it does not provide security checks introduced in the C11 standard. Replace with analogous functions that support length arguments or provides boundary checks such as 'memset_s' in case of C11
memset(rss, 0, sizeof(int) * NR_MM_COUNTERS);
^
include/linux/fortify-string.h:272:25: note: expanded from macro 'memset'
#define memset(p, c, s) __fortify_memset_chk(p, c, s, \
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/fortify-string.h:265:2: note: expanded from macro '__fortify_memset_chk'
__underlying_memset(p, c, __fortify_size); \
^~~~~~~~~~~~~~~~~~~
include/linux/fortify-string.h:47:29: note: expanded from macro '__underlying_memset'
#define __underlying_memset __builtin_memset
^~~~~~~~~~~~~~~~
>> mm/memory.c:1013:2: warning: Value stored to 'orig_ptep' is never read [clang-analyzer-deadcode.DeadStores]
orig_ptep = ptep;
^ ~~~~
mm/memory.c:1013:2: note: Value stored to 'orig_ptep' is never read
orig_ptep = ptep;
^ ~~~~
mm/memory.c:2586:3: warning: 1st function call argument is an uninitialized value [clang-analyzer-core.CallAndMessage]
pte_unmap_unlock(mapped_pte, ptl);
^
include/linux/mm.h:2352:2: note: expanded from macro 'pte_unmap_unlock'
spin_unlock(ptl); \
^
mm/memory.c:2758:9: note: Calling '__apply_to_page_range'
return __apply_to_page_range(mm, addr, size, fn, data, false);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
mm/memory.c:2710:14: note: Assuming 'addr' is < 'end'
if (WARN_ON(addr >= end))
^
include/asm-generic/bug.h:122:25: note: expanded from macro 'WARN_ON'
int __ret_warn_on = !!(condition); \
^~~~~~~~~
mm/memory.c:2710:6: note: Taking false branch
if (WARN_ON(addr >= end))
^
include/asm-generic/bug.h:123:2: note: expanded from macro 'WARN_ON'
if (unlikely(__ret_warn_on)) \
^
mm/memory.c:2710:2: note: Taking false branch
if (WARN_ON(addr >= end))
^
mm/memory.c:2715:10: note: Assuming the condition is false
next = pgd_addr_end(addr, end);
^
include/linux/pgtable.h:784:3: note: expanded from macro 'pgd_addr_end'
(__boundary - 1 < (end) - 1)? __boundary: (end); \
^~~~~~~~~~~~~~~~~~~~~~~~~~
mm/memory.c:2715:10: note: '?' condition is false
next = pgd_addr_end(addr, end);
^
include/linux/pgtable.h:784:2: note: expanded from macro 'pgd_addr_end'
(__boundary - 1 < (end) - 1)? __boundary: (end); \
^
mm/memory.c:2716:22: note: Left side of '&&' is false
if (pgd_none(*pgd) && !create)
^
mm/memory.c:2718:7: note: Taking false branch
if (WARN_ON_ONCE(pgd_leaf(*pgd)))
^
include/asm-generic/bug.h:111:2: note: expanded from macro 'WARN_ON_ONCE'
if (unlikely(__ret_warn_on)) \
^
mm/memory.c:2718:3: note: Taking false branch
if (WARN_ON_ONCE(pgd_leaf(*pgd)))
^
mm/memory.c:2720:7: note: Left side of '&&' is true
if (!pgd_none(*pgd) && WARN_ON_ONCE(pgd_bad(*pgd))) {
^
mm/memory.c:2720:26: note: Taking false branch
if (!pgd_none(*pgd) && WARN_ON_ONCE(pgd_bad(*pgd))) {
^
include/asm-generic/bug.h:111:2: note: expanded from macro 'WARN_ON_ONCE'
if (unlikely(__ret_warn_on)) \
^
mm/memory.c:2720:3: note: Taking false branch
if (!pgd_none(*pgd) && WARN_ON_ONCE(pgd_bad(*pgd))) {
^
mm/memory.c:2725:9: note: Calling 'apply_to_p4d_range'
err = apply_to_p4d_range(mm, pgd, addr, next,
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
mm/memory.c:2673:6: note: 'create' is false
if (create) {
^~~~~~
mm/memory.c:2673:2: note: Taking false branch
if (create) {
^
mm/memory.c:2682:22: note: Left side of '&&' is false
if (p4d_none(*p4d) && !create)
^
mm/memory.c:2684:7: note: Taking false branch
if (WARN_ON_ONCE(p4d_leaf(*p4d)))
^
include/asm-generic/bug.h:111:2: note: expanded from macro 'WARN_ON_ONCE'
if (unlikely(__ret_warn_on)) \
^
mm/memory.c:2684:3: note: Taking false branch
if (WARN_ON_ONCE(p4d_leaf(*p4d)))
^
mm/memory.c:2686:7: note: Left side of '&&' is true
if (!p4d_none(*p4d) && WARN_ON_ONCE(p4d_bad(*p4d))) {
^
mm/memory.c:2686:26: note: Taking false branch
if (!p4d_none(*p4d) && WARN_ON_ONCE(p4d_bad(*p4d))) {
^
include/asm-generic/bug.h:111:2: note: expanded from macro 'WARN_ON_ONCE'
if (unlikely(__ret_warn_on)) \
^
mm/memory.c:2686:3: note: Taking false branch
if (!p4d_none(*p4d) && WARN_ON_ONCE(p4d_bad(*p4d))) {
^
mm/memory.c:2691:9: note: Calling 'apply_to_pud_range'
err = apply_to_pud_range(mm, p4d, addr, next,
vim +/orig_ptep +1013 mm/memory.c
^1da177e4c3f41 Linus Torvalds 2005-04-16 1002
e4e2e178c5a43b Chih-En Lin 2022-05-20 1003 static inline void cow_pte_rss(struct mm_struct *mm, struct vm_area_struct *vma,
e4e2e178c5a43b Chih-En Lin 2022-05-20 1004 pmd_t *pmdp, unsigned long addr, unsigned long end, bool inc_dec)
e4e2e178c5a43b Chih-En Lin 2022-05-20 1005 {
e4e2e178c5a43b Chih-En Lin 2022-05-20 1006 int rss[NR_MM_COUNTERS];
e4e2e178c5a43b Chih-En Lin 2022-05-20 1007 pte_t *orig_ptep, *ptep;
e4e2e178c5a43b Chih-En Lin 2022-05-20 1008 struct page *page;
e4e2e178c5a43b Chih-En Lin 2022-05-20 1009
e4e2e178c5a43b Chih-En Lin 2022-05-20 1010 init_rss_vec(rss);
e4e2e178c5a43b Chih-En Lin 2022-05-20 1011
e4e2e178c5a43b Chih-En Lin 2022-05-20 1012 ptep = pte_offset_map(pmdp, addr);
e4e2e178c5a43b Chih-En Lin 2022-05-20 @1013 orig_ptep = ptep;
e4e2e178c5a43b Chih-En Lin 2022-05-20 1014 arch_enter_lazy_mmu_mode();
e4e2e178c5a43b Chih-En Lin 2022-05-20 1015 do {
e4e2e178c5a43b Chih-En Lin 2022-05-20 1016 if (pte_none(*ptep) || pte_special(*ptep))
e4e2e178c5a43b Chih-En Lin 2022-05-20 1017 continue;
e4e2e178c5a43b Chih-En Lin 2022-05-20 1018
e4e2e178c5a43b Chih-En Lin 2022-05-20 1019 page = vm_normal_page(vma, addr, *ptep);
e4e2e178c5a43b Chih-En Lin 2022-05-20 1020 if (page) {
e4e2e178c5a43b Chih-En Lin 2022-05-20 1021 if (inc_dec)
e4e2e178c5a43b Chih-En Lin 2022-05-20 1022 rss[mm_counter(page)]++;
e4e2e178c5a43b Chih-En Lin 2022-05-20 1023 else
e4e2e178c5a43b Chih-En Lin 2022-05-20 1024 rss[mm_counter(page)]--;
e4e2e178c5a43b Chih-En Lin 2022-05-20 1025 }
e4e2e178c5a43b Chih-En Lin 2022-05-20 1026 } while (ptep++, addr += PAGE_SIZE, addr != end);
e4e2e178c5a43b Chih-En Lin 2022-05-20 1027 arch_leave_lazy_mmu_mode();
e4e2e178c5a43b Chih-En Lin 2022-05-20 1028 add_mm_rss_vec(mm, rss);
e4e2e178c5a43b Chih-En Lin 2022-05-20 1029 }
e4e2e178c5a43b Chih-En Lin 2022-05-20 1030
--
0-DAY CI Kernel Test Service
https://01.org/lkp
^ permalink raw reply [flat|nested] 5+ messages in thread* [RFC PATCH 0/6] Introduce Copy-On-Write to Page Table
@ 2022-05-19 18:31 Chih-En Lin
2022-05-19 18:31 ` [RFC PATCH 4/6] mm: Add COW PTE fallback function Chih-En Lin
0 siblings, 1 reply; 5+ messages in thread
From: Chih-En Lin @ 2022-05-19 18:31 UTC (permalink / raw)
To: Andrew Morton, linux-mm
Cc: Ingo Molnar, Peter Zijlstra, Juri Lelli, Vincent Guittot,
Dietmar Eggemann, Steven Rostedt, Ben Segall, Mel Gorman,
Daniel Bristot de Oliveira, Christian Brauner,
Matthew Wilcox (Oracle), Vlastimil Babka, William Kucharski,
John Hubbard, Yunsheng Lin, Arnd Bergmann, Suren Baghdasaryan,
Chih-En Lin, Colin Cross, Feng Tang, Eric W. Biederman,
Mike Rapoport, Geert Uytterhoeven, Anshuman Khandual,
Aneesh Kumar K.V, Daniel Axtens, Jonathan Marek, Christophe Leroy,
Pasha Tatashin, Peter Xu, Andrea Arcangeli, Thomas Gleixner,
Andy Lutomirski, Sebastian Andrzej Siewior, Fenghua Yu,
David Hildenbrand, linux-kernel, Kaiyang Zhao, Huichun Feng,
Jim Huang
When creating the user process, it usually uses the Copy-On-Write (COW)
mechanism to save the memory usage and the cost of time for copying.
COW defers the work of copying private memory and shares it across the
processes as read-only. If either process wants to write in these
memories, it will page fault and copy the shared memory, so the process
will now get its private memory right here, which is called break COW.
Presently this kind of technology is only used as the mapping memory.
It still needs to copy the entire page table from the parent.
It might cost a lot of time and memory to copy each page table when the
parent already has a lot of page tables allocated. For example, here is
the state table for mapping the 1 GB memory of forking.
mmap before fork mmap after fork
MemTotal: 32746776 kB 32746776 kB
MemFree: 31468152 kB 31463244 kB
AnonPages: 1073836 kB 1073628 kB
Mapped: 39520 kB 39992 kB
PageTables: 3356 kB 5432 kB
This patch introduces Copy-On-Write to the page table. This patch only
implements the COW on the PTE level. It's based on the paper
On-Demand Fork [1]. Summary of the implementation for the paper:
- Only implements the COW to the anonymous mapping
- Only do COW to the PTE table which the range is all covered by a
single VMA.
- Use the reference count to control the COW PTE table lifetime.
Decrease the counter when breaking COW or dereference the COW PTE
table. When the counter reduces to zero, free the PTE table.
The paper is based on v5.6, and this patch is for v.518-rc6. And, this
patch has some differences between the version of paper. To reduce the
work of duplicating page tables, I adapted the restriction of the COW
page table. Excluding the brk and shared memory, it will do the COW to
all the PTE tables. With a reference count of one, we reuse the table
when breaking COW. To handle the page table state of the process, it
adds the ownership of the COW PTE table. It uses the address of the PMD
index for the ownership of the PTE table to maintain the COW PTE table
state to the RSS and pgtable_bytes.
If we do the COW to the PTE table once as the time we touch the PMD
entry, it cannot preserves the reference count of the COW PTE table.
Since the address range of VMA may overlap the PTE table, the copying
function will use VMA to travel the page table for copying it.
So it may increase the reference count of the COW PTE table multiple
times in one COW page table forking. Generically it will only increase
once time as the child reference it. To solve this problem, it needs to
check the destination of PMD entry does exist. And the reference count
of the source PTE table is more than one before doing the COW.
Here is the patch of a state table for mapping the 1 GB memory of
forking.
mmap before fork mmap after fork
MemTotal: 32746776 kB 32746776 kB
MemFree: 31471324 kB 31468888 kB
AnonPages: 1073628 kB 1073660 kB
Mapped: 39264 kB 39504 kB
PageTables: 3304 kB 3396 kB
TODO list:
- Handle the swap
- Rewrite the TLB flush for zapping the COW PTE table.
- Experiment COW to the entire page table. (Now just for PTE level)
- Bug in some case from copy_pte_range()::vm_normal_page()::print_bad_pte().
- Bug of Bad RSS counter in multiple times COW PTE table forking.
[1] https://dl.acm.org/doi/10.1145/3447786.3456258
This patch is based on v5.18-rc6.
---
Chih-En Lin (6):
mm: Add a new mm flag for Copy-On-Write PTE table
mm: clone3: Add CLONE_COW_PGTABLE flag
mm, pgtable: Add ownership for the PTE table
mm: Add COW PTE fallback function
mm, pgtable: Add the reference counter for COW PTE
mm: Expand Copy-On-Write to PTE table
include/linux/mm.h | 2 +
include/linux/mm_types.h | 2 +
include/linux/pgtable.h | 44 +++++
include/linux/sched/coredump.h | 5 +-
include/uapi/linux/sched.h | 1 +
kernel/fork.c | 6 +-
mm/memory.c | 329 ++++++++++++++++++++++++++++++---
mm/mmap.c | 4 +
mm/mremap.c | 5 +
9 files changed, 373 insertions(+), 25 deletions(-)
--
2.36.1
^ permalink raw reply [flat|nested] 5+ messages in thread* [RFC PATCH 4/6] mm: Add COW PTE fallback function
2022-05-19 18:31 [RFC PATCH 0/6] Introduce Copy-On-Write to Page Table Chih-En Lin
@ 2022-05-19 18:31 ` Chih-En Lin
2022-05-20 0:20 ` kernel test robot
2022-05-20 14:21 ` Christophe Leroy
0 siblings, 2 replies; 5+ messages in thread
From: Chih-En Lin @ 2022-05-19 18:31 UTC (permalink / raw)
To: Andrew Morton, linux-mm
Cc: Ingo Molnar, Peter Zijlstra, Juri Lelli, Vincent Guittot,
Dietmar Eggemann, Steven Rostedt, Ben Segall, Mel Gorman,
Daniel Bristot de Oliveira, Christian Brauner,
Matthew Wilcox (Oracle), Vlastimil Babka, William Kucharski,
John Hubbard, Yunsheng Lin, Arnd Bergmann, Suren Baghdasaryan,
Chih-En Lin, Colin Cross, Feng Tang, Eric W. Biederman,
Mike Rapoport, Geert Uytterhoeven, Anshuman Khandual,
Aneesh Kumar K.V, Daniel Axtens, Jonathan Marek, Christophe Leroy,
Pasha Tatashin, Peter Xu, Andrea Arcangeli, Thomas Gleixner,
Andy Lutomirski, Sebastian Andrzej Siewior, Fenghua Yu,
David Hildenbrand, linux-kernel, Kaiyang Zhao, Huichun Feng,
Jim Huang
The lifetime of COW PTE will handle by ownership and a reference count.
When the process wants to write the COW PTE, which reference count is 1,
it will reuse the COW PTE instead of copying then free.
Only the owner will update its RSS state and the record of page table
bytes allocation. So we need to handle when the non-owner process gets
the fallback COW PTE.
This commit prepares for the following implementation of the reference
count for COW PTE.
Signed-off-by: Chih-En Lin <shiyn.lin@gmail.com>
---
mm/memory.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 66 insertions(+)
diff --git a/mm/memory.c b/mm/memory.c
index 76e3af9639d9..dcb678cbb051 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -1000,6 +1000,34 @@ page_copy_prealloc(struct mm_struct *src_mm, struct vm_area_struct *vma,
return new_page;
}
+static inline void cow_pte_rss(struct mm_struct *mm, struct vm_area_struct *vma,
+ pmd_t *pmdp, unsigned long addr, unsigned long end, bool inc_dec)
+{
+ int rss[NR_MM_COUNTERS];
+ pte_t *orig_ptep, *ptep;
+ struct page *page;
+
+ init_rss_vec(rss);
+
+ ptep = pte_offset_map(pmdp, addr);
+ orig_ptep = ptep;
+ arch_enter_lazy_mmu_mode();
+ do {
+ if (pte_none(*ptep) || pte_special(*ptep))
+ continue;
+
+ page = vm_normal_page(vma, addr, *ptep);
+ if (page) {
+ if (inc_dec)
+ rss[mm_counter(page)]++;
+ else
+ rss[mm_counter(page)]--;
+ }
+ } while (ptep++, addr += PAGE_SIZE, addr != end);
+ arch_leave_lazy_mmu_mode();
+ add_mm_rss_vec(mm, rss);
+}
+
static int
copy_pte_range(struct vm_area_struct *dst_vma, struct vm_area_struct *src_vma,
pmd_t *dst_pmd, pmd_t *src_pmd, unsigned long addr,
@@ -4554,6 +4582,44 @@ static vm_fault_t wp_huge_pud(struct vm_fault *vmf, pud_t orig_pud)
return VM_FAULT_FALLBACK;
}
+/* COW PTE fallback to normal PTE:
+ * - two state here
+ * - After break child : [parent, rss=1, ref=1, write=NO , owner=parent]
+ * to [parent, rss=1, ref=1, write=YES, owner=NULL ]
+ * - After break parent: [child , rss=0, ref=1, write=NO , owner=NULL ]
+ * to [child , rss=1, ref=1, write=YES, owner=NULL ]
+ */
+void cow_pte_fallback(struct vm_area_struct *vma, pmd_t *pmd,
+ unsigned long addr)
+{
+ struct mm_struct *mm = vma->vm_mm;
+ unsigned long start, end;
+ pmd_t new;
+
+ BUG_ON(pmd_write(*pmd));
+
+ start = addr & PMD_MASK;
+ end = (addr + PMD_SIZE) & PMD_MASK;
+
+ /* If pmd is not owner, it needs to increase the rss.
+ * Since only the owner has the RSS state for the COW PTE.
+ */
+ if (!cow_pte_owner_is_same(pmd, pmd)) {
+ cow_pte_rss(mm, vma, pmd, start, end, true /* inc */);
+ mm_inc_nr_ptes(mm);
+ smp_wmb();
+ pmd_populate(mm, pmd, pmd_page(*pmd));
+ }
+
+ /* Reuse the pte page */
+ set_cow_pte_owner(pmd, NULL);
+ new = pmd_mkwrite(*pmd);
+ set_pmd_at(mm, addr, pmd, new);
+
+ BUG_ON(!pmd_write(*pmd));
+ BUG_ON(pmd_page(*pmd)->cow_pte_owner);
+}
+
/*
* These routines also need to handle stuff like marking pages dirty
* and/or accessed for architectures that don't do it in hardware (most
--
2.36.1
^ permalink raw reply related [flat|nested] 5+ messages in thread* Re: [RFC PATCH 4/6] mm: Add COW PTE fallback function
2022-05-19 18:31 ` [RFC PATCH 4/6] mm: Add COW PTE fallback function Chih-En Lin
@ 2022-05-20 0:20 ` kernel test robot
2022-05-20 14:21 ` Christophe Leroy
1 sibling, 0 replies; 5+ messages in thread
From: kernel test robot @ 2022-05-20 0:20 UTC (permalink / raw)
To: Chih-En Lin; +Cc: llvm, kbuild-all
Hi Chih-En,
[FYI, it's a private test report for your RFC patch.]
[auto build test ERROR on tip/sched/core]
[also build test ERROR on soc/for-next linus/master v5.18-rc7 next-20220519]
[cannot apply to akpm-mm/mm-everything]
[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]
url: https://github.com/intel-lab-lkp/linux/commits/Chih-En-Lin/Introduce-Copy-On-Write-to-Page-Table/20220520-023243
base: https://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git 734387ec2f9d77b00276042b1fa7c95f48ee879d
config: arm-shannon_defconfig (https://download.01.org/0day-ci/archive/20220520/202205200816.ZhOASVVs-lkp@intel.com/config)
compiler: clang version 15.0.0 (https://github.com/llvm/llvm-project e00cbbec06c08dc616a0d52a20f678b8fbd4e304)
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# install arm cross compiling tool for clang build
# apt-get install binutils-arm-linux-gnueabi
# https://github.com/intel-lab-lkp/linux/commit/e4e2e178c5a43b37925972bc0eab9976d41d35c7
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review Chih-En-Lin/Introduce-Copy-On-Write-to-Page-Table/20220520-023243
git checkout e4e2e178c5a43b37925972bc0eab9976d41d35c7
# save the config file
mkdir build_dir && cp config build_dir/.config
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=arm SHELL=/bin/bash
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
All errors (new ones prefixed by >>):
mm/memory.c:1007:9: warning: variable 'orig_ptep' set but not used [-Wunused-but-set-variable]
pte_t *orig_ptep, *ptep;
^
>> mm/memory.c:4616:8: error: call to undeclared function 'pmd_mkwrite'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
new = pmd_mkwrite(*pmd);
^
>> mm/memory.c:4617:2: error: call to undeclared function 'set_pmd_at'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
set_pmd_at(mm, addr, pmd, new);
^
mm/memory.c:4617:2: note: did you mean 'set_pte_at'?
arch/arm/include/asm/pgtable.h:225:6: note: 'set_pte_at' declared here
void set_pte_at(struct mm_struct *mm, unsigned long addr,
^
mm/memory.c:4592:6: warning: no previous prototype for function 'cow_pte_fallback' [-Wmissing-prototypes]
void cow_pte_fallback(struct vm_area_struct *vma, pmd_t *pmd,
^
mm/memory.c:4592:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
void cow_pte_fallback(struct vm_area_struct *vma, pmd_t *pmd,
^
static
2 warnings and 2 errors generated.
vim +/pmd_mkwrite +4616 mm/memory.c
4584
4585 /* COW PTE fallback to normal PTE:
4586 * - two state here
4587 * - After break child : [parent, rss=1, ref=1, write=NO , owner=parent]
4588 * to [parent, rss=1, ref=1, write=YES, owner=NULL ]
4589 * - After break parent: [child , rss=0, ref=1, write=NO , owner=NULL ]
4590 * to [child , rss=1, ref=1, write=YES, owner=NULL ]
4591 */
4592 void cow_pte_fallback(struct vm_area_struct *vma, pmd_t *pmd,
4593 unsigned long addr)
4594 {
4595 struct mm_struct *mm = vma->vm_mm;
4596 unsigned long start, end;
4597 pmd_t new;
4598
4599 BUG_ON(pmd_write(*pmd));
4600
4601 start = addr & PMD_MASK;
4602 end = (addr + PMD_SIZE) & PMD_MASK;
4603
4604 /* If pmd is not owner, it needs to increase the rss.
4605 * Since only the owner has the RSS state for the COW PTE.
4606 */
4607 if (!cow_pte_owner_is_same(pmd, pmd)) {
4608 cow_pte_rss(mm, vma, pmd, start, end, true /* inc */);
4609 mm_inc_nr_ptes(mm);
4610 smp_wmb();
4611 pmd_populate(mm, pmd, pmd_page(*pmd));
4612 }
4613
4614 /* Reuse the pte page */
4615 set_cow_pte_owner(pmd, NULL);
> 4616 new = pmd_mkwrite(*pmd);
> 4617 set_pmd_at(mm, addr, pmd, new);
4618
4619 BUG_ON(!pmd_write(*pmd));
4620 BUG_ON(pmd_page(*pmd)->cow_pte_owner);
4621 }
4622
--
0-DAY CI Kernel Test Service
https://01.org/lkp
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: [RFC PATCH 4/6] mm: Add COW PTE fallback function
2022-05-19 18:31 ` [RFC PATCH 4/6] mm: Add COW PTE fallback function Chih-En Lin
2022-05-20 0:20 ` kernel test robot
@ 2022-05-20 14:21 ` Christophe Leroy
2022-05-21 4:15 ` Chih-En Lin
1 sibling, 1 reply; 5+ messages in thread
From: Christophe Leroy @ 2022-05-20 14:21 UTC (permalink / raw)
To: Chih-En Lin, Andrew Morton, linux-mm@kvack.org
Cc: Ingo Molnar, Peter Zijlstra, Juri Lelli, Vincent Guittot,
Dietmar Eggemann, Steven Rostedt, Ben Segall, Mel Gorman,
Daniel Bristot de Oliveira, Christian Brauner,
Matthew Wilcox (Oracle), Vlastimil Babka, William Kucharski,
John Hubbard, Yunsheng Lin, Arnd Bergmann, Suren Baghdasaryan,
Colin Cross, Feng Tang, Eric W. Biederman, Mike Rapoport,
Geert Uytterhoeven, Anshuman Khandual, Aneesh Kumar K.V,
Daniel Axtens, Jonathan Marek, Pasha Tatashin, Peter Xu,
Andrea Arcangeli, Thomas Gleixner, Andy Lutomirski,
Sebastian Andrzej Siewior, Fenghua Yu, David Hildenbrand,
linux-kernel@vger.kernel.org, Kaiyang Zhao, Huichun Feng,
Jim Huang
Le 19/05/2022 à 20:31, Chih-En Lin a écrit :
> The lifetime of COW PTE will handle by ownership and a reference count.
> When the process wants to write the COW PTE, which reference count is 1,
> it will reuse the COW PTE instead of copying then free.
>
> Only the owner will update its RSS state and the record of page table
> bytes allocation. So we need to handle when the non-owner process gets
> the fallback COW PTE.
>
> This commit prepares for the following implementation of the reference
> count for COW PTE.
>
> Signed-off-by: Chih-En Lin <shiyn.lin@gmail.com>
> ---
> mm/memory.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 66 insertions(+)
>
> diff --git a/mm/memory.c b/mm/memory.c
> index 76e3af9639d9..dcb678cbb051 100644
> --- a/mm/memory.c
> +++ b/mm/memory.c
> @@ -1000,6 +1000,34 @@ page_copy_prealloc(struct mm_struct *src_mm, struct vm_area_struct *vma,
> return new_page;
> }
>
> +static inline void cow_pte_rss(struct mm_struct *mm, struct vm_area_struct *vma,
> + pmd_t *pmdp, unsigned long addr, unsigned long end, bool inc_dec)
Parenthesis alignment is not correct.
You should run 'scripts/checkpatch.pl --strict' on you patch.
> +{
> + int rss[NR_MM_COUNTERS];
> + pte_t *orig_ptep, *ptep;
> + struct page *page;
> +
> + init_rss_vec(rss);
> +
> + ptep = pte_offset_map(pmdp, addr);
> + orig_ptep = ptep;
> + arch_enter_lazy_mmu_mode();
> + do {
> + if (pte_none(*ptep) || pte_special(*ptep))
> + continue;
> +
> + page = vm_normal_page(vma, addr, *ptep);
> + if (page) {
> + if (inc_dec)
> + rss[mm_counter(page)]++;
> + else
> + rss[mm_counter(page)]--;
> + }
> + } while (ptep++, addr += PAGE_SIZE, addr != end);
> + arch_leave_lazy_mmu_mode();
> + add_mm_rss_vec(mm, rss);
> +}
> +
> static int
> copy_pte_range(struct vm_area_struct *dst_vma, struct vm_area_struct *src_vma,
> pmd_t *dst_pmd, pmd_t *src_pmd, unsigned long addr,
> @@ -4554,6 +4582,44 @@ static vm_fault_t wp_huge_pud(struct vm_fault *vmf, pud_t orig_pud)
> return VM_FAULT_FALLBACK;
> }
>
> +/* COW PTE fallback to normal PTE:
> + * - two state here
> + * - After break child : [parent, rss=1, ref=1, write=NO , owner=parent]
> + * to [parent, rss=1, ref=1, write=YES, owner=NULL ]
> + * - After break parent: [child , rss=0, ref=1, write=NO , owner=NULL ]
> + * to [child , rss=1, ref=1, write=YES, owner=NULL ]
> + */
> +void cow_pte_fallback(struct vm_area_struct *vma, pmd_t *pmd,
> + unsigned long addr)
There should be a prototype in a header somewhere for a non static function.
You are encouraged to run 'make mm/memory.o C=2' to check sparse reports.
> +{
> + struct mm_struct *mm = vma->vm_mm;
> + unsigned long start, end;
> + pmd_t new;
> +
> + BUG_ON(pmd_write(*pmd));
You seem to add a lot of BUG_ONs(). Are they really necessary ? See
https://docs.kernel.org/process/deprecated.html?highlight=bug_on#bug-and-bug-on
You may also use VM_BUG_ON().
> +
> + start = addr & PMD_MASK;
> + end = (addr + PMD_SIZE) & PMD_MASK;
> +
> + /* If pmd is not owner, it needs to increase the rss.
> + * Since only the owner has the RSS state for the COW PTE.
> + */
> + if (!cow_pte_owner_is_same(pmd, pmd)) {
> + cow_pte_rss(mm, vma, pmd, start, end, true /* inc */);
> + mm_inc_nr_ptes(mm);
> + smp_wmb();
> + pmd_populate(mm, pmd, pmd_page(*pmd));
> + }
> +
> + /* Reuse the pte page */
> + set_cow_pte_owner(pmd, NULL);
> + new = pmd_mkwrite(*pmd);
> + set_pmd_at(mm, addr, pmd, new);
> +
> + BUG_ON(!pmd_write(*pmd));
> + BUG_ON(pmd_page(*pmd)->cow_pte_owner);
> +}
> +
> /*
> * These routines also need to handle stuff like marking pages dirty
> * and/or accessed for architectures that don't do it in hardware (most
> --
> 2.36.1
>
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: [RFC PATCH 4/6] mm: Add COW PTE fallback function
2022-05-20 14:21 ` Christophe Leroy
@ 2022-05-21 4:15 ` Chih-En Lin
0 siblings, 0 replies; 5+ messages in thread
From: Chih-En Lin @ 2022-05-21 4:15 UTC (permalink / raw)
To: Christophe Leroy
Cc: Andrew Morton, linux-mm@kvack.org, Ingo Molnar, Peter Zijlstra,
Juri Lelli, Vincent Guittot, Dietmar Eggemann, Steven Rostedt,
Ben Segall, Mel Gorman, Daniel Bristot de Oliveira,
Christian Brauner, Matthew Wilcox (Oracle), Vlastimil Babka,
William Kucharski, John Hubbard, Yunsheng Lin, Arnd Bergmann,
Suren Baghdasaryan, Colin Cross, Feng Tang, Eric W. Biederman,
Mike Rapoport, Geert Uytterhoeven, Anshuman Khandual,
Aneesh Kumar K.V, Daniel Axtens, Jonathan Marek, Pasha Tatashin,
Peter Xu, Andrea Arcangeli, Thomas Gleixner, Andy Lutomirski,
Sebastian Andrzej Siewior, Fenghua Yu, David Hildenbrand,
linux-kernel@vger.kernel.org, Kaiyang Zhao, Huichun Feng,
Jim Huang
On Fri, May 20, 2022 at 02:21:54PM +0000, Christophe Leroy wrote:
> > +/* COW PTE fallback to normal PTE:
> > + * - two state here
> > + * - After break child : [parent, rss=1, ref=1, write=NO , owner=parent]
> > + * to [parent, rss=1, ref=1, write=YES, owner=NULL ]
> > + * - After break parent: [child , rss=0, ref=1, write=NO , owner=NULL ]
> > + * to [child , rss=1, ref=1, write=YES, owner=NULL ]
> > + */
> > +void cow_pte_fallback(struct vm_area_struct *vma, pmd_t *pmd,
> > + unsigned long addr)
>
> There should be a prototype in a header somewhere for a non static function.
>
> You are encouraged to run 'make mm/memory.o C=2' to check sparse reports.
>
I will do all the above checking before sending the next version.
> > +{
> > + struct mm_struct *mm = vma->vm_mm;
> > + unsigned long start, end;
> > + pmd_t new;
> > +
> > + BUG_ON(pmd_write(*pmd));
>
> You seem to add a lot of BUG_ONs(). Are they really necessary ? See
> https://docs.kernel.org/process/deprecated.html?highlight=bug_on#bug-and-bug-on
>
> You may also use VM_BUG_ON().
>
Sure.
I added BUG_ON() when doing the debug.
I will consider again which one is necessary.
And change to use VM_BUG_ON().
Thanks.
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2022-05-21 4:15 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-05-20 10:16 [RFC PATCH 4/6] mm: Add COW PTE fallback function kernel test robot
-- strict thread matches above, loose matches on Subject: below --
2022-05-19 18:31 [RFC PATCH 0/6] Introduce Copy-On-Write to Page Table Chih-En Lin
2022-05-19 18:31 ` [RFC PATCH 4/6] mm: Add COW PTE fallback function Chih-En Lin
2022-05-20 0:20 ` kernel test robot
2022-05-20 14:21 ` Christophe Leroy
2022-05-21 4:15 ` Chih-En Lin
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.