Bug 121306
| Summary: | fork doesn't handle copy-on-write correctly | ||||||
|---|---|---|---|---|---|---|---|
| Product: | Red Hat Enterprise Linux 3 | Reporter: | Sebastien BLAISOT <sblaisot> | ||||
| Component: | kernel | Assignee: | Arjan van de Ven <arjanv> | ||||
| Status: | CLOSED NOTABUG | QA Contact: | Brian Brock <bbrock> | ||||
| Severity: | high | Docs Contact: | |||||
| Priority: | medium | ||||||
| Version: | 3.0 | CC: | petrides, riel | ||||
| Target Milestone: | --- | ||||||
| Target Release: | --- | ||||||
| Hardware: | i686 | ||||||
| OS: | Linux | ||||||
| Whiteboard: | |||||||
| Fixed In Version: | Doc Type: | Bug Fix | |||||
| Doc Text: | Story Points: | --- | |||||
| Clone Of: | Environment: | ||||||
| Last Closed: | 2004-04-20 11:45:07 UTC | Type: | --- | ||||
| Regression: | --- | Mount Type: | --- | ||||
| Documentation: | --- | CRM: | |||||
| Verified Versions: | Category: | --- | |||||
| oVirt Team: | --- | RHEL 7.3 requirements from Atomic Host: | |||||
| Cloudforms Team: | --- | Target Upstream Version: | |||||
| Embargoed: | |||||||
| Attachments: |
|
||||||
Created attachment 99555 [details]
test program to demonstrate the problem
this is the test program I used.
it creates a 32MB memory buffer, then forks.
the child process write in all the buffer 1MB at a time.
after each writes, it shows the content of /proc/<pid>/statm
interesting field is the third one : Number of pages that are shared
opps, made a mistake withe the compilation command. this is gcc -Wall -o testfork7 testfork7.c The shared pages statistic is reported so low because they are measured differently, not because any deficiency in COW. COW still works fine. Older kernels used to walk all the page table entries to count how many of the pages were shared with other processes. This was too inefficient. Think of a server with a thousand Oracle processes, each having 2.7GB of virtual memory. Every screen update in top(1) would end up scanning the ptes for 2.7TB of memory! Because of this, the newer kernels no longer look at page table entries. Instead, they count entire MAP_SHARED VMAs as shared memory. They no longer count the still shared COW pages in anonymous memory, since it is way too inefficient to count those. |
From Bugzilla Helper: User-Agent: Mozilla/5.0 (X11; U; Linux i686; fr-FR; rv:1.6) Gecko/20040116 Description of problem: when forking (calling fork()), the data of the program should be shared between the two precesses using a copy-on-write mechanism, as stated in the fork(2) man page. * This is NOT the case with RedHat Enterprise Linux 2.1 or 3.0 (event without errata applied) nor with RedHat 9 * This is OK with RedHat Linux 7.2, 7.3 and 8.0 without arrata applied, but not anymore with these versions when KERNEL errata applied * This is correct with Fedora-core 1, event with kernel errata applied, and with other distributions too. Version-Release number of selected component (if applicable): How reproducible: Always Steps to Reproduce: 1. compile testfork7.c (g++ -Wall -o testfork7 testfork7.c) 2. launch it (./testfork7) 3. observe that the third column (shared pages) is very low, even just after the fork Actual Results: Number of pages that are shared starts very low (no share except code) and doesn't decrease [root@testRHEL tmp]# ./testfork7 Signification des colones : 1. Total program size, in kilobytes 2. Size of memory portions, in kilobytes 3. Number of pages that are shared 4. Number of pages that are code 5. Number of pages of data/stack 6. Number of library pages 7. Number of dirty pages 8330 8330 113 2 0 8328 3 8330 8330 113 2 0 8328 1 8330 8330 113 2 0 8328 1 8330 8330 113 2 0 8328 1 8330 8330 113 2 0 8328 1 8330 8330 113 2 0 8328 1 8330 8330 113 2 0 8328 1 8330 8330 113 2 0 8328 1 8330 8330 113 2 0 8328 1 8330 8330 113 2 0 8328 1 8330 8330 113 2 0 8328 1 8330 8330 113 2 0 8328 1 8330 8330 113 2 0 8328 1 8330 8330 113 2 0 8328 1 8330 8330 113 2 0 8328 1 8330 8330 113 2 0 8328 1 8330 8330 113 2 0 8328 1 8330 8330 113 2 0 8328 1 8330 8330 113 2 0 8328 1 8330 8330 113 2 0 8328 1 8330 8330 113 2 0 8328 1 8330 8330 113 2 0 8328 1 8330 8330 113 2 0 8328 1 8330 8330 113 2 0 8328 1 8330 8330 113 2 0 8328 1 8330 8330 113 2 0 8328 1 8330 8330 113 2 0 8328 1 8330 8330 113 2 0 8328 1 8330 8330 113 2 0 8328 1 8330 8330 113 2 0 8328 1 8330 8330 113 2 0 8328 1 8330 8330 113 2 0 8328 1 8330 8330 113 2 0 8328 1 8330 8330 113 2 0 8328 1 [root@testRHEL tmp]# Expected Results: results below are from RH linux 7.2 without errata applied. Number of pages that are shared starts high (all data shared) and decreases as the child process writes in them. copy-on-write mechanism works as expected [root@test72 tmp]# ./testfork7 Signification des colones : 1. Total program size, in kilobytes 2. Size of memory portions, in kilobytes 3. Number of pages that are shared 4. Number of pages that are code 5. Number of pages of data/stack 6. Number of library pages 7. Number of dirty pages 8284 8284 77 2 0 8282 8207 8284 8284 8280 2 0 8282 8207 8284 8284 8023 2 0 8282 8207 8284 8284 7767 2 0 8282 8207 8284 8284 7511 2 0 8282 8207 8284 8284 7255 2 0 8282 8207 8284 8284 6999 2 0 8282 8207 8284 8284 6743 2 0 8282 8207 8284 8284 6487 2 0 8282 8207 8284 8284 6231 2 0 8282 8207 8284 8284 5975 2 0 8282 8207 8284 8284 5719 2 0 8282 8207 8284 8284 5463 2 0 8282 8207 8284 8284 5207 2 0 8282 8207 8284 8284 4951 2 0 8282 8207 8284 8284 4695 2 0 8282 8207 8284 8284 4439 2 0 8282 8207 8284 7833 3732 2 0 7831 7756 8284 8089 3732 2 0 8087 8012 8284 4471 87 2 0 4469 4394 8284 4625 87 2 0 4623 4548 8284 4881 87 2 0 4879 4804 8225 4893 21 2 0 4891 4875 8225 5149 21 2 0 5147 5131 8225 5405 21 2 0 5403 5387 8225 5661 21 2 0 5659 5643 8225 5874 21 2 0 5872 5856 8225 5764 21 2 0 5762 5746 8225 5489 21 2 0 5487 5471 8225 5247 21 2 0 5245 5229 8225 5020 21 2 0 5018 5002 8225 4414 21 2 0 4412 4396 8225 4670 21 2 0 4668 4652 8225 4926 21 2 0 4924 4908 [root@test72 tmp]#