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
