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);

Attachment: pgpQjVHJNzgee.pgp
Description: PGP signature

Reply via email to