Hi, the attached patch allows Apache2::SizeLimit to use the new /proc/PID/smaps instead of /proc/PID/statm. This takes into account copy-on-write pages when counting shared memory.
The patch looks if /proc/PID/smaps exists and if Linux::Smaps is installed. If not it uses the old /proc/PID/statm. Hence, it is compatible with old linuxes. /proc/PID/smaps exists by now in the mm-series of the linux kernel. I hope the patch will take its way into the vanilla kernel in the not so distant future. The following handler shows the effect: <Perl> require Apache2::SizeLimit; package X; use strict; use Apache2::RequestRec (); use Apache2::RequestIO (); use Apache2::Const -compile=>qw(OK); my $x="a"x(1024*1024); sub handler { my $r=shift; my $args=$r->args; my ($size, $shared)=$Apache2::SizeLimit::HOW_BIG_IS_IT->(); $x=~tr/a/b/ if( $args ); my ($size2, $shared2)=$Apache2::SizeLimit::HOW_BIG_IS_IT->(); $r->content_type('text/plain'); $r->print("1: size=$size shared=$shared\n"); $r->print("2: size=$size2 shared=$shared2\n"); return Apache2::Const::OK; } </Perl> <Location /X> SetHandler modperl PerlResponseHandler X </Location> The parent apache allocates a megabyte for the string in $x. The tr-command then overwrites all "a" with "b" if the handler is called with an argument. This write is done in place, thus, the process size doesn't change. Only $x is not shared anymore by means of COW between the parent and the child. When Smaps are available curl shows: [EMAIL PROTECTED]:~/work/mp2> curl http://localhost:8181/X?1 1: size=13452 shared=7456 2: size=13452 shared=6432 The shared memory has lost 1024 kB. Without Smaps it says: [EMAIL PROTECTED]:~/work/mp2> curl http://localhost:8181/X?1 1: size=13052 shared=3628 2: size=13052 shared=3636 One can see the kernel lies about the shared memory. It simply doesn't count COW pages as shared. Both experiments are done with a Suse9.3, apache 2.0.54, mod_perl 2.0.1 and Linux::Smaps 0.01. The first one uses linux 2.6.13-rc4-mm1 (with a little patch that will go into the next mm-version, see http://marc.theaimsgroup.com/?l=linux-kernel&m=112335328222533&w=2), the second with Suses default kernel (2.6.11.4-20a-default). Torsten
--- mod_perl-2.0.1/lib/Apache2/SizeLimit.pm~ 2005-04-26 20:58:44.000000000 +0200 +++ mod_perl-2.0.1/lib/Apache2/SizeLimit.pm 2005-08-07 17:56:00.691361040 +0200 @@ -56,7 +56,11 @@ } elsif (LINUX) { - $HOW_BIG_IS_IT = \&linux_size_check; + if ( eval { require Linux::Smaps } and Linux::Smaps->new($$) ) { + $HOW_BIG_IS_IT = \&linux_smaps_size_check; + } else { + $HOW_BIG_IS_IT = \&linux_size_check; + } } elsif (BSD_LIKE) { @@ -85,6 +89,11 @@ } } +sub linux_smaps_size_check { + my $s=Linux::Smaps->new($$)->all; + return ($s->size, $s->shared_clean+$s->shared_dirty); +} + # return process size (in KB) sub linux_size_check { my($size, $resident, $share) = (0, 0, 0);
pgpQjVHJNzgee.pgp
Description: PGP signature