Bug 121306 - fork doesn't handle copy-on-write correctly
fork doesn't handle copy-on-write correctly
Status: CLOSED NOTABUG
Product: Red Hat Enterprise Linux 3
Classification: Red Hat
Component: kernel (Show other bugs)
3.0
i686 Linux
medium Severity high
: ---
: ---
Assigned To: Arjan van de Ven
Brian Brock
:
Depends On:
Blocks:
  Show dependency treegraph
 
Reported: 2004-04-20 06:10 EDT by Sebastien BLAISOT
Modified: 2007-11-30 17:07 EST (History)
2 users (show)

See Also:
Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed: 2004-04-20 07:45:07 EDT
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---


Attachments (Terms of Use)
test program to demonstrate the problem (1.39 KB, text/plain)
2004-04-20 06:12 EDT, Sebastien BLAISOT
no flags Details

  None (edit)
Description Sebastien BLAISOT 2004-04-20 06:10:21 EDT
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]#
Comment 1 Sebastien BLAISOT 2004-04-20 06:12:59 EDT
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
Comment 2 Sebastien BLAISOT 2004-04-20 06:25:00 EDT
opps, made a mistake withe the compilation command.
this is 
gcc -Wall -o testfork7 testfork7.c
Comment 3 Rik van Riel 2004-04-20 07:45:07 EDT
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.

Note You need to log in before you can comment on or make changes to this bug.